Files
beenvoice/apps/mobile/lib/app-lock.ts
T
soconnor d057ba208d Add 'apps/mobile/' from commit '5fa30f365f21531094cd4d2045042bb4f1370ac3'
git-subtree-dir: apps/mobile
git-subtree-mainline: 86f8987dff
git-subtree-split: 5fa30f365f
2026-08-16 21:42:59 -04:00

80 lines
2.7 KiB
TypeScript

import * as SecureStore from "expo-secure-store";
import { normalizeSecureStoreKey } from "@/lib/secure-store-keys";
function lockKey(accountId: string, field: "enabled" | "pin" | "biometric") {
return normalizeSecureStoreKey(`beenvoice.app-lock.${accountId}.${field}`);
}
const LEGACY_ENABLED_KEY = "beenvoice_app_lock_enabled";
const LEGACY_PIN_KEY = "beenvoice_app_lock_pin";
const LEGACY_BIOMETRIC_KEY = "beenvoice_app_lock_biometric";
async function migrateLegacyLockIfNeeded(accountId: string): Promise<void> {
const [legacyEnabled, legacyPin, legacyBiometric, accountEnabled] = await Promise.all([
SecureStore.getItemAsync(LEGACY_ENABLED_KEY),
SecureStore.getItemAsync(LEGACY_PIN_KEY),
SecureStore.getItemAsync(LEGACY_BIOMETRIC_KEY),
SecureStore.getItemAsync(lockKey(accountId, "enabled")),
]);
if (accountEnabled != null || legacyEnabled !== "1") return;
if (legacyPin) {
await setStoredPin(accountId, legacyPin);
}
await setAppLockEnabled(accountId, true);
if (legacyBiometric === "1") {
await setBiometricEnabled(accountId, true);
}
await Promise.all([
SecureStore.deleteItemAsync(LEGACY_ENABLED_KEY),
SecureStore.deleteItemAsync(LEGACY_PIN_KEY),
SecureStore.deleteItemAsync(LEGACY_BIOMETRIC_KEY),
]);
}
export async function getAppLockEnabled(accountId: string): Promise<boolean> {
await migrateLegacyLockIfNeeded(accountId);
const value = await SecureStore.getItemAsync(lockKey(accountId, "enabled"));
return value === "1";
}
export async function setAppLockEnabled(accountId: string, enabled: boolean): Promise<void> {
if (enabled) {
await SecureStore.setItemAsync(lockKey(accountId, "enabled"), "1");
} else {
await SecureStore.deleteItemAsync(lockKey(accountId, "enabled"));
}
}
export async function getStoredPin(accountId: string): Promise<string | null> {
return SecureStore.getItemAsync(lockKey(accountId, "pin"));
}
export async function setStoredPin(accountId: string, pin: string): Promise<void> {
await SecureStore.setItemAsync(lockKey(accountId, "pin"), pin);
}
export async function clearStoredPin(accountId: string): Promise<void> {
await SecureStore.deleteItemAsync(lockKey(accountId, "pin"));
}
export async function getBiometricEnabled(accountId: string): Promise<boolean> {
const value = await SecureStore.getItemAsync(lockKey(accountId, "biometric"));
return value === "1";
}
export async function setBiometricEnabled(accountId: string, enabled: boolean): Promise<void> {
if (enabled) {
await SecureStore.setItemAsync(lockKey(accountId, "biometric"), "1");
} else {
await SecureStore.deleteItemAsync(lockKey(accountId, "biometric"));
}
}
export function isValidPin(pin: string): boolean {
return /^\d{4,6}$/.test(pin);
}