diff --git a/frontend/src/lib/components/apps/editor/PublicAppFrame.svelte b/frontend/src/lib/components/apps/editor/PublicAppFrame.svelte index e994767488..a351117e5c 100644 --- a/frontend/src/lib/components/apps/editor/PublicAppFrame.svelte +++ b/frontend/src/lib/components/apps/editor/PublicAppFrame.svelte @@ -35,7 +35,11 @@ import { EMBED_NAV_CONTEXT_KEY, type EmbedNav } from '../types' import { loadAppPreview } from './loadAppPreview' import RawAppSdkConsent from '$lib/components/raw_apps/RawAppSdkConsent.svelte' - import { hasStoredSdkConsent, storeSdkConsent } from '$lib/components/raw_apps/sdkScopes' + import { + hasStoredSdkConsent, + sdkConsentCovers, + storeSdkConsent + } from '$lib/components/raw_apps/sdkScopes' type EmbedToken = { token?: string | null @@ -388,7 +392,7 @@ appPath = resp.app_path ?? appPath workspaceId = resp.workspace_id ?? workspaceId const granted = resp.sdk_scopes ?? [] - if (!granted.every((s) => approved.includes(s))) { + if (!sdkConsentCovers(approved, granted)) { // The app was redeployed with more scopes between the prompt and the // mint. Never inject a token carrying scopes the viewer wasn't shown: // drop it and ask again with the new set. diff --git a/frontend/src/lib/components/raw_apps/RawAppEditor.svelte b/frontend/src/lib/components/raw_apps/RawAppEditor.svelte index 8a0655d70e..2288403438 100644 --- a/frontend/src/lib/components/raw_apps/RawAppEditor.svelte +++ b/frontend/src/lib/components/raw_apps/RawAppEditor.svelte @@ -50,7 +50,14 @@ import { createAppSelectedContext, type AppCodeSelectionElement } from '../copilot/chat/context' import { captureScale, MAX_IMAGE_EDGE } from '../copilot/chat/imageUtils' import { rawAppLintStore } from './lintStore' - import { dbSchemas } from '$lib/stores' + import { dbSchemas, userStore } from '$lib/stores' + import RawAppSdkConsent from './RawAppSdkConsent.svelte' + import { + hasStoredSdkConsent, + movePreviewSdkConsent, + sdkConsentCovers, + storeSdkConsent + } from './sdkScopes' import { MousePointerSquareDashed, RefreshCw, @@ -414,6 +421,9 @@ // carry our origin, so they travel wrapped: listeners that trust a same-origin // message must not see the isolated app's as their own. let previewControllerUrl: string | undefined = undefined + // Editor-to-controller only, never relayed to the app: the consent prompt lives in + // the editor, so the pop-out says why it is blank. + const PREVIEW_NOTICE = 'wm:previewNotice' onDestroy(() => { if (previewControllerUrl) URL.revokeObjectURL(previewControllerUrl) }) @@ -423,14 +433,19 @@ [ `