diff --git a/apps/mobile/app/components/app-lock-overlay/index.tsx b/apps/mobile/app/components/app-lock-overlay/index.tsx index a066357f8..4a15791bf 100644 --- a/apps/mobile/app/components/app-lock-overlay/index.tsx +++ b/apps/mobile/app/components/app-lock-overlay/index.tsx @@ -103,6 +103,8 @@ const AppLockedOverlay = () => { ) return; + biometricUnlockAwaitingUserInput.current = true; + if (Platform.OS === "android") { const activityName = await NotesnookModule.getActivityName(); if (activityName !== "MainActivity") return; @@ -118,10 +120,11 @@ const AppLockedOverlay = () => { enabled(false); password.current = undefined; } + biometricUnlockAwaitingUserInput.current = false; setTimeout(() => { - biometricUnlockAwaitingUserInput.current = false; + if (biometricUnlockAwaitingUserInput.current) return; useSettingStore.getState().setRequestBiometrics(false); - }, 1); + }, 500); }, [biometricsAuthEnabled, lockApp]); const onSubmit = async () => { @@ -156,7 +159,11 @@ const AppLockedOverlay = () => { useUserStore.getState().disableAppLockRequests ) return; - if (appLocked && appState === "active") { + if ( + appLocked && + appState === "active" && + !useSettingStore.getState().requestBiometrics + ) { biometricUnlockAwaitingUserInput.current = true; onUnlockAppRequested(); } diff --git a/apps/mobile/app/hooks/use-app-events.tsx b/apps/mobile/app/hooks/use-app-events.tsx index a64368f0c..c62eb7120 100644 --- a/apps/mobile/app/hooks/use-app-events.tsx +++ b/apps/mobile/app/hooks/use-app-events.tsx @@ -485,7 +485,6 @@ export const useAppEvents = () => { const onAppStateChanged = async (state: AppStateStatus) => { if (state === "active") { if (SettingsService.shouldLockAppOnEnterForeground()) { - console.log("Locked app on enter foreground"); useUserStore.getState().lockApp(true); } @@ -497,12 +496,7 @@ export const useAppEvents = () => { ) { enabled(false); } - if (SettingsService.canLockAppInBackground()) { - if (useSettingStore.getState().requestBiometrics) { - useSettingStore.getState().setRequestBiometrics(false); - return; - } - } + checkAutoBackup(); await reconnectSSE(); await checkForShareExtensionLaunchedInBackground(); @@ -543,10 +537,11 @@ export const useAppEvents = () => { } } if ( - SettingsService.get().privacyScreen || - SettingsService.canLockAppInBackground() + (SettingsService.get().privacyScreen || + SettingsService.canLockAppInBackground()) && + !useSettingStore.getState().requestBiometrics ) { - !useSettingStore.getState().requestBiometrics ? enabled(true) : null; + enabled(true); } } }; diff --git a/apps/mobile/app/screens/settings/picker/index.tsx b/apps/mobile/app/screens/settings/picker/index.tsx index ac18da566..2d975d840 100644 --- a/apps/mobile/app/screens/settings/picker/index.tsx +++ b/apps/mobile/app/screens/settings/picker/index.tsx @@ -18,7 +18,7 @@ along with this program. If not, see . */ import React, { useRef, useState } from "react"; -import { View } from "react-native"; +import { TouchableHighlight, View } from "react-native"; import Menu, { MenuItem } from "react-native-reanimated-material-menu"; import Icon from "react-native-vector-icons/MaterialCommunityIcons"; import { PressableButton } from "../../../components/ui/pressable"; @@ -126,6 +126,7 @@ export function SettingsPicker({ } > + {options.map((item) => ( ({ onChange(item); } }} + underlayColor={colors.primary.hover} style={{ backgroundColor: compareValue(currentValue, item) - ? colors.secondary.background + ? colors.selected.background : "transparent", width: "100%", maxWidth: width diff --git a/apps/mobile/app/services/backup.js b/apps/mobile/app/services/backup.js index 15a84bd5d..7747573ed 100644 --- a/apps/mobile/app/services/backup.js +++ b/apps/mobile/app/services/backup.js @@ -154,7 +154,7 @@ async function updateNextBackupTime() { * @param {string} context * @returns {Promise<{path?: string, error?: Error}}> */ -async function run(progress, context = "global") { +async function run(progress = false, context = "global") { let androidBackupDirectory = await checkBackupDirExists(false, context); if (!androidBackupDirectory) return { diff --git a/apps/mobile/app/services/biometrics.ts b/apps/mobile/app/services/biometrics.ts index c11b99b9b..8a51d8cc7 100644 --- a/apps/mobile/app/services/biometrics.ts +++ b/apps/mobile/app/services/biometrics.ts @@ -26,6 +26,7 @@ import { MMKV } from "../common/database/mmkv"; import Storage from "../common/database/storage"; import { useSettingStore } from "../stores/use-setting-store"; import { ToastOptions, ToastManager } from "./event-manager"; +import { useUserStore } from "../stores/use-user-store"; const KeychainConfig = Platform.select({ ios: { @@ -122,6 +123,10 @@ async function getCredentials(title?: string, description?: string) { async function validateUser(title: string, description?: string) { try { + useUserStore.setState({ + disableAppLockRequests: true + }); + useSettingStore.getState().setAppDidEnterBackgroundForAction(true); await FingerprintScanner.authenticate( Platform.select({ ios: { @@ -135,10 +140,18 @@ async function validateUser(title: string, description?: string) { } }) as AuthenticateIOS ); + useUserStore.setState({ + disableAppLockRequests: false + }); + useSettingStore.getState().setAppDidEnterBackgroundForAction(false); FingerprintScanner.release(); return true; } catch (error) { const e = error as { name: string }; + useUserStore.setState({ + disableAppLockRequests: false + }); + useSettingStore.getState().setAppDidEnterBackgroundForAction(false); FingerprintScanner.release(); if (e.name === "DeviceLocked") { ToastManager.show({ diff --git a/apps/mobile/app/services/settings.ts b/apps/mobile/app/services/settings.ts index 0daa8679b..6186138e6 100644 --- a/apps/mobile/app/services/settings.ts +++ b/apps/mobile/app/services/settings.ts @@ -28,6 +28,7 @@ import { import { NotesnookModule } from "../utils/notesnook-module"; import { scale, updateSize } from "../utils/size"; import { DatabaseLogger } from "../common/database"; +import { useUserStore } from "../stores/use-user-store"; function reset() { const settings = get(); if (settings.reminder !== "off" && settings.reminder !== "useroff") { @@ -195,6 +196,12 @@ function appEnteredBackground() { } function shouldLockAppOnEnterForeground() { + if ( + useUserStore.getState().disableAppLockRequests || + useSettingStore.getState().requestBiometrics + ) + return false; + const settings = get(); if (!settings.appLockEnabled) return false; if (settings.appLockTimer === -1) return false; diff --git a/apps/mobile/native/ios/Notesnook.xcodeproj/project.pbxproj b/apps/mobile/native/ios/Notesnook.xcodeproj/project.pbxproj index 3a7eb50f6..b7c38071c 100644 --- a/apps/mobile/native/ios/Notesnook.xcodeproj/project.pbxproj +++ b/apps/mobile/native/ios/Notesnook.xcodeproj/project.pbxproj @@ -1003,7 +1003,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2080; + CURRENT_PROJECT_VERSION = 2081; DEVELOPMENT_TEAM = 53CWBG3QUC; ENABLE_BITCODE = NO; "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; @@ -1108,7 +1108,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 2080; + CURRENT_PROJECT_VERSION = 2081; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC; "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; @@ -1341,7 +1341,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2080; + CURRENT_PROJECT_VERSION = 2081; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 53CWBG3QUC; "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; @@ -1384,7 +1384,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2080; + CURRENT_PROJECT_VERSION = 2081; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC; @@ -1427,7 +1427,7 @@ CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2080; + CURRENT_PROJECT_VERSION = 2081; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 53CWBG3QUC; "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; @@ -1532,7 +1532,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2080; + CURRENT_PROJECT_VERSION = 2081; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;