@agent-native/dispatch 0.27.17 → 0.27.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/create_workspace_app_embed_session.d.ts.map +1 -1
- package/dist/actions/create_workspace_app_embed_session.js +9 -1
- package/dist/actions/create_workspace_app_embed_session.js.map +1 -1
- package/dist/actions/provider-api-register.d.ts +2 -2
- package/dist/shared/feature-flags.d.ts +2 -2
- package/dist/shared/feature-flags.d.ts.map +1 -1
- package/dist/shared/feature-flags.js +1 -1
- package/dist/shared/feature-flags.js.map +1 -1
- package/package.json +2 -2
- package/src/actions/create_workspace_app_embed_session.spec.ts +12 -0
- package/src/actions/create_workspace_app_embed_session.ts +11 -1
- package/src/shared/feature-flags.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_workspace_app_embed_session.d.ts","sourceRoot":"","sources":["../../src/actions/create_workspace_app_embed_session.ts"],"names":[],"mappings":"AAcA;;;;GAIG;AACH,wBAAsB,iCAAiC,CACrD,OAAO,EAAE,OAAO,GAAG,SAAS,GAC3B,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"create_workspace_app_embed_session.d.ts","sourceRoot":"","sources":["../../src/actions/create_workspace_app_embed_session.ts"],"names":[],"mappings":"AAcA;;;;GAIG;AACH,wBAAsB,iCAAiC,CACrD,OAAO,EAAE,OAAO,GAAG,SAAS,GAC3B,OAAO,CAAC,IAAI,CAAC,CAiDf"}
|
|
@@ -18,8 +18,16 @@ export async function assertWorkspaceEmbedSessionCaller(headers) {
|
|
|
18
18
|
if (!headers)
|
|
19
19
|
return;
|
|
20
20
|
const fetchSite = headers.get("sec-fetch-site")?.trim().toLowerCase();
|
|
21
|
+
// Electron's Chromium fetch adds Sec-Fetch-Site even for the native broker's
|
|
22
|
+
// server request. The custom header is not sendable by a cross-origin page
|
|
23
|
+
// without a successful CORS preflight, so it is the native CSRF marker.
|
|
24
|
+
if (fetchSite &&
|
|
25
|
+
fetchSite !== "same-origin" &&
|
|
26
|
+
headers.get("x-agent-native-csrf")?.trim() === "1") {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
21
29
|
// Browsers always send Sec-Fetch-Site and page scripts cannot forge or strip
|
|
22
|
-
// this forbidden header. Native clients
|
|
30
|
+
// this forbidden header. Native clients without fetch metadata authenticate
|
|
23
31
|
// through the normal action request context below.
|
|
24
32
|
if (!fetchSite)
|
|
25
33
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_workspace_app_embed_session.js","sourceRoot":"","sources":["../../src/actions/create_workspace_app_embed_session.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { getRequestContext } from \"@agent-native/core/server\";\nimport { z } from \"zod\";\n\nimport { listWorkspaceApps } from \"../server/lib/app-creation-store.js\";\nimport { createWorkspaceSsoEmbedSession } from \"../server/lib/mcp-gateway.js\";\n\nfunction isPathWithinApp(pathname: string, appPath: string): boolean {\n const normalized = appPath.replace(/\\/+$/, \"\") || \"/\";\n return normalized === \"/\"\n ? pathname.startsWith(\"/\")\n : pathname === normalized || pathname.startsWith(`${normalized}/`);\n}\n\n/**\n * Browser callers must come from the Dispatch parent surface. Native callers\n * carry the parent bearer explicitly; direct in-process action calls have no\n * request headers and are already inside the server authorization boundary.\n */\nexport async function assertWorkspaceEmbedSessionCaller(\n headers: Headers | undefined,\n): Promise<void> {\n if (!headers) return;\n\n const fetchSite = headers.get(\"sec-fetch-site\")?.trim().toLowerCase();\n // Browsers always send Sec-Fetch-Site and page scripts cannot forge or strip\n // this forbidden header. Native clients
|
|
1
|
+
{"version":3,"file":"create_workspace_app_embed_session.js","sourceRoot":"","sources":["../../src/actions/create_workspace_app_embed_session.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { getRequestContext } from \"@agent-native/core/server\";\nimport { z } from \"zod\";\n\nimport { listWorkspaceApps } from \"../server/lib/app-creation-store.js\";\nimport { createWorkspaceSsoEmbedSession } from \"../server/lib/mcp-gateway.js\";\n\nfunction isPathWithinApp(pathname: string, appPath: string): boolean {\n const normalized = appPath.replace(/\\/+$/, \"\") || \"/\";\n return normalized === \"/\"\n ? pathname.startsWith(\"/\")\n : pathname === normalized || pathname.startsWith(`${normalized}/`);\n}\n\n/**\n * Browser callers must come from the Dispatch parent surface. Native callers\n * carry the parent bearer explicitly; direct in-process action calls have no\n * request headers and are already inside the server authorization boundary.\n */\nexport async function assertWorkspaceEmbedSessionCaller(\n headers: Headers | undefined,\n): Promise<void> {\n if (!headers) return;\n\n const fetchSite = headers.get(\"sec-fetch-site\")?.trim().toLowerCase();\n // Electron's Chromium fetch adds Sec-Fetch-Site even for the native broker's\n // server request. The custom header is not sendable by a cross-origin page\n // without a successful CORS preflight, so it is the native CSRF marker.\n if (\n fetchSite &&\n fetchSite !== \"same-origin\" &&\n headers.get(\"x-agent-native-csrf\")?.trim() === \"1\"\n ) {\n return;\n }\n // Browsers always send Sec-Fetch-Site and page scripts cannot forge or strip\n // this forbidden header. Native clients without fetch metadata authenticate\n // through the normal action request context below.\n if (!fetchSite) return;\n if (fetchSite !== \"same-origin\") {\n throw new Error(\"Workspace app sessions must be requested by Dispatch.\");\n }\n\n const referer = headers.get(\"referer\");\n const requestOrigin = getRequestContext()?.requestOrigin;\n if (!referer || !requestOrigin) {\n throw new Error(\"Workspace app sessions must be requested by Dispatch.\");\n }\n\n let refererUrl: URL;\n try {\n refererUrl = new URL(referer);\n } catch {\n throw new Error(\"Workspace app sessions must be requested by Dispatch.\");\n }\n if (refererUrl.origin !== requestOrigin) {\n throw new Error(\"Workspace app sessions must be requested by Dispatch.\");\n }\n const apps = await listWorkspaceApps({\n includeAgentCards: false,\n audience: \"all\",\n });\n if (\n apps.some(\n (app) =>\n !app.isDispatch && isPathWithinApp(refererUrl.pathname, app.path),\n )\n ) {\n throw new Error(\"Workspace apps cannot mint sessions for themselves.\");\n }\n}\n\nexport default defineAction({\n description:\n \"Create a one-time app-scoped embed session for a workspace app opened inside Dispatch. This browser-only path is rollout-gated and never exposes an app's reusable session to another app.\",\n schema: z.object({\n app: z\n .string()\n .optional()\n .describe(\"Workspace app id when path is app-relative.\"),\n url: z\n .string()\n .optional()\n .describe(\"Absolute app URL or app-relative path.\"),\n path: z\n .string()\n .optional()\n .describe(\"App-relative path. Requires app when url is not provided.\"),\n chrome: z\n .enum([\"full\", \"minimal\"])\n .optional()\n .describe(\"Embed chrome preference. Defaults to full.\"),\n }),\n readOnly: false,\n parallelSafe: false,\n agentTool: false,\n toolCallable: false,\n run: async (args, context) => {\n await assertWorkspaceEmbedSessionCaller(context?.requestHeaders);\n return createWorkspaceSsoEmbedSession(args);\n },\n});\n"]}
|
|
@@ -47,8 +47,8 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
47
47
|
notes?: string | undefined;
|
|
48
48
|
scope?: "org" | "user" | undefined;
|
|
49
49
|
}, {
|
|
50
|
-
message?: undefined;
|
|
51
50
|
id?: undefined;
|
|
51
|
+
message?: undefined;
|
|
52
52
|
deleted?: undefined;
|
|
53
53
|
providers: {
|
|
54
54
|
id: string;
|
|
@@ -65,9 +65,9 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
65
65
|
registered?: undefined;
|
|
66
66
|
label?: undefined;
|
|
67
67
|
} | {
|
|
68
|
+
id?: undefined;
|
|
68
69
|
message?: undefined;
|
|
69
70
|
count?: undefined;
|
|
70
|
-
id?: undefined;
|
|
71
71
|
deleted?: undefined;
|
|
72
72
|
providers?: undefined;
|
|
73
73
|
found: boolean;
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
* action checks this flag too; the client hook only selects the presentation
|
|
4
4
|
* path and keeps the legacy embed route available while the flag is off.
|
|
5
5
|
*/
|
|
6
|
-
export declare const DISPATCH_WORKSPACE_SSO_FLAG: import("@agent-native/core/feature-flags").FeatureFlagDefinition;
|
|
7
|
-
export declare const DISPATCH_WORKSPACE_APP_LIST_FLAG: import("@agent-native/core/feature-flags").FeatureFlagDefinition;
|
|
6
|
+
export declare const DISPATCH_WORKSPACE_SSO_FLAG: import("@agent-native/core/feature-flags/registry").FeatureFlagDefinition;
|
|
7
|
+
export declare const DISPATCH_WORKSPACE_APP_LIST_FLAG: import("@agent-native/core/feature-flags/registry").FeatureFlagDefinition;
|
|
8
8
|
//# sourceMappingURL=feature-flags.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-flags.d.ts","sourceRoot":"","sources":["../../src/shared/feature-flags.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,
|
|
1
|
+
{"version":3,"file":"feature-flags.d.ts","sourceRoot":"","sources":["../../src/shared/feature-flags.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,2EAKtC,CAAC;AAEH,eAAO,MAAM,gCAAgC,2EAK3C,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineFeatureFlag } from "@agent-native/core/feature-flags";
|
|
1
|
+
import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
|
|
2
2
|
/**
|
|
3
3
|
* Browser-only rollout for app-scoped sessions in Dispatch panes. The server
|
|
4
4
|
* action checks this flag too; the client hook only selects the presentation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-flags.js","sourceRoot":"","sources":["../../src/shared/feature-flags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"feature-flags.js","sourceRoot":"","sources":["../../src/shared/feature-flags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAE9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,iBAAiB,CAAC;IAC3D,GAAG,EAAE,wBAAwB;IAC7B,WAAW,EAAE,4BAA4B;IACzC,WAAW,EACT,mFAAmF;CACtF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gCAAgC,GAAG,iBAAiB,CAAC;IAChE,GAAG,EAAE,6BAA6B;IAClC,WAAW,EAAE,oBAAoB;IACjC,WAAW,EACT,gFAAgF;CACnF,CAAC,CAAC","sourcesContent":["import { defineFeatureFlag } from \"@agent-native/core/feature-flags/registry\";\n\n/**\n * Browser-only rollout for app-scoped sessions in Dispatch panes. The server\n * action checks this flag too; the client hook only selects the presentation\n * path and keeps the legacy embed route available while the flag is off.\n */\nexport const DISPATCH_WORKSPACE_SSO_FLAG = defineFeatureFlag({\n key: \"dispatch.workspace-sso\",\n displayName: \"Dispatch workspace sign-in\",\n description:\n \"Let Dispatch use the signed-in workspace identity for exact registered app panes.\",\n});\n\nexport const DISPATCH_WORKSPACE_APP_LIST_FLAG = defineFeatureFlag({\n key: \"dispatch.workspace-app-list\",\n displayName: \"Workspace app list\",\n description:\n \"Show apps from the signed-in workspace in native desktop and mobile app lists.\",\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/dispatch",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.19",
|
|
4
4
|
"description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"typescript-7": "npm:typescript@^7.0.2",
|
|
102
102
|
"vite": "8.1.0",
|
|
103
103
|
"vitest": "^4.1.5",
|
|
104
|
-
"@agent-native/core": "0.159.
|
|
104
|
+
"@agent-native/core": "0.159.5"
|
|
105
105
|
},
|
|
106
106
|
"peerDependencies": {
|
|
107
107
|
"@agent-native/core": ">=0.8.0",
|
|
@@ -49,6 +49,18 @@ describe("assertWorkspaceEmbedSessionCaller", () => {
|
|
|
49
49
|
expect(apps.listWorkspaceApps).not.toHaveBeenCalled();
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
+
it("allows the native marker when Chromium adds cross-site fetch metadata", async () => {
|
|
53
|
+
await expect(
|
|
54
|
+
assertWorkspaceEmbedSessionCaller(
|
|
55
|
+
new Headers({
|
|
56
|
+
"Sec-Fetch-Site": "cross-site",
|
|
57
|
+
"X-Agent-Native-CSRF": "1",
|
|
58
|
+
}),
|
|
59
|
+
),
|
|
60
|
+
).resolves.toBeUndefined();
|
|
61
|
+
expect(apps.listWorkspaceApps).not.toHaveBeenCalled();
|
|
62
|
+
});
|
|
63
|
+
|
|
52
64
|
it("allows a same-origin Dispatch browser caller", async () => {
|
|
53
65
|
await expect(
|
|
54
66
|
assertWorkspaceEmbedSessionCaller(
|
|
@@ -23,8 +23,18 @@ export async function assertWorkspaceEmbedSessionCaller(
|
|
|
23
23
|
if (!headers) return;
|
|
24
24
|
|
|
25
25
|
const fetchSite = headers.get("sec-fetch-site")?.trim().toLowerCase();
|
|
26
|
+
// Electron's Chromium fetch adds Sec-Fetch-Site even for the native broker's
|
|
27
|
+
// server request. The custom header is not sendable by a cross-origin page
|
|
28
|
+
// without a successful CORS preflight, so it is the native CSRF marker.
|
|
29
|
+
if (
|
|
30
|
+
fetchSite &&
|
|
31
|
+
fetchSite !== "same-origin" &&
|
|
32
|
+
headers.get("x-agent-native-csrf")?.trim() === "1"
|
|
33
|
+
) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
26
36
|
// Browsers always send Sec-Fetch-Site and page scripts cannot forge or strip
|
|
27
|
-
// this forbidden header. Native clients
|
|
37
|
+
// this forbidden header. Native clients without fetch metadata authenticate
|
|
28
38
|
// through the normal action request context below.
|
|
29
39
|
if (!fetchSite) return;
|
|
30
40
|
if (fetchSite !== "same-origin") {
|