From 86698afc24309397105f5da56b2882e2d90d5a81 Mon Sep 17 00:00:00 2001 From: MechaCat02 Date: Sun, 7 Jun 2026 20:58:35 +0200 Subject: [PATCH] fix(dashboard): F-U-008 + F-U-014 back-link to app slug, public_base_url for webhook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit F-U-008: scripts/[id]'s "← Scripts" back-link used `base + '/'` which the root page redirects to /apps. The breadcrumb already resolves appSlug; switch the back-link to `{base}/apps/{appSlug}` (falling back to `{base}/apps` when appSlug isn't loaded yet). F-U-014: emailInboundUrl built the webhook URL from window.location.origin — wrong when the admin browses via an internal LAN address but the public webhook URL is on a different host. VersionInfo.public_base_url already exists for exactly this case; the apps/[slug] page now loads /version alongside the app fetch and prefers public_base_url for the webhook URL display. Falls back to window.location.origin if /version hasn't loaded. AUDIT.md anchors: F-U-008, F-U-014. Co-Authored-By: Claude Opus 4.7 (1M context) --- dashboard/src/routes/apps/[slug]/+page.svelte | 17 ++++++++++++++++- dashboard/src/routes/scripts/[id]/+page.svelte | 4 +++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/dashboard/src/routes/apps/[slug]/+page.svelte b/dashboard/src/routes/apps/[slug]/+page.svelte index 46c1fd4..25a722e 100644 --- a/dashboard/src/routes/apps/[slug]/+page.svelte +++ b/dashboard/src/routes/apps/[slug]/+page.svelte @@ -54,6 +54,10 @@ let myRole = $state(null); let loadError = $state(null); let loading = $state(true); + /// F-U-014: the canonical public origin (from `/version`). Used to + /// build webhook URLs the operator shares with external systems so + /// they don't accidentally inherit the admin's LAN address. + let publicBaseUrl = $state(null); let activeTab = $state('scripts'); let scripts = $state([]); @@ -379,9 +383,14 @@ // The inbound-email webhook URL for a given email trigger (shown so // the operator can configure their provider). + // F-U-014: prefer the server-known public_base_url (from /version) + // so the URL we hand the operator works from outside the admin's + // network. Fall back to window.location.origin only if /version + // hasn't loaded yet (visibly distinguishable in the UI). function emailInboundUrl(triggerId: string): string { if (!app) return ''; - return `${window.location.origin}/api/v1/email-inbound/${app.id}/${triggerId}`; + const origin = publicBaseUrl ?? window.location.origin; + return `${origin.replace(/\/$/, '')}/api/v1/email-inbound/${app.id}/${triggerId}`; } async function confirmRemoveTrigger() { @@ -601,6 +610,12 @@ loading = true; loadError = null; try { + // F-U-014: fire the /version request alongside the app fetch so + // emailInboundUrl can prefer the server-known public_base_url. + api + .version() + .then((v) => (publicBaseUrl = v.public_base_url || null)) + .catch(() => (publicBaseUrl = null)); const fetched = await api.apps.get(slug); if (fetched.redirect_to && fetched.redirect_to !== slug) { await goto(`${base}/apps/${fetched.redirect_to}`, { replaceState: true }); diff --git a/dashboard/src/routes/scripts/[id]/+page.svelte b/dashboard/src/routes/scripts/[id]/+page.svelte index 5f41150..330b261 100644 --- a/dashboard/src/routes/scripts/[id]/+page.svelte +++ b/dashboard/src/routes/scripts/[id]/+page.svelte @@ -417,7 +417,9 @@
- ← Scripts + + ← {appSlug ?? 'Apps'} + {#if scriptLoading}

Loading…