import * as SecureStore from "expo-secure-store"; import { authStoragePrefix, buildAccountId } from "@/lib/accounts"; import { normalizeSecureStoreKey } from "@/lib/secure-store-keys"; export const GUEST_AUTH_STORAGE_PREFIX = "beenvoice:guest"; const CHUNK_MARKER = "\u0001ba-chunks:"; const AUTH_STORAGE_SUFFIXES = ["_cookie", "_session_data", "_last_login_method"] as const; function storageKeyForPrefix(prefix: string, suffix: (typeof AUTH_STORAGE_SUFFIXES)[number]) { return normalizeSecureStoreKey(`${prefix}${suffix}`); } async function copySecureStoreEntry(fromKey: string, toKey: string): Promise { const value = await SecureStore.getItemAsync(fromKey); if (value == null) return; await SecureStore.setItemAsync(toKey, value); if (!value.startsWith(CHUNK_MARKER)) return; const count = Number(value.slice(CHUNK_MARKER.length)); if (!Number.isInteger(count) || count < 1) return; for (let i = 0; i < count; i += 1) { const chunk = await SecureStore.getItemAsync(`${fromKey}.${i}`); if (chunk != null) { await SecureStore.setItemAsync(`${toKey}.${i}`, chunk); } } } export async function migrateAuthStorage(fromPrefix: string, toPrefix: string): Promise { if (fromPrefix === toPrefix) return; await Promise.all( AUTH_STORAGE_SUFFIXES.map((suffix) => copySecureStoreEntry(storageKeyForPrefix(fromPrefix, suffix), storageKeyForPrefix(toPrefix, suffix)), ), ); } export async function finalizeAuthenticatedAccount(input: { apiUrl: string; userId: string; email: string; name: string; activeAccountId: string | null; registerAccount: (input: { instanceUrl: string; userId: string; email: string; name: string; }) => Promise; }): Promise { const accountId = buildAccountId(input.apiUrl, input.userId); const targetPrefix = authStoragePrefix(accountId); const sourcePrefix = input.activeAccountId ? authStoragePrefix(input.activeAccountId) : GUEST_AUTH_STORAGE_PREFIX; await migrateAuthStorage(sourcePrefix, targetPrefix); await input.registerAccount({ instanceUrl: input.apiUrl, userId: input.userId, email: input.email, name: input.name, }); }