/** * WiFi Password Secure Storage Service * * Provides secure storage for WiFi passwords using expo-secure-store. * Replaces AsyncStorage for improved security. */ import * as SecureStore from 'expo-secure-store'; const WIFI_PASSWORDS_KEY = 'WIFI_PASSWORDS'; const LEGACY_SINGLE_PASSWORD_KEY = 'LAST_WIFI_PASSWORD'; export interface WiFiPasswordMap { [ssid: string]: string; } /** * Save WiFi password for a specific network * @param ssid Network SSID * @param password Network password */ export async function saveWiFiPassword(ssid: string, password: string): Promise { try { // Get existing passwords const existing = await getAllWiFiPasswords(); // Add/update the password existing[ssid] = password; // Save back to SecureStore await SecureStore.setItemAsync(WIFI_PASSWORDS_KEY, JSON.stringify(existing)); console.log('[WiFiPasswordStore] Password saved for network:', ssid); } catch (error) { console.error('[WiFiPasswordStore] Failed to save password:', error); throw error; } } /** * Get WiFi password for a specific network * @param ssid Network SSID * @returns Password or undefined if not found */ export async function getWiFiPassword(ssid: string): Promise { try { const passwords = await getAllWiFiPasswords(); return passwords[ssid]; } catch (error) { console.error('[WiFiPasswordStore] Failed to get password:', error); return undefined; } } /** * Get all saved WiFi passwords * @returns Map of SSID to password */ export async function getAllWiFiPasswords(): Promise { try { const stored = await SecureStore.getItemAsync(WIFI_PASSWORDS_KEY); if (stored) { return JSON.parse(stored); } return {}; } catch (error) { console.error('[WiFiPasswordStore] Failed to get all passwords:', error); return {}; } } /** * Remove WiFi password for a specific network * @param ssid Network SSID */ export async function removeWiFiPassword(ssid: string): Promise { try { const existing = await getAllWiFiPasswords(); // Remove the password delete existing[ssid]; // Save back to SecureStore if (Object.keys(existing).length > 0) { await SecureStore.setItemAsync(WIFI_PASSWORDS_KEY, JSON.stringify(existing)); } else { // If no passwords left, remove the key entirely await SecureStore.deleteItemAsync(WIFI_PASSWORDS_KEY); } console.log('[WiFiPasswordStore] Password removed for network:', ssid); } catch (error) { console.error('[WiFiPasswordStore] Failed to remove password:', error); throw error; } } /** * Clear all saved WiFi passwords * Should be called on logout */ export async function clearAllWiFiPasswords(): Promise { try { await SecureStore.deleteItemAsync(WIFI_PASSWORDS_KEY); console.log('[WiFiPasswordStore] All WiFi passwords cleared'); } catch (error) { console.error('[WiFiPasswordStore] Failed to clear passwords:', error); throw error; } } /** * Migrate WiFi passwords from AsyncStorage to SecureStore * This function should be called once during app startup to migrate existing data */ export async function migrateFromAsyncStorage(): Promise { try { const AsyncStorage = require('@react-native-async-storage/async-storage').default; // Check if migration already done const existing = await SecureStore.getItemAsync(WIFI_PASSWORDS_KEY); if (existing) { console.log('[WiFiPasswordStore] Migration already completed'); return; } // Try to get old data from AsyncStorage const oldPasswords = await AsyncStorage.getItem('WIFI_PASSWORDS'); if (oldPasswords) { // Migrate to SecureStore await SecureStore.setItemAsync(WIFI_PASSWORDS_KEY, oldPasswords); // Remove from AsyncStorage await AsyncStorage.removeItem('WIFI_PASSWORDS'); await AsyncStorage.removeItem(LEGACY_SINGLE_PASSWORD_KEY); console.log('[WiFiPasswordStore] Successfully migrated passwords from AsyncStorage'); } else { console.log('[WiFiPasswordStore] No passwords to migrate'); } } catch (error) { console.error('[WiFiPasswordStore] Migration failed:', error); // Don't throw - migration failure shouldn't break the app } }