feat: Sprint 5 — PIN lock, biometric auth, sync screen, QR code, merge logic
- lib/pinService.ts: PIN storage/verification via expo-secure-store - lib/syncService.ts: sync abstraction with full merge logic (mDNS/TCP stubbed) - app/lock.tsx: full-screen PIN lock with biometric support - components/ui/PinPad.tsx: reusable 6-digit PIN pad component - components/sync/QRScanner.tsx: QR code scanner via expo-camera - app/(tabs)/sync.tsx: Sync tab with QR display, partner input, history - app/sync-progress.tsx: animated sync progress screen with summary - app/(tabs)/settings.tsx: full settings with PIN setup, security, data sections - app/(tabs)/_layout.tsx: added Sync tab (RefreshCw icon) - app/_layout.tsx: AppState listener locks app after 60s background - package.json: added expo-secure-store, react-native-qrcode-svg
This commit is contained in:
52
lib/pinService.ts
Normal file
52
lib/pinService.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
// lib/pinService.ts
|
||||
import * as SecureStore from 'expo-secure-store';
|
||||
|
||||
const PIN_KEY = 'territory_log_pin';
|
||||
const PIN_ENABLED_KEY = 'territory_log_pin_enabled';
|
||||
const BIOMETRIC_ENABLED_KEY = 'territory_log_biometric_enabled';
|
||||
|
||||
export async function isPinEnabled(): Promise<boolean> {
|
||||
try {
|
||||
const val = await SecureStore.getItemAsync(PIN_ENABLED_KEY);
|
||||
return val === 'true';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function setPin(pin: string): Promise<void> {
|
||||
await SecureStore.setItemAsync(PIN_KEY, pin);
|
||||
await SecureStore.setItemAsync(PIN_ENABLED_KEY, 'true');
|
||||
}
|
||||
|
||||
export async function verifyPin(pin: string): Promise<boolean> {
|
||||
try {
|
||||
const stored = await SecureStore.getItemAsync(PIN_KEY);
|
||||
return stored === pin;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function disablePin(): Promise<void> {
|
||||
await SecureStore.deleteItemAsync(PIN_KEY);
|
||||
await SecureStore.setItemAsync(PIN_ENABLED_KEY, 'false');
|
||||
await SecureStore.setItemAsync(BIOMETRIC_ENABLED_KEY, 'false');
|
||||
}
|
||||
|
||||
export async function getPinEnabled(): Promise<boolean> {
|
||||
return isPinEnabled();
|
||||
}
|
||||
|
||||
export async function isBiometricEnabled(): Promise<boolean> {
|
||||
try {
|
||||
const val = await SecureStore.getItemAsync(BIOMETRIC_ENABLED_KEY);
|
||||
return val === 'true';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function setBiometricEnabled(enabled: boolean): Promise<void> {
|
||||
await SecureStore.setItemAsync(BIOMETRIC_ENABLED_KEY, enabled ? 'true' : 'false');
|
||||
}
|
||||
Reference in New Issue
Block a user