Reflects tonight's work: scripts/authentik-setup.sh actually run for the first time (three bugs found/fixed), OIDC login and client self-registration verified end-to-end on both dev and prod. Closes the loop on issues #10/#12/#17.
6.2 KiB
Backlog from overnight session — 2026-07-16
Written to the repo because the available Gitea credential (write:repository only)
cannot create issues. Transfer these to Gitea once a token with
read:issue + write:issue scope exists.
Blockers needing Jerod's input
B1. Gitea API token for agent workflows
The stored git credential can push code but not read/create issues
(required=[read:issue], token scope=write:repository). Create a token at
git.jerodrigged.com/user/settings/applications with read:user, write:issue,
write:repository and set it as GITEA_TOKEN (user env var) on this machine.
B2. Production (CT111) api/.env is a blank template
Prod moved off the GitHub deploy path this session (see B4) — api/.env now
lives on CT111 and is deployed to via git push origin main:prod, no longer
auto-templated by GitHub Actions.
Update 2026-07-20: OIDC_* and SESSION_SECRET are now filled in and
verified working (see #12/#17). Still outstanding:
- admin dashboard login is disabled (no
ADMIN_SECRET) - new bookings send no n8n notification — real clients could book silently
- calendar availability shows all dates free (no Google creds)
SITE_URLstill points at CT114's LAN IP (192.168.1.192:8080) instead ofhttps://lisilou.jerodrigged.com;CORS_ORIGINis stilllocalhost:8080Deliberately left alone tonight — these need real values from Jerod (an n8n webhook URL, Google service account, a chosen admin passphrase), not something to fill with placeholders.docker compose up -d api(notrestart— it doesn't reloadenv_filechanges) after editing.
B3. Authentik provider + groups (issues #10/#12) RESOLVED 2026-07-20
scripts/authentik-setup.sh was run for real against auth.jerodrigged.com (it
never had been before). Three bugs found and fixed along the way — see the
closing comments on #12 and #17 for the full writeup. Provider, application,
lisilou-admin group, and the client enrollment flow are all live; api/.env
is filled on both dev and prod; verified end-to-end via a real authorization-
code+PKCE round trip on both hosts.
B4. Decide the deploy topology (dev vs prod)
Discovered overnight: lisilou.jerodrigged.com → NPM (CT102) → CT111, deployed
by GitHub Actions from github.com/jhodgkin/lisilou-portfolio; the Gitea repo
deploys to CT114 (dev). The public site was 20 commits stale because pushes
stopped reaching GitHub. I've synced GitHub main and both pipelines are green, but:
- keeping two remotes in sync manually will drift again (mirror Gitea→GitHub, or point NPM at CT114, or move prod deploy to Gitea Actions)
- CT111 and CT114 have separate SQLite DBs — real bookings live on CT111 only
homelab/docs/infrastructure.mdis stale (lists CT114 as Keycloak; CT111 notes don't mention the GitHub runner deploy chain)
B5. dev-lisilou.jerodrigged.com has no NPM proxy host RESOLVED 2026-07-16
Root cause was a typo in the NPM proxy host domain (jerodriggec.com); Jerod
corrected it and the host is live. Original notes kept below for context.
B5 (original notes)
The Cloudflare tunnel delivers the hostname to NPM (CT102), but NPM has no proxy
host for it, so it falls through to the "Jerod Rigged" default landing page.
Verified: curl -H "Host: dev-lisilou.jerodrigged.com" http://192.168.1.185/
→ landing page, while the same probe with Host: lisilou.jerodrigged.com →
healthy. I could not fix this without the NPM admin login (192.168.1.185:81 —
presumably in Vaultwarden; factory default is disabled, and neither SSH nor the
ansible key works from this machine).
Fix (2 min in NPM UI): Hosts → Proxy Hosts → Add:
- Domain:
dev-lisilou.jerodrigged.com - Scheme
http, Forward Host192.168.1.192, Port8080 - Websockets ON, Block Common Exploits ON; SSL tab: same as the
lisilou.jerodrigged.comhost Also confirm the hostname exists as a public hostname/CNAME in the CF tunnel config (it already resolves and reaches NPM, so likely fine).
So the agent can do this next time: put the NPM admin credential in a place
Claude can reach (e.g. NPM_ADMIN_IDENTITY/NPM_ADMIN_SECRET env vars, or an
API-only NPM user), or install/authorize the ~/.ssh/ansible_ed25519 key on
this machine.
Security
S1. Signed-contract download is unauthenticated and enumerable
GET /api/bookings/:id/contract serves any signed contract by numeric id (kept
because n8n email links use it). Replace with HMAC-signed URLs
(?token=…, using SESSION_SECRET) and update the n8n workflow template.
S2. Dev ADMIN_SECRET committed in playwright.config.js
9yPu… is in git history and matches the dev instance. Rotate the dev secret and
inject via env/Gitea secret instead of a hardcoded default.
Content (needed to look professional — code is ready, assets are missing)
C1. Real photography on the prod volume
/images/hero.jpg— new: homepage hero photo (soft scrim applied automatically)- portfolio category covers (
/images/portfolio/*-cover.jpg) or working Immich album links — cards currently show the styled placeholder - location photos (
/images/locations/<id>/hero.jpg,1.jpg,2.jpg) /images/logo.png,/images/favicon.ico, profile photo Verify the Immich share albums referenced insite.jsonresolve on prod.
C2. Contract template PDF
api/contracts/model-release.pdf is absent on both instances — the e-sign step
falls back and no PDF gets stamped. Drop the real contract on the volumes.
C3. Confirm public contact details
site.json has hello@lisilou.com and an empty phone; Venmo username
LisiLouPhoto — confirm all are real before promoting the site.
Nice-to-haves spotted during the walkthrough
- Portfolio lightbox: verify Immich proxy flow end-to-end on prod (couldn't test without albums)
/dashboardand/my-bookingsaren't linked from anywhere for the photographer; consider a footer link or bookmark- Add
robots.txt+ real meta description / OpenGraph tags for sharing - The "designer plugin" requested for the design review doesn't exist in this
Claude Code environment — the pass was done manually (screenshots + fixes);
if there's a specific plugin to install, add it to
.claude/settings.json