|
|
|
|
@@ -47,8 +47,11 @@ answers:
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The web client shows the message as a toast wherever an action fails with that code. The Android
|
|
|
|
|
app maps the code to a new error kind with the same wording; today it would show the generic
|
|
|
|
|
"Something went wrong", which is misleading for a reviewer.
|
|
|
|
|
app does the same with a snackbar (DM19): an interceptor on its one HTTP client spots the code on
|
|
|
|
|
any `403` and reports the server's sentence, so a module's own wording (a refused console command)
|
|
|
|
|
reaches the screen as written. The screen still shows its own failure line, except where that line
|
|
|
|
|
blames the role ("You don't have permission for that action", on the admin screens), which says the
|
|
|
|
|
demo sentence instead. Load screens get a `DEMO_LOCKED` error kind, with no Retry button.
|
|
|
|
|
|
|
|
|
|
Reads are never locked, with one exception: the bridge's config (§3.5). Every page can be opened
|
|
|
|
|
and every form filled in; only the save is refused. That keeps the demo useful as a tour of the admin panel.
|
|
|
|
|
@@ -103,7 +106,7 @@ wipe puts them back (§7).
|
|
|
|
|
| Other people's sessions | `DELETE /auth/me/sessions/:id` **on a demo account**, whichever session it names (DM17) | Sign every other visitor out of the shared account |
|
|
|
|
|
| Password reset | `POST /auth/password/forgot`, `POST /auth/password/reset/:token` | Reset a demo account's password |
|
|
|
|
|
| Registration | `POST /auth/register` (DM16) | Settings are open, so a visitor could switch `player_registration` on. The route is what keeps registration closed (§4) |
|
|
|
|
|
| Settings that reach a lock | `PUT /admin/settings` when the body names `site_mode*`, `module_source_hosts`, `teams_voice_*` or `demo_*` | That route writes arbitrary keys, so these would get around the site-mode, Modules and team-voice rows above, or rewrite the banner and the published logins. The answer names the keys (`keys: [...]`) |
|
|
|
|
|
| Settings that reach a lock | `PUT /admin/settings` when the body names `site_mode*`, `module_source_hosts`, `teams_voice_*`, `demo_*` or `hero_layout` | That route writes arbitrary keys, so these would get around the site-mode, Modules and team-voice rows above, rewrite the banner and the published logins, or publish the homepage hero (DM21). The answer names the keys (`keys: [...]`) |
|
|
|
|
|
|
|
|
|
|
**Why DM17 locks the whole route.** A mobile access token carries no id for its refresh-token row,
|
|
|
|
|
so the server cannot tell which row in `GET /auth/me/sessions` is the caller's own. Signing out is
|
|
|
|
|
@@ -120,6 +123,12 @@ so the server cannot tell which row in `GET /auth/me/sessions` is the caller's o
|
|
|
|
|
changed and come back at the wipe, except the keys in the "Settings that reach a lock" row above.
|
|
|
|
|
Brand images are uploads, so they fall under the upload lock.
|
|
|
|
|
|
|
|
|
|
**The hero editor previews but does not publish (DM21).** Admin → Hero autosaves to
|
|
|
|
|
`hero_layout_draft`, and its Preview opens the homepage with that draft, so both keep working. Its
|
|
|
|
|
Publish writes `hero_layout`, the hero every visitor sees, and is refused; the editor's status line
|
|
|
|
|
and the toast give the demo sentence. Its image uploads fall under the upload lock. The demo admins
|
|
|
|
|
share one login, so they share one draft, and the wipe resets it.
|
|
|
|
|
|
|
|
|
|
**Which accounts are demo accounts.** The four usernames in §4 are fixed in core
|
|
|
|
|
(`server/src/demo/mode.js`), not read from the seed fixture: the lock checks them on every request,
|
|
|
|
|
and a fixture that dropped one would unlock the account everybody shares. The lock decides by the
|
|
|
|
|
@@ -256,7 +265,8 @@ address with (§5), and the static logins cover every role.
|
|
|
|
|
The seed writes both into one settings row, `demo_state`, which `PUT /admin/settings` cannot touch
|
|
|
|
|
(§3.3). The web client shows a thin strip on every page: "Demo site — anything you change is wiped at
|
|
|
|
|
14:00 UTC. Sign-ins: demo-admin / demo-player … — passwords on the sign-in page". The app shows the same
|
|
|
|
|
strip on Home. Both read `resetsAt`, so neither needs to know the schedule. The time is said in UTC,
|
|
|
|
|
strip on Home, but it does not list the passwords: its strip names the site's sign-in page instead
|
|
|
|
|
("passwords at demo.runicgateway.com/account/login"), DM20. Both read `resetsAt`, so neither needs to know the schedule. The time is said in UTC,
|
|
|
|
|
not converted, so it matches the schedule published on `/beta`.
|
|
|
|
|
|
|
|
|
|
**The toast.** Every web request goes through one request primitive (`client/src/api/client.js`),
|
|
|
|
|
@@ -422,6 +432,9 @@ down.
|
|
|
|
|
| DM16 | (build) Settings are open, so `player_registration` can be switched on. Lock registration? | Yes: **`POST /auth/register`** is a Tier A lock. Invites stay open (§3.3) |
|
|
|
|
|
| DM17 | (build) The server cannot tell which mobile session is the caller's own. What does the other-sessions lock do? | **`DELETE /auth/me/sessions/:id` is locked outright on a demo account**; `POST /auth/mobile/logout` stays open (§3.3) |
|
|
|
|
|
| DM18 | (build, step 2) Saving an event is core's route, and core never asks a module about a step's params. How is a denied command refused at save? | **A new core hook:** an event action's optional `demoRefuses(params)`, asked at create, save and publish on the demo, refusing `403 DEMO_LOCKED` (§3.4). `MODULE_API` 1.19.0; Module-Rust then needs `^1.19.0` |
|
|
|
|
|
| DM19 | (build, step 4) Each app screen writes its own failure line, and the admin screens turn every `403` into "You don't have permission for that action". How does the app show a refusal? | **One app-wide snackbar** with the server's sentence, like the web's toast, and the screens whose `403` line blames the role say the demo sentence instead. `ErrorKind.DEMO_LOCKED` for load screens (§3.1) |
|
|
|
|
|
| DM20 | (build, step 4) Should the app's sign-in screen list the logins, as the web's does? | **No, the banner only.** The Home strip names the site's sign-in page for the passwords; Google's reviewer gets `play-review`'s from the Play Console (§6) |
|
|
|
|
|
| DM21 | (amendment, 2026-10-26) Settings are open, so the hero editor's Publish changes the homepage every visitor sees. What may a visitor do in the hero editor? | **Edit and preview, never publish.** `hero_layout` joins the protected settings keys; the draft and Preview stay open; uploads were already locked. Server lock only: Publish stays clickable and answers the demo sentence (§3.3) |
|
|
|
|
|
|
|
|
|
|
DNS and HTTPS for `demo.runicgateway.com` come from an external reverse proxy, which the org lead is
|
|
|
|
|
setting up. The app sits behind it on plain HTTP; core already trusts one proxy hop for
|
|
|
|
|
@@ -460,14 +473,24 @@ through that proxy.
|
|
|
|
|
that cannot be read never unlocks the file. A config that does not parse is withheld whole on the
|
|
|
|
|
demo, because its secrets cannot be found to redact.
|
|
|
|
|
3. **Kit** (`Integration-kit`): a paragraph on `demoLocks` and `ctx.demoMode`, and the
|
|
|
|
|
`core-ref.json` re-pin. One PR.
|
|
|
|
|
4. **App** (`Android-app`): the `DEMO_LOCKED` error kind and the banner on Home. One PR.
|
|
|
|
|
`core-ref.json` re-pin. One PR. **Built 2026-10-26** as `Integration-kit#17`, pinned to the
|
|
|
|
|
sha `website#224` merged as (1.19.0). Chapter 2 gains a section on a public demo site, which
|
|
|
|
|
also covers `onDemoSeed` (DM15), and chapter 5 covers `demoRefuses` (DM18). Both hooks were
|
|
|
|
|
decided after this list was written. Module-Rust's own pin moved to the same sha in
|
|
|
|
|
`Module-Rust#63`.
|
|
|
|
|
4. **App** (`Android-app`): the `DEMO_LOCKED` error kind and the banner on Home. One PR. **Built
|
|
|
|
|
2026-10-26** as `Android-app#61`, into `edge`, with the snackbar (DM19) and the banner only (DM20).
|
|
|
|
|
The refusal is read in `core/result/DemoLocked.kt` and spotted by `core/net/DemoLockInterceptor`;
|
|
|
|
|
the strip is `ui/demo/DemoBanner`. Checked on an emulator against `website` `main` with
|
|
|
|
|
`DEMO_MODE=true` and `seed:demo`: the strip, a shared login's username change refused, and the
|
|
|
|
|
admin site-mode switch refused with the demo sentence in place of the permission line.
|
|
|
|
|
5. **Deployment** (`website`): `deploy/demo/`, `demo-wipe.yml` (with §7.5's bundle step) and
|
|
|
|
|
`demo-baseline.yml`; the first deploy on `demo-site`; setting up the default set and capturing
|
|
|
|
|
the baseline. Then a walk of every static login, every Tier A lock and the upload lock, in the
|
|
|
|
|
browser and the app, plus one full wipe cycle that restores a changed permission, NPC and
|
|
|
|
|
event; a denied console command refused at save and at run; and a plugin config changed and
|
|
|
|
|
reloaded through the editor, with the bridge's config refused for reading and another plugin's
|
|
|
|
|
secret field redacted. One PR.
|
|
|
|
|
secret field redacted; and the hero editor's draft previewed while its Publish is refused
|
|
|
|
|
(DM21). One PR.
|
|
|
|
|
6. **Play**: the sign-in details in the Play Console point at `play-review`;
|
|
|
|
|
runicgateway.com `/beta` publishes the logins.
|
|
|
|
|
|