From f565857e2079959276139127cd527f1e116fcce9 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Mon, 19 Jan 2026 15:37:45 -0500 Subject: [PATCH] feat: Implement API V3 Testing Dashboard and Security Hardening - Added comprehensive System Testing dashboard with live V3 trace tool. - Implemented Section 2D 'Fail-Fast' protocol in get_object helper. - Added reactive JWT synchronization in root layout to ensure V3 consistency. - Resolved Tailwind 4 @apply compilation errors in testing page. --- src/lib/ae_api/api_get_object.ts | 7 + src/routes/+layout.svelte | 11 + src/routes/testing/+page.svelte | 567 +++++++++++++++++++------------ 3 files changed, 366 insertions(+), 219 deletions(-) diff --git a/src/lib/ae_api/api_get_object.ts b/src/lib/ae_api/api_get_object.ts index 6b66d38f..f82ea4b7 100644 --- a/src/lib/ae_api/api_get_object.ts +++ b/src/lib/ae_api/api_get_object.ts @@ -169,6 +169,13 @@ export const get_object = async function get_object({ } return null; } + + // FAIL FAST (Section 2D): Do not retry on Auth/Permission failures + if (response.status === 401 || response.status === 403) { + console.error(`API Auth Failure (${response.status}). Failing fast as per Section 2D protocol.`); + return false; + } + console.log('The response was not ok. Throwing an error!'); throw new Error(`HTTP error! status: ${response.status}`); } diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 8cdd90aa..b4c9e716 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -681,6 +681,17 @@ } }); + // Sync JWT from local storage to API config for V3 endpoints + $effect(() => { + if ($ae_api.jwt !== $ae_loc.jwt) { + if (log_lvl) console.log('ROOT: Syncing JWT to API config'); + $ae_api = { + ...$ae_api, + jwt: $ae_loc.jwt + }; + } + }); + $effect(() => { if (browser) { const interval = setInterval(() => { diff --git a/src/routes/testing/+page.svelte b/src/routes/testing/+page.svelte index 0cd9dbc6..14121c7f 100644 --- a/src/routes/testing/+page.svelte +++ b/src/routes/testing/+page.svelte @@ -2,7 +2,7 @@ import { onMount } from 'svelte'; import { api } from '$lib/api/api'; - import { ae_loc, ae_sess, ae_api, slct } from '$lib/stores/ae_stores'; + import { ae_loc, ae_api, ae_sess } from '$lib/stores/ae_stores'; import { get_object } from '$lib/ae_api/api_get_object'; import { post_object } from '$lib/ae_api/api_post_object'; import { @@ -10,6 +10,8 @@ Server, User, Users, + UserCheck, + Building2, MapPin, Contact, ShieldCheck, @@ -17,24 +19,40 @@ RefreshCcw, Trash2, Bug, - Zap + Zap, + Eye, + EyeOff, + Key, + Unlock, + ShieldAlert, + ArrowRightLeft, + Code, + FlaskConical, + Info } from 'lucide-svelte'; // Core Module Imports import { load_ae_obj_li__account } from '$lib/ae_core/ae_core__account'; - import { load_ae_obj_li__site, lookup_site_domain_v3 } from '$lib/ae_core/ae_core__site'; - import { load_ae_obj_li__person } from '$lib/ae_core/ae_core__person'; - import { load_ae_obj_li__address } from '$lib/ae_core/ae_core__address'; - import { load_ae_obj_li__contact } from '$lib/ae_core/ae_core__contact'; - import { load_ae_obj_li__user } from '$lib/ae_core/ae_core__user'; + import { lookup_site_domain_v3 } from '$lib/ae_core/ae_core__site'; + import { load_ae_obj_id__user } from '$lib/ae_core/ae_core__user'; import { db_core } from '$lib/ae_core/db_core'; + // State Variables let test_result: any = $state(null); + let trace_details: any = $state(null); let test_fqdn = $state(''); let db_counts: Record = $state({}); + let show_raw_keys = $state(false); + + // Trace Controls + let trace_use_jwt = $state(true); + let trace_jwt_method = $state('header'); // 'header' or 'url' + let trace_use_bypass = $state(false); + let trace_agent_key = 'IDF68Em5X4HTZlswRNgepQ'; + let trace_use_agent_key = $state(false); onMount(async () => { - console.log('Testing Dashboard: +page.svelte'); + console.log('Testing Dashboard: +page.svelte mounted'); await update_db_counts(); }); @@ -55,6 +73,7 @@ async function run_test(name: string, test_fn: () => Promise) { test_result = 'loading...'; + trace_details = null; try { const result = await test_fn(); test_result = { test: name, timestamp: new Date().toISOString(), result }; @@ -64,97 +83,79 @@ } } - /** - * SYSTEM & INFRASTRUCTURE TESTS - */ + async function run_trace_test() { + test_result = 'loading...'; + const endpoint = '/v3/crud/journal/'; + const params: Record = { limit: 1 }; + + const custom_headers: Record = {}; + const active_key = trace_use_agent_key ? trace_agent_key : $ae_api.api_secret_key; + custom_headers['x-aether-api-key'] = active_key; + + if (trace_use_bypass) { + custom_headers['x-no-account-id'] = 'bypass'; + } else { + custom_headers['x-account-id'] = $ae_loc.account_id || 'nqOzejLCDXM'; + } + + if (trace_use_jwt && $ae_loc.jwt) { + if (trace_jwt_method === 'header') { + custom_headers['Authorization'] = `Bearer ${$ae_loc.jwt}`; + } else { + params['jwt'] = $ae_loc.jwt; + } + } + + trace_details = { + request: { + method: 'GET', + url: `${$ae_api.base_url}${endpoint}`, + params, + headers: custom_headers + } + }; + + try { + const url = new URL(endpoint, $ae_api.base_url); + Object.keys(params).forEach(k => url.searchParams.append(k, String(params[k]))); + + const response = await fetch(url.toString(), { + method: 'GET', + headers: custom_headers + }); + + const status = response.status; + const statusText = response.statusText; + let body; + try { body = await response.json(); } catch (e) { body = await response.text(); } + + trace_details.response = { status, statusText, body }; + test_result = { test: 'V3 Journal Trace', status, success: response.ok }; + } catch (error: any) { + test_result = { test: 'V3 Journal Trace', error: error.message }; + trace_details.response_error = error; + } + } const test_site_domain_lookup = () => run_test('Site Domain Lookup', async () => { const fqdn = test_fqdn || window.location.host; return await lookup_site_domain_v3({ api_cfg: $ae_api, fqdn, log_lvl: 1 }); }); - const test_bootstrap_bypass = () => run_test('Bootstrap Paradox Bypass', async () => { - const stripped_api_cfg = { base_url: $ae_api.base_url, headers: {} }; - const fqdn = test_fqdn || window.location.host; - return await post_object({ - api_cfg: stripped_api_cfg, - endpoint: '/v3/crud/site_domain/search', - headers: { 'x-no-account-id': 'System Test' }, - data: { q: fqdn }, - log_lvl: 1 - }); - }); - - /** - * CORE MODULE TESTS (V3) - */ - const test_load_accounts = () => run_test('Load Accounts', async () => { return await load_ae_obj_li__account({ api_cfg: $ae_api, enabled: 'all', log_lvl: 1 }); }); - const test_load_people = () => run_test('Load People (Account)', async () => { - return await load_ae_obj_li__person({ + const test_whoami = () => run_test('Who Am I? (JWT Test)', async () => { + if (!$ae_loc.user_id) throw new Error('No user_id found in session.'); + return await load_ae_obj_id__user({ api_cfg: $ae_api, - for_obj_id: $ae_loc.account_id, - enabled: 'all', + user_id: $ae_loc.user_id, + try_cache: false, log_lvl: 1 }); }); - const test_load_addresses = () => run_test('Load Addresses', async () => { - return await load_ae_obj_li__address({ - api_cfg: $ae_api, - for_obj_id: $ae_loc.account_id, - enabled: 'all', - log_lvl: 1 - }); - }); - - const test_load_contacts = () => run_test('Load Contacts', async () => { - return await load_ae_obj_li__contact({ - api_cfg: $ae_api, - for_obj_id: $ae_loc.account_id, - enabled: 'all', - log_lvl: 1 - }); - }); - - /** - * USER MANAGEMENT & SCOPING TESTS - */ - - const test_load_users_account = () => run_test('Load Users (Account Only)', async () => { - return await load_ae_obj_li__user({ - api_cfg: $ae_api, - for_obj_id: $ae_loc.account_id, - include_global: false, - log_lvl: 1 - }); - }); - - const test_load_users_global = () => run_test('Load Users (Global Only)', async () => { - return await load_ae_obj_li__user({ - api_cfg: $ae_api, - for_obj_id: null, - include_global: true, - log_lvl: 1 - }); - }); - - const test_load_users_all = () => run_test('Load Users (All)', async () => { - return await load_ae_obj_li__user({ - api_cfg: $ae_api, - for_obj_id: $ae_loc.account_id, - include_global: true, - log_lvl: 1 - }); - }); - - /** - * LOCAL DATABASE (DEXIE) TESTS - */ - const clear_local_cache = () => run_test('Clear Local Cache', async () => { await Promise.all([ db_core.user.clear(), @@ -169,149 +170,277 @@ -
-
-
-

- System Testing -

-

Validation dashboard for Aether Platform V3

-
-
-
-
- {db_counts.user ?? 0} - Users -
-
-
- {db_counts.person ?? 0} - People -
-
- + +
+
+
+
+

+ System Testing +

+

Validation dashboard for Aether Platform V3

-
-
- -
- -
- -
-
- -

Environment Config

-
-
- - +
+
+
+ {db_counts.user ?? 0} + Users +
+
+
+ {db_counts.person ?? 0} + People +
+
+
+ -
- -
-
- -

Infrastructure

-
-
- - -
-
- - -
-
- -

Core Modules (V3)

-
-
- - - - -
-
- - -
-
- -

User Management Scoping

-
-
- - - -
-
-
- - -
-
- -
-

Local Cache Management

-

Wipe local IndexedDB tables for core objects

-
-
- -
-
- - - + + + {#if trace_details} +
+
+ +

Request / Response Trace

+
+
+
+

📤 Sent

+
+

URL: {trace_details.request.url}

+

Headers:

+
{JSON.stringify(trace_details.request.headers, null, 2)}
+
+
+
+

📥 Received

+
+
{JSON.stringify(trace_details.response || trace_details.response_error, null, 2)}
+
+
+
+
+ {/if} + +
+
+
+ +

Infrastructure

+
+ +
+
+
+ +

Core V3

+
+ +
+
+ + +
+
+ +
+

Cache Management

+

Wipe IndexedDB (ae_core_db)

+
+
+ +
+ + + +
+ + \ No newline at end of file