166 lines
11 KiB
Markdown
166 lines
11 KiB
Markdown
---
|
|
phase: 03-event-write-back-pwa-install
|
|
plan: 08
|
|
type: execute
|
|
wave: 5
|
|
depends_on: ["03-04", "03-06", "03-07"]
|
|
files_modified:
|
|
- .planning/phases/03-event-write-back-pwa-install/03-GATE2-RESULTS.md
|
|
autonomous: false
|
|
requirements: [CAL-04, CAL-05, CAL-06, PWA-01, PWA-02]
|
|
user_setup:
|
|
- service: authelia
|
|
why: "Gate 2 verifies real Authelia OIDC login over the public Pangolin URL including the iOS standalone-PWA flow (success criterion 6, D-14)"
|
|
env_vars:
|
|
- name: OIDC_AUTH_EXTERNAL_URL
|
|
source: "Set to the public familysync URL (e.g. https://familysync.<domain>) so redirect_uri is correct behind Pangolin"
|
|
dashboard_config:
|
|
- task: "Register FamilySync as an OIDC confidential client (code flow + PKCE S256, client_secret_basic) and ensure the redirect_uri matches the public URL"
|
|
location: "Authelia configuration"
|
|
- task: "Expose familysync through Pangolin/Newt (Mode A local test rig is sufficient — Unraid prod optional until go-live, D-15)"
|
|
location: "Pangolin / Newt connector"
|
|
|
|
must_haves:
|
|
truths:
|
|
- "A real member completes Authelia OIDC login over the public Pangolin URL in a desktop browser; the session persists across a browser restart"
|
|
- "On iPhone, the member installs FamilySync to the Home Screen and completes login WITHOUT the redirect breaking out of standalone mode"
|
|
- "Each member shows a distinct, stable color (AUTH-03) in the live deploy"
|
|
- "Create, edit, and delete an event end-to-end through the live deploy; the change appears in the native Fastmail app on the next sync (CAL-04/05/06)"
|
|
- "The installed PWA opens full-screen with no browser chrome on iOS and Android (PWA-01/02)"
|
|
artifacts:
|
|
- path: ".planning/phases/03-event-write-back-pwa-install/03-GATE2-RESULTS.md"
|
|
provides: "Recorded Gate 2 verification results (pass/fail per checklist row)"
|
|
key_links:
|
|
- from: "live deploy"
|
|
to: "docs/deployment.md Gate 2 checklist"
|
|
via: "operator executes each row"
|
|
pattern: "Gate 2"
|
|
---
|
|
|
|
<objective>
|
|
Execute and record the Phase 1 Gate 2 live-verification carried into Phase 3 (success
|
|
criterion 6, D-14/D-15): real Authelia OIDC login over the public Pangolin URL — most
|
|
critically the iOS standalone-PWA login flow — plus session persistence, distinct stable
|
|
member colors, and an end-to-end create/edit/delete through the live stack. This is the
|
|
first real external auth test and the load-bearing check for the non-technical member.
|
|
|
|
Purpose: all prior plans build behind the dev-auth bypass (D-13). Nothing has proven the
|
|
OIDC redirect survives iOS standalone mode or that writes round-trip to Fastmail in a real
|
|
deploy. This plan closes that gap and records the outcome.
|
|
|
|
Output: 03-GATE2-RESULTS.md with a pass/fail line per Gate 2 checklist row.
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
|
</execution_context>
|
|
|
|
<context>
|
|
@.planning/PROJECT.md
|
|
@.planning/ROADMAP.md
|
|
@docs/deployment.md
|
|
@.planning/phases/03-event-write-back-pwa-install/03-RESEARCH.md
|
|
</context>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: Build and deploy FamilySync to the Mode A local test rig behind Pangolin</name>
|
|
<files>.planning/phases/03-event-write-back-pwa-install/03-GATE2-RESULTS.md</files>
|
|
<read_first>
|
|
- docs/deployment.md (§Mode A local test rig setup; §Pangolin idle/read timeout requirements; §Gate 2 checklist at line ~215)
|
|
- .planning/PROJECT.md (D-14 dev-auth bypass context; D-15 Mode A local Newt rig)
|
|
- apps/api/src/index.ts (OIDC guard mounts only when devBypassActive is false — production build must NOT set DEV_AUTH_BYPASS)
|
|
</read_first>
|
|
<action>
|
|
Per docs/deployment.md Mode A: produce a production build (NODE_ENV=production so the OIDC guard is mounted, dev-bypass OFF), serve the PWA static build + API, and expose it through the local Newt connector / Pangolin test subdomain. Confirm `OIDC_AUTH_EXTERNAL_URL` is set to the public URL and the Authelia client redirect_uri matches. Confirm the public `/health` responds over the tunnel. Create `03-GATE2-RESULTS.md` and record the deploy details (URL, build SHA, date) as the header before the checklist. If any infra step requires operator-only credentials/config, stop and surface it via the checkpoint in Task 2 rather than guessing.
|
|
</action>
|
|
<verify>
|
|
<automated>cd /home/luc/Projects/familysync && pnpm --filter @familysync/pwa build && pnpm --filter @familysync/api build && test -f .planning/phases/03-event-write-back-pwa-install/03-GATE2-RESULTS.md</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- Both apps build clean for production.
|
|
- 03-GATE2-RESULTS.md exists with the deploy header (URL, build, date).
|
|
- Public `/health` reachable through the tunnel (record the curl result in the file).
|
|
</acceptance_criteria>
|
|
<done>A production build is live on the Mode A rig behind Pangolin; results file scaffolded.</done>
|
|
</task>
|
|
|
|
<task type="checkpoint:human-verify" gate="blocking-human">
|
|
<name>Task 2: [Gate 2] Live Authelia OIDC + iOS standalone login + distinct colors</name>
|
|
<read_first>
|
|
- docs/deployment.md (§Gate 2 checklist, esp. row 4 — iOS PWA Add-to-Home-Screen + standalone login)
|
|
- .planning/phases/03-event-write-back-pwa-install/03-RESEARCH.md (§Pitfall 2 — iOS standalone OIDC redirect; symptom = stuck in Safari after login; fix = scope:'/' + /callback not SW-intercepted)
|
|
</read_first>
|
|
<action>Execute the docs/deployment.md Gate 2 checklist on the live public URL: real Authelia OIDC desktop login, session persistence across a browser restart, distinct stable per-member colors, and the load-bearing iOS Add-to-Home-Screen + standalone login (redirect must not break out of standalone). Record each row PASS/FAIL in 03-GATE2-RESULTS.md; on iOS failure apply the Pitfall-2 remedy and retest.</action>
|
|
<what-built>The full Phase 3 stack (write-back + outbox worker + PWA install) is deployed to the Mode A rig behind the public Pangolin URL with real Authelia OIDC (dev-bypass OFF). The service worker denylist (Plan 07) keeps `/callback` server-handled.</what-built>
|
|
<how-to-verify>
|
|
Work through docs/deployment.md §Gate 2 checklist on the live public URL and record each row in 03-GATE2-RESULTS.md:
|
|
1. Desktop browser: open the public URL, complete Authelia OIDC login, land on the app — no Fastmail credentials prompted.
|
|
2. Restart the browser, revisit — still logged in (session persists, AUTH-02).
|
|
3. Confirm each of the two members shows a distinct, stable color (AUTH-03).
|
|
4. iPhone: open in Safari, follow the in-app iOS install walkthrough, Add to Home Screen, launch standalone. Complete login — confirm the redirect does NOT break out of standalone (you stay in the app, not dropped to Safari). This is the load-bearing check (Pitfall 2).
|
|
5. Confirm the installed PWA opens full-screen with no browser chrome on iOS and Android (PWA-01).
|
|
</how-to-verify>
|
|
<acceptance_criteria>
|
|
- Each Gate 2 checklist row recorded PASS in 03-GATE2-RESULTS.md, especially the iOS standalone login row.
|
|
- If iOS standalone login FAILS: record the symptom, apply the Pitfall-2 remedy (verify manifest scope:'/' + start_url:'/', confirm /callback is in the SW denylist and reaches the server), redeploy, retest.
|
|
</acceptance_criteria>
|
|
<resume-signal>Type "gate2 pass" with the iOS standalone result, or describe the failure (e.g. "stuck in Safari after login").</resume-signal>
|
|
</task>
|
|
|
|
<task type="checkpoint:human-verify" gate="blocking-human">
|
|
<name>Task 3: [Gate 2] End-to-end create / edit / delete round-trips to Fastmail</name>
|
|
<read_first>
|
|
- .planning/phases/03-event-write-back-pwa-install/03-UI-SPEC.md (§Interaction Contract — sync-state feedback, delete interaction)
|
|
- .planning/phases/03-event-write-back-pwa-install/03-CONTEXT.md (success criteria 1-3: create/edit/delete appear in native Fastmail on next sync)
|
|
</read_first>
|
|
<action>On the live deploy, perform create (timed, all-day, weekly recurring), edit, and delete through the UI and confirm each round-trips to the native Fastmail app on the next sync; observe the SyncStateToast Syncing→Saved flow and (if reproducible) a 412 conflict re-fetch. Record each result in 03-GATE2-RESULTS.md.</action>
|
|
<what-built>Create/edit/delete UI (EventForm, popover footer, delete dialog), the outbox worker, and the polled SyncStateToast are all live on the deploy.</what-built>
|
|
<how-to-verify>
|
|
On the live deploy (logged in as a real member):
|
|
1. Create a timed event and an all-day event (and one weekly recurring event). Confirm the "Syncing…" toast → "Saved", and that each event appears in the native Fastmail app within the next sync cycle (CAL-04/CAL-07).
|
|
2. Edit an existing event's title and time; confirm the change persists in Fastmail (CAL-05).
|
|
3. Delete an event via the two-tap confirmation; confirm it disappears from all views on the next sync (CAL-06).
|
|
4. (Optional, if reproducible) Trigger a 412 conflict by editing the same event from the Fastmail app first; confirm the conflict toast appears and the calendar re-fetches (D-08).
|
|
</how-to-verify>
|
|
<acceptance_criteria>
|
|
- Create (timed + all-day + recurring), edit, and delete each recorded PASS in 03-GATE2-RESULTS.md with confirmation they round-tripped to the native Fastmail app.
|
|
- Sync toast behavior (Syncing → Saved; persistent error on failure) observed and recorded.
|
|
</acceptance_criteria>
|
|
<resume-signal>Type "writeback pass" with the Fastmail round-trip results, or describe any write that did not appear.</resume-signal>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<threat_model>
|
|
## Trust Boundaries
|
|
|
|
| Boundary | Description |
|
|
|----------|-------------|
|
|
| public internet → Pangolin → app | First real external exposure of the auth + write path |
|
|
|
|
## STRIDE Threat Register
|
|
|
|
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
|
|-----------|----------|-----------|-------------|-----------------|
|
|
| T-03-23 | Spoofing | dev-auth bypass accidentally active in the live deploy | mitigate | Production build sets NODE_ENV=production → bypass forced OFF, OIDC unconditionally mounted (index.ts); verify the login is real Authelia, not the dev user |
|
|
| T-03-24 | Information Disclosure | OIDC redirect_uri mismatch leaking codes or failing login | mitigate | OIDC_AUTH_EXTERNAL_URL set to the public URL; Authelia client redirect_uri matches (deployment.md) |
|
|
| T-03-25 | Tampering | SW intercepting /callback in the live build | mitigate | Plan 07 denylist verified against the production build; Gate 2 row 4 confirms standalone login end-to-end |
|
|
</threat_model>
|
|
|
|
<verification>
|
|
- Both apps build for production; public /health reachable through the tunnel.
|
|
- 03-GATE2-RESULTS.md records PASS for: desktop OIDC login, session persistence, distinct colors, iOS standalone login, full-screen install, and create/edit/delete Fastmail round-trips.
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- Success criterion 6 satisfied: live Authelia OIDC over Pangolin works including iOS standalone-PWA login; sessions persist; distinct stable colors.
|
|
- Success criteria 1-5 confirmed live: create/edit/delete round-trip to Fastmail; installable + full-screen on iOS and Android.
|
|
</success_criteria>
|
|
|
|
<output>
|
|
Create `.planning/phases/03-event-write-back-pwa-install/03-08-SUMMARY.md` when done.
|
|
</output>
|