import * as SecureStore from 'expo-secure-store'; import * as LocalAuthentication from 'expo-local-authentication'; const PIN_KEY = 'goon.applock.pin'; const ENABLED_KEY = 'goon.applock.enabled'; const BIO_KEY = 'goon.applock.bio_enabled'; const TIMEOUT_KEY = 'goon.applock.timeout_seconds'; export const DEFAULT_TIMEOUT_SECONDS = 60; export interface AppLockSettings { enabled: boolean; bioEnabled: boolean; timeoutSeconds: number; hasPin: boolean; } export async function getSettings(): Promise { const [enabled, bio, timeout, pin] = await Promise.all([ SecureStore.getItemAsync(ENABLED_KEY), SecureStore.getItemAsync(BIO_KEY), SecureStore.getItemAsync(TIMEOUT_KEY), SecureStore.getItemAsync(PIN_KEY), ]); const t = timeout ? parseInt(timeout, 10) : DEFAULT_TIMEOUT_SECONDS; return { enabled: enabled === '1', bioEnabled: bio === '1', timeoutSeconds: Number.isFinite(t) ? t : DEFAULT_TIMEOUT_SECONDS, hasPin: !!pin, }; } export async function setEnabled(v: boolean): Promise { await SecureStore.setItemAsync(ENABLED_KEY, v ? '1' : '0'); } export async function setBioEnabled(v: boolean): Promise { await SecureStore.setItemAsync(BIO_KEY, v ? '1' : '0'); } export async function setTimeoutSeconds(s: number): Promise { await SecureStore.setItemAsync(TIMEOUT_KEY, String(Math.max(0, Math.floor(s)))); } export async function setPin(pin: string): Promise { if (!/^\d{4,8}$/.test(pin)) throw new Error('PIN must be 4-8 digits'); await SecureStore.setItemAsync(PIN_KEY, pin); } export async function verifyPin(pin: string): Promise { const stored = await SecureStore.getItemAsync(PIN_KEY); return stored !== null && stored === pin; } export async function clearPin(): Promise { await SecureStore.deleteItemAsync(PIN_KEY); } export async function biometricAvailable(): Promise { const hw = await LocalAuthentication.hasHardwareAsync(); if (!hw) return false; const enrolled = await LocalAuthentication.isEnrolledAsync(); return enrolled; } export async function authenticateBiometric(): Promise { const res = await LocalAuthentication.authenticateAsync({ promptMessage: 'Unlock Goon', cancelLabel: 'Use PIN', disableDeviceFallback: true, }); return res.success; }