diff --git a/CONTEXT.md b/CONTEXT.md index 0fb215a..53fd989 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -3,6 +3,18 @@ > Created with the REUSE.md rollout (2026-07-03). Authoritative history: `hub/CHANGELOG.md` (hub), > `website/CHANGELOG.md`, `scripts/CHANGELOG.md`; end-of-task detail in `REPORT.md`. +- **2026-07-12 — HUB v0.50.0 SHIPPED + LIVE: customer-claim password arc (closes DRILL-day0-vm + F-4/F-5).** The customer OWNS the dashboard password via a one-time claim code the hub emails to + the registered address (`bcrypt(code)` stored, plaintext only in the send). `internal/claim` + engine (EnsureIssued idempotent Day-0/live-box issue+email, Resend, RequestReset 3/day, + MarkClaimed set-only) + `store.customer_claims` (RotateClaimCode bumps generation + preserves + claimed_at) + delivery (config bake `web.claim_code_*`, report-ACK `claim` object, `POST + /api/v1/claim/reset-request`) + Setup-tab chip/resend + 3 Hungarian emails. Pairs with controller + **v0.122.0** (the gate). **LIVE-proven on drill box demo-vm-felhom: gate ON via the real edge (/ → + 302 claim page, /api → 401); code emailed to the registered address.** Deployed felhom-hub:0.50.0 + (ArgoCD synced/healthy). Floor raise 0.120→0.122 = operator's supervised LAST step. Observed: the + hub issues a claim code for EVERY reporting customer on first report (benign for pre-0.122 boxes — + no gate, ACK ignored). Report: documentation/audits/DRILL-day0-vm-2026-07-12.md (F-4/F-5 RESOLVED). - **2026-07-12 — HUB v0.49.0 SHIPPED: Edit tab merge (edit-a) + scoped auto-refresh + riders** (CHANGELOG v0.49.0; commits `e740147` → `2e03de1` → `1d94b1a` + docs/manifest). The standalone customer edit page merged into the customer page's **Edit** tab (renamed from Settings): shared diff --git a/REPORT.md b/REPORT.md index 22dbe47..7d22ad5 100644 --- a/REPORT.md +++ b/REPORT.md @@ -2,66 +2,37 @@ > **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md). -## Hub v0.49.0 — Edit tab merge (edit-a), scoped auto-refresh, + two riders — 2026-07-12 +## Hub v0.50.0 — customer-claim password arc (closes DRILL-day0-vm F-4/F-5) — 2026-07-12 -**⚠ VERSION NOTE (deviation from the spec):** the task targeted **v0.48.0**, but hub v0.48.0 -(`app_start_failed` allowlist, CAMPAIGN-3 Task D) had **already shipped and was the live manifest -tag** when this train started. A published tag is never re-pointed (pinned-version discipline), so -this train shipped as **v0.49.0**. Everything else is per spec. +Hub half of the customer-owned dashboard-password gate (controller v0.122.0 is the other half). +The customer sets + owns the password via a one-time claim code the hub emails to the registered +address; the hub stores only `bcrypt(code)`. **DEPLOYED: `felhom-hub:0.50.0` live on k3s (ArgoCD +synced/healthy, `Listening on :8080` at 18:47 CEST).** -### Baseline / commits +### What shipped -- Baseline: `3e949bc` (spec said `0ed87f5`; the one extra commit was docs-only, `git diff 0ed87f5..3e949bc -- hub/` empty — no hub code drift). -- `e740147` — Part 1: `config_form_body` sub-template + `configFormData` builder (behavior-neutral). -- `2e03de1` — Part 2: Edit tab merge, danger zone, header cleanup, 302, redirect anchors, server-side required fields, Group A/B tests. -- `1d94b1a` — Parts 3+4: scoped auto-refresh, style.css cache-bust (all 11 templates), CLAUDE.md `git add -A` ban, Group C/D tests. -- `b1ab0ea` — Part 5: CHANGELOG v0.49.0, REUSE.md rows, CONTEXT.md, `manifests/hub.yaml` → 0.49.0. +- **`internal/claim`** — the code engine: `EnsureIssued` (idempotent Day-0/live-box issue+email), + `Resend` (operator rotate), `RequestReset` (controller-forwarded, 3/day cap), `MarkClaimed` + (set-only + one confirmation email). Plaintext code exists ONLY inside the email send. +- **`store.customer_claims`** — `RotateClaimCode` (generation bump = single active code; PRESERVES + `claimed_at`), `GetClaim`, `MarkClaimed` (set-only), `BumpResetCount`. +- **Delivery**: `GET /api/v1/config/{id}` issues the first code + bakes `web.claim_code_*` into the + generated controller.yaml; the report ACK serves `claim {code_hash, generation, issued_at}` + (allowlisted) + ingests `claimed` (set-only); `POST /api/v1/claim/reset-request` (self-scoped). +- **UI**: customer-page Setup tab claim chip + "Kód újraküldése" (`POST /configs/{id}/claim-resend`). +- **Emails**: three Hungarian templates (claim / reset / claimed) via the notify dispatcher. +- 15 tests (engine, ACK/config, UI); red-proofs for the generation bump + reset-non-DoS proven. -### Files touched +### Live validation -`hub/internal/web/{configs.go, pbsdr.go}`, `hub/internal/web/templates/{config_form.html, config_form_body.html(new), customer_unified.html, +9 templates (cache-bust line only)}`, tests `{customer_edit_tab_test.go(new), refresh_cachebust_test.go(new), customer_tabs_test.go, pbsdr_test.go}`, docs `{hub/CHANGELOG.md, REUSE.md, CONTEXT.md, CLAUDE.md, REPORT.md}`, `manifests/hub.yaml`. +Drill box demo-vm-felhom: on the first report after hub 0.50.0 + controller 0.122.0, the hub issued ++ emailed the claim code to the registered address and the ACK delivered the hash — the controller +gate flipped ON (proven via the real Cloudflare edge: `/` → 302 claim page, `/api` → 401). Observed: +the hub issues a code for EVERY reporting managed customer on first report (peti + demo also received +emails) — benign, since a pre-v0.122 controller ignores the ACK claim field and has no gate. -### Test results (all green: `go build ./... && go vet ./... && go test ./...` per commit) +### Version note -- web package: **54 tests** (43 before → +11 new: Group A ×2, Group B ×3 + 7-case anchor table, Group C ×1, Group D ×1); full repo 13 packages ok. -- **Group A** — Edit panel renders form (`action=/configs/c1/edit`) + Controller Update + Geo + Danger zone; forms are siblings (no `