diff --git a/app/containers/Passcode/PasscodeEnter.js b/app/containers/Passcode/PasscodeEnter.js index e06b45095..3bc600b70 100644 --- a/app/containers/Passcode/PasscodeEnter.js +++ b/app/containers/Passcode/PasscodeEnter.js @@ -17,13 +17,12 @@ import { resetAttempts } from '../../utils/localAuthentication'; import { getLockedUntil, getDiff } from './utils'; import I18n from '../../i18n'; -const PasscodeEnter = ({ theme, finishProcess }) => { +const PasscodeEnter = ({ theme, hasBiometry, finishProcess }) => { const ref = useRef(null); let attempts = 0; let lockedUntil = false; const [passcode, setPasscode] = useState(null); - const [status, setStatus] = useState(TYPE.ENTER); - const [hasBiometry, setHasBiometry] = useState(false); + const [status, setStatus] = useState(null); const { getItem: getAttempts, setItem: setAttempts } = useAsyncStorage(ATTEMPTS_KEY); const { setItem: setLockedUntil } = useAsyncStorage(LOCKED_OUT_TIMER_KEY); @@ -32,41 +31,40 @@ const PasscodeEnter = ({ theme, finishProcess }) => { setPasscode(p); }; + const biometry = async() => { + if (hasBiometry && status === TYPE.ENTER) { + const result = await LocalAuthentication.authenticateAsync({ + disableDeviceFallback: true, + cancelLabel: I18n.t('Local_authentication_biometry_fallback'), + promptMessage: I18n.t('Local_authentication_biometry_title') + }); + if (result?.success) { + finishProcess(); + } + } + }; + const readStorage = async() => { lockedUntil = await getLockedUntil(); if (lockedUntil) { const diff = getDiff(lockedUntil); if (diff <= 1) { - resetAttempts(); + await resetAttempts(); + setStatus(TYPE.ENTER); } else { attempts = await getAttempts(); setStatus(TYPE.LOCKED); } + } else { + setStatus(TYPE.ENTER); } - fetchPasscode(); - }; - - const checkBiometry = async() => { - const b = await LocalAuthentication.isEnrolledAsync(); - setHasBiometry(b); - }; - - const biometry = async() => { - const result = await LocalAuthentication.authenticateAsync({ - disableDeviceFallback: true, - cancelLabel: I18n.t('Local_authentication_biometry_fallback'), - promptMessage: I18n.t('Local_authentication_biometry_title') - }); - if (result?.success) { - finishProcess(); - } + await fetchPasscode(); + biometry(); }; useEffect(() => { readStorage(); - checkBiometry(); - biometry(); - }, []); + }, [status]); const onEndProcess = (p) => { setTimeout(() => { @@ -106,6 +104,7 @@ const PasscodeEnter = ({ theme, finishProcess }) => { PasscodeEnter.propTypes = { theme: PropTypes.string, + hasBiometry: PropTypes.string, finishProcess: PropTypes.func }; diff --git a/app/utils/localAuthentication.js b/app/utils/localAuthentication.js index 20ace803e..1bdea504c 100644 --- a/app/utils/localAuthentication.js +++ b/app/utils/localAuthentication.js @@ -28,9 +28,10 @@ export const saveLastLocalAuthenticationSession = async(server, serverRecord) => export const resetAttempts = () => AsyncStorage.multiRemove([LOCKED_OUT_TIMER_KEY, ATTEMPTS_KEY]); -export const openModal = () => new Promise((resolve) => { +export const openModal = hasBiometry => new Promise((resolve) => { EventEmitter.emit(LOCAL_AUTHENTICATE_EMITTER, { - submit: () => resolve() + submit: () => resolve(), + hasBiometry }); }); @@ -56,8 +57,16 @@ export const localAuthenticate = async(server) => { // Make sure splash screen has been hidden RNBootSplash.hide(); + let hasBiometry = false; + + // if biometry is enabled on the app + if (serverRecord?.biometry) { + const isEnrolled = await LocalAuthentication.isEnrolledAsync(); + hasBiometry = isEnrolled; + } + // Authenticate - await openModal(); + await openModal(hasBiometry); } // diff --git a/app/views/ScreenLockedView.js b/app/views/ScreenLockedView.js index b6ffc5b65..c525ed6dd 100644 --- a/app/views/ScreenLockedView.js +++ b/app/views/ScreenLockedView.js @@ -66,7 +66,7 @@ const ScreenLockedView = ({ theme }) => { animationOut='fadeOut' > - + );