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.
|
- 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.
|
- 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
|
### Journals
|
||||||
- Private personal data. Always authenticated. Passcode/encryption features exist.
|
- Private personal data. Always authenticated. Passcode/encryption features exist.
|
||||||
- Never expose journal content publicly.
|
- Never expose journal content publicly.
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
/** @type {import('./$types').LayoutLoad} */
|
/** @type {import('./$types').LayoutLoad} */
|
||||||
// console.log(`IDAA BB - [account_id] +layout.ts start`);
|
|
||||||
|
|
||||||
// import { error } from '@sveltejs/kit';
|
// Data loading for IDAA Archives has been moved to the $effect in +page.svelte
|
||||||
import { browser } from '$app/environment';
|
// (gated on novi_verified / trusted_access). +layout.ts runs before layout effects and
|
||||||
import { archives_func } from '$lib/ae_archives/ae_archives_functions';
|
// fires during SvelteKit link prefetch, making it unsafe for private IDAA content.
|
||||||
|
|
||||||
export async function load({ fetch, params, parent }) {
|
export async function load({ parent }) {
|
||||||
// route
|
|
||||||
const log_lvl: number = 0;
|
const log_lvl: number = 0;
|
||||||
|
|
||||||
const data = await parent();
|
const data = await parent();
|
||||||
@@ -21,40 +19,10 @@ export async function load({ fetch, params, parent }) {
|
|||||||
);
|
);
|
||||||
ae_acct = {
|
ae_acct = {
|
||||||
api: data.ae_api || {},
|
api: data.ae_api || {},
|
||||||
slct: {
|
slct: { account_id: account_id }
|
||||||
account_id: account_id
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (browser) {
|
|
||||||
const load_archive_obj_li = archives_func.load_ae_obj_li__archive({
|
|
||||||
api_cfg: ae_acct.api,
|
|
||||||
for_obj_type: 'account',
|
|
||||||
for_obj_id: account_id,
|
|
||||||
inc_content_li: false,
|
|
||||||
enabled: 'enabled',
|
|
||||||
hidden: 'not_hidden',
|
|
||||||
limit: 29,
|
|
||||||
order_by_li: {
|
|
||||||
priority: 'DESC',
|
|
||||||
sort: 'DESC',
|
|
||||||
updated_on: 'DESC',
|
|
||||||
created_on: 'DESC',
|
|
||||||
name: 'ASC'
|
|
||||||
},
|
|
||||||
params: params,
|
|
||||||
try_cache: true,
|
|
||||||
log_lvl: log_lvl
|
|
||||||
});
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log(`load_archive_obj_li = `, load_archive_obj_li);
|
|
||||||
}
|
|
||||||
ae_acct.slct.archive_obj_li = load_archive_obj_li;
|
|
||||||
}
|
|
||||||
|
|
||||||
// WARNING: Precaution against shared data between sites and sessions.
|
|
||||||
data[account_id] = ae_acct;
|
data[account_id] = ae_acct;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ let log_lvl: number = $state(0);
|
|||||||
|
|
||||||
// *** Import Svelte specific
|
// *** Import Svelte specific
|
||||||
// import { page } from '$app/state';
|
// import { page } from '$app/state';
|
||||||
|
import { untrack } from 'svelte';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
// import { goto, invalidate, pushState, replaceState } from '$app/navigation';
|
// import { goto, invalidate, pushState, replaceState } from '$app/navigation';
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ import {
|
|||||||
idaa_slct,
|
idaa_slct,
|
||||||
idaa_trig
|
idaa_trig
|
||||||
} from '$lib/stores/ae_idaa_stores';
|
} from '$lib/stores/ae_idaa_stores';
|
||||||
// import { archives_func } from '$lib/ae_archives/ae_archives_functions';
|
import { archives_func } from '$lib/ae_archives/ae_archives_functions';
|
||||||
|
|
||||||
import Comp__archive_obj_li from './ae_idaa_comp__archive_obj_li.svelte';
|
import Comp__archive_obj_li from './ae_idaa_comp__archive_obj_li.svelte';
|
||||||
import Help_tech from '$lib/app_components/e_app_help_tech.svelte';
|
import Help_tech from '$lib/app_components/e_app_help_tech.svelte';
|
||||||
@@ -68,6 +69,34 @@ let lq__archive_obj_li = $derived(
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Initial archive list load — gated on novi_verified.
|
||||||
|
// WHY $effect and not +layout.ts: layout load functions fire on SvelteKit link prefetch,
|
||||||
|
// causing private IDAA data to be written to IDB before Novi auth runs.
|
||||||
|
// $effect only runs post-mount, after the layout has completed Novi verification.
|
||||||
|
$effect(() => {
|
||||||
|
if (!$idaa_loc.novi_verified && !$ae_loc.trusted_access) return;
|
||||||
|
untrack(() => {
|
||||||
|
archives_func.load_ae_obj_li__archive({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
for_obj_type: 'account',
|
||||||
|
for_obj_id: $ae_loc.account_id,
|
||||||
|
inc_content_li: false,
|
||||||
|
enabled: 'enabled',
|
||||||
|
hidden: 'not_hidden',
|
||||||
|
limit: 29,
|
||||||
|
order_by_li: {
|
||||||
|
priority: 'DESC',
|
||||||
|
sort: 'DESC',
|
||||||
|
updated_on: 'DESC',
|
||||||
|
created_on: 'DESC',
|
||||||
|
name: 'ASC'
|
||||||
|
},
|
||||||
|
try_cache: true,
|
||||||
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if (browser) {
|
if (browser) {
|
||||||
console.log('Browser environment detected.');
|
console.log('Browser environment detected.');
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ let { data }: Props = $props();
|
|||||||
let log_lvl: number = 0;
|
let log_lvl: number = 0;
|
||||||
|
|
||||||
// *** Import Svelte specific
|
// *** Import Svelte specific
|
||||||
import { onMount, onDestroy } from 'svelte';
|
import { onMount, onDestroy, untrack } from 'svelte';
|
||||||
|
|
||||||
// *** Import other supporting libraries
|
// *** Import other supporting libraries
|
||||||
import { Modal } from 'flowbite-svelte';
|
import { Modal } from 'flowbite-svelte';
|
||||||
@@ -64,6 +64,33 @@ $effect(() => {
|
|||||||
$idaa_slct.archive_id = page.params.archive_id;
|
$idaa_slct.archive_id = page.params.archive_id;
|
||||||
// $idaa_slct.archive_obj = ae_acct.slct.archive_obj;
|
// $idaa_slct.archive_obj = ae_acct.slct.archive_obj;
|
||||||
|
|
||||||
|
// Load single archive with content — gated on auth.
|
||||||
|
// WHY $effect and not +page.ts: +page.ts runs during SvelteKit link prefetch,
|
||||||
|
// causing private IDAA data to be written to IDB before Novi auth runs.
|
||||||
|
// $effect only runs post-mount, after the layout has completed Novi verification.
|
||||||
|
$effect(() => {
|
||||||
|
if (!$idaa_loc.novi_verified && !$ae_loc.trusted_access) return;
|
||||||
|
const archive_id = $idaa_slct.archive_id;
|
||||||
|
if (!archive_id) return;
|
||||||
|
untrack(() => {
|
||||||
|
archives_func.load_ae_obj_id__archive({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
archive_id: archive_id,
|
||||||
|
inc_content_li: true,
|
||||||
|
enabled: 'enabled',
|
||||||
|
hidden: 'all',
|
||||||
|
limit: 99,
|
||||||
|
log_lvl: log_lvl
|
||||||
|
}).then((results) => {
|
||||||
|
if (!results) {
|
||||||
|
console.warn(
|
||||||
|
`IDAA Archives [archive_id] $effect: Archive ${archive_id} not found via API or Cache.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// *** Functions and Logic
|
// *** Functions and Logic
|
||||||
let lq__archive_obj = $derived(
|
let lq__archive_obj = $derived(
|
||||||
liveQuery(async () => {
|
liveQuery(async () => {
|
||||||
|
|||||||
@@ -1,56 +1,30 @@
|
|||||||
import type { PageLoad } from './$types';
|
import type { PageLoad } from './$types';
|
||||||
|
|
||||||
console.log(`ae_p_idaa_archives [archive_id] +page.ts start`);
|
// Data loading for IDAA Archives [archive_id] has been moved to the $effect in +page.svelte
|
||||||
|
// (gated on novi_verified / trusted_access). +page.ts runs before layout effects and
|
||||||
import { browser } from '$app/environment';
|
// fires during SvelteKit link prefetch, making it unsafe for private IDAA content.
|
||||||
import { archives_func } from '$lib/ae_archives/ae_archives_functions';
|
|
||||||
|
|
||||||
export const load = (async ({ params, parent }) => {
|
export const load = (async ({ params, parent }) => {
|
||||||
// route
|
|
||||||
const log_lvl: number = 0;
|
const log_lvl: number = 0;
|
||||||
|
|
||||||
const data = await parent();
|
const data = await parent();
|
||||||
data.log_lvl = log_lvl;
|
data.log_lvl = log_lvl;
|
||||||
|
|
||||||
const account_id = data.account_id;
|
const account_id = data.account_id;
|
||||||
const ae_acct = data[account_id];
|
let ae_acct = data[account_id];
|
||||||
|
|
||||||
const archive_id = params.archive_id;
|
if (!ae_acct) {
|
||||||
|
console.warn(
|
||||||
ae_acct.slct.archive_id = archive_id;
|
`ae IDAA Archives [archive_id] +page.ts: Account ${account_id} not found in data. Initializing ghost acct.`
|
||||||
|
);
|
||||||
if (browser) {
|
ae_acct = {
|
||||||
if (log_lvl) {
|
api: data.ae_api || {},
|
||||||
console.log(
|
slct: { account_id: account_id }
|
||||||
`ae_idaa_archives archives [archive_id] +page.ts: archive_id = `,
|
};
|
||||||
archive_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// NOTE: Fire in background — do NOT await. Newly created archives are already in Dexie
|
|
||||||
// (saved by create_ae_obj__archive), so the liveQuery renders immediately. For direct
|
|
||||||
// links or refreshes, the archive loads from the API and Dexie updates reactively.
|
|
||||||
// Awaiting here blocked the SvelteKit navigation, causing a visible "refresh" delay.
|
|
||||||
archives_func
|
|
||||||
.load_ae_obj_id__archive({
|
|
||||||
api_cfg: ae_acct.api,
|
|
||||||
archive_id: archive_id,
|
|
||||||
inc_content_li: true,
|
|
||||||
enabled: 'enabled',
|
|
||||||
hidden: 'all', // 'not_hidden' to load only visible entries
|
|
||||||
limit: 99,
|
|
||||||
log_lvl: log_lvl
|
|
||||||
})
|
|
||||||
.then((results) => {
|
|
||||||
if (!results) {
|
|
||||||
console.warn(
|
|
||||||
`ae IDAA Archives [archive_id] +page.ts: Archive ${archive_id} not found via API or Cache.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARNING: Precaution against shared data between sites and presentations.
|
ae_acct.slct.archive_id = params.archive_id;
|
||||||
data[account_id] = ae_acct;
|
|
||||||
|
|
||||||
|
data[account_id] = ae_acct;
|
||||||
return data;
|
return data;
|
||||||
}) satisfies PageLoad;
|
}) satisfies PageLoad;
|
||||||
|
|||||||
@@ -1,53 +1,31 @@
|
|||||||
import type { PageLoad } from './$types';
|
import type { PageLoad } from './$types';
|
||||||
|
|
||||||
console.log(`ae_idaa_bulletin_board [post_id] +page.ts start`);
|
// Data loading for IDAA BB [post_id] has been moved to the $effect in bb/+layout.svelte
|
||||||
|
// (triggered via $idaa_trig.post_id, gated inside the auth-verified layout render).
|
||||||
import { browser } from '$app/environment';
|
// +page.ts runs before layout effects and fires during SvelteKit link prefetch,
|
||||||
import { posts_func } from '$lib/ae_posts/ae_posts_functions';
|
// making it unsafe for private IDAA content.
|
||||||
|
|
||||||
export const load = (async ({ params, parent }) => {
|
export const load = (async ({ params, parent }) => {
|
||||||
// route
|
|
||||||
const log_lvl: number = 0;
|
const log_lvl: number = 0;
|
||||||
|
|
||||||
const data = await parent();
|
const data = await parent();
|
||||||
data.log_lvl = log_lvl;
|
data.log_lvl = log_lvl;
|
||||||
|
|
||||||
const account_id = data.account_id;
|
const account_id = data.account_id;
|
||||||
const ae_acct = data[account_id];
|
let ae_acct = data[account_id];
|
||||||
|
|
||||||
const post_id = params.post_id;
|
if (!ae_acct) {
|
||||||
|
console.warn(
|
||||||
ae_acct.slct.post_id = post_id;
|
`ae IDAA BB [post_id] +page.ts: Account ${account_id} not found in data. Initializing ghost acct.`
|
||||||
|
);
|
||||||
if (browser) {
|
ae_acct = {
|
||||||
if (log_lvl) {
|
api: data.ae_api || {},
|
||||||
console.log(
|
slct: { account_id: account_id }
|
||||||
`ae_idaa_posts posts [post_id] +page.ts: post_id = `,
|
};
|
||||||
post_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// NOTE: Fire in background — do NOT await. Newly created posts are already in Dexie
|
|
||||||
// (saved by create_ae_obj__post), so the liveQuery renders immediately. For direct
|
|
||||||
// links or refreshes, the post loads from the API and Dexie updates reactively.
|
|
||||||
// Awaiting here blocked the SvelteKit navigation, causing a visible "refresh" delay.
|
|
||||||
posts_func
|
|
||||||
.load_ae_obj_id__post({
|
|
||||||
api_cfg: ae_acct.api,
|
|
||||||
post_id: post_id,
|
|
||||||
inc_comment_li: true,
|
|
||||||
log_lvl: log_lvl
|
|
||||||
})
|
|
||||||
.then((results) => {
|
|
||||||
if (!results) {
|
|
||||||
console.warn(
|
|
||||||
`ae IDAA BB [post_id] +page.ts: Post ${post_id} not found via API or Cache.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARNING: Precaution against shared data between sites.
|
ae_acct.slct.post_id = params.post_id;
|
||||||
data[account_id] = ae_acct;
|
|
||||||
|
|
||||||
|
data[account_id] = ae_acct;
|
||||||
return data;
|
return data;
|
||||||
}) satisfies PageLoad;
|
}) satisfies PageLoad;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
slct_trigger
|
slct_trigger
|
||||||
} from '$lib/stores/ae_stores';
|
} from '$lib/stores/ae_stores';
|
||||||
import { db_events } from '$lib/ae_events/db_events';
|
import { db_events } from '$lib/ae_events/db_events';
|
||||||
// import { events_func } from '$lib/ae_events/ae_events_functions';
|
import { events_func } from '$lib/ae_events/ae_events_functions';
|
||||||
import {
|
import {
|
||||||
idaa_loc,
|
idaa_loc,
|
||||||
idaa_sess,
|
idaa_sess,
|
||||||
@@ -53,6 +53,29 @@ $effect(() => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Load single event — gated on auth.
|
||||||
|
// WHY $effect and not +page.ts: +page.ts runs during SvelteKit link prefetch,
|
||||||
|
// causing private IDAA data to be written to IDB before Novi auth runs.
|
||||||
|
// $effect only runs post-mount, after the layout has completed Novi verification.
|
||||||
|
$effect(() => {
|
||||||
|
if (!$idaa_loc.novi_verified && !$ae_loc.trusted_access) return;
|
||||||
|
const event_id = ae_acct?.slct?.event_id;
|
||||||
|
if (!event_id) return;
|
||||||
|
untrack(() => {
|
||||||
|
events_func.load_ae_obj_id__event({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
event_id: event_id,
|
||||||
|
log_lvl: log_lvl
|
||||||
|
}).then((results) => {
|
||||||
|
if (!results) {
|
||||||
|
console.warn(
|
||||||
|
`IDAA Recovery Meetings [event_id] $effect: Event ${event_id} not found via API or Cache.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// *** Functions and Logic
|
// *** Functions and Logic
|
||||||
let lq__event_obj = $derived(
|
let lq__event_obj = $derived(
|
||||||
liveQuery(async () => {
|
liveQuery(async () => {
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
import type { PageLoad } from './$types';
|
import type { PageLoad } from './$types';
|
||||||
|
|
||||||
console.log(`ae_p_idaa_events [event_id] +page.ts start`);
|
// Data loading for IDAA Recovery Meetings [event_id] has been moved to the $effect in +page.svelte
|
||||||
|
// (gated on novi_verified / trusted_access). +page.ts runs before layout effects and
|
||||||
// import { error } from '@sveltejs/kit';
|
// fires during SvelteKit link prefetch, making it unsafe for private IDAA content.
|
||||||
import { browser } from '$app/environment';
|
|
||||||
import { events_func } from '$lib/ae_events/ae_events_functions';
|
|
||||||
|
|
||||||
export const load = (async ({ params, parent }) => {
|
export const load = (async ({ params, parent }) => {
|
||||||
// route
|
|
||||||
const log_lvl: number = 0;
|
const log_lvl: number = 0;
|
||||||
|
|
||||||
const data = await parent();
|
const data = await parent();
|
||||||
@@ -22,54 +19,12 @@ export const load = (async ({ params, parent }) => {
|
|||||||
);
|
);
|
||||||
ae_acct = {
|
ae_acct = {
|
||||||
api: data.ae_api || {},
|
api: data.ae_api || {},
|
||||||
slct: {
|
slct: { account_id: account_id }
|
||||||
account_id: account_id
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const event_id = params.event_id;
|
ae_acct.slct.event_id = params.event_id;
|
||||||
|
|
||||||
ae_acct.slct.event_id = event_id;
|
|
||||||
|
|
||||||
if (browser) {
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log(
|
|
||||||
`ae_idaa_events events [event_id] +page.ts: event_id = `,
|
|
||||||
event_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Load event object
|
|
||||||
const load_event_obj = await events_func.load_ae_obj_id__event({
|
|
||||||
api_cfg: ae_acct.api,
|
|
||||||
event_id: event_id,
|
|
||||||
log_lvl: log_lvl
|
|
||||||
});
|
|
||||||
// .then((results) => {
|
|
||||||
// if (!results) {
|
|
||||||
// error(404, {
|
|
||||||
// message: 'IDAA Recovery Meetings - Event not found'
|
|
||||||
// });
|
|
||||||
// } else {
|
|
||||||
// // ae_acct.slct.event_obj = results;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log(`load_event_obj = `, load_event_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!load_event_obj) {
|
|
||||||
console.warn(
|
|
||||||
`ae IDAA Recovery Meeting [event_id] +page.ts: Event ${event_id} not found via API or Cache.`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
ae_acct.slct.event_obj = load_event_obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WARNING: Precaution against shared data between sites and presentations.
|
|
||||||
data[account_id] = ae_acct;
|
data[account_id] = ae_acct;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}) satisfies PageLoad;
|
}) satisfies PageLoad;
|
||||||
|
|||||||
Reference in New Issue
Block a user