Skip to content

Commit

Permalink
[local-authentication] Add more options to the iOS authenticateAsync …
Browse files Browse the repository at this point in the history
…options (#6891)

# Why

This resolves an open issue [#4799](#4799).  I also added the option to customize the cancel label.

# How

I reviewed the [Apple documentation](https://developer.apple.com/documentation/localauthentication/logging_a_user_into_your_app_with_face_id_or_touch_id?language=objc) and added the appropriate options to select the correct policy to evaluate against.

# Test Plan

I will test this on a number of devices by copying over the source into my node_modules, building the app, and testing on multiple devices.
  • Loading branch information
beaur committed Feb 5, 2020
1 parent da23eaf commit be6d733
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 3 deletions.
4 changes: 3 additions & 1 deletion docs/pages/versions/unversioned/sdk/local-authentication.md
Expand Up @@ -64,7 +64,9 @@ Attempts to authenticate via Fingerprint/TouchID (or FaceID if available on the

- **options (_object_)** -- An object of options.
- **promptMessage (_string_)** -- A message that is shown alongside the TouchID or FaceID prompt. (**iOS only**)
- **fallbackLabel (_string_)** -- Allows to customize the default `Use Passcode` label shown after several failed authentication attempts. Setting this option to an empty string disables fallback to device passcode. (**iOS only**)
- **cancelLabel (_string_)** -- Allows to customize the default `Cancel` label shown. (**iOS only**)
- **fallbackLabel (_string_)** -- Allows to customize the default `Use Passcode` label shown after several failed authentication attempts. Setting this option to an empty string disables this button from showing in the prompt. (**iOS only**)
- **disableDeviceFallback (_boolean_)** -- After several failed attempts the system will fallback to the device passcode. This setting allows you to disable this option and instead handle the fallback yourself. This can be preferable in certain custom authentication workflows. This behaviour maps to using the iOS [LAPolicyDeviceOwnerAuthenticationWithBiometrics](https://developer.apple.com/documentation/localauthentication/lapolicy/lapolicydeviceownerauthenticationwithbiometrics?language=objc) policy rather than the [LAPolicyDeviceOwnerAuthentication](https://developer.apple.com/documentation/localauthentication/lapolicy/lapolicydeviceownerauthentication?language=objc) policy. Defaults to `false`. (**iOS only**)

#### Returns

Expand Down
Expand Up @@ -68,7 +68,9 @@ @implementation EXLocalAuthentication
{
NSString *warningMessage;
NSString *reason = options[@"promptMessage"];
NSString *cancelLabel = options[@"cancelLabel"];
NSString *fallbackLabel = options[@"fallbackLabel"];
NSString *disableDeviceFallback = options[@"disableDeviceFallback"];

if ([[self class] isFaceIdDevice]) {
NSString *usageDescription = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"NSFaceIDUsageDescription"];
Expand All @@ -84,11 +86,16 @@ @implementation EXLocalAuthentication
context.localizedFallbackTitle = fallbackLabel;
}

if (cancelLabel != nil) {
context.localizedCancelTitle = cancelLabel;
}

if (@available(iOS 11.0, *)) {
context.interactionNotAllowed = false;
}

[context evaluatePolicy:LAPolicyDeviceOwnerAuthentication
if (disableDeviceFallback) {
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:reason
reply:^(BOOL success, NSError *error) {
resolve(@{
Expand All @@ -97,6 +104,18 @@ @implementation EXLocalAuthentication
@"warning": UMNullIfNil(warningMessage),
});
}];
} else {
[context evaluatePolicy:LAPolicyDeviceOwnerAuthentication
localizedReason:reason
reply:^(BOOL success, NSError *error) {
resolve(@{
@"success": @(success),
@"error": error == nil ? [NSNull null] : [self convertErrorCode:error],
@"warning": UMNullIfNil(warningMessage),
});
}];
}

}

- (NSString *)convertErrorCode:(NSError *)error
Expand Down
Expand Up @@ -8,5 +8,7 @@ export enum AuthenticationType {
export type AuthOptions = {
// iOS only
promptMessage?: string;
cancelLabel?: string;
fallbackLabel?: string;
disableDeviceFallback?: boolean;
};
Expand Up @@ -6,10 +6,12 @@ beforeEach(() => {
ExpoLocalAuthentication.authenticateAsync.mockImplementation(async () => ({ success: true }));
});

it(`uses promptMessage and fallbackLabel on iOS`, async () => {
it(`uses options on iOS`, async () => {
const options = {
promptMessage: 'Authentication is required',
cancelLabel: 'Abort',
fallbackLabel: 'Use passcode',
disableDeviceFallback: false,
};
await LocalAuthentication.authenticateAsync(options);

Expand Down

0 comments on commit be6d733

Please sign in to comment.