From ccb2b702fec70dcb66032ff296ea572b723d6f9e Mon Sep 17 00:00:00 2001 From: NGPixel Date: Sat, 29 Aug 2026 03:22:07 -0400 Subject: [PATCH] feat: remaining auth + mail implementation + sample content utility --- .devcontainer/devcontainer.json | 10 +- .devcontainer/docker-compose.yml | 18 + CLAUDE.md | 22 +- backend/api/authentication.ts | 326 ++++++ backend/api/mail.ts | 77 ++ backend/api/schemas/authentication.ts | 8 +- backend/api/system.ts | 78 ++ backend/api/users.ts | 113 +- backend/base.yml | 13 + backend/locales/en.json | 36 +- backend/models/authentication.ts | 27 + backend/models/index.ts | 2 + backend/models/mail.ts | 429 ++++++++ backend/models/pages.ts | 29 + backend/models/users.ts | 370 ++++++- .../authentication/local/definition.yml | 2 +- backend/package-lock.json | 21 + backend/package.json | 2 + .../_assets/icons/ultraviolet-eraser.svg | 1 + .../icons/ultraviolet-popcorn-maker.svg | 1 + frontend/scripts/generate-icons.mjs | 16 +- frontend/src/components/AuthLoginPanel.vue | 399 ++++++- frontend/src/components/ChangePwdDialog.vue | 6 +- frontend/src/components/UserCreateDialog.vue | 12 +- frontend/src/components/UserEditOverlay.vue | 30 +- frontend/src/components/shared/WInput.vue | 26 +- frontend/src/helpers/sampleContent.js | 996 ++++++++++++++++++ frontend/src/pages/AdminMail.vue | 41 +- frontend/src/pages/AdminUtilities.vue | 215 +++- frontend/src/pages/Login.vue | 383 +------ 30 files changed, 3239 insertions(+), 470 deletions(-) create mode 100644 backend/models/mail.ts create mode 100644 frontend/public/_assets/icons/ultraviolet-eraser.svg create mode 100644 frontend/public/_assets/icons/ultraviolet-popcorn-maker.svg create mode 100644 frontend/src/helpers/sampleContent.js diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f0804dc23..5e12f1856 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -31,9 +31,13 @@ // Use 'forwardPorts' to make a list of ports inside the container available locally. // This can be used to network with other containers or with the host. - "forwardPorts": [3000, 3001, 5432, 8000], + "forwardPorts": [1025, 3000, 3001, 5432, 8000, 8025], "portsAttributes": { + "1025": { + "label": "Mailpit SMTP", + "onAutoForward": "silent" + }, "3000": { "label": "Application Backend", "onAutoForward": "silent" @@ -49,6 +53,10 @@ "8000": { "label": "PGAdmin", "onAutoForward": "silent" + }, + "8025": { + "label": "Mailpit", + "onAutoForward": "silent" } }, diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 028a007ec..01f4227a9 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -37,6 +37,24 @@ services: POSTGRES_USER: postgres POSTGRES_DB: postgres + # A mail server that delivers nothing, which is what makes it useful: everything the wiki sends — + # a registration's confirmation link, a password reset, the admin area's test button — lands in a + # web inbox at http://localhost:8025 instead of somebody's mailbox. + # + # Configure it under Admin -> Mail: host `localhost`, port 1025, TLS off, no username or password. + # Sharing the database container's network namespace is what makes `localhost` reach it. + mailpit: + image: axllent/mailpit:latest + restart: unless-stopped + environment: + # -> Nothing here is reachable from outside the container, and a dev instance should not fail a + # send because of a credential nobody has set: any AUTH is accepted, over a plain connection. + - MP_SMTP_AUTH_ACCEPT_ANY=true + - MP_SMTP_AUTH_ALLOW_INSECURE=true + # -> Deliberately no volume: these are test messages, and a mailbox that survives a rebuild is a + # mailbox full of last month's password resets. + network_mode: service:db + pgadmin: image: dpage/pgadmin4:latest environment: diff --git a/CLAUDE.md b/CLAUDE.md index 486d2fc69..3d649f754 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -35,7 +35,11 @@ The backend is **TypeScript 7**; `frontend/` and `blocks/` are JavaScript. See `assets/_assets/`. Served by the backend. Don't hand-edit. - `dev/` — deployment/packaging artifacts: `dev/build/Dockerfile` (production image), `dev/helm/`, `dev/packer/`, `dev/noto-emoji-build/`. -- `.devcontainer/` — VS Code dev container (app + postgres + pgAdmin via docker-compose). +- `.devcontainer/` — VS Code dev container (app + postgres + pgAdmin + mailpit via docker-compose). + Mailpit is the mail server for development: it accepts everything and delivers nothing, so a + confirmation link or a password reset lands in a web inbox at `http://localhost:8025` rather than a + real mailbox. Point the wiki at it under **Admin → Mail** — host `localhost`, port 1025, TLS off, + no credentials. - `localazy.json` — translation sync config; locale strings live in `backend/locales/`. ### `backend/` @@ -722,17 +726,15 @@ store; no SVG is ever written into content. An earlier iteration of 3.x used GraphQL/Apollo. **All of it is deprecated** — there is no GraphQL server left in `backend/`, and `APOLLO_CLIENT` is not defined as a global, so any call still going -through it throws. `blocks/block-index/` also still imports a `tree.graphql`. +through it throws. -Three files under `frontend/src/` make live `APOLLO_CLIENT` calls, and each needs a REST endpoint -that does not exist yet, so the feature behind it is currently broken: +**One call is left.** `pages/AdminNavigation.vue`'s `save()` sends the navigation tree and its mode +through `APOLLO_CLIENT.mutate`, so saving the navigation is broken until it is ported. Nothing else +under `frontend/src/` references the global. That handler needs more than the endpoint, mind: it also +calls `this.$store.commit(...)` nine times over, and the file is `