Skip to content

Commit 985b902

Browse files
author
wslaghekke
committed
Document that reserved scopes should not be included in scopes field
Update gradle Fallback to interactive authentication if silent auth fails on android, iOS already does this
1 parent 53a43b9 commit 985b902

File tree

9 files changed

+132
-112
lines changed

9 files changed

+132
-112
lines changed
-17.6 KB
Binary file not shown.
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-all.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
44
networkTimeout=10000
5+
validateDistributionUrl=true
56
zipStoreBase=GRADLE_USER_HOME
67
zipStorePath=wrapper/dists

android/gradlew

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
# See the License for the specific language governing permissions and
1616
# limitations under the License.
1717
#
18+
# SPDX-License-Identifier: Apache-2.0
19+
#
1820

1921
##############################################################################
2022
#
@@ -55,7 +57,7 @@
5557
# Darwin, MinGW, and NonStop.
5658
#
5759
# (3) This script is generated from the Groovy template
58-
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
60+
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
5961
# within the Gradle project.
6062
#
6163
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +82,12 @@ do
8082
esac
8183
done
8284

83-
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
84-
85-
APP_NAME="Gradle"
85+
# This is normally unused
86+
# shellcheck disable=SC2034
8687
APP_BASE_NAME=${0##*/}
87-
88-
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
89-
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
88+
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
89+
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
90+
' "$PWD" ) || exit
9091

9192
# Use the maximum available, or set MAX_FD != -1 to use that value.
9293
MAX_FD=maximum
@@ -127,26 +128,35 @@ if [ -n "$JAVA_HOME" ] ; then
127128
fi
128129
if [ ! -x "$JAVACMD" ] ; then
129130
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
131+
130132
Please set the JAVA_HOME variable in your environment to match the
131133
location of your Java installation."
132134
fi
133135
else
134136
JAVACMD=java
135-
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137+
if ! command -v java >/dev/null 2>&1
138+
then
139+
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
140+
136141
Please set the JAVA_HOME variable in your environment to match the
137142
location of your Java installation."
143+
fi
138144
fi
139145

140146
# Increase the maximum file descriptors if we can.
141147
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
142148
case $MAX_FD in #(
143149
max*)
150+
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
151+
# shellcheck disable=SC2039,SC3045
144152
MAX_FD=$( ulimit -H -n ) ||
145153
warn "Could not query maximum file descriptor limit"
146154
esac
147155
case $MAX_FD in #(
148156
'' | soft) :;; #(
149157
*)
158+
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
159+
# shellcheck disable=SC2039,SC3045
150160
ulimit -n "$MAX_FD" ||
151161
warn "Could not set maximum file descriptor limit to $MAX_FD"
152162
esac
@@ -191,18 +201,28 @@ if "$cygwin" || "$msys" ; then
191201
done
192202
fi
193203

194-
# Collect all arguments for the java command;
195-
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
196-
# shell script including quotes and variable substitutions, so put them in
197-
# double quotes to make sure that they get re-expanded; and
198-
# * put everything else in single quotes, so that it's not re-expanded.
204+
205+
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
206+
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
207+
208+
# Collect all arguments for the java command:
209+
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
210+
# and any embedded shellness will be escaped.
211+
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
212+
# treated as '${Hostname}' itself on the command line.
199213

200214
set -- \
201215
"-Dorg.gradle.appname=$APP_BASE_NAME" \
202216
-classpath "$CLASSPATH" \
203217
org.gradle.wrapper.GradleWrapperMain \
204218
"$@"
205219

220+
# Stop when "xargs" is not available.
221+
if ! command -v xargs >/dev/null 2>&1
222+
then
223+
die "xargs is not available"
224+
fi
225+
206226
# Use "xargs" to parse quoted args.
207227
#
208228
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.

android/gradlew.bat

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
@rem See the License for the specific language governing permissions and
1414
@rem limitations under the License.
1515
@rem
16+
@rem SPDX-License-Identifier: Apache-2.0
17+
@rem
1618

17-
@if "%DEBUG%" == "" @echo off
19+
@if "%DEBUG%"=="" @echo off
1820
@rem ##########################################################################
1921
@rem
2022
@rem Gradle startup script for Windows
@@ -25,10 +27,14 @@
2527
if "%OS%"=="Windows_NT" setlocal
2628

2729
set DIRNAME=%~dp0
28-
if "%DIRNAME%" == "" set DIRNAME=.
30+
if "%DIRNAME%"=="" set DIRNAME=.
31+
@rem This is normally unused
2932
set APP_BASE_NAME=%~n0
3033
set APP_HOME=%DIRNAME%
3134

35+
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
36+
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37+
3238
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
3339
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
3440

@@ -37,62 +43,50 @@ if defined JAVA_HOME goto findJavaFromJavaHome
3743

3844
set JAVA_EXE=java.exe
3945
%JAVA_EXE% -version >NUL 2>&1
40-
if "%ERRORLEVEL%" == "0" goto init
46+
if %ERRORLEVEL% equ 0 goto execute
4147

42-
echo.
43-
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
44-
echo.
45-
echo Please set the JAVA_HOME variable in your environment to match the
46-
echo location of your Java installation.
48+
echo. 1>&2
49+
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50+
echo. 1>&2
51+
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52+
echo location of your Java installation. 1>&2
4753

4854
goto fail
4955

5056
:findJavaFromJavaHome
5157
set JAVA_HOME=%JAVA_HOME:"=%
5258
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
5359

54-
if exist "%JAVA_EXE%" goto init
60+
if exist "%JAVA_EXE%" goto execute
5561

56-
echo.
57-
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
58-
echo.
59-
echo Please set the JAVA_HOME variable in your environment to match the
60-
echo location of your Java installation.
62+
echo. 1>&2
63+
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64+
echo. 1>&2
65+
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66+
echo location of your Java installation. 1>&2
6167

6268
goto fail
6369

64-
:init
65-
@rem Get command-line arguments, handling Windows variants
66-
67-
if not "%OS%" == "Windows_NT" goto win9xME_args
68-
69-
:win9xME_args
70-
@rem Slurp the command line arguments.
71-
set CMD_LINE_ARGS=
72-
set _SKIP=2
73-
74-
:win9xME_args_slurp
75-
if "x%~1" == "x" goto execute
76-
77-
set CMD_LINE_ARGS=%*
78-
7970
:execute
8071
@rem Setup the command line
8172

8273
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
8374

75+
8476
@rem Execute Gradle
85-
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
77+
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
8678

8779
:end
8880
@rem End local scope for the variables with windows NT shell
89-
if "%ERRORLEVEL%"=="0" goto mainEnd
81+
if %ERRORLEVEL% equ 0 goto mainEnd
9082

9183
:fail
9284
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
9385
rem the _cmd.exe /c_ return code!
94-
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
95-
exit /b 1
86+
set EXIT_CODE=%ERRORLEVEL%
87+
if %EXIT_CODE% equ 0 set EXIT_CODE=1
88+
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89+
exit /b %EXIT_CODE%
9690

9791
:mainEnd
9892
if "%OS%"=="Windows_NT" endlocal

android/settings.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
rootProject.name = "capacitor-plugin-msauth-android"
2+
13
include ':capacitor-android'
24
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')

android/src/main/java/nl/recognize/msauthplugin/MsAuthPlugin.java

Lines changed: 62 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import com.getcapacitor.annotation.Permission;
1212
import com.microsoft.identity.client.*;
1313
import com.microsoft.identity.client.exception.MsalException;
14+
import com.microsoft.identity.client.exception.MsalUiRequiredException;
15+
1416
import java.io.File;
1517
import java.io.FileWriter;
1618
import java.io.IOException;
@@ -113,76 +115,76 @@ protected String getAuthorityUrl(ISingleAccountPublicClientApplication context)
113115
return context.getConfiguration().getDefaultAuthority().getAuthorityURL().toString();
114116
}
115117

116-
private void acquireTokenInteractively(
117-
ISingleAccountPublicClientApplication context,
118-
List<String> scopes,
119-
final TokenResultCallback callback
120-
) {
121-
AcquireTokenParameters.Builder params = new AcquireTokenParameters.Builder()
122-
.startAuthorizationFromActivity(this.getActivity())
123-
.withScopes(scopes)
124-
.withPrompt(Prompt.SELECT_ACCOUNT)
125-
.withCallback(
126-
new AuthenticationCallback() {
127-
@Override
128-
public void onCancel() {
129-
Logger.info("Login cancelled");
130-
callback.tokenReceived(null);
131-
}
118+
private void acquireToken(ISingleAccountPublicClientApplication context, List<String> scopes, final TokenResultCallback callback)
119+
throws MsalException, InterruptedException {
120+
String authority = getAuthorityUrl(context);
132121

133-
@Override
134-
public void onSuccess(IAuthenticationResult authenticationResult) {
135-
TokenResult tokenResult = new TokenResult();
122+
ICurrentAccountResult result = context.getCurrentAccount();
123+
if (result.getCurrentAccount() != null) {
124+
try {
125+
Logger.info("Starting silent login flow");
126+
AcquireTokenSilentParameters.Builder builder = new AcquireTokenSilentParameters.Builder()
127+
.withScopes(scopes)
128+
.fromAuthority(authority)
129+
.forAccount(result.getCurrentAccount());
136130

137-
IAccount account = authenticationResult.getAccount();
138-
tokenResult.setAccessToken(authenticationResult.getAccessToken());
139-
tokenResult.setIdToken(account.getIdToken());
140-
tokenResult.setScopes(authenticationResult.getScope());
131+
AcquireTokenSilentParameters parameters = builder.build();
132+
IAuthenticationResult silentAuthResult = context.acquireTokenSilent(parameters);
133+
IAccount account = silentAuthResult.getAccount();
141134

142-
callback.tokenReceived(tokenResult);
143-
}
135+
TokenResult tokenResult = new TokenResult();
136+
tokenResult.setAccessToken(silentAuthResult.getAccessToken());
137+
tokenResult.setIdToken(account.getIdToken());
138+
tokenResult.setScopes(silentAuthResult.getScope());
144139

145-
@Override
146-
public void onError(MsalException ex) {
147-
Logger.error("Unable to acquire token interactively", ex);
148-
callback.tokenReceived(null);
149-
}
150-
}
151-
);
152-
153-
context.acquireToken(params.build());
154-
}
140+
callback.tokenReceived(tokenResult);
155141

156-
private void acquireToken(ISingleAccountPublicClientApplication context, List<String> scopes, final TokenResultCallback callback)
157-
throws MsalException, InterruptedException {
158-
String authority = getAuthorityUrl(context);
142+
return;
143+
} catch (MsalUiRequiredException ex) {
144+
Logger.error("Silent login failed", ex);
145+
}
146+
}
159147

160-
final ICurrentAccountResult ca;
161-
if ((ca = context.getCurrentAccount()) != null && ca.getCurrentAccount() == null) {
162-
Logger.info("Starting interactive login flow");
163-
this.acquireTokenInteractively(context, scopes, callback);
164-
} else {
165-
Logger.info("Starting silent login flow");
166-
AcquireTokenSilentParameters.Builder builder = new AcquireTokenSilentParameters.Builder()
148+
Logger.info("Starting interactive login flow");
149+
AcquireTokenParameters.Builder params = new AcquireTokenParameters.Builder()
150+
.startAuthorizationFromActivity(this.getActivity())
167151
.withScopes(scopes)
168-
.fromAuthority(authority);
169-
170-
if (ca != null && ca.getCurrentAccount() != null) {
171-
Logger.info("Silent login flow for current account");
172-
builder = builder.forAccount(ca.getCurrentAccount());
173-
}
152+
.withPrompt(Prompt.SELECT_ACCOUNT)
153+
.withCallback(
154+
new AuthenticationCallback() {
155+
@Override
156+
public void onCancel() {
157+
Logger.info("Login cancelled");
158+
callback.tokenReceived(null);
159+
}
160+
161+
@Override
162+
public void onSuccess(IAuthenticationResult authenticationResult) {
163+
TokenResult tokenResult = new TokenResult();
164+
165+
IAccount account = authenticationResult.getAccount();
166+
tokenResult.setAccessToken(authenticationResult.getAccessToken());
167+
tokenResult.setIdToken(account.getIdToken());
168+
tokenResult.setScopes(authenticationResult.getScope());
169+
170+
callback.tokenReceived(tokenResult);
171+
}
172+
173+
@Override
174+
public void onError(MsalException ex) {
175+
Logger.error("Unable to acquire token interactively", ex);
176+
callback.tokenReceived(null);
177+
}
178+
}
179+
);
174180

175-
AcquireTokenSilentParameters parameters = builder.build();
176-
IAuthenticationResult silentAuthResult = context.acquireTokenSilent(parameters);
177-
IAccount account = silentAuthResult.getAccount();
181+
if (result.getCurrentAccount() != null) {
182+
// Set loginHint otherwise MSAL throws an exception because of mismatched account
183+
params.withLoginHint(result.getCurrentAccount().getUsername());
184+
}
178185

179-
TokenResult tokenResult = new TokenResult();
180-
tokenResult.setAccessToken(silentAuthResult.getAccessToken());
181-
tokenResult.setIdToken(account.getIdToken());
182-
tokenResult.setScopes(silentAuthResult.getScope());
186+
context.acquireToken(params.build());
183187

184-
callback.tokenReceived(tokenResult);
185-
}
186188
}
187189

188190
private ISingleAccountPublicClientApplication createContextFromPluginCall(PluginCall call)

0 commit comments

Comments
 (0)