Add administrator sign-in and private-safe room directory

Connect personal operator-provisioned admin keys, persisted roles and eight-hour sessions, current/all-session revocation and a filtered room directory. Additive schema protects final owner, revokes disabled accounts and records safe audit history. No game state changes; remaining administration scope stays explicit.

Verified: typecheck, lint, 5196 offline tests, 52 HTTP tests, production build; authenticated local HTTP and desktop/mobile browser checks. Independent privacy/security review fixed malformed nested roster searches and read-time session revocation. Preserved 1,671 prior rooms and 3,538 seats. Container/deployed acceptance follows publication.
This commit is contained in:
Quintine committed 2026-09-22 09:36:11 +10:00
1 parent 36a03bda9c
commit c2d392e155
27 files changed
+3164 -13

No files matched your search

+94 -4
View File
@@ -1,15 +1,16 @@
# Administration panel requirements
Added to the goal on 22 September 2026 at the user's request. This is required
product scope, not a claim that the panel is implemented. Reuse the existing
room, session, recovery and persistence systems where suitable.
product scope. The first access and directory prototype is available at `/admin`;
the remaining room operations are unfinished. Reuse the existing room, session,
recovery and persistence systems where suitable.
## Required capabilities
| Area | Required behavior | Stage |
| --- | --- | --- |
| Administrator access | Secure administrator sign-in, server-enforced permissions, session revocation and a documented initial-owner setup. A room host is not automatically a site administrator. | Missing |
| Room directory | Search, filter, sort and paginate rooms; show lifecycle status, host, roster, rules/modules, last activity and pending decision ownership without exposing private game information. | Missing |
| Administrator access | Personal access keys, server-enforced owner/operator/viewer roles, persistent eight-hour sessions, individual/all-session sign-out and operator provisioning/revocation. A room host is not a site administrator. Account-management UI and further operational permissions remain. | Prototyped |
| Room directory | Search room codes/public player names, filter status/rules, sort and paginate; show host, roster, modules, game change time and bounded decision ownership. Detailed setup/shared-window ownership and later lifecycle metadata remain. | Prototyped |
| Create and configure | Create rooms with supported rules and human/AI seats, manage lobby settings and invitations, and assign a host through an explicit workflow. Preserve normal prerequisites and readiness rules. | Missing |
| Lifecycle and removal | Pause/resume, lock/unlock new joins, close/end, archive, restore and delete selected rooms. Offer recoverable removal and explicit permanent deletion with clear scope, consequences and safeguards for related records. | Missing |
| Participant support | Remove disruptive participants or revoke access, manage appropriate restrictions, assist saved-seat recovery and host reassignment, and use supported AI takeover/replacement without losing forces, cards or decisions. | Missing |
@@ -20,6 +21,95 @@ Track each area through Missing, Prototyped, Integrated, Verified and Polished.
As implementation begins, link its controls, server actions, persistence,
documentation and evidence. A working directory alone is not a full admin panel.
## Access and directory prototype
Use **Administration** in the home-page footer or visit `/admin`. Every directory
request checks a separate administrator session; seat cookies and forwarded
identity headers cannot grant access. The standalone NAS runtime has no trusted
Sites identity dispatcher, so this panel uses separately provisioned personal
keys. Each key contains a random 256-bit secret. Only its SHA-256 hash is stored;
sign-in issues a separate random, hashed session with an eight-hour absolute
expiry. HTTPS uses Secure, HttpOnly, SameSite=Strict cookies scoped to the admin
API. Mutations require the exact configured origin and bounded JSON requests.
All three roles may read the current directory and sign out their own sessions.
Owner/operator mutation capabilities will be added with the room-management
slices. The role is checked from the live account, never accepted from a client.
Disabling an account invalidates its sessions; later re-enabling it cannot restore
them. The database refuses to disable, demote or delete the final enabled owner.
No default key, public account creation or host-to-administrator promotion exists.
The directory uses an explicit field allowlist, independent of any player view.
It never returns hands, Traitors, predictions, plans, private messages, recovery
records or raw saved state. Searches inspect only codes and public player names.
Each page is limited to 25 rooms and repeats authorization in its read transaction
so concurrent revocation cannot expose a later directory snapshot. Malformed
saves are marked unreadable without leaking their contents or breaking searches.
Last game change refers to the room's saved-state timestamp, not private messages.
Shared windows and setup currently use broad pending labels; these labels do not
assert that a human is stalled or identify hidden-card-dependent eligibility.
Implementation: [panel](../app/admin/page.tsx), [access](../db/admin-access.ts),
[directory](../db/admin-directory.ts), [HTTP boundary](../lib/admin-http.ts),
[additive migration](../drizzle/0008_admin_access.sql), and
[operator CLI](../tools/admin-access.mjs). The migration's explicit SQLite triggers
enforce final-owner protection and account revocation/provisioning audit; retain
them when generating future schema changes. Audit browsing is still pending.
### Initial owner and access recovery
From the development checkout, apply additive migrations, then create a personal
owner key in a new private directory outside the checkout:
```sh
npm run db:local
node tools/admin-access.mjs --name 'Owner' --role owner --out /private/dune-owner
npx wrangler d1 execute DB --local --config tools/wrangler.local.json --persist-to .wrangler/state --file /private/dune-owner/provision.sql
```
The parent directory must already exist. Output files are mode 0600 in a new
mode-0700 directory. `access-key.txt` contains the sign-in key; `provision.sql`
contains only its hash. Keep the key in a private password manager or protected
file, outside Git, logs and chat. The command never connects to a database or
prints the key. Apply the SQL only to the intended instance. Do not upload a
development key to production; provision separate accounts there.
For the container, run the bundled CLI inside the existing `dune` container
(using its actual container ID/name), with output such as `/data/admin-owner`.
Apply the generated SQL using `node node_modules/wrangler/bin/wrangler.js d1
execute DB --local --config tools/wrangler.local.json --persist-to /data --file
/data/admin-owner/provision.sql`. A protected volume snapshot should precede
operational changes. Retrieve the key through an authorized private channel and
retain the account ID shown by the CLI. No application restart is needed.
To revoke an account, generate a new private output directory with
`node tools/admin-access.mjs --revoke ACCOUNT_UUID --out /private/dune-revoke`
and apply its `revoke.sql` using the same instance-specific command. To replace
a lost/compromised owner key, provision a replacement owner first, verify access,
then revoke the previous account. Existing games and seats are unchanged.
**Sign out everywhere** revokes browser sessions but keeps the personal key valid.
### Focused verification
```sh
npm test -- admin-access admin-directory admin-http
npm run test:integration -- admin-boundary
node tools/verify-admin.mjs --url http://localhost:3000 --key-file /private/dune-qa/access-key.txt --qa-account ACCOUNT_UUID --out /private/dune-admin-report
```
The HTTP verifier requires a **dedicated QA administrator account** and explicitly
checks its ID before proceeding: it creates one named QA room and signs out all
sessions of that QA account. Never supply a human operator's normal key. It checks
authentication, cookie properties, ordinary-host denial, directory privacy,
session revocation and unchanged game/seat continuation. Private reports retain
room IDs and safe outcomes, never keys/cookies. The container verifier provisions
its own disposable QA account and checks admin-session continuity across restart
and replacement, followed by the HTTP flow and HTTPS-proxy cookie behavior.
Local browser checks cover sign-in, directory filters, refresh restoration and
mobile layout. Final source-bound checks and separately recorded deployed
acceptance accompany each checkpoint; a local pass is not production evidence.
## Behavior and safeguards
Every privileged endpoint must authenticate and authorize its caller. Support
+7 -3
View File
@@ -9,9 +9,13 @@ Expansion starts and full rules/publication acceptance remain gated.**
The user added a complete [administration panel](ADMIN_PANEL.md) to the goal on
22 September: secure admin access, room creation/removal and lifecycle controls,
participant support, backup/restore, operational views and audited actions.
This is required scope, not implemented functionality, and belongs before full
AI refinement/calibration. Existing rules, Git, subagent and preservation
requirements remain in force.
The first prototype now connects separate administrator sign-in, persistent
sessions/revocation and a searchable, filtered, paginated room directory at
`/admin`. Private game contents remain excluded. Operator provisioning and
recovery instructions are in the admin guide. Room creation, lifecycle/removal,
participant support, backups and operational controls remain unfinished; these
belong before full AI refinement/calibration. Existing rules, Git, subagent and
preservation requirements remain in force.
The goal also requires testing the deployed application at
**https://dune.procrastination.games**. Match the running revision, exercise
+17
View File
@@ -1,5 +1,22 @@
# Dune implementation status
## 22 September 2026 — Administrator access and room directory prototype
The first [admin panel](ADMIN_PANEL.md#access-and-directory-prototype) slice adds
personal operator-provisioned keys, live owner/operator/viewer permissions,
separate persistent eight-hour sessions, current/all-session sign-out and a
privacy-preserving room directory. Additive schema/trigger changes protect the
last enabled owner, invalidate disabled-account sessions and retain safe audit
events. Filters, paging, public roster inspection, refresh and mobile controls
are connected; no existing game state is rewritten.
Independent review found and resolved malformed-roster search failure and a
revocation race at directory reads. Focused auth/SQL/privacy tests, authenticated
HTTP and local browser checks precede source-bound check/build/integration and
deployed acceptance. Evidence and actual final results belong to the checkpoint
report. Room lifecycle, creation, participant support, backups, audit browsing
and complete administration acceptance remain open; AI refinement remains gated.
## 22 September 2026 — Administration and deployed verification added to the goal
The user requested a complete [admin panel](ADMIN_PANEL.md), including adding