style(13-03): apply Prettier formatting across repo
Mechanical reformat — no logic changes. 398 files changed, 19125 insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc (singleQuote:true, semi:true, tabWidth:2, trailingComma:all, printWidth:100). Isolated per D-13-08 for reviewability.
This commit is contained in:
@@ -3,7 +3,7 @@ phase: 03-event-write-back-pwa-install
|
||||
plan: 07
|
||||
type: execute
|
||||
wave: 3
|
||||
depends_on: ["03-01"]
|
||||
depends_on: ['03-01']
|
||||
files_modified:
|
||||
- apps/pwa/vite.config.ts
|
||||
- apps/pwa/index.html
|
||||
@@ -18,27 +18,27 @@ user_setup: []
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "The production build emits a valid manifest.webmanifest with name/icons/display:standalone/scope:/ and a service worker"
|
||||
- 'The production build emits a valid manifest.webmanifest with name/icons/display:standalone/scope:/ and a service worker'
|
||||
- "The service worker's navigateFallbackDenylist excludes /callback, /api/, /health so the OIDC redirect is never intercepted (Gate 2 risk)"
|
||||
- "On iOS Safari non-standalone, a first-visit install banner appears with a 5-step annotated Add-to-Home-Screen walkthrough"
|
||||
- "On Android, an Install banner appears only when beforeinstallprompt fires and triggers the native prompt"
|
||||
- "Neither install surface renders when the app is already installed (display-mode: standalone)"
|
||||
- 'On iOS Safari non-standalone, a first-visit install banner appears with a 5-step annotated Add-to-Home-Screen walkthrough'
|
||||
- 'On Android, an Install banner appears only when beforeinstallprompt fires and triggers the native prompt'
|
||||
- 'Neither install surface renders when the app is already installed (display-mode: standalone)'
|
||||
artifacts:
|
||||
- path: "apps/pwa/vite.config.ts"
|
||||
provides: "VitePWA manifest + SW config with auth-safe denylist"
|
||||
contains: "navigateFallbackDenylist"
|
||||
- path: "apps/pwa/src/components/InstallPrompt.tsx"
|
||||
provides: "iOS walkthrough banner/sheet + Android beforeinstallprompt banner"
|
||||
- path: 'apps/pwa/vite.config.ts'
|
||||
provides: 'VitePWA manifest + SW config with auth-safe denylist'
|
||||
contains: 'navigateFallbackDenylist'
|
||||
- path: 'apps/pwa/src/components/InstallPrompt.tsx'
|
||||
provides: 'iOS walkthrough banner/sheet + Android beforeinstallprompt banner'
|
||||
min_lines: 80
|
||||
key_links:
|
||||
- from: "apps/pwa/vite.config.ts"
|
||||
to: "OIDC /callback"
|
||||
via: "navigateFallbackDenylist excludes /callback"
|
||||
pattern: "callback"
|
||||
- from: "apps/pwa/src/components/InstallPrompt.tsx"
|
||||
to: "iOS standalone detection"
|
||||
via: "isIOSSafariNonStandalone + display-mode media query"
|
||||
pattern: "standalone"
|
||||
- from: 'apps/pwa/vite.config.ts'
|
||||
to: 'OIDC /callback'
|
||||
via: 'navigateFallbackDenylist excludes /callback'
|
||||
pattern: 'callback'
|
||||
- from: 'apps/pwa/src/components/InstallPrompt.tsx'
|
||||
to: 'iOS standalone detection'
|
||||
via: 'isIOSSafariNonStandalone + display-mode media query'
|
||||
pattern: 'standalone'
|
||||
---
|
||||
|
||||
<objective>
|
||||
@@ -84,6 +84,7 @@ Output: configured VitePWA build, install icons + meta, InstallPrompt mounted in
|
||||
Generate the three icon PNGs into apps/pwa/public/: `icon-192.png` (192×192), `icon-512.png` (512×512), `apple-touch-icon.png` (180×180). Create a simple solid `#4A90D9` background with a white "F" / calendar glyph using an available CLI tool (ImageMagick `convert`, `sharp` via a one-off node script, or similar). If no image tool is available, set autonomous:false is NOT needed — emit minimal valid PNGs programmatically (node Buffer / sharp). The icons must be valid PNGs at the exact pixel dimensions.
|
||||
|
||||
Add to apps/pwa/index.html `<head>` the five entries from RESEARCH.md Pattern 5: apple-touch-icon link (180×180), theme-color meta (#4A90D9), apple-mobile-web-app-capable yes, apple-mobile-web-app-status-bar-style default, apple-mobile-web-app-title FamilySync.
|
||||
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /home/luc/Projects/familysync && pnpm --filter @familysync/pwa build && test -f apps/pwa/dist/manifest.webmanifest && node -e "const m=require('./apps/pwa/dist/manifest.webmanifest');if(m.display!=='standalone'||m.scope!=='/'||!m.icons.some(i=>i.sizes==='512x512'))process.exit(1)" && grep -q "navigateFallbackDenylist" apps/pwa/vite.config.ts && grep -q "apple-touch-icon" apps/pwa/index.html</automated>
|
||||
@@ -128,19 +129,21 @@ Output: configured VitePWA build, install icons + meta, InstallPrompt mounted in
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| Boundary | Description |
|
||||
| --------------------------- | ------------------------------------------------------------ |
|
||||
| service worker → navigation | The SW can intercept navigations including the OIDC callback |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-03-20 | Spoofing | SW serving a cached shell for /callback, breaking OIDC code exchange / iOS standalone login | mitigate | `navigateFallbackDenylist: [/^\/callback/, /^\/api\//, /^\/health/]`; verified against a production build (Pitfall 1/6); Gate 2 confirms end-to-end (Plan 08) |
|
||||
| T-03-21 | Tampering | SW caching authenticated API responses | mitigate | `runtimeCaching: []` — no /api caching; /api in denylist |
|
||||
| T-03-22 | Information Disclosure | manifest/icons leaking nothing sensitive | accept | Static public assets only; no secrets in manifest |
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
| --------- | ---------------------- | ------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| T-03-20 | Spoofing | SW serving a cached shell for /callback, breaking OIDC code exchange / iOS standalone login | mitigate | `navigateFallbackDenylist: [/^\/callback/, /^\/api\//, /^\/health/]`; verified against a production build (Pitfall 1/6); Gate 2 confirms end-to-end (Plan 08) |
|
||||
| T-03-21 | Tampering | SW caching authenticated API responses | mitigate | `runtimeCaching: []` — no /api caching; /api in denylist |
|
||||
| T-03-22 | Information Disclosure | manifest/icons leaking nothing sensitive | accept | Static public assets only; no secrets in manifest |
|
||||
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
@@ -150,10 +153,11 @@ Output: configured VitePWA build, install icons + meta, InstallPrompt mounted in
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- PWA-01: app installs to Home Screen (manifest + SW, standalone) on iOS and Android.
|
||||
- PWA-02: first-time guided install (iOS walkthrough + Android prompt); never shown when installed.
|
||||
- OIDC `/callback` is never SW-intercepted (Gate 2 prerequisite).
|
||||
</success_criteria>
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/03-event-write-back-pwa-install/03-07-SUMMARY.md` when done.
|
||||
|
||||
Reference in New Issue
Block a user