From 8f1e080a0bc3d915be56fbd1fd99fc4f125023a0 Mon Sep 17 00:00:00 2001 From: kyleleow <40191153+kyleleow@users.noreply.github.com> Date: Tue, 28 Sep 2021 14:36:56 +0800 Subject: [PATCH] `privacy lock` - update label (#949) * feat: add authentication name to privacy lock label Fixes #911 * translation: add entries * feat: fix fingerprint check * feat: refactor label to accept param To allow localized string composition * translation: update entries * feat: replace device's passcode with device's lock To avoid confusion with app passcode --- mobile-app/app/contexts/LocalAuthContext.tsx | 35 +++++++++++++++++++ .../screens/Settings/SettingsScreen.tsx | 9 +++-- mobile-app/app/translations/languages/de.json | 10 +++++- .../app/translations/languages/zh-Hans.json | 10 +++++- .../app/translations/languages/zh-Hant.json | 10 +++++- 5 files changed, 68 insertions(+), 6 deletions(-) diff --git a/mobile-app/app/contexts/LocalAuthContext.tsx b/mobile-app/app/contexts/LocalAuthContext.tsx index 9d13181020..eb9bbb5f71 100644 --- a/mobile-app/app/contexts/LocalAuthContext.tsx +++ b/mobile-app/app/contexts/LocalAuthContext.tsx @@ -3,6 +3,7 @@ import * as LocalAuthentication from 'expo-local-authentication' import { AuthenticationType, LocalAuthenticationOptions, SecurityLevel } from 'expo-local-authentication' import React, { createContext, useContext, useEffect, useState } from 'react' import { PrivacyLockPersistence } from '@api/wallet/privacy_lock' +import { Platform } from 'react-native' export interface PrivacyLockContextI { // user's hardware condition, external @@ -13,6 +14,7 @@ export interface PrivacyLockContextI { isDeviceProtected: boolean isAuthenticating: boolean setIsAuthenticating: (isAuthenticating: boolean) => void + getAuthenticationNaming: () => string | undefined // API isEnabled: boolean @@ -93,6 +95,39 @@ export function PrivacyLockContextProvider (props: React.PropsWithChildren) return } return await context.setEnabled(!isPrivacyLock) + }, + getAuthenticationNaming: () => { + if (Platform.OS === 'ios') { + switch (securityLevel) { + case SecurityLevel.SECRET: + return 'device\'s lock' + + case SecurityLevel.BIOMETRIC: + if (biometricHardwares.includes(AuthenticationType.FACIAL_RECOGNITION)) { + return 'Face ID' + } else if (biometricHardwares.includes(AuthenticationType.FINGERPRINT)) { + return 'Touch ID' + } else { + // no-op for iris scanner(android-only) + } + } + } else if (Platform.OS === 'android') { + switch (securityLevel) { + case SecurityLevel.SECRET: + return 'device\'s lock' + + case SecurityLevel.BIOMETRIC: + if (biometricHardwares.includes(AuthenticationType.FACIAL_RECOGNITION)) { + return 'face recognition' + } else if (biometricHardwares.includes(AuthenticationType.FINGERPRINT)) { + return 'fingerprint' + } else { + return 'iris scan' + } + } + } else { + // no-op: does not handle other devices + } } } diff --git a/mobile-app/app/screens/AppNavigator/screens/Settings/SettingsScreen.tsx b/mobile-app/app/screens/AppNavigator/screens/Settings/SettingsScreen.tsx index d91fbc747b..14676a7e3c 100644 --- a/mobile-app/app/screens/AppNavigator/screens/Settings/SettingsScreen.tsx +++ b/mobile-app/app/screens/AppNavigator/screens/Settings/SettingsScreen.tsx @@ -112,6 +112,7 @@ export function SettingsScreen ({ navigation }: Props): JSX.Element { onToggle={async () => { await localAuth.togglePrivacyLock() }} + authenticationName={localAuth.getAuthenticationNaming()} /> ) } @@ -224,8 +225,9 @@ function RowExitWalletItem (): JSX.Element { function PrivacyLockToggle ({ value, - onToggle -}: { disabled?: boolean, value: boolean, onToggle: (newValue: boolean) => void }): JSX.Element { + onToggle, + authenticationName +}: { disabled?: boolean, value: boolean, onToggle: (newValue: boolean) => void, authenticationName?: string }): JSX.Element { return ( <> - {translate('screens/Settings', 'Privacy Lock')} + {authenticationName !== undefined && + translate('screens/Settings', 'Secure with {{option}}', { option: translate('screens/Settings', authenticationName) })}