diff --git a/apps/rebreak-native/stores/appLock.ts b/apps/rebreak-native/stores/appLock.ts index eadcd4b..29a1433 100644 --- a/apps/rebreak-native/stores/appLock.ts +++ b/apps/rebreak-native/stores/appLock.ts @@ -1,6 +1,21 @@ import { create } from 'zustand'; import AsyncStorage from '@react-native-async-storage/async-storage'; -import * as LocalAuthentication from 'expo-local-authentication'; + +// expo-local-authentication ist ein NATIVE-Modul. In einem Dev-Client, der noch +// VOR dem Hinzufügen dieser Dependency gebaut wurde, fehlt der native Teil → +// `require()` wirft "Cannot find native module 'ExpoLocalAuthentication'" und +// würde die ganze App beim Start crashen (appLock wird im RootLayout importiert). +// Daher: defensiv laden. Fehlt das Modul → App-Sperre einfach „nicht verfügbar", +// der Rest der App läuft normal weiter. In jedem echten Build (EAS / frischer +// `expo prebuild`) ist das Modul drin und alles funktioniert. +type LocalAuthModule = typeof import('expo-local-authentication'); +let LocalAuthentication: LocalAuthModule | null = null; +try { + // eslint-disable-next-line @typescript-eslint/no-var-requires, global-require + LocalAuthentication = require('expo-local-authentication') as LocalAuthModule; +} catch { + LocalAuthentication = null; +} /** * App-Sperre (Face ID / Touch ID). @@ -47,6 +62,11 @@ export const useAppLockStore = create((set, get) => ({ ready: false, init: async () => { + if (!LocalAuthentication) { + // Native-Modul fehlt (alter Dev-Client) → Sperre nicht verfügbar, App läuft weiter. + set({ enabled: false, available: false, locked: false, ready: true }); + return; + } const [storedRaw, hasHardware, isEnrolled] = await Promise.all([ AsyncStorage.getItem(STORAGE_KEY), LocalAuthentication.hasHardwareAsync(), @@ -76,6 +96,7 @@ export const useAppLockStore = create((set, get) => ({ }, authenticate: async (promptMessage) => { + if (!LocalAuthentication) return false; const result = await LocalAuthentication.authenticateAsync({ promptMessage: promptMessage ?? DEFAULT_PROMPT, // Geräte-Passcode als Fallback erlauben (Face ID schlägt 3x fehl → Passcode).