Skip to content
initializeSecurity() runs from main.tsx.
- Providers are created in
App.tsx.
- Router renders
SelfHostedDashboard for /.
getDatabaseProvider() reads the selected provider (supabase or sqlite) from local storage.
- If no provider is configured, the database configuration UI is shown.
- For Supabase: credentials are tested and then persisted to local storage; the Supabase client is refreshed with new credentials.
- For SQLite: no credentials are needed; the sql.js engine initialises the schema automatically on first open.
PassphraseGate loads the active username context and checks whether that user has vault_config.
- Existing user path: verifies passphrase via bcrypt for new format or unwraps legacy DEK.
- New user path: Create New User opens
UserRegistration, validates uniqueness, and calls registerNewUser(...).
- Registration creates an isolated vault (
raw_dek + bcrypt_hash) and default categories for that username.
- On unlock, dashboard interactions can encrypt/decrypt secrets.
DashboardSettings -> User Management lists registered usernames from vault_config.
UserSwitcher updates active username context and forces a clean reload/lock transition.
- Target user must still unlock with that user’s passphrase before secrets are readable.
- Add/edit modal captures metadata and secret fields.
- Secret fields are encrypted via
useEncryption().encryptCredential().
- Row is inserted/updated in
credentials with secret_blob and encrypted_at.
- Edit flow can decrypt
secret_blob via useEncryption().decryptCredential() to prefill fields.
- Detail flow (
CredentialDetailModal) also decrypts secret_blob when vault is unlocked, allowing secure reveal/copy actions without entering edit mode.
- Vault auto-lock timeout defaults to 15 minutes.
- Timer resets on vault activity.
- Lock clears in-memory key references and returns app to locked state.