import { Platform } from 'react-native'; import * as SecureStore from 'expo-secure-store'; import AsyncStorage from '@react-native-async-storage/async-storage'; /** * 🚀 Unified Storage System for biiproject * Handles both Native (AsyncStorage/SecureStore) and Web (LocalStorage) seamlessly. */ const SENSITIVE_KEYS = ['user_token', 'saved_pass', 'biometric_credentials']; // In-memory fallback for environments where storage is unavailable (e.g. some web modes or broken native modules) const memoryStorage: Record = {}; export const storage = { save: async (key: string, value: string) => { try { if (Platform.OS === 'web') { if (typeof localStorage !== 'undefined') { localStorage.setItem(key, value); } else { memoryStorage[key] = value; } } else { if (SENSITIVE_KEYS.includes(key)) { // SecureStore might fail if biometrics are not configured or on some Android versions try { await SecureStore.setItemAsync(key, value); } catch (e) { console.warn(`[Storage] SecureStore failed for ${key}, falling back to AsyncStorage`, e); await AsyncStorage.setItem(key, value); } } else { await AsyncStorage.setItem(key, value); } } return true; } catch (error) { console.error(`Storage Save Error [${key}]:`, error); memoryStorage[key] = value; // Last resort return false; } }, get: async (key: string) => { try { if (Platform.OS === 'web') { if (typeof localStorage !== 'undefined') { return localStorage.getItem(key); } return memoryStorage[key] || null; } else { if (SENSITIVE_KEYS.includes(key)) { try { const val = await SecureStore.getItemAsync(key); if (val) return val; } catch (e) { console.warn(`[Storage] SecureStore read failed for ${key}`, e); } // Check fallback return await AsyncStorage.getItem(key); } else { return await AsyncStorage.getItem(key); } } } catch (error) { console.warn(`Storage Get Error [${key}]:`, error); return memoryStorage[key] || null; } }, remove: async (key: string) => { try { if (Platform.OS === 'web') { if (typeof localStorage !== 'undefined') { localStorage.removeItem(key); } delete memoryStorage[key]; } else { if (SENSITIVE_KEYS.includes(key)) { try { await SecureStore.deleteItemAsync(key); } catch (e) { console.warn(`[Storage] SecureStore delete failed for ${key}`, e); } await AsyncStorage.removeItem(key); } else { await AsyncStorage.removeItem(key); } } return true; } catch (error) { console.error(`Storage Remove Error [${key}]:`, error); return false; } } };