**Motivations:** - Migrer api-relay vers base de données SQLite (production) - Ajouter authentification API key pour endpoints POST (protection abus) - PersistentNonceCache pour service-login-verify (IndexedDB/localStorage) - Écran paramètres crypto avancés UserWallet - Documenter options non implémentées (Merkle, évolutions api-relay) **Root causes:** - N/A (évolutions + correctifs) **Correctifs:** - N/A **Evolutions:** - api-relay: DatabaseStorageService (SQLite), StorageAdapter (compatibilité), ApiKeyService (génération/validation), auth middleware (Bearer/X-API-Key), endpoints admin (/admin/api-keys), migration script (migrate-to-db.ts), suppression saveToDisk périodique - service-login-verify: PersistentNonceCache (IndexedDB avec fallback localStorage, TTL, cleanup), export dans index - userwallet: CryptoSettingsScreen (hashAlgorithm, jsonCanonizationStrict, ecdhCurve, nonceTtlMs, timestampWindowMs), modifications LoginScreen, LoginForm, CreateIdentityScreen, ImportIdentityScreen, DataExportImportScreen, PairingDisplayScreen, RelaySettingsScreen, ServiceListScreen, MemberSelectionScreen, GlobalActionBar - features: OPTIONS_NON_IMPLENTEES.md (analyse Merkle trees, évolutions api-relay) **Pages affectées:** - api-relay: package.json, index.ts, middleware/auth.ts, services/database.ts, services/storageAdapter.ts, services/apiKeyService.ts, scripts/migrate-to-db.ts - service-login-verify: persistentNonceCache.ts, index.ts, tsconfig.json, dist/ - userwallet: App, CryptoSettingsScreen, LoginScreen, LoginForm, CreateIdentityScreen, ImportIdentityScreen, DataExportImportScreen, PairingDisplayScreen, RelaySettingsScreen, ServiceListScreen, MemberSelectionScreen, GlobalActionBar - features: OPTIONS_NON_IMPLENTEES.md - data: sync-utxos.log
92 lines
3.3 KiB
TypeScript
92 lines
3.3 KiB
TypeScript
import {
|
|
BrowserRouter,
|
|
Routes,
|
|
Route,
|
|
useLocation,
|
|
} from 'react-router-dom';
|
|
import { PairingWordsProvider } from './contexts/PairingWordsContext';
|
|
import { GlobalActionBar } from './components/GlobalActionBar';
|
|
import { HomeScreen } from './components/HomeScreen';
|
|
import { CreateIdentityScreen } from './components/CreateIdentityScreen';
|
|
import { ImportIdentityScreen } from './components/ImportIdentityScreen';
|
|
import { PairingDisplayScreen } from './components/PairingDisplayScreen';
|
|
import { RelaySettingsScreen } from './components/RelaySettingsScreen';
|
|
import { PairManagementScreen } from './components/PairManagementScreen';
|
|
import { SyncScreen } from './components/SyncScreen';
|
|
import { LoginScreen } from './components/LoginScreen';
|
|
import { LoginSignScreen } from './components/LoginSignScreen';
|
|
import { ServiceListScreen } from './components/ServiceListScreen';
|
|
import { MemberSelectionScreen } from './components/MemberSelectionScreen';
|
|
import { DiagnosticScreen } from './components/DiagnosticScreen';
|
|
import { ServiceSyncScreen } from './components/ServiceSyncScreen';
|
|
import { CryptoSettingsScreen } from './components/CryptoSettingsScreen';
|
|
import { DataExportImportScreen } from './components/DataExportImportScreen';
|
|
import { UnlockScreen } from './components/UnlockScreen';
|
|
import { useChannel } from './hooks/useChannel';
|
|
import { useIdentity } from './hooks/useIdentity';
|
|
import './index.css';
|
|
|
|
const PAIRING_DISPLAY_PATH = '/pairing-display';
|
|
|
|
function usePairingDisplayBypass(): boolean {
|
|
const location = useLocation();
|
|
return location.pathname === PAIRING_DISPLAY_PATH;
|
|
}
|
|
|
|
function AppContent(): JSX.Element {
|
|
useChannel();
|
|
|
|
return (
|
|
<Routes>
|
|
<Route path="/" element={<HomeScreen />} />
|
|
<Route path="/create-identity" element={<CreateIdentityScreen />} />
|
|
<Route path="/import-identity" element={<ImportIdentityScreen />} />
|
|
<Route path="/login" element={<LoginScreen />} />
|
|
<Route path="/login-sign" element={<LoginSignScreen />} />
|
|
<Route path="/manage-pairs" element={<PairManagementScreen />} />
|
|
<Route path="/relay-settings" element={<RelaySettingsScreen />} />
|
|
<Route path="/sync" element={<SyncScreen />} />
|
|
<Route path="/services" element={<ServiceListScreen />} />
|
|
<Route path="/select-member" element={<MemberSelectionScreen />} />
|
|
<Route path="/diagnostic" element={<DiagnosticScreen />} />
|
|
<Route path="/service-sync" element={<ServiceSyncScreen />} />
|
|
<Route path="/crypto-settings" element={<CryptoSettingsScreen />} />
|
|
<Route path="/data" element={<DataExportImportScreen />} />
|
|
</Routes>
|
|
);
|
|
}
|
|
|
|
function AppGate(): JSX.Element {
|
|
const { identity, isProtected, isUnlocked, isLoading } = useIdentity();
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div role="status" aria-live="polite" aria-busy="true">
|
|
Chargement…
|
|
</div>
|
|
);
|
|
}
|
|
if (identity !== null && isProtected && !isUnlocked) {
|
|
return <UnlockScreen />;
|
|
}
|
|
return <AppContent />;
|
|
}
|
|
|
|
function AppRoot(): JSX.Element {
|
|
const bypass = usePairingDisplayBypass();
|
|
return (
|
|
<PairingWordsProvider>
|
|
<GlobalActionBar />
|
|
{bypass ? <PairingDisplayScreen /> : <AppGate />}
|
|
</PairingWordsProvider>
|
|
);
|
|
}
|
|
|
|
export function App(): JSX.Element {
|
|
return (
|
|
<BrowserRouter>
|
|
<AppRoot />
|
|
</BrowserRouter>
|
|
);
|
|
}
|