5.4 KiB
5.4 KiB
Per-User Profile Directory System
Problem
When logging in as a new user (different nsec), the browser:
- Restores the previous user's tabs (session restore from global SQLite)
- Shows the previous user's Nostr events on the profile page
- Shows the previous user's bookmarks, history, and recents
Solution
Create a per-user profile directory keyed by npub, with each user getting their own SQLite database, session, bookmarks, and history.
Directory Structure
~/.sovereign_browser/
├── identity.json # last used npub (for login dialog default)
├── global.db # global settings (agent server, theme, shortcuts, inspector)
└── profiles/
├── npub1abc.../
│ ├── browser.db # per-user: events, history, session, bookmarks, key_value
│ └── identity.json # this user's nsec/npub
├── npub1def.../
│ ├── browser.db
│ └── identity.json
└── ...
What Stays Global vs Per-User
Global (in ~/.sovereign_browser/global.db)
agent_server_enabled,agent_server_port,agent_allowed_origins,agent_login_timeout_mstheme_darkshortcut.*(keyboard shortcuts)inspector_x/y/w/hdev_extras,file_access,universal_access(security settings — these are WebKit-level, not per-user)
Per-User (in ~/.sovereign_browser/profiles/<npub>/browser.db)
restore_session,new_tab_url,tab_bar_position,show_tab_close_buttons,middle_click_close,ctrl_tab_switch,max_tabs,tab_drag_reorderbootstrap_relays,search_engine- Session (open tabs)
- History
- Bookmarks
- Nostr events (kind 0, 3, 10002)
- key_value table (per-user settings)
Implementation Steps
Step 1: Add db_init_with_path(const char *path) to db.c
Currently db_init() hardcodes ~/.sovereign_browser/browser.db. Add a variant that takes a path. Keep db_init() for the global database.
Step 2: Add profile directory management
New functions in a profile.c module (or add to key_store.c):
profile_get_dir(const char *npub, char *out, size_t out_sz)— returns~/.sovereign_browser/profiles/<npub>/profile_ensure_dir(const char *npub)— creates the directory if it doesn't existprofile_get_db_path(const char *npub, char *out, size_t out_sz)— returns~/.sovereign_browser/profiles/<npub>/browser.dbprofile_get_identity_path(const char *npub, char *out, size_t out_sz)— returns~/.sovereign_browser/profiles/<npub>/identity.json
Step 3: Split settings into global and per-user
In settings.c:
settings_load_global()— loads from global.db (agent server, theme, shortcuts, inspector, security)settings_load_user()— loads from the per-user browser.db (session, tabs, relays, search)settings_save_global()— saves global settings to global.dbsettings_save_user()— saves per-user settings to browser.db
Or simpler: keep one settings_load() / settings_save() but have it read from the appropriate database based on which keys are global vs per-user.
Step 4: Change the login flow in main.c
Current flow:
db_init()— opens global browser.dbsettings_load()— loads all settings from browser.dbshortcuts_load()— loads shortcuts from browser.db- Login (GTK dialog or agent login or CLI)
relay_fetch()— fetches events from relayssession_restore()— restores tabs from browser.db
New flow:
db_init_global()— opens global.db for global settingssettings_load_global()— loads global settings (agent server, theme, shortcuts, inspector)shortcuts_load()— loads shortcuts from global.db- Login — get npub
profile_ensure_dir(npub)— create~/.sovereign_browser/profiles/<npub>/db_init_user(npub)— close global.db, openprofiles/<npub>/browser.dbsettings_load_user()— load per-user settings from browser.dbrelay_fetch()— fetch events from relays into per-user browser.dbsession_restore()— restore tabs from per-user browser.db
Step 5: Migration
On first run with the new system:
- If
~/.sovereign_browser/browser.dbexists and~/.sovereign_browser/profiles/doesn't:- After login, copy
browser.dbtoprofiles/<npub>/browser.db - Move global settings from browser.db to global.db
- Keep browser.db as backup (or rename to browser.db.old)
- After login, copy
Step 6: Identity persistence
~/.sovereign_browser/identity.json— stores the last-used npub (not nsec)~/.sovereign_browser/profiles/<npub>/identity.json— stores the nsec/npub for that profile- On startup, read the last-used npub from global identity.json to pre-fill the login dialog
Files to Modify
src/db.c/src/db.h— adddb_init_with_path(),db_close(),db_init_global()src/settings.c/src/settings.h— split into global/per-user load/savesrc/main.c— change the startup flowsrc/key_store.c— update identity persistence to per-profilesrc/session.c— no change (already uses db_session_* which will use the per-user db)src/shortcuts.c— load from global.db instead of browser.db- New:
src/profile.c/src/profile.h— profile directory management
Risk Assessment
- Medium risk — changes the database initialization flow which affects all data access
- Migration needed — existing users need their data moved to per-profile dirs
- Testing needed — login with different users, verify data isolation