Phase 8: optional accounts, per-user data, shared demo key
Guest-first multi-user mode behind AIDND_MULTI_USER (local installs unchanged): signed-cookie guest sessions bootstrapped by /api/auth/me, register upgrades the guest in place, login/logout, per-IP rate limits. Every router scoped by user_id; Settings become per-user with the API key Fernet-encrypted at rest and write-only through the API. Users without a key get a server-funded demo key (OpenRouter free models, 20 turns/day, memory bank disabled on demo turns). Public read-only demo scenarios (seed_demo.py); debug log restricted to local mode. Frontend: auth modal + guest nudge, 401 re-establish/retry, demo banner and key management in Settings. Migrations 13-23 adopt existing data under a local user and encrypt stored keys. Verified: migration on a copy of real data.db, two-session isolation + register/login via curl and Chrome, demo cap 429, live OpenRouter turn through the encrypted-key path, vite build + oxlint. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KFsGHju9szibJJa2YJcdbg
This commit is contained in:
co-authored by
Claude Fable 5
parent
253b533d3b
commit
de4db373f2
@@ -94,6 +94,56 @@ a:hover { color: var(--accent-bright); }
|
||||
}
|
||||
.topnav a.navlink:hover { color: var(--text); }
|
||||
|
||||
/* Phase 8: account area (hosted multi-user mode only) */
|
||||
.nav-account {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
min-width: 0;
|
||||
}
|
||||
.nav-account button { padding: 5px 12px; font-size: 0.82rem; }
|
||||
.guest-nudge {
|
||||
color: var(--text-dim);
|
||||
font-size: 0.78rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.account-email {
|
||||
color: var(--text-dim);
|
||||
font-size: 0.82rem;
|
||||
max-width: 220px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
button.linklike {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
color: var(--accent);
|
||||
font-size: 0.82rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
button.linklike:hover { text-decoration: underline; }
|
||||
@media (max-width: 900px) {
|
||||
.guest-nudge { display: none; }
|
||||
}
|
||||
|
||||
/* Phase 8: demo-key banner (Settings) */
|
||||
.demo-banner {
|
||||
border: 1px solid var(--border-bright);
|
||||
border-left: 3px solid var(--accent);
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
margin-bottom: 18px;
|
||||
color: var(--text-dim);
|
||||
font-size: 0.88rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.demo-banner strong { color: var(--accent-bright); }
|
||||
|
||||
.page {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
|
||||
Reference in New Issue
Block a user