mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
Every entry in LISTMONK_SETTINGS was one boot late. Listmonk reads settings into koanf once at startup (cmd/main.go:186 initSettings) and builds the media store from them (:205); the only reload trigger is SIGHUP (:315). The role writes them with a direct UPDATE from 02_manager_ops.yml:34, after the single `notify: compose up` in the whole role has already been flushed at :8. A DB write reaches neither koanf nor the settings API, and `changed_when: false` meant the task could not notify a handler even if one existed. It never self-healed either: notify fires only on a changed config.toml, which on the second run is identical, so no recreate. In the CI shape -- fresh stack, one deploy, then Playwright -- the settings were guaranteed inactive. What was therefore never in effect: upload.provider=s3 and the whole upload.s3.* block (uploads went to the container filesystem, not the bucket), security.oidc (so /admin/login rendered no SSO control at all), smtp, and app.root_url -- which is why the deployed instance's public pages linked to http://localhost:9000. Proven against listmonk/listmonk:v6.2.0 with a throwaway Postgres: with the settings written and no reload, /admin/login has no OIDC form; after `docker kill --signal HUP` the same URL renders `<form method="post" action="/auth/oidc">`. `container recreate` is the existing shared handler, already used for exactly this in web-app-peertube/tasks/oidc/enable.yml. The OIDC control is still not reachable by the shared persona helper after the reload: clickOidcLoginLink prefers the strict locator, and Listmonk's native submit button's accessible name is exactly "Login" while the OIDC button is "Login with <name>" -- so the strict matcher takes the wrong control. There is no setting that hides the native form; cmd/auth.go renderLoginPage hardcodes PasswordEnabled. appearance.public.custom_js is a real v6.2.0 setting, injected into /admin/login and served same-origin, so a few lines of JS submit the OIDC form and the second hop disappears. The shared helper stays untouched, which keeps the 61 other roles that route through it out of this. Measured with the helper's own source driving a real browser: no reload -> no form; reload alone -> reached: false; reload plus custom_js -> reached: true. The administrator persona is unblocked accordingly. biber stays blocked, and for the third distinct reason this role has been given: Listmonk matches OIDC users by e-mail and provisions no biber account, cmd/auth.go OIDCFinish 404s unless security.oidc.auto_create_users is set, and createOIDCUser needs a real default_user_role_id -- the seeded database holds only Super Admin. Three nocheck rationales in playwright.env.j2 asserted things that are false: that mail delivery is "covered by the sys-svc-mail integration tests" (no such tests exist; the coverage is in web-app-mailu's own spec), and twice that the CSP helper asserts the injector origin (personas/utils/csp.js:96 bails with `if (!host) continue`, and no consumer role renders CSS_BASE_URL). Rewritten to what is actually true. Not fixed here, recorded in TODO.md: security.enable_captcha, security.captcha_key and security.captcha_secret do not exist in v6.2.0 -- the live table carries one security.captcha object -- so all three UPDATEs match zero rows and hCaptcha has never been active. Repairing that would switch a captcha on for the public subscription form, which is a behaviour change nobody asked for. Unverified: the logout leg. Whether inAppLogout finds Listmonk's Vue user menu, and whether assertCspInjections passes against the admin SPA, has not been run. The first deploy settles both. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
24 lines
1.5 KiB
Markdown
24 lines
1.5 KiB
Markdown
# To-dos
|
|
|
|
- Three settings keys in `vars/main.yml` are silent no-ops on v6.2.0:
|
|
`security.enable_captcha`, `security.captcha_key` and `security.captcha_secret`.
|
|
The live `settings` table carries a single `security.captcha` object
|
|
(`{"altcha": {…}, "hcaptcha": {"key", "secret", "enabled"}}`), so all three
|
|
`UPDATE`s match zero rows and neither `ON_ERROR_STOP` nor the reaper notices.
|
|
hCaptcha has therefore never been active, which also makes the
|
|
`HCAPTCHA_SERVICE_ENABLED` rationale in `templates/playwright.env.j2` describe
|
|
protection that is not there. Rewrite the three keys as one object, then
|
|
decide whether a captcha on the public subscription form is wanted at all.
|
|
- Unblock the `biber` persona. Listmonk matches OIDC users by e-mail and the
|
|
role provisions no biber account; `cmd/auth.go` `OIDCFinish` 404s unless
|
|
`security.oidc.auto_create_users` is true, and `createOIDCUser` passes
|
|
`UserRoleID` as a plain int, so `default_user_role_id` must name a real role.
|
|
The seeded database holds exactly one (`id=1 Super Admin`), so unblocking
|
|
biber means first creating a limited Listmonk user role. It buys no coverage
|
|
the administrator persona does not already buy.
|
|
- Add `files/playwright/test-seaweedfs.js` now that the administrator persona
|
|
runs. The only bucket-write surface is the admin Media view; the model is
|
|
`roles/web-app-pixelfed/files/playwright/test-seaweedfs.js`. The
|
|
`# nocheck: seaweedfs-playwright` marker in `meta/services.yml` comes off with
|
|
it.
|