- api: DeviceRegistration device-only, login/changePassword/resolveUser, interception 401 (purge) exonérée sur le login ; type User aligné sur le fil (is_admin) - SecureStore (expo-secure-store v57) : token + profil, jamais en SQLite ; miroir active_user_id - AuthContext : statut loading/signedOut/signedIn, bootstrap register→restore, signIn/signOut, garde-fou switch de compte - app/login.tsx + gate de routes dans _layout (Redirect signedOut) ; i18n fr/en - DB v5 : user_id sur pending_operations + resource_permissions (UNIQUE par user), repos scopés (user_id IS ? OR IS NULL) - syncOutbox : delta permissions par compte (Map), outbox poussée du compte actif uniquement - tests: register/login/401/resolve/changePassword, scoping outbox+permissions, migrations v5 ; e2e live revert register→login admin
42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
import * as SecureStore from 'expo-secure-store';
|
|
import type { User } from '../api/types';
|
|
|
|
// Clés SecureStore (iOS keychain / Android Keystore). Le token et le profil du
|
|
// compte connecté ne sont JAMAIS persistés en SQLite : un miroir non-sensible
|
|
// (active_user_id) est répété en base pour le scoping des repositories.
|
|
const TOKEN_KEY = 'vaultdrop.auth_token';
|
|
const ACCOUNT_KEY = 'vaultdrop.account';
|
|
|
|
export async function getStoredToken(): Promise<string | null> {
|
|
try {
|
|
return await SecureStore.getItemAsync(TOKEN_KEY);
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function getStoredAccount(): Promise<User | null> {
|
|
try {
|
|
const raw = await SecureStore.getItemAsync(ACCOUNT_KEY);
|
|
if (!raw) return null;
|
|
const parsed = JSON.parse(raw) as User;
|
|
if (typeof parsed?.id !== 'string' || typeof parsed?.username !== 'string') return null;
|
|
return parsed;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function setStoredSession(token: string, user: User): Promise<void> {
|
|
await SecureStore.setItemAsync(TOKEN_KEY, token);
|
|
await SecureStore.setItemAsync(ACCOUNT_KEY, JSON.stringify(user));
|
|
}
|
|
|
|
export async function clearStoredSession(): Promise<void> {
|
|
try {
|
|
await SecureStore.deleteItemAsync(TOKEN_KEY);
|
|
await SecureStore.deleteItemAsync(ACCOUNT_KEY);
|
|
} catch {
|
|
// clés absentes → rien à supprimer
|
|
}
|
|
} |