Skip to content

Commit 916894a

Browse files
[Breaking Change] Add allowedAuthenticatorsOn{Enable,Authenticate}
1 parent 0a29e35 commit 916894a

File tree

4 files changed

+54
-21
lines changed

4 files changed

+54
-21
lines changed

packages/authgear-capacitor/android/src/main/java/com/authgear/capacitor/Authgear.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -237,19 +237,19 @@ JSONObject getDeviceInfo(Context ctx) throws Exception {
237237
return rootMap;
238238
}
239239

240-
int checkBiometricSupported(Context ctx, int flags) throws Exception {
240+
int checkBiometricSupported(Context ctx, int allowedAuthenticatorsOnEnableFlags, int allowedAuthenticatorsOnAuthenticateFlags) throws Exception {
241241
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
242242
throw this.makeBiometricMinimumAPILevelException();
243243
}
244244

245245
BiometricManager manager = BiometricManager.from(ctx);
246-
int result = manager.canAuthenticate(flags);
246+
int result = manager.canAuthenticate(allowedAuthenticatorsOnEnableFlags);
247247

248248
if (result == BiometricManager.BIOMETRIC_SUCCESS) {
249249
// Further test if the key pair generator can be initialized.
250250
// https://issuetracker.google.com/issues/147374428#comment9
251251
try {
252-
this.createKeyPairGenerator(this.makeGenerateKeyPairSpec("__test__", true, flags, true));
252+
this.createKeyPairGenerator(this.makeGenerateKeyPairSpec("__test__", true, allowedAuthenticatorsOnAuthenticateFlags, true));
253253
} catch (Exception e) {
254254
// This branch is reachable only when there is a weak face and no strong fingerprints.
255255
// So we treat this situation as BIOMETRIC_ERROR_NONE_ENROLLED.
@@ -266,11 +266,11 @@ void createBiometricPrivateKey(AppCompatActivity activity, BiometricOptions opti
266266
throw this.makeBiometricMinimumAPILevelException();
267267
}
268268

269-
BiometricPrompt.PromptInfo promptInfo = this.buildPromptInfo(options);
269+
BiometricPrompt.PromptInfo promptInfo = this.buildPromptInfo(options, options.allowedAuthenticatorsOnEnableFlags);
270270
KeyGenParameterSpec spec = this.makeGenerateKeyPairSpec(
271271
options.alias,
272272
true,
273-
this.authenticatorTypesToKeyProperties(options.flags),
273+
this.authenticatorTypesToKeyProperties(options.allowedAuthenticatorsOnAuthenticateFlags),
274274
options.invalidatedByBiometricEnrollment
275275
);
276276
KeyPair keyPair = this.createKeyPair(spec);
@@ -289,7 +289,7 @@ void signWithBiometricPrivateKey(AppCompatActivity activity, BiometricOptions op
289289
throw this.makeBiometricMinimumAPILevelException();
290290
}
291291

292-
BiometricPrompt.PromptInfo promptInfo = this.buildPromptInfo(options);
292+
BiometricPrompt.PromptInfo promptInfo = this.buildPromptInfo(options, options.allowedAuthenticatorsOnAuthenticateFlags);
293293
KeyPair keyPair = this.getPrivateKey(options.alias);
294294
this.signBiometricJWT(
295295
activity,
@@ -435,14 +435,15 @@ private KeyPair getPrivateKey(String alias) throws Exception {
435435
}
436436

437437
private BiometricPrompt.PromptInfo buildPromptInfo(
438-
BiometricOptions options
438+
BiometricOptions options,
439+
int flags
439440
) {
440441
BiometricPrompt.PromptInfo.Builder builder = new BiometricPrompt.PromptInfo.Builder();
441442
builder.setTitle(options.title);
442443
builder.setSubtitle(options.subtitle);
443444
builder.setDescription(options.description);
444-
builder.setAllowedAuthenticators(options.flags);
445-
if ((options.flags & BiometricManager.Authenticators.DEVICE_CREDENTIAL) == 0) {
445+
builder.setAllowedAuthenticators(flags);
446+
if ((flags & BiometricManager.Authenticators.DEVICE_CREDENTIAL) == 0) {
446447
builder.setNegativeButtonText(options.negativeButtonText);
447448
}
448449
return builder.build();

packages/authgear-capacitor/android/src/main/java/com/authgear/capacitor/AuthgearPlugin.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,14 @@ private void handleOpenAuthorizeURLWithWebView(PluginCall call, ActivityResult a
189189
@PluginMethod
190190
public void checkBiometricSupported(PluginCall call) {
191191
JSObject android = call.getObject("android");
192-
JSONArray constraint = this.jsObjectGetArray(android, "constraint");
193-
int flags = this.constraintToFlag(constraint);
192+
JSONArray allowedAuthenticatorsOnEnable = this.jsObjectGetArray(android, "allowedAuthenticatorsOnEnable");
193+
JSONArray allowedAuthenticatorsOnAuthenticate = this.jsObjectGetArray(android, "allowedAuthenticatorsOnAuthenticate");
194+
int allowedAuthenticatorsOnEnableFlags = this.constraintToFlag(allowedAuthenticatorsOnEnable);
195+
int allowedAuthenticatorsOnAuthenticateFlags = this.constraintToFlag(allowedAuthenticatorsOnAuthenticate);
194196

195197
Context ctx = this.getContext();
196198
try {
197-
int result = this.implementation.checkBiometricSupported(ctx, flags);
199+
int result = this.implementation.checkBiometricSupported(ctx, allowedAuthenticatorsOnEnableFlags, allowedAuthenticatorsOnAuthenticateFlags);
198200
if (result == BiometricManager.BIOMETRIC_SUCCESS) {
199201
call.resolve();
200202
} else {
@@ -214,19 +216,23 @@ public void createBiometricPrivateKey(PluginCall call) {
214216
String kid = call.getString("kid");
215217
String alias = "com.authgear.keys.biometric." + kid;
216218
JSObject android = call.getObject("android");
217-
JSONArray constraint = this.jsObjectGetArray(android, "constraint");
218219
boolean invalidatedByBiometricEnrollment = android.getBool("invalidatedByBiometricEnrollment");
219-
int flags = this.constraintToFlag(constraint);
220220
String title = android.getString("title");
221221
String subtitle = android.getString("subtitle");
222222
String description = android.getString("description");
223223
String negativeButtonText = android.getString("negativeButtonText");
224224

225+
JSONArray allowedAuthenticatorsOnEnable = this.jsObjectGetArray(android, "allowedAuthenticatorsOnEnable");
226+
JSONArray allowedAuthenticatorsOnAuthenticate = this.jsObjectGetArray(android, "allowedAuthenticatorsOnAuthenticate");
227+
int allowedAuthenticatorsOnEnableFlags = this.constraintToFlag(allowedAuthenticatorsOnEnable);
228+
int allowedAuthenticatorsOnAuthenticateFlags = this.constraintToFlag(allowedAuthenticatorsOnAuthenticate);
229+
225230
BiometricOptions options = new BiometricOptions();
226231
options.payload = payload;
227232
options.kid = kid;
228233
options.alias = alias;
229-
options.flags = flags;
234+
options.allowedAuthenticatorsOnEnableFlags = allowedAuthenticatorsOnEnableFlags;
235+
options.allowedAuthenticatorsOnAuthenticateFlags = allowedAuthenticatorsOnAuthenticateFlags;
230236
options.invalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
231237
options.title = title;
232238
options.subtitle = subtitle;
@@ -269,19 +275,23 @@ public void signWithBiometricPrivateKey(PluginCall call) {
269275
String kid = call.getString("kid");
270276
String alias = "com.authgear.keys.biometric." + kid;
271277
JSObject android = call.getObject("android");
272-
JSONArray constraint = this.jsObjectGetArray(android, "constraint");
273278
boolean invalidatedByBiometricEnrollment = android.getBool("invalidatedByBiometricEnrollment");
274-
int flags = this.constraintToFlag(constraint);
275279
String title = android.getString("title");
276280
String subtitle = android.getString("subtitle");
277281
String description = android.getString("description");
278282
String negativeButtonText = android.getString("negativeButtonText");
279283

284+
JSONArray allowedAuthenticatorsOnEnable = this.jsObjectGetArray(android, "allowedAuthenticatorsOnEnable");
285+
JSONArray allowedAuthenticatorsOnAuthenticate = this.jsObjectGetArray(android, "allowedAuthenticatorsOnAuthenticate");
286+
int allowedAuthenticatorsOnEnableFlags = this.constraintToFlag(allowedAuthenticatorsOnEnable);
287+
int allowedAuthenticatorsOnAuthenticateFlags = this.constraintToFlag(allowedAuthenticatorsOnAuthenticate);
288+
280289
BiometricOptions options = new BiometricOptions();
281290
options.payload = payload;
282291
options.kid = kid;
283292
options.alias = alias;
284-
options.flags = flags;
293+
options.allowedAuthenticatorsOnEnableFlags = allowedAuthenticatorsOnEnableFlags;
294+
options.allowedAuthenticatorsOnAuthenticateFlags = allowedAuthenticatorsOnAuthenticateFlags;
285295
options.invalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
286296
options.title = title;
287297
options.subtitle = subtitle;

packages/authgear-capacitor/android/src/main/java/com/authgear/capacitor/BiometricOptions.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ class BiometricOptions {
66
JSObject payload;
77
String kid;
88
String alias;
9-
int flags;
9+
int allowedAuthenticatorsOnEnableFlags;
10+
int allowedAuthenticatorsOnAuthenticateFlags;
1011
boolean invalidatedByBiometricEnrollment;
1112
String title;
1213
String subtitle;

packages/authgear-capacitor/src/types.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ export interface BiometricOptionsIOS {
297297
*
298298
* @public
299299
*/
300-
export enum BiometricAccessConstraintAndroid {
300+
export enum BiometricAuthenticatorAndroid {
301301
/**
302302
* The user can use Class 3 biometric to authenticate.
303303
*
@@ -346,7 +346,28 @@ export interface BiometricOptionsAndroid {
346346
* @public
347347
*/
348348
negativeButtonText: string;
349-
constraint: BiometricAccessConstraintAndroid[];
349+
/**
350+
* Set the allowed authenticators when the user enables biometric.
351+
* This must be a subset of allowedAuthenticatorsOnAuthenticate because
352+
* you normally want to ensure the user performed at least once biometric authentication during setup,
353+
* but allow the user to fallback to passcode for subsequent biometric authentication.
354+
*
355+
* See {@link BiometricAuthenticatorAndroid}
356+
*
357+
* @public
358+
*/
359+
allowedAuthenticatorsOnEnable: BiometricAuthenticatorAndroid[];
360+
/**
361+
* Set the allowed authenticators when the user performs biometric authentication.
362+
* This must be a superset of allowedAuthenticatorsOnEnable because
363+
* you normally want to ensure the user performed at least once biometric authentication during setup,
364+
* but allow the user to fallback to passcode for subsequent biometric authentication.
365+
*
366+
* See {@link BiometricAuthenticatorAndroid}
367+
*
368+
* @public
369+
*/
370+
allowedAuthenticatorsOnAuthenticate: BiometricAuthenticatorAndroid[];
350371
/**
351372
* The user needs to set up biometric again when a new biometric is enrolled or all enrolled biometrics are removed.
352373
*

0 commit comments

Comments
 (0)