Skip to content

Admin Area

j5guy edited this page Jul 25, 2026 · 2 revisions

Admin Area

Becoming an admin

There's no promote-a-user button — admin status is granted exactly once, at account creation:

  • Set ADMIN_EMAIL in .env to the email address that should be an admin, before that account is created (signup, or restoring from a backup). Whichever account is created with that email gets isAdmin: true at creation time; changing ADMIN_EMAIL afterward doesn't retroactively grant it to an account that already exists.
  • To grant it to an existing account instead, update the user document directly in MongoDB (db.users.updateOne({ email: "..." }, { $set: { isAdmin: true } })), then log out and back in — login re-reads isAdmin from the database into the session. This only ever flips a boolean; it never touches vault key material, so it can't be used to read anyone's encrypted data.

Admins get an Admin link in the nav bar, and access to everything below at /admin — anyone else hitting /admin gets a 403.

Categories and tags

Shared taxonomy used to organize waypoints across every account on the deployment (not per-user).

  • Categories — a name plus a color swatch.
  • Tags — name only.

Any authenticated user can create a new category or tag (used by a "create if missing" flow in the vault UI, so people aren't blocked waiting on an admin for a new label) — but renaming or deleting either is admin-only, since both are shared and a rename/delete affects every account using them.

Email (SMTP)

Configure outbound email (invite / access-request / access-granted notifications) directly from the UI, without editing .env or redeploying:

  • Host / Port / Implicit TLS / Username / Password / From address — the same fields .env's SMTP_* variables cover. Saving here takes priority over .env and applies immediately.
  • Save stores the settings in MongoDB — the password is AES-256-GCM encrypted at rest (keyed off sessionSecret) and is never sent back to the browser; leave the password field blank on a later save to keep the one already stored.
  • Test connection verifies the (unsaved or saved) settings by actually logging in to the SMTP server, without sending anything.
  • Reset to .env clears the database override and falls back to whatever's in .env (or "not configured" if that's blank too).

A status badge shows which source is currently active — Configured (database), Configured (.env), or Not configured. The public status page (/status) also checks this and links straight back here if email is down or unconfigured.

Scheduled backups

Dumps every account's vault straight from the database on a schedule, for whole-server disaster recovery — distinct from the per-account export any user can trigger themselves from Settings (see Backup and Restore). Same zero-decryption property: nothing here needs anyone's master password.

  • Enable, set a frequency (hours between runs) and a retention count (how many backup files to keep before the oldest are deleted automatically). Saving takes priority over .env (BACKUP_ENABLED/BACKUP_FREQUENCY_HOURS/BACKUP_RETENTION_COUNT) and applies within 15 minutes, no redeploy needed.
  • Run backup now triggers one immediately, rather than waiting for it to come due.
  • The list below shows every backup file currently on disk, with a Download link for each.
  • Restoring one — including onto a brand new deployment, on different MongoDB entirely — is a CLI step (node scripts/restoreFullBackup.js <file>), covered in Backup and Restore.

Audit log

/admin/audit-log — the most recent 200 events (time, action, actor, target, IP). Append-only; never contains vault contents or key material, only what happened and who did it. Tracked actions: account login/lockout/password changes, recovery kit generation and use, account restores, waypoint create/update/delete, upload add/delete, trusted-contact invites/acceptance/confirmation, emergency access requests/denials/grants/revocations, SMTP settings changes, and scheduled-backup settings changes/manual runs/downloads.

Manually triggering the emergency-access promotion job

The scheduled job that auto-grants access requests past their waiting period runs automatically every ~15 minutes (services/jobs/scheduler.js, started from server.js). To trigger it immediately instead of waiting real days:

npm run promote-grants
# or, in Docker:
docker compose exec app node scripts/runPromoteGrants.js

Clone this wiki locally