diff --git a/website/DEMO_MODE.md b/website/DEMO_MODE.md index 9a50a45..a9bdc54 100644 --- a/website/DEMO_MODE.md +++ b/website/DEMO_MODE.md @@ -71,7 +71,8 @@ routes in `module.json` (DM1, §3.2). ```json "demoLocks": [ { "method": "PUT", "path": "/admin/rust/servers/:id" }, - { "method": "DELETE", "path": "/admin/rust/servers/:id" } + { "method": "DELETE", "path": "/admin/rust/servers/:id" }, + { "method": "DELETE", "path": "/player/rust/links/:steamId" } ] ``` @@ -118,6 +119,7 @@ so the server cannot tell which row in `GET /auth/me/sessions` is the caller's o | --- | --- | --- | | The link to the rig | `PUT`/`DELETE /admin/rust/servers/:id` | Repoint or delete the sidecar link; the site goes dark | | The bridge's config, **read or written** | `GET`/`POST /admin/rust/config/:serverId/file`, `GET …/writes…` for the `RunicGateway` plugin's files, which are also left out of `GET …/files` | It holds the bridge's link to the sidecar and its credentials. Read, it would let someone talk to the sidecar directly over HTTP (DM14, §3.5) | +| Removing a Steam link (DM27) | `DELETE /player/rust/links/:steamId` (`demoLocks`), and staff's `DELETE /admin/users/:id/rust/links/:steamId`, which the module's handler refuses behind `ctx.demoMode` because it serves under core's users mount, where a module may not declare a lock | `demo-player`'s stand-in link is what its Rust pages, rewards and permission grants hang on; unlinked, the player tour is empty until the wipe | **Settings stay open (DM2).** Theme, navigation and the other `PUT /admin/settings` values can be changed and come back at the wipe, except the keys in the "Settings that reach a lock" row above. @@ -366,7 +368,10 @@ current `rust-oxide`. **Done:** the org lead created the subuser and added the s - creates the four accounts (§4), or resets them if they exist: password, role, active, 2FA off; - sets the site live with registration disabled, plus any `settings` the fixture adds; - writes the seeded site content: news posts, wiki pages, pages and the demo events. It does - this only on the first run against a database, so a re-run never duplicates it; + this only on the first run against a database, so a re-run never duplicates it. With the + events it switches on, in the events switchboard (EVENTS.md §K), every action their steps + use, uncapped. A fresh database starts every `change` and `irreversible` action switched + off, so without this the seeded events could not run (DM28); - hands each installed module its `modules.` section through the module's `onDemoSeed` hook (DM15, `MODULE_API` 1.18.0). The Rust module writes its own server row, with the rig's sidecar URL and token, and `demo-player`'s stand-in Steam link (DM6), and the default set's NPC faction @@ -487,6 +492,9 @@ down. | DM24 | (build, step 5) The module's demo code was on `edge` only, so no release could be installed. Cut over? | **Yes, now:** `Module-Rust` `edge` → `main` releases v0.6.0, the first with `protocol` in its install manifest | | DM25 | (amendment, 2026-10-27) Uploads are locked, but an image pasted into rich text is saved as a `data:` URI inside the JSON body. Block it? | **Yes, on every write and for every `data:` URI.** Core refuses any write whose JSON body has a `data:` URI in any string, on any route, the same way the multipart rule needs no list (§3.3) | | DM26 | (build, step 5, 2026-10-27) The restored rig is marked managed, so a fresh site adopts none of its NPC profiles and empties them on its first push; chat styles are never adopted. How does the default set bring them back? | **Seed them.** Module-Rust's `onDemoSeed` also takes `npcs` (factions, profiles) and `chat` (a style per group), written before the site's first sync (§7.1, §7.3). Patch release v0.6.1 | +| DM27 | (step-5 walk, W4, 2026-10-28) `demo-player` can remove its stand-in Steam link, and staff can remove it from Admin → Users. Lock it, or leave it to the wipe? | **Lock it, both ways.** The player's route through `demoLocks`; the staff route in its handler, because it serves under core's users mount (§3.3). Module-Rust patch release | +| DM28 | (step-5 walk, W1, 2026-10-28) The seeded events' actions start switched off on a fresh database, so they fail when run. Fix? | **Yes.** `seed:demo` switches on every action a seeded event uses, uncapped, with the events (§7.3). Core only, no `MODULE_API` change | +| DM29 | (step-5 walk, W2, 2026-10-28) `SECRET_WORDS` also hides harmless fields such as "Allow Master Key" and "TC Auth Only". Narrow it? | **No, leave it as is** | 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 @@ -560,5 +568,54 @@ through that proxy. chat titles (DM26). **Public URL:** `demo.runicgateway.com` is served through Pangolin. Cloudflare's proxy in front of it made the app log Cloudflare's addresses as the visitors' IPs, under the default `TRUST_PROXY=1`. Cloudflare was set to DNS only, and the app now logs the real visitor. + DM26 then seeded the NPC profiles and chat titles, and restored wipes 378 and 381 brought the + whole default set back. + + **The walk (2026-10-28)**, on `website` `main`, `Module-Rust` v0.6.1 and Rust bundle 2026.10.22, + with the rig on Rust build 26139947 (the public branch that day): + - **Every lock, through the API:** all 87 checks passed. They cover each Tier A row for all three + published logins, the case and trailing-slash forms, the four upload routes, multipart sent to + an unlisted core route and to a module route, the `data:` URI forms (plain, `data:`, split + by a newline, in the hero draft, in a module write), both server-link locks, the bridge's config + under four spellings for reading and writing, the file list and write history without the + bridge, the Servers view without the sidecar URL, a redacted field, the raw-JSON save, a form + edit of a flagged field, and `noindex`. Prose containing `Data:` still saves. + - **The deny list at save:** 21 checks. Every §3.4 command was refused in a run step, under + each spelling (`global.`, `o.`, upper case, padding), in a teardown command, in a reward step + and in an edit of an existing event. The open commands (`say`, `server.writecfg`, `env.*`, + `weather.*`, `oxide.grant`, `kick`) all saved. + - **The deny list at run:** this half cannot be reached on the live demo, because every save path + asks first. It was run on a local core instead, on the v0.6.1 release tarball: an event holding + `quit` was saved and published with `DEMO_MODE` off, the core was restarted with it on, and the + run's step failed with the deny sentence before any command was sent. + - **In the browser**, as `demo-player`, `demo-moderator` and `demo-admin`: the strip, the logins + and **Use** buttons, the toast and the inline line on a refused username change, the moderator's + queues, and the hero editor saving and previewing its draft while Publish is refused. The config + editor left the bridge out and showed a redacted field read-only. A config change to AutoDoors + saved, reloaded the plugin on the rig and appeared in the history. The browser half ran + against the host's LAN address, because Chrome on the walking machine would not open the + public name, although `curl` and the emulator did. + - **In the app** (`Android-app` `edge`, debug build, public HTTPS address): the Home strip, sign-in + as `demo-admin`, and the maintenance switch refused with the inline line and the snackbar. + - **One wipe cycle:** before the 08:00 UTC wipe the walk changed AutoDoors' config, took a + permission out of `vip` and retitled it, deleted the `guard-1` placement, edited the greeting + event, added to the hero draft and enabled an event action. After the wipe all of them were + back as the default set has them, with all four NPCs alive. The site reseeded at 08:07 and the + rig was fully back at 08:17. + + **Found by the walk** (the org lead's answers, 2026-10-28): + - **The seeded events could not run.** A fresh database has every event action switched off, so + Server greeting, Treasure drop and Payday showed as ready but failed when started ("not + enabled on this deployment"). **Fixed (DM28):** the seed switches on the actions they use. + - **The credential check over-flags.** `SECRET_WORDS` matches words such as `key` and `auth` + inside longer names ("Allow Master Key", "TC Auth Only", a drone preset key), so on the demo + those harmless fields are hidden and read-only. **Left as is (DM29).** + - **`play-review` was not walked**: its password is only in the host's `.env`. It is read on the + host and walked after the two fixes land. + - `demo-player` could remove its stand-in Steam link, and staff could remove it for them. + **Locked (DM27).** + - The public URL did not open in Chrome on the walker's PC, while curl and the emulator reached + it; the org lead opened it through the proxy without trouble, so it is local to that PC. + - Nothing seeds the moderation queues, so the moderator tour shows empty lists. 6. **Play**: the sign-in details in the Play Console point at `play-review`; runicgateway.com `/beta` publishes the logins.