Publish menus from the browser instead of scp
The admin signs in with the shared password, creates a Menu Set, drops photos into it (shrunk in the browser first), reorders Pages by dragging or with up/down buttons, previews the Draft exactly as customers would see it, and publishes it over the previous set. Restore and delete close the loop. Mutations need a session, a same-origin request and a CSRF token derived from the session; a Draft's media is served only to a session holder.
This commit is contained in:
1 parent
9cb4021229
commit
58ecfa0dc3
14 files changed
+1824
-15
No files matched your search
@@ -6,10 +6,11 @@ photographed Pages, replacing the `scp`-a-JPG workflow. One instance per Site;
|
||||
|
||||
## Status
|
||||
|
||||
Built: Site config, the Menu Set store, the image pipeline, and the
|
||||
Built: Site config, the Menu Set store, the image pipeline, the
|
||||
customer-facing renderer (landing page, Section pages, archived sets, media
|
||||
route) with the approved design. Not yet built: the admin, the container and
|
||||
the Ansible role.
|
||||
route) with the approved design, and the admin (sign in, create a set, upload
|
||||
and reorder Pages, preview, publish, restore, delete). Not yet built: the
|
||||
container, the Ansible playbook and the deploy.
|
||||
|
||||
## Layout
|
||||
|
||||
@@ -19,9 +20,10 @@ src/storage/manifest.ts Manifest type, validation, atomic JSON writes
|
||||
src/storage/sets.ts The Menu Set store: create, add Pages, publish, restore, delete
|
||||
src/storage/validate.ts Boot validation: fatal problems and warnings
|
||||
src/images/pipeline.ts sharp variants: Original, Viewing image, Thumbnail
|
||||
src/auth.ts scrypt password hash, signed session cookie, login throttle
|
||||
src/render/ HTML builder, document shell, the customer pages
|
||||
src/auth.ts scrypt password hash, session cookie, login throttle, CSRF
|
||||
src/render/ HTML builder, document shell, the customer pages, the admin
|
||||
src/routes/public.ts Landing, Section, archive and media routes
|
||||
src/routes/admin.ts Sign in, dashboard, editor, upload, publish, restore, delete
|
||||
src/server.ts buildApp (what tests drive) and main (what the container runs)
|
||||
public/ Hand-written CSS, ~2KB of progressive-enhancement JS, Archivo
|
||||
config/ Per-Site config, one file per Site
|
||||
@@ -42,6 +44,20 @@ npm run seed # placeholder Pages in .dev/data, for design review
|
||||
npm run dev # http://localhost:3000 against .dev
|
||||
```
|
||||
|
||||
To sign in locally, put a password hash in `.dev/site.env`:
|
||||
|
||||
```sh
|
||||
printf 'ADMIN_PASSWORD_HASH=%s\nSESSION_SECRET=%s\n' \
|
||||
"$(node -e "import('./src/auth.ts').then(async m => process.stdout.write(await m.hashPassword('your password')))")" \
|
||||
"$(node -e "process.stdout.write(require('node:crypto').randomBytes(32).toString('base64url'))")" \
|
||||
> .dev/site.env
|
||||
```
|
||||
|
||||
## Who can do what
|
||||
|
||||
`/` and `/<section>/` are public. `/admin` needs the password; a Draft's Pages
|
||||
are served only to a signed-in session, and Originals have no route at all.
|
||||
|
||||
## Storage model
|
||||
|
||||
```
|
||||
|
||||
Reference in new issue
Block a user