Skip to content

feat: one-time admin setup, admin-only password login and account administration - #119

Merged
flexdinesh merged 1 commit into
mainfrom
feat/admin-identity
Oct 26, 2026
Merged

flexdinesh merged 1 commit into
mainfrom
feat/admin-identity

Conversation

@flexdinesh

@flexdinesh flexdinesh commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Stack 1/3: one admin, admin-only password sign-in, account administration.

  • Behavior owner and resulting change: identityservice owns admin setup and administration rules; reviewstore persists them. While no admin exists, each start stores a hashed one-time setup secret (24h, replaced on restart) and logs <public URL>/setup#t=…. Setup creates the single admin in one transaction. Password login (/admin/login, unlinked) is admin only; refusals are the same 401. Admin routes list, disable, enable and delete accounts (/api/v2/admin/users*); the admin cannot disable or delete itself. Disabling revokes sessions and tokens in the same transaction; deleting removes the account's data and queued jobs; both evict running services. Removed: public signup, DIFFX_SERVER_USERNAME/PASSWORD/SIGNUP_ENABLED bootstrap, diffx-server user create. user reset-password recovers only the admin. Web: /setup and /admin/login pages; members see a not-yet-available sign-in notice; password settings admin only.
  • Contracts/invariants affected; local/remote implications: schema 13 adds tables only (admin_account, admin_setup, disabled_accounts, google_identities, account_invites, google_auth_states); 11 and 12 upgrade in place. OpenAPI: signup removed; /api/v2/setup GET/POST; admin user routes; AccountUser.admin; Bootstrap.googleEnabled replaces signupEnabled. New DIFFX_SERVER_PUBLIC_URL / --public-url. Local mode unaffected (googleEnabled false, no account pages).
  • Validation results; remaining risks: mise run check and the pre-push suite pass. Store tests: setup once, expiry, concurrent setup yields one admin, disable/delete. Transport tests: setup flow, admin-only login, admin routes require admin session and CSRF, restart persistence. Real-binary script (18 checks): link logged/rotated/hashed/single use, signup gone, self-disable 403, no link once an admin exists, reset-password. Risk: a reload of /setup after the fragment is read loses the token (the link still works).
  • Intentional architecture/design changes and rationale: identity bootstrap from env/flags is replaced by a logged one-time link so no default credential exists. testsupport gains identity helpers (boundary rule updated). Docs: system.md, architecture.md, development.md, release.md, docs site.
  • UI evidence: /setup strips the secret from the URL before any request; checked in the browser on desktop; uses existing auth page layout and form primitives.

…inistration

Schema 13 adds admin, setup, disabled-account, Google identity and invite
tables. Startup logs a hashed 24h setup link while no admin exists. Password
login is admin only; admin routes list, disable, enable and delete accounts.
Removes public signup, env bootstrap and user create.
@flexdinesh
flexdinesh added this pull request to stack #122 October 26, 2026 13:32
@flexdinesh
flexdinesh merged commit 2adae84 into main Oct 26, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant