docs(website): record slice 1, and correct two rules it disproved
The install service and admin API as built (website#142), plus the two things §2.7.2 got wrong before there was any code to check them against. The top-level directory rule was checking against nothing real. module-uo's release workflow packs module-uo-<version>/, not uo/, so "reject a top-level directory whose name is not the manifest's id" would have refused every bundle that exists. That level is stripped instead - its name belongs to whoever published the bundle, the directory it lands in has to be the id the loader scans for - and what replaces the check is stronger: the UNPACKED module.json must agree with the install manifest about id and version. And tar has to be pinned forward rather than merely depended on. Installing it gets 6.x, which npm audit reports as critical, and the advisory list reads as this feature's own threat model: hardlink traversal via drive-relative linkpath, symlink poisoning, hardlink escape through a symlink chain, PAX size override on GNU long-name headers, decompression DoS. Refusing symlink and hardlink entry types outright is what takes the extractor off most of that list rather than depending on the library to contain them. Also records the measurement behind the two-pass unpack, which was assumed in the plan and is now known: node-tar DOES reject an escaping member, but late. An archive whose fourth member escapes throws and leaves the first three on disk - and the loader only asks whether module.json is present, so a half-unpacked bundle is a module as far as the next boot is concerned. Refreshes api-route-inventory.json (158 -> 166 public) and the route count in BACKEND_DESIGN, and documents module_source_hosts beside the other seeded settings keys - bootstrapped from the environment, owned by the database. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -275,7 +275,15 @@ Seeded with the 8 spec categories: `new-player-guide, maps-atlas, systems, items
|
||||
Seeded keys: `site_mode` (default `maintenance`), `site_mode_changed_at`,
|
||||
`site_mode_changed_by`, `maintenance_message`, `status_message`, `homepage_teaser`,
|
||||
`contact_email` (=UOMysticmoon@gmail.com), `site_title`, `player_registration`
|
||||
(default `disabled`), `mobile_app_links_enabled`.
|
||||
(default `disabled`), `mobile_app_links_enabled`, `module_source_hosts`.
|
||||
|
||||
`module_source_hosts` is the allowlist of hostnames a module may be installed from
|
||||
(MODULE_SYSTEM.md §2.7.2 decision 6), edited in Admin → Modules and audited as
|
||||
`module.sources`. It is **bootstrapped** from `MODULE_SOURCE_HOSTS` and not owned by
|
||||
it: `seedDefault` is an `INSERT IGNORE`, so the environment supplies a default on a
|
||||
fresh install and changing the variable later cannot reach back in and overwrite what
|
||||
an operator chose. Installs are `https`-only, every redirect hop is re-checked against
|
||||
this list, and an empty value forbids every install rather than allowing every host.
|
||||
|
||||
**Keys a MODULE seeds into this table.** `settings` is core's, but a module's
|
||||
schema fragment may `INSERT IGNORE` its own rows into it, and module-uo seeds two:
|
||||
@@ -731,7 +739,7 @@ are authoritative, and they answer different questions:
|
||||
|
||||
| Artifact | Source of truth for | Generated by |
|
||||
|---|---|---|
|
||||
| `server/routes.manifest.json` — mirrored as [api-route-inventory.json](./api-route-inventory.json) | **What URLs CORE serves.** 158 public routes + 2 on the internal listener, sorted, method + path only. | `npm run routes:manifest`, by walking the live Express stack |
|
||||
| `server/routes.manifest.json` — mirrored as [api-route-inventory.json](./api-route-inventory.json) | **What URLs CORE serves.** 166 public routes + 2 on the internal listener, sorted, method + path only. | `npm run routes:manifest`, by walking the live Express stack |
|
||||
| `server/swagger/swagger-output.json` — merged into `/api/docs` | **What each core route means.** Parameters, bodies, response codes, security. | `npm run swagger`, from `#swagger.*` annotations |
|
||||
|
||||
Both are **core's**. An installed module's routes are in neither: they are in that module's own
|
||||
|
||||
Reference in New Issue
Block a user