fix(idaa): strip API calls from all +page.ts/+layout.ts, gate loading in $effect
SvelteKit load functions fire during link prefetch before Novi auth completes; `if (browser)` guards do not prevent this. Moving all IDAA data fetching into $effect hooks gated on `novi_verified || trusted_access` closes the IDB pre-population race across archives, bb/[post_id], and recovery_meetings/[event_id]. Also documents the Auth-Before-Cache rule and per-route status in AE__Permissions_and_Security.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -113,6 +113,37 @@ Returns `1` if `level_a` is higher, `-1` if lower, `0` if equal. Useful for thre
|
||||
- IDAA users authenticate via Novi UUID at `authenticated` level or higher.
|
||||
- A prior agent accidentally exposed IDAA BB data publicly — treat any IDAA exposure as Sev-1.
|
||||
|
||||
#### IDAA IndexedDB (IDB) Caching — Auth-Before-Cache Rule
|
||||
|
||||
**Root cause discovered 2026-04:** SvelteKit `+page.ts`/`+layout.ts` load functions run *before* layout `$effect` hooks and fire during link prefetch (hover). `if (browser)` guards do NOT prevent this — they only prevent SSR. This means API calls inside these files execute before Novi auth completes, writing private IDAA data to the user's IndexedDB even for unauthenticated sessions.
|
||||
|
||||
**The fix — established pattern for all IDAA routes:**
|
||||
|
||||
1. **Load/layout `.ts` files = thin shells.** Pass URL params only. No API calls. No `if (browser)` data fetching.
|
||||
2. **Data loading = `$effect` in `.svelte` files**, gated on:
|
||||
```svelte
|
||||
if (!$idaa_loc.novi_verified && !$ae_loc.trusted_access) return;
|
||||
```
|
||||
3. **Three IDB purge paths** in `(idaa)/+layout.svelte` (auth failure, anonymous no-UUID, Reset & Retry button) clear `db_posts`, `db_archives`, and `db_events` tables.
|
||||
|
||||
**Auth path matrix:**
|
||||
|
||||
| User type | `novi_verified` | `trusted_access` | Can load data? | Purge fires? |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Anonymous / unauthenticated | false | false | No | Yes (Case 1) |
|
||||
| Novi-verified IDAA member | true | false | Yes | No |
|
||||
| Manager / trusted access | false | true | Yes | No (Case 3 exemption) |
|
||||
|
||||
**Applied to routes (as of 2026-04-19):**
|
||||
- `idaa/bb/+page.svelte` — `$effect` gate added; `bb/+page.ts` stripped
|
||||
- `idaa/bb/[post_id]/+page.ts` — stripped; loading handled by trigger in `bb/+layout.svelte`
|
||||
- `idaa/archives/+page.svelte` — `$effect` gate added; `archives/+layout.ts` stripped
|
||||
- `idaa/archives/[archive_id]/+page.svelte` — `$effect` gate added; `[archive_id]/+page.ts` stripped
|
||||
- `idaa/recovery_meetings/+page.svelte` — `$effect` gate already present; `+layout.ts` stripped
|
||||
- `idaa/recovery_meetings/[event_id]/+page.svelte` — `$effect` gate added; `+page.ts` stripped
|
||||
|
||||
**When adding a new IDAA route:** never put API calls in `+page.ts`/`+layout.ts`. Always gate data fetching with the `$effect` pattern above.
|
||||
|
||||
### Journals
|
||||
- Private personal data. Always authenticated. Passcode/encryption features exist.
|
||||
- Never expose journal content publicly.
|
||||
|
||||
Reference in New Issue
Block a user