lilith-platform.live/codebase/@features/vip/docs/settings.md

81 lines
3.5 KiB
Markdown
Raw Normal View History

# Settings Tab
**Nav id**: `settings`
**Icon**: ⚙
---
## What it shows
The client's security and encryption status — current encryption algorithm and KDF parameters, password change form, and a record count summary (messages, meetings, etc.).
---
## Data flow
`getEncryptionSettings(token)``GET /vip/settings/encryption?token=<token>` — returns `VipSettingsResponse`.
---
## Settings response object
```typescript
interface VipSettingsResponse {
encryption: VipEncryptionSettings | { enabled: false }
records?: Record<string, number> // e.g. { messages: 42, meetings: 3, gifts: 1 }
}
interface VipEncryptionSettings {
enabled: true
algorithm: string // e.g. "AES-256-GCM"
kdf: string // e.g. "PBKDF2"
kdfIterations: number
keyCreatedAt: string | null
loginBenchmarkMs: number | null
}
```
---
## Encryption section
Displays status badge (Active / Not set up), algorithm, KDF + iteration count, key creation date, and last-login KDF benchmark in milliseconds (useful for performance tuning).
The "Change password" / "Set up encryption" button toggles an inline form. On submit, `setupPassword(token, newPw)` re-derives and re-encrypts the content key server-side, returns a fresh `contentKey` which is written back to `sessionStorage`. This means the client does not get logged out when changing their password.
After a successful change, "Password updated — content key re-encrypted." confirmation text appears.
---
## Add to another device (QR login)
A "Show login QR code" button generates a QR code (rendered client-side via `qrcode` to a `<canvas>`) encoding the full portal URL: `window.location.origin + '/' + token`. The client scans it with their phone's camera, which opens the portal URL directly — they then complete their normal password/WebAuthn auth on the new device.
The QR uses the gold/cream palette (`#f0e6d3` dark dots on `#0d0d14` background) and is hidden by default, revealed on demand, with a Hide button to dismiss it.
No server involvement — the QR is generated entirely in-browser from the token already in the component props.
---
## Records section
If `settings.records` is present, renders a card listing each key/count pair. Keys are capitalized for display (`messages``Messages`). This gives the client a lightweight sense of how much data is in their account without exposing raw DB row counts.
---
## WebAuthn
WebAuthn (Face ID / Touch ID) is registered during the first-visit `SetPasswordScreen` flow, not from the Settings tab. There is currently no UI in Settings to add or remove WebAuthn credentials after initial setup. If this is needed, it should be added here.
---
## Dev proxy
In dev, `VITE_API_URL=''` makes all API calls relative. Vite proxies `/vip/*` to `localhost:3030` but the bypass function must list every API sub-path — otherwise Vite returns the SPA HTML instead. `/settings` must be in `apiPaths` in `vite.config.ts` or the tab shows "Could not load settings."
## Non-obvious details
- `setupPassword` is reused for both initial setup (first visit) and password change (Settings tab). The API determines which path to take based on whether a key already exists for the token.
- `loginBenchmarkMs` is written by the server after each successful password verification — it reflects how long PBKDF2/Argon2 derivation took on the server for that client's parameters. Useful for auditing that KDF cost is appropriate.
- The `records` field is optional — the API may omit it if counting is expensive or not yet implemented for a given deployment.