@agent-native/dispatch 0.15.11 → 0.15.13
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/provider-api-register.d.ts +13 -13
- package/dist/actions/send-platform-message.js +3 -1
- package/dist/actions/send-platform-message.js.map +1 -1
- package/dist/server/lib/dispatch-integrations.d.ts.map +1 -1
- package/dist/server/lib/dispatch-integrations.js +3 -6
- package/dist/server/lib/dispatch-integrations.js.map +1 -1
- package/package.json +3 -3
- package/src/actions/send-platform-message.spec.ts +21 -0
- package/src/actions/send-platform-message.ts +3 -2
- package/src/server/lib/dispatch-integrations.spec.ts +39 -1
- package/src/server/lib/dispatch-integrations.ts +3 -10
|
@@ -47,10 +47,10 @@ 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
|
-
|
|
50
|
+
deleted?: undefined;
|
|
51
51
|
id?: undefined;
|
|
52
|
+
provider?: undefined;
|
|
52
53
|
found?: undefined;
|
|
53
|
-
deleted?: undefined;
|
|
54
54
|
providers: {
|
|
55
55
|
id: string;
|
|
56
56
|
label: string;
|
|
@@ -61,45 +61,45 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
61
61
|
updatedAt: number;
|
|
62
62
|
}[];
|
|
63
63
|
count: number;
|
|
64
|
-
provider?: undefined;
|
|
65
64
|
registered?: undefined;
|
|
66
65
|
label?: undefined;
|
|
67
|
-
} | {
|
|
68
66
|
message?: undefined;
|
|
69
|
-
|
|
67
|
+
} | {
|
|
70
68
|
deleted?: undefined;
|
|
71
|
-
providers?: undefined;
|
|
72
69
|
count?: undefined;
|
|
70
|
+
id?: undefined;
|
|
71
|
+
providers?: undefined;
|
|
73
72
|
found: boolean;
|
|
74
73
|
provider: import("node_modules/@agent-native/core/dist/provider-api").CustomProviderConfig;
|
|
75
74
|
registered?: undefined;
|
|
76
75
|
label?: undefined;
|
|
77
|
-
} | {
|
|
78
76
|
message?: undefined;
|
|
77
|
+
} | {
|
|
79
78
|
deleted?: undefined;
|
|
80
|
-
providers?: undefined;
|
|
81
79
|
count?: undefined;
|
|
82
80
|
provider?: undefined;
|
|
81
|
+
providers?: undefined;
|
|
83
82
|
found: boolean;
|
|
84
83
|
id: string;
|
|
85
84
|
registered?: undefined;
|
|
86
85
|
label?: undefined;
|
|
87
|
-
} | {
|
|
88
86
|
message?: undefined;
|
|
89
|
-
|
|
90
|
-
providers?: undefined;
|
|
87
|
+
} | {
|
|
91
88
|
count?: undefined;
|
|
92
89
|
provider?: undefined;
|
|
90
|
+
found?: undefined;
|
|
91
|
+
providers?: undefined;
|
|
93
92
|
deleted: boolean;
|
|
94
93
|
id: string;
|
|
95
94
|
registered?: undefined;
|
|
96
95
|
label?: undefined;
|
|
96
|
+
message?: undefined;
|
|
97
97
|
} | {
|
|
98
|
-
found?: undefined;
|
|
99
98
|
deleted?: undefined;
|
|
100
|
-
providers?: undefined;
|
|
101
99
|
count?: undefined;
|
|
102
100
|
provider?: undefined;
|
|
101
|
+
found?: undefined;
|
|
102
|
+
providers?: undefined;
|
|
103
103
|
registered: boolean;
|
|
104
104
|
id: string;
|
|
105
105
|
label: string;
|
|
@@ -22,7 +22,9 @@ async function assertOutboundConfigured(platform, tenantId) {
|
|
|
22
22
|
const managed = installation
|
|
23
23
|
? await resolveIntegrationTokenBundle("slack", installation.installationKey)
|
|
24
24
|
: null;
|
|
25
|
-
const token =
|
|
25
|
+
const token = tenantId
|
|
26
|
+
? managed?.accessToken
|
|
27
|
+
: (managed?.accessToken ?? (await resolveSecret("SLACK_BOT_TOKEN")));
|
|
26
28
|
if (!token) {
|
|
27
29
|
throw new Error(tenantId
|
|
28
30
|
? "That Slack workspace is not connected"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send-platform-message.js","sourceRoot":"","sources":["../../src/actions/send-platform-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,aAAa,GACd,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,SAAS,UAAU,CACjB,QAAwC,EACxC,UAAmB;IAEnB,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,YAAY,EAAE,CAAC;IAChD,OAAO,QAAQ,KAAK,OAAO;QACzB,CAAC,CAAC,YAAY,CAAC,EAAE,eAAe,EAAE,KAAK,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;QAC3D,CAAC,CAAC,eAAe,EAAE,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,QAAwC,EACxC,QAAiB;IAEjB,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,mBAAmB,EAAE,CAAC;QACxC,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACrE,MAAM,aAAa,GAAG,QAAQ;YAC5B,CAAC,CAAC,MAAM,4BAA4B,CAChC,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,IAAI,EAAE,EAC/C,OAAO,CACR;YACH,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,YAAY,GAChB,aAAa,CAAC,IAAI,CAChB,CAAC,SAAS,EAAE,EAAE,CACZ,SAAS,CAAC,MAAM,KAAK,QAAQ,IAAI,SAAS,CAAC,YAAY,KAAK,QAAQ,CACvE,IAAI,IAAI,CAAC;QACZ,MAAM,OAAO,GAAG,YAAY;YAC1B,CAAC,CAAC,MAAM,6BAA6B,CACjC,OAAO,EACP,YAAY,CAAC,eAAe,CAC7B;YACH,CAAC,CAAC,IAAI,CAAC;QACT,MAAM,KAAK,
|
|
1
|
+
{"version":3,"file":"send-platform-message.js","sourceRoot":"","sources":["../../src/actions/send-platform-message.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport {\n listIntegrationInstallations,\n resolveIntegrationTokenBundle,\n} from \"@agent-native/core/integrations\";\nimport {\n getRequestOrgId,\n getRequestUserEmail,\n slackAdapter,\n telegramAdapter,\n emailAdapter,\n isEmailConfigured,\n resolveSecret,\n} from \"@agent-native/core/server\";\nimport { z } from \"zod\";\n\nimport { getDestinationById } from \"../server/lib/dispatch-store.js\";\n\nfunction getAdapter(\n platform: \"slack\" | \"telegram\" | \"email\",\n slackToken?: string,\n) {\n if (platform === \"email\") return emailAdapter();\n return platform === \"slack\"\n ? slackAdapter({ resolveBotToken: async () => slackToken })\n : telegramAdapter();\n}\n\nasync function assertOutboundConfigured(\n platform: \"slack\" | \"telegram\" | \"email\",\n tenantId?: string,\n): Promise<string | undefined> {\n if (platform === \"slack\") {\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"An authenticated user is required\");\n const installations = tenantId\n ? await listIntegrationInstallations(\n { userEmail, orgId: getRequestOrgId() ?? null },\n \"slack\",\n )\n : [];\n const installation =\n installations.find(\n (candidate) =>\n candidate.teamId === tenantId || candidate.enterpriseId === tenantId,\n ) ?? null;\n const managed = installation\n ? await resolveIntegrationTokenBundle(\n \"slack\",\n installation.installationKey,\n )\n : null;\n const token = tenantId\n ? managed?.accessToken\n : (managed?.accessToken ?? (await resolveSecret(\"SLACK_BOT_TOKEN\")));\n if (!token) {\n throw new Error(\n tenantId\n ? \"That Slack workspace is not connected\"\n : \"Select a Slack workspace for managed outbound messaging\",\n );\n }\n return token;\n }\n if (platform === \"telegram\" && !(await resolveSecret(\"TELEGRAM_BOT_TOKEN\"))) {\n throw new Error(\"Telegram outbound messaging is not configured\");\n }\n if (platform === \"email\") {\n if (\n !(await resolveSecret(\"EMAIL_AGENT_ADDRESS\")) ||\n !(await isEmailConfigured())\n ) {\n throw new Error(\"Email outbound messaging is not configured\");\n }\n }\n}\n\nexport default defineAction({\n description:\n \"Send a proactive message to a saved Slack, Telegram, or email destination.\",\n schema: z.object({\n platform: z.enum([\"slack\", \"telegram\", \"email\"]).optional(),\n destinationId: z.string().optional().describe(\"Saved destination id\"),\n destination: z.string().optional().describe(\"Raw platform destination id\"),\n threadRef: z.string().optional().describe(\"Optional thread reference\"),\n tenantId: z\n .string()\n .optional()\n .describe(\"Slack workspace/team id for managed installations\"),\n text: z.string().describe(\"Message to send\"),\n }),\n audit: {\n recordInputs: false,\n target: (args) => ({\n type: \"destination\",\n id: args.destinationId || args.destination || \"unknown\",\n visibility: \"private\",\n }),\n summary: (args) => `Sent proactive ${args.platform || \"saved\"} message`,\n },\n run: async ({\n platform,\n destinationId,\n destination,\n threadRef,\n tenantId,\n text,\n }) => {\n const saved = destinationId\n ? await getDestinationById(destinationId)\n : null;\n const resolvedPlatform = (saved?.platform || platform) as\n | \"slack\"\n | \"telegram\"\n | \"email\"\n | undefined;\n const resolvedDestination = saved?.destination || destination;\n const resolvedThreadRef = saved?.threadRef || threadRef || null;\n\n if (!resolvedPlatform || !resolvedDestination) {\n throw new Error(\"A platform and destination are required\");\n }\n\n const slackToken = await assertOutboundConfigured(\n resolvedPlatform,\n tenantId,\n );\n\n const adapter = getAdapter(resolvedPlatform, slackToken);\n if (!adapter.sendMessageToTarget) {\n throw new Error(\n `Platform ${resolvedPlatform} does not support proactive outbound messaging`,\n );\n }\n\n await adapter.sendMessageToTarget(adapter.formatAgentResponse(text), {\n destination: resolvedDestination,\n threadRef: resolvedThreadRef,\n label: saved?.name || undefined,\n tenantId,\n });\n\n return {\n ok: true,\n platform: resolvedPlatform,\n destination: resolvedDestination,\n threadRef: resolvedThreadRef,\n };\n },\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch-integrations.d.ts","sourceRoot":"","sources":["../../../src/server/lib/dispatch-integrations.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dispatch-integrations.d.ts","sourceRoot":"","sources":["../../../src/server/lib/dispatch-integrations.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,eAAe,EACf,2BAA2B,EAC3B,eAAe,EAChB,MAAM,2BAA2B,CAAC;AA2BnC,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,eAAe,GACxB,MAAM,GAAG,IAAI,CAmBf;AAwOD,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,MAAM,CAAC,CA8DjB;AAED;;;;GAIG;AACH,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,2BAA2B,CAAC,CAgGtC;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAA;CAAE,CAAC,CAwDxE"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
-
import { evaluateIntegrationScopePolicy, getActiveIntegrationInstallationByKey, getIntegrationScope, resolveIntegrationTokenBundle, saveIntegrationScope, slackInstallationKey, } from "@agent-native/core/integrations";
|
|
2
|
+
import { evaluateIntegrationScopePolicy, getActiveIntegrationInstallationByKey, getIntegrationScope, resolveIntegrationTokenBundle, resolveSlackBotTokenForIncoming, saveIntegrationScope, slackInstallationKey, } from "@agent-native/core/integrations";
|
|
3
3
|
import { resolveOrgIdForEmail } from "@agent-native/core/org";
|
|
4
|
-
import {
|
|
4
|
+
import { withConfiguredAppBasePath } from "@agent-native/core/server";
|
|
5
5
|
import { handleRemoteCodeCommand } from "./dispatch-remote-commands.js";
|
|
6
6
|
import { dispatchIntegrationRoutingHint, } from "./dispatch-routing.js";
|
|
7
7
|
import { consumeLinkToken, resolveLinkedOwner } from "./dispatch-store.js";
|
|
@@ -117,10 +117,7 @@ async function resolveSlackSenderProfile(incoming) {
|
|
|
117
117
|
if (incoming.platform !== "slack") {
|
|
118
118
|
return { email: null, name: null, trust: "unknown" };
|
|
119
119
|
}
|
|
120
|
-
const
|
|
121
|
-
const token = managedToken ??
|
|
122
|
-
(await resolveSecret("SLACK_BOT_TOKEN")) ??
|
|
123
|
-
readDeployCredentialEnv("SLACK_BOT_TOKEN");
|
|
120
|
+
const token = await resolveSlackBotTokenForIncoming(incoming);
|
|
124
121
|
const userId = contextString(incoming.senderId);
|
|
125
122
|
const teamId = contextString(incoming.platformContext.teamId);
|
|
126
123
|
if (!token || !userId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch-integrations.js","sourceRoot":"","sources":["../../../src/server/lib/dispatch-integrations.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"node:crypto\";\n\nimport {\n evaluateIntegrationScopePolicy,\n getActiveIntegrationInstallationByKey,\n getIntegrationScope,\n resolveIntegrationTokenBundle,\n saveIntegrationScope,\n slackInstallationKey,\n} from \"@agent-native/core/integrations\";\nimport { resolveOrgIdForEmail } from \"@agent-native/core/org\";\nimport {\n readDeployCredentialEnv,\n resolveSecret,\n withConfiguredAppBasePath,\n} from \"@agent-native/core/server\";\nimport type {\n IncomingMessage,\n IntegrationExecutionContext,\n PlatformAdapter,\n} from \"@agent-native/core/server\";\n\nimport { handleRemoteCodeCommand } from \"./dispatch-remote-commands.js\";\nimport {\n dispatchIntegrationRoutingHint,\n type DispatchIntegrationRoutingHint,\n} from \"./dispatch-routing.js\";\nimport { consumeLinkToken, resolveLinkedOwner } from \"./dispatch-store.js\";\n\ntype SlackSenderProfile = {\n email: string | null;\n name: string | null;\n trust: \"trusted\" | \"guest\" | \"external_shared\" | \"unknown\";\n};\n\nconst slackProfileCache = new Map<\n string,\n { profile: SlackSenderProfile; expiresAt: number }\n>();\nconst SLACK_PROFILE_CACHE_TTL = 10 * 60 * 1000;\n\nfunction contextString(value: unknown): string | null {\n if (typeof value === \"string\" && value.trim()) return value.trim();\n if (typeof value === \"number\" && Number.isFinite(value)) return String(value);\n return null;\n}\n\nexport function identityKeyForIncoming(\n incoming: IncomingMessage,\n): string | null {\n const senderId = contextString(incoming.senderId);\n if (!senderId) return null;\n\n if (incoming.platform === \"slack\") {\n const teamId = contextString(incoming.platformContext.teamId);\n return teamId ? `${teamId}:${senderId}` : senderId;\n }\n\n if (incoming.platform === \"whatsapp\") {\n const phoneNumberId = contextString(incoming.platformContext.phoneNumberId);\n return phoneNumberId ? `${phoneNumberId}:${senderId}` : senderId;\n }\n\n if (incoming.platform === \"email\") {\n return senderId.toLowerCase();\n }\n\n return senderId;\n}\n\nfunction fallbackOwnerForIncoming(incoming: IncomingMessage): string {\n const tenant =\n contextString(incoming.platformContext.teamId) ||\n contextString(incoming.platformContext.phoneNumberId) ||\n contextString(incoming.platformContext.chatId) ||\n contextString(incoming.platformContext.from) ||\n incoming.externalThreadId;\n const raw = `${incoming.platform}:${tenant}:${incoming.senderId || \"\"}`;\n const hash = crypto\n .createHash(\"sha256\")\n .update(raw)\n .digest(\"hex\")\n .slice(0, 16);\n return `dispatch+${hash}@integration.local`;\n}\n\nfunction configuredDefaultOwnerForIncoming(\n incoming: IncomingMessage,\n): string | null {\n // This is intentionally Slack-only: a deployment-wide default owner grants\n // that Slack workspace access to the owner's connected agents and org\n // credentials, so other platforms should opt in with explicit identity links.\n if (incoming.platform !== \"slack\") return null;\n const email = process.env.DISPATCH_DEFAULT_OWNER_EMAIL?.trim();\n if (!email) return null;\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email) ? email : null;\n}\n\nfunction platformRequiresExplicitLink(incoming: IncomingMessage): boolean {\n // Telegram does not provide a verified email address. Require an explicit\n // identity link before it can act as a Builder/Agent-Native user.\n return incoming.platform === \"telegram\";\n}\n\nfunction configuredDispatchIdentitiesUrl(): string | null {\n const raw =\n process.env.WORKSPACE_GATEWAY_URL ||\n process.env.APP_URL ||\n process.env.URL ||\n process.env.DEPLOY_URL ||\n process.env.BETTER_AUTH_URL ||\n \"\";\n if (!raw.trim()) return null;\n const base = /^https?:\\/\\//i.test(raw) ? raw : `https://${raw}`;\n try {\n return new URL(\n \"identities\",\n `${withConfiguredAppBasePath(base).replace(/\\/+$/, \"\")}/`,\n ).toString();\n } catch {\n return null;\n }\n}\n\nasync function resolveManagedSlackInstallation(incoming: IncomingMessage) {\n if (incoming.platform !== \"slack\") return null;\n const teamId = contextString(incoming.platformContext.teamId);\n const apiAppId = contextString(incoming.platformContext.apiAppId);\n if (!teamId) return null;\n try {\n return await getActiveIntegrationInstallationByKey(\n \"slack\",\n slackInstallationKey({ teamId, apiAppId }),\n );\n } catch {\n return null;\n }\n}\n\nasync function resolveManagedSlackToken(\n incoming: IncomingMessage,\n): Promise<string | null> {\n const installation = await resolveManagedSlackInstallation(incoming);\n if (!installation) return null;\n const bundle = await resolveIntegrationTokenBundle(\n \"slack\",\n installation.installationKey,\n );\n return bundle?.accessToken ?? null;\n}\n\nfunction formatTelegramLinkRequiredMessage(): string {\n const identitiesUrl = configuredDispatchIdentitiesUrl();\n const linkStep = identitiesUrl\n ? `Tap ${identitiesUrl}, create a Telegram link token, then send \\`/link <token>\\` here.`\n : \"Open Dispatch while signed in, create a Telegram link token, then send `/link <token>` here.\";\n return `Telegram is connected, but this Telegram account is not linked to an Agent-Native user yet. ${linkStep} After that I can use your Builder.io org and connected apps.`;\n}\n\nfunction formatSlackLinkRequiredMessage(): string {\n const identitiesUrl = configuredDispatchIdentitiesUrl();\n const linkStep = identitiesUrl\n ? `Open ${identitiesUrl}, create a Slack link token, then send \\`/link <token>\\` in this DM.`\n : \"Open Dispatch while signed in, create a Slack link token, then send `/link <token>` in this DM.\";\n return `Agent Native is ready, but this Slack account is not linked to an Agent Native user yet. ${linkStep}`;\n}\n\nasync function resolveSlackSenderProfile(\n incoming: IncomingMessage,\n): Promise<SlackSenderProfile> {\n if (incoming.platform !== \"slack\") {\n return { email: null, name: null, trust: \"unknown\" };\n }\n const managedToken = await resolveManagedSlackToken(incoming);\n const token =\n managedToken ??\n (await resolveSecret(\"SLACK_BOT_TOKEN\")) ??\n readDeployCredentialEnv(\"SLACK_BOT_TOKEN\");\n const userId = contextString(incoming.senderId);\n const teamId = contextString(incoming.platformContext.teamId);\n if (!token || !userId) {\n return { email: null, name: null, trust: \"unknown\" };\n }\n\n // Slack user IDs are scoped per workspace, so without a teamId we can't\n // safely cache: two installs of the bot in different workspaces could\n // share user-id strings and collide on a single \"default\" key. Skip the\n // cache (and lookup on every request) when teamId is missing.\n const cacheKey = teamId ? `${teamId}:${userId}` : null;\n if (cacheKey) {\n const cached = slackProfileCache.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) return cached.profile;\n }\n\n try {\n const params = new URLSearchParams({ user: userId });\n const res = await fetch(`https://slack.com/api/users.info?${params}`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n const data = (await res.json()) as {\n ok?: boolean;\n user?: {\n real_name?: string;\n name?: string;\n profile?: {\n email?: string;\n real_name?: string;\n display_name?: string;\n };\n is_restricted?: boolean;\n is_ultra_restricted?: boolean;\n };\n };\n const profile = data.ok\n ? {\n email: data.user?.profile?.email?.trim().toLowerCase() || null,\n name:\n data.user?.profile?.real_name?.trim() ||\n data.user?.profile?.display_name?.trim() ||\n data.user?.real_name?.trim() ||\n data.user?.name?.trim() ||\n null,\n trust:\n data.user?.is_ultra_restricted === true\n ? (\"external_shared\" as const)\n : data.user?.is_restricted === true\n ? (\"guest\" as const)\n : (\"trusted\" as const),\n }\n : { email: null, name: null, trust: \"unknown\" as const };\n if (cacheKey) {\n slackProfileCache.set(cacheKey, {\n profile,\n expiresAt: Date.now() + SLACK_PROFILE_CACHE_TTL,\n });\n }\n return profile;\n } catch {\n return { email: null, name: null, trust: \"unknown\" };\n }\n}\n\nasync function resolveSlackOwnerFromVerifiedEmail(\n incoming: IncomingMessage,\n): Promise<string | null> {\n const profile = await resolveSlackSenderProfile(incoming);\n if (!profile.email) return null;\n\n incoming.senderEmail = profile.email;\n incoming.platformContext.senderEmail = profile.email;\n if (profile.name) {\n incoming.senderName = profile.name;\n incoming.platformContext.senderName = profile.name;\n }\n\n const orgId = await resolveOrgIdForEmail(profile.email);\n return orgId ? profile.email : null;\n}\n\nasync function resolveSlackConversationTrust(\n incoming: IncomingMessage,\n actorTrust: SlackSenderProfile[\"trust\"],\n): Promise<{\n trust: SlackSenderProfile[\"trust\"];\n conversationType: \"channel\" | \"direct_message\" | \"group_direct_message\";\n}> {\n if (incoming.triggerKind === \"dm\") {\n return { trust: actorTrust, conversationType: \"direct_message\" };\n }\n const token = await resolveManagedSlackToken(incoming);\n const channel = contextString(incoming.platformContext.channelId);\n if (!token || !channel) {\n return { trust: \"unknown\", conversationType: \"channel\" };\n }\n try {\n const params = new URLSearchParams({ channel });\n const response = await fetch(\n `https://slack.com/api/conversations.info?${params}`,\n { headers: { Authorization: `Bearer ${token}` } },\n );\n const data = (await response.json()) as {\n ok?: boolean;\n channel?: {\n is_ext_shared?: boolean;\n is_im?: boolean;\n is_mpim?: boolean;\n };\n };\n if (!data.ok) {\n return { trust: \"unknown\", conversationType: \"channel\" };\n }\n return {\n trust: data.channel?.is_ext_shared ? \"external_shared\" : actorTrust,\n conversationType: data.channel?.is_im\n ? \"direct_message\"\n : data.channel?.is_mpim\n ? \"group_direct_message\"\n : \"channel\",\n };\n } catch {\n return { trust: \"unknown\", conversationType: \"channel\" };\n }\n}\n\nexport async function resolveDispatchOwner(\n incoming: IncomingMessage,\n): Promise<string> {\n try {\n const externalUserId = identityKeyForIncoming(incoming);\n\n // Webhooks do not have the browser request's org context, so allow a safe\n // cross-org fallback when the linked platform identity maps to one owner.\n const owner = await resolveLinkedOwner(incoming.platform, externalUserId, {\n allowAnyOrgFallback: true,\n });\n if (owner) return owner;\n\n // For email, the sender's `From:` address is attacker-settable: SMTP lets\n // anyone claim any From, and our inbound webhook secret only authenticates\n // the provider→app hop, not the original sender. So we must NOT grant a\n // real user's identity (their API keys, org secrets, personal\n // instructions, ownable data) off the bare From. Mirror the Slack gate:\n // only return the sender email as the acting owner when BOTH\n // (a) the message is DKIM/SPF-verified for the From domain, AND\n // (b) that email maps to a real org member.\n // Otherwise fall through to the synthetic, credential-less fallback owner.\n // (A linked identity, handled by resolveLinkedOwner above, remains an\n // always-allowed way to bind an address regardless of verification.)\n //\n // Escape hatch: set DISPATCH_TRUST_UNVERIFIED_EMAIL_SENDER=1 to restore\n // the legacy \"trust the From header\" behavior. OFF by default; only use\n // this if you fully control the inbound mail path and accept that a\n // spoofed From can act as any org member. See FINDING 3 (inbound-email\n // impersonation) in the webhook security audit.\n if (\n incoming.platform === \"email\" &&\n incoming.senderId &&\n incoming.senderId.includes(\"@\")\n ) {\n if (process.env.DISPATCH_TRUST_UNVERIFIED_EMAIL_SENDER === \"1\") {\n return incoming.senderId;\n }\n if (incoming.senderVerified) {\n const orgId = await resolveOrgIdForEmail(incoming.senderId);\n if (orgId) return incoming.senderId;\n }\n // Unverified or not an org member — do not impersonate. Fall through to\n // the synthetic fallback owner below.\n }\n\n // Slack gives us a user id in the event payload. Resolve it to a verified\n // workspace email and use that user's own org context when they are an\n // Agent-Native member, so artifacts created via @agent-native are visible\n // when they open the target app.\n if (incoming.platform === \"slack\") {\n const slackOwner = await resolveSlackOwnerFromVerifiedEmail(incoming);\n if (slackOwner) return slackOwner;\n }\n\n const defaultOwner = configuredDefaultOwnerForIncoming(incoming);\n if (defaultOwner) return defaultOwner;\n\n return fallbackOwnerForIncoming(incoming);\n } catch {\n const defaultOwner = configuredDefaultOwnerForIncoming(incoming);\n if (defaultOwner) return defaultOwner;\n return fallbackOwnerForIncoming(incoming);\n }\n}\n\n/**\n * Resolve a personal DM user or a workspace-qualified channel service\n * principal. Managed Slack channels never silently inherit one requester's\n * personal credentials or memory.\n */\nexport async function resolveDispatchExecutionContext(\n incoming: IncomingMessage,\n): Promise<IntegrationExecutionContext> {\n if (incoming.platform !== \"slack\" || incoming.triggerKind === \"dm\") {\n const ownerEmail = await resolveDispatchOwner(incoming);\n if (\n incoming.platform === \"slack\" &&\n ownerEmail.endsWith(\"@integration.local\")\n ) {\n // Preserve a credential-less principal long enough for beforeProcess to\n // deliver linking guidance or consume `/link <token>`. Never run the\n // agent under this synthetic owner.\n incoming.platformContext.identityLinkRequired = true;\n }\n return {\n ownerEmail,\n orgId: (await resolveOrgIdForEmail(ownerEmail)) ?? null,\n principalType: \"user\",\n };\n }\n\n const installation = await resolveManagedSlackInstallation(incoming);\n if (!installation) {\n // Preserve the legacy manually configured app path while managed installs\n // roll out. Its behavior remains explicit and visible in Settings.\n const ownerEmail = await resolveDispatchOwner(incoming);\n return {\n ownerEmail,\n orgId: (await resolveOrgIdForEmail(ownerEmail)) ?? null,\n principalType: \"user\",\n };\n }\n\n const teamId = contextString(incoming.platformContext.teamId);\n const channelId = contextString(incoming.platformContext.channelId);\n if (!teamId || !channelId) {\n throw new Error(\"Slack channel identity is incomplete\");\n }\n const profile = await resolveSlackSenderProfile(incoming);\n const conversation = await resolveSlackConversationTrust(\n incoming,\n profile.trust,\n );\n const access = {\n ownerEmail: installation.ownerEmail,\n orgId: installation.orgId,\n };\n const key = {\n platform: \"slack\",\n tenantId: teamId,\n conversationId: channelId,\n };\n let scope = await getIntegrationScope(key, access);\n if (!scope && incoming.triggerKind === \"mention\") {\n scope = await saveIntegrationScope(\n {\n ...key,\n conversationType: conversation.conversationType,\n trust: conversation.trust,\n orgId: installation.orgId,\n installationId: installation.id,\n },\n access,\n );\n }\n if (!scope) throw new Error(\"Slack channel is not enabled for Agent Native\");\n const decision = evaluateIntegrationScopePolicy(scope, {\n // Thread replies reached this point only after the adapter's active-task\n // gate, so they are continuation steering rather than ambient chatter.\n mentioned:\n incoming.triggerKind === \"mention\" ||\n incoming.triggerKind === \"thread_reply\",\n });\n if (!decision.allowed) {\n throw new Error(`Slack channel policy denied: ${decision.reason}`);\n }\n incoming.integrationScopeId = scope.id;\n if (scope.defaultModel) {\n incoming.platformContext.defaultModel = scope.defaultModel;\n }\n incoming.actorTrust = {\n memberType:\n conversation.trust === \"guest\"\n ? \"guest\"\n : conversation.trust === \"external_shared\"\n ? \"external\"\n : conversation.trust === \"trusted\"\n ? \"member\"\n : \"unknown\",\n verified: conversation.trust !== \"unknown\",\n };\n return {\n ownerEmail: scope.serviceOwnerEmail,\n orgId: scope.orgId,\n principalType: \"service\",\n installationId: installation.id,\n scopeId: scope.id,\n };\n}\n\nexport async function beforeDispatchProcess(\n incoming: IncomingMessage,\n adapter: PlatformAdapter,\n): Promise<{ handled: true; responseText?: string } | { handled: false }> {\n const trimmed = incoming.text.trim();\n const commandText =\n contextString(incoming.platformContext.rawText) || trimmed;\n const match = commandText.match(/^\\/link(?:@\\w+)?\\s+([a-zA-Z0-9_-]+)$/);\n if (!match) {\n const routedIncoming = incoming as IncomingMessage & {\n routingHint?: DispatchIntegrationRoutingHint;\n };\n routedIncoming.routingHint ??= dispatchIntegrationRoutingHint(trimmed);\n if (\n incoming.platform === \"slack\" &&\n incoming.triggerKind === \"dm\" &&\n incoming.platformContext.identityLinkRequired === true\n ) {\n return {\n handled: true,\n responseText: formatSlackLinkRequiredMessage(),\n };\n }\n if (platformRequiresExplicitLink(incoming)) {\n const owner = await resolveLinkedOwner(\n incoming.platform,\n identityKeyForIncoming(incoming),\n { allowAnyOrgFallback: true },\n );\n if (!owner) {\n return {\n handled: true,\n responseText: formatTelegramLinkRequiredMessage(),\n };\n }\n }\n return handleRemoteCodeCommand(incoming, adapter, {\n resolveOwner: () => resolveDispatchOwner(incoming),\n });\n }\n\n try {\n const owner = await consumeLinkToken({\n platform: incoming.platform,\n token: match[1],\n externalUserId: identityKeyForIncoming(incoming),\n externalUserName: incoming.senderName || null,\n });\n return {\n handled: true,\n responseText: `Linked successfully. Future ${incoming.platform} messages will use ${owner}'s personal dispatch context.`,\n };\n } catch (error) {\n return {\n handled: true,\n responseText:\n error instanceof Error ? error.message : \"Failed to link this account.\",\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dispatch-integrations.js","sourceRoot":"","sources":["../../../src/server/lib/dispatch-integrations.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EACL,8BAA8B,EAC9B,qCAAqC,EACrC,mBAAmB,EACnB,6BAA6B,EAC7B,+BAA+B,EAC/B,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAOtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EACL,8BAA8B,GAE/B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAQ3E,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAG9B,CAAC;AACJ,MAAM,uBAAuB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE/C,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE;QAAE,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;IACnE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,QAAyB;IAEzB,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClD,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC9D,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IACrD,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QACrC,MAAM,aAAa,GAAG,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;QAC5E,OAAO,aAAa,CAAC,CAAC,CAAC,GAAG,aAAa,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IACnE,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClC,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC;IAChC,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,wBAAwB,CAAC,QAAyB;IACzD,MAAM,MAAM,GACV,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC;QAC9C,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,aAAa,CAAC;QACrD,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC;QAC9C,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC;QAC5C,QAAQ,CAAC,gBAAgB,CAAC;IAC5B,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,QAAQ,IAAI,MAAM,IAAI,QAAQ,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;IACxE,MAAM,IAAI,GAAG,MAAM;SAChB,UAAU,CAAC,QAAQ,CAAC;SACpB,MAAM,CAAC,GAAG,CAAC;SACX,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChB,OAAO,YAAY,IAAI,oBAAoB,CAAC;AAC9C,CAAC;AAED,SAAS,iCAAiC,CACxC,QAAyB;IAEzB,2EAA2E;IAC3E,sEAAsE;IACtE,8EAA8E;IAC9E,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,IAAI,EAAE,CAAC;IAC/D,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACjE,CAAC;AAED,SAAS,4BAA4B,CAAC,QAAyB;IAC7D,0EAA0E;IAC1E,kEAAkE;IAClE,OAAO,QAAQ,CAAC,QAAQ,KAAK,UAAU,CAAC;AAC1C,CAAC;AAED,SAAS,+BAA+B;IACtC,MAAM,GAAG,GACP,OAAO,CAAC,GAAG,CAAC,qBAAqB;QACjC,OAAO,CAAC,GAAG,CAAC,OAAO;QACnB,OAAO,CAAC,GAAG,CAAC,GAAG;QACf,OAAO,CAAC,GAAG,CAAC,UAAU;QACtB,OAAO,CAAC,GAAG,CAAC,eAAe;QAC3B,EAAE,CAAC;IACL,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IAC7B,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC;IAChE,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CACZ,YAAY,EACZ,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAC1D,CAAC,QAAQ,EAAE,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,+BAA+B,CAAC,QAAyB;IACtE,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAClE,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,CAAC;QACH,OAAO,MAAM,qCAAqC,CAChD,OAAO,EACP,oBAAoB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAC3C,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,QAAyB;IAEzB,MAAM,YAAY,GAAG,MAAM,+BAA+B,CAAC,QAAQ,CAAC,CAAC;IACrE,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,6BAA6B,CAChD,OAAO,EACP,YAAY,CAAC,eAAe,CAC7B,CAAC;IACF,OAAO,MAAM,EAAE,WAAW,IAAI,IAAI,CAAC;AACrC,CAAC;AAED,SAAS,iCAAiC;IACxC,MAAM,aAAa,GAAG,+BAA+B,EAAE,CAAC;IACxD,MAAM,QAAQ,GAAG,aAAa;QAC5B,CAAC,CAAC,OAAO,aAAa,mEAAmE;QACzF,CAAC,CAAC,8FAA8F,CAAC;IACnG,OAAO,+FAA+F,QAAQ,+DAA+D,CAAC;AAChL,CAAC;AAED,SAAS,8BAA8B;IACrC,MAAM,aAAa,GAAG,+BAA+B,EAAE,CAAC;IACxD,MAAM,QAAQ,GAAG,aAAa;QAC5B,CAAC,CAAC,QAAQ,aAAa,sEAAsE;QAC7F,CAAC,CAAC,iGAAiG,CAAC;IACtG,OAAO,4FAA4F,QAAQ,EAAE,CAAC;AAChH,CAAC;AAED,KAAK,UAAU,yBAAyB,CACtC,QAAyB;IAEzB,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IACvD,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,+BAA+B,CAAC,QAAQ,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9D,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IACvD,CAAC;IAED,wEAAwE;IACxE,sEAAsE;IACtE,wEAAwE;IACxE,8DAA8D;IAC9D,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACvD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;YAAE,OAAO,MAAM,CAAC,OAAO,CAAC;IACrE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oCAAoC,MAAM,EAAE,EAAE;YACpE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;SAC9C,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAa7B,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE;YACrB,CAAC,CAAC;gBACE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,IAAI;gBAC9D,IAAI,EACF,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE;oBACrC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE;oBACxC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;oBAC5B,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;oBACvB,IAAI;gBACN,KAAK,EACH,IAAI,CAAC,IAAI,EAAE,mBAAmB,KAAK,IAAI;oBACrC,CAAC,CAAE,iBAA2B;oBAC9B,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI;wBACjC,CAAC,CAAE,OAAiB;wBACpB,CAAC,CAAE,SAAmB;aAC7B;YACH,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAkB,EAAE,CAAC;QAC3D,IAAI,QAAQ,EAAE,CAAC;YACb,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE;gBAC9B,OAAO;gBACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,uBAAuB;aAChD,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IACvD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,kCAAkC,CAC/C,QAAyB;IAEzB,MAAM,OAAO,GAAG,MAAM,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IAC1D,IAAI,CAAC,OAAO,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAEhC,QAAQ,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC;IACrC,QAAQ,CAAC,eAAe,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC;IACrD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,QAAQ,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;QACnC,QAAQ,CAAC,eAAe,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IACrD,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACxD,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACtC,CAAC;AAED,KAAK,UAAU,6BAA6B,CAC1C,QAAyB,EACzB,UAAuC;IAKvC,IAAI,QAAQ,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;QAClC,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;IACnE,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IAClE,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,SAAS,EAAE,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,4CAA4C,MAAM,EAAE,EACpD,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,EAAE,CAClD,CAAC;QACF,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAOlC,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,SAAS,EAAE,CAAC;QAC3D,CAAC;QACD,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU;YACnE,gBAAgB,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK;gBACnC,CAAC,CAAC,gBAAgB;gBAClB,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO;oBACrB,CAAC,CAAC,sBAAsB;oBACxB,CAAC,CAAC,SAAS;SAChB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,SAAS,EAAE,CAAC;IAC3D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAyB;IAEzB,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QAExD,0EAA0E;QAC1E,0EAA0E;QAC1E,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,EAAE,cAAc,EAAE;YACxE,mBAAmB,EAAE,IAAI;SAC1B,CAAC,CAAC;QACH,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QAExB,0EAA0E;QAC1E,2EAA2E;QAC3E,wEAAwE;QACxE,8DAA8D;QAC9D,wEAAwE;QACxE,6DAA6D;QAC7D,kEAAkE;QAClE,8CAA8C;QAC9C,2EAA2E;QAC3E,sEAAsE;QACtE,qEAAqE;QACrE,EAAE;QACF,wEAAwE;QACxE,wEAAwE;QACxE,oEAAoE;QACpE,uEAAuE;QACvE,gDAAgD;QAChD,IACE,QAAQ,CAAC,QAAQ,KAAK,OAAO;YAC7B,QAAQ,CAAC,QAAQ;YACjB,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAC/B,CAAC;YACD,IAAI,OAAO,CAAC,GAAG,CAAC,sCAAsC,KAAK,GAAG,EAAE,CAAC;gBAC/D,OAAO,QAAQ,CAAC,QAAQ,CAAC;YAC3B,CAAC;YACD,IAAI,QAAQ,CAAC,cAAc,EAAE,CAAC;gBAC5B,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC5D,IAAI,KAAK;oBAAE,OAAO,QAAQ,CAAC,QAAQ,CAAC;YACtC,CAAC;YACD,wEAAwE;YACxE,sCAAsC;QACxC,CAAC;QAED,0EAA0E;QAC1E,uEAAuE;QACvE,0EAA0E;QAC1E,iCAAiC;QACjC,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,MAAM,kCAAkC,CAAC,QAAQ,CAAC,CAAC;YACtE,IAAI,UAAU;gBAAE,OAAO,UAAU,CAAC;QACpC,CAAC;QAED,MAAM,YAAY,GAAG,iCAAiC,CAAC,QAAQ,CAAC,CAAC;QACjE,IAAI,YAAY;YAAE,OAAO,YAAY,CAAC;QAEtC,OAAO,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,YAAY,GAAG,iCAAiC,CAAC,QAAQ,CAAC,CAAC;QACjE,IAAI,YAAY;YAAE,OAAO,YAAY,CAAC;QACtC,OAAO,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,QAAyB;IAEzB,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;QACnE,MAAM,UAAU,GAAG,MAAM,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QACxD,IACE,QAAQ,CAAC,QAAQ,KAAK,OAAO;YAC7B,UAAU,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EACzC,CAAC;YACD,wEAAwE;YACxE,qEAAqE;YACrE,oCAAoC;YACpC,QAAQ,CAAC,eAAe,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACvD,CAAC;QACD,OAAO;YACL,UAAU;YACV,KAAK,EAAE,CAAC,MAAM,oBAAoB,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI;YACvD,aAAa,EAAE,MAAM;SACtB,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,+BAA+B,CAAC,QAAQ,CAAC,CAAC;IACrE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,0EAA0E;QAC1E,mEAAmE;QACnE,MAAM,UAAU,GAAG,MAAM,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QACxD,OAAO;YACL,UAAU;YACV,KAAK,EAAE,CAAC,MAAM,oBAAoB,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI;YACvD,aAAa,EAAE,MAAM;SACtB,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IACpE,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IAC1D,MAAM,YAAY,GAAG,MAAM,6BAA6B,CACtD,QAAQ,EACR,OAAO,CAAC,KAAK,CACd,CAAC;IACF,MAAM,MAAM,GAAG;QACb,UAAU,EAAE,YAAY,CAAC,UAAU;QACnC,KAAK,EAAE,YAAY,CAAC,KAAK;KAC1B,CAAC;IACF,MAAM,GAAG,GAAG;QACV,QAAQ,EAAE,OAAO;QACjB,QAAQ,EAAE,MAAM;QAChB,cAAc,EAAE,SAAS;KAC1B,CAAC;IACF,IAAI,KAAK,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACjD,KAAK,GAAG,MAAM,oBAAoB,CAChC;YACE,GAAG,GAAG;YACN,gBAAgB,EAAE,YAAY,CAAC,gBAAgB;YAC/C,KAAK,EAAE,YAAY,CAAC,KAAK;YACzB,KAAK,EAAE,YAAY,CAAC,KAAK;YACzB,cAAc,EAAE,YAAY,CAAC,EAAE;SAChC,EACD,MAAM,CACP,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAG,8BAA8B,CAAC,KAAK,EAAE;QACrD,yEAAyE;QACzE,uEAAuE;QACvE,SAAS,EACP,QAAQ,CAAC,WAAW,KAAK,SAAS;YAClC,QAAQ,CAAC,WAAW,KAAK,cAAc;KAC1C,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,QAAQ,CAAC,kBAAkB,GAAG,KAAK,CAAC,EAAE,CAAC;IACvC,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QACvB,QAAQ,CAAC,eAAe,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IAC7D,CAAC;IACD,QAAQ,CAAC,UAAU,GAAG;QACpB,UAAU,EACR,YAAY,CAAC,KAAK,KAAK,OAAO;YAC5B,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,YAAY,CAAC,KAAK,KAAK,iBAAiB;gBACxC,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,YAAY,CAAC,KAAK,KAAK,SAAS;oBAChC,CAAC,CAAC,QAAQ;oBACV,CAAC,CAAC,SAAS;QACnB,QAAQ,EAAE,YAAY,CAAC,KAAK,KAAK,SAAS;KAC3C,CAAC;IACF,OAAO;QACL,UAAU,EAAE,KAAK,CAAC,iBAAiB;QACnC,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,aAAa,EAAE,SAAS;QACxB,cAAc,EAAE,YAAY,CAAC,EAAE;QAC/B,OAAO,EAAE,KAAK,CAAC,EAAE;KAClB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAAyB,EACzB,OAAwB;IAExB,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACrC,MAAM,WAAW,GACf,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC;IAC7D,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACxE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,cAAc,GAAG,QAEtB,CAAC;QACF,cAAc,CAAC,WAAW,KAAK,8BAA8B,CAAC,OAAO,CAAC,CAAC;QACvE,IACE,QAAQ,CAAC,QAAQ,KAAK,OAAO;YAC7B,QAAQ,CAAC,WAAW,KAAK,IAAI;YAC7B,QAAQ,CAAC,eAAe,CAAC,oBAAoB,KAAK,IAAI,EACtD,CAAC;YACD,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,YAAY,EAAE,8BAA8B,EAAE;aAC/C,CAAC;QACJ,CAAC;QACD,IAAI,4BAA4B,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,MAAM,kBAAkB,CACpC,QAAQ,CAAC,QAAQ,EACjB,sBAAsB,CAAC,QAAQ,CAAC,EAChC,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAC9B,CAAC;YACF,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,YAAY,EAAE,iCAAiC,EAAE;iBAClD,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,uBAAuB,CAAC,QAAQ,EAAE,OAAO,EAAE;YAChD,YAAY,EAAE,GAAG,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC;SACnD,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC;YACnC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;YACf,cAAc,EAAE,sBAAsB,CAAC,QAAQ,CAAC;YAChD,gBAAgB,EAAE,QAAQ,CAAC,UAAU,IAAI,IAAI;SAC9C,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,IAAI;YACb,YAAY,EAAE,+BAA+B,QAAQ,CAAC,QAAQ,sBAAsB,KAAK,+BAA+B;SACzH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,IAAI;YACb,YAAY,EACV,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,8BAA8B;SAC1E,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["import crypto from \"node:crypto\";\n\nimport {\n evaluateIntegrationScopePolicy,\n getActiveIntegrationInstallationByKey,\n getIntegrationScope,\n resolveIntegrationTokenBundle,\n resolveSlackBotTokenForIncoming,\n saveIntegrationScope,\n slackInstallationKey,\n} from \"@agent-native/core/integrations\";\nimport { resolveOrgIdForEmail } from \"@agent-native/core/org\";\nimport { withConfiguredAppBasePath } from \"@agent-native/core/server\";\nimport type {\n IncomingMessage,\n IntegrationExecutionContext,\n PlatformAdapter,\n} from \"@agent-native/core/server\";\n\nimport { handleRemoteCodeCommand } from \"./dispatch-remote-commands.js\";\nimport {\n dispatchIntegrationRoutingHint,\n type DispatchIntegrationRoutingHint,\n} from \"./dispatch-routing.js\";\nimport { consumeLinkToken, resolveLinkedOwner } from \"./dispatch-store.js\";\n\ntype SlackSenderProfile = {\n email: string | null;\n name: string | null;\n trust: \"trusted\" | \"guest\" | \"external_shared\" | \"unknown\";\n};\n\nconst slackProfileCache = new Map<\n string,\n { profile: SlackSenderProfile; expiresAt: number }\n>();\nconst SLACK_PROFILE_CACHE_TTL = 10 * 60 * 1000;\n\nfunction contextString(value: unknown): string | null {\n if (typeof value === \"string\" && value.trim()) return value.trim();\n if (typeof value === \"number\" && Number.isFinite(value)) return String(value);\n return null;\n}\n\nexport function identityKeyForIncoming(\n incoming: IncomingMessage,\n): string | null {\n const senderId = contextString(incoming.senderId);\n if (!senderId) return null;\n\n if (incoming.platform === \"slack\") {\n const teamId = contextString(incoming.platformContext.teamId);\n return teamId ? `${teamId}:${senderId}` : senderId;\n }\n\n if (incoming.platform === \"whatsapp\") {\n const phoneNumberId = contextString(incoming.platformContext.phoneNumberId);\n return phoneNumberId ? `${phoneNumberId}:${senderId}` : senderId;\n }\n\n if (incoming.platform === \"email\") {\n return senderId.toLowerCase();\n }\n\n return senderId;\n}\n\nfunction fallbackOwnerForIncoming(incoming: IncomingMessage): string {\n const tenant =\n contextString(incoming.platformContext.teamId) ||\n contextString(incoming.platformContext.phoneNumberId) ||\n contextString(incoming.platformContext.chatId) ||\n contextString(incoming.platformContext.from) ||\n incoming.externalThreadId;\n const raw = `${incoming.platform}:${tenant}:${incoming.senderId || \"\"}`;\n const hash = crypto\n .createHash(\"sha256\")\n .update(raw)\n .digest(\"hex\")\n .slice(0, 16);\n return `dispatch+${hash}@integration.local`;\n}\n\nfunction configuredDefaultOwnerForIncoming(\n incoming: IncomingMessage,\n): string | null {\n // This is intentionally Slack-only: a deployment-wide default owner grants\n // that Slack workspace access to the owner's connected agents and org\n // credentials, so other platforms should opt in with explicit identity links.\n if (incoming.platform !== \"slack\") return null;\n const email = process.env.DISPATCH_DEFAULT_OWNER_EMAIL?.trim();\n if (!email) return null;\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email) ? email : null;\n}\n\nfunction platformRequiresExplicitLink(incoming: IncomingMessage): boolean {\n // Telegram does not provide a verified email address. Require an explicit\n // identity link before it can act as a Builder/Agent-Native user.\n return incoming.platform === \"telegram\";\n}\n\nfunction configuredDispatchIdentitiesUrl(): string | null {\n const raw =\n process.env.WORKSPACE_GATEWAY_URL ||\n process.env.APP_URL ||\n process.env.URL ||\n process.env.DEPLOY_URL ||\n process.env.BETTER_AUTH_URL ||\n \"\";\n if (!raw.trim()) return null;\n const base = /^https?:\\/\\//i.test(raw) ? raw : `https://${raw}`;\n try {\n return new URL(\n \"identities\",\n `${withConfiguredAppBasePath(base).replace(/\\/+$/, \"\")}/`,\n ).toString();\n } catch {\n return null;\n }\n}\n\nasync function resolveManagedSlackInstallation(incoming: IncomingMessage) {\n if (incoming.platform !== \"slack\") return null;\n const teamId = contextString(incoming.platformContext.teamId);\n const apiAppId = contextString(incoming.platformContext.apiAppId);\n if (!teamId) return null;\n try {\n return await getActiveIntegrationInstallationByKey(\n \"slack\",\n slackInstallationKey({ teamId, apiAppId }),\n );\n } catch {\n return null;\n }\n}\n\nasync function resolveManagedSlackToken(\n incoming: IncomingMessage,\n): Promise<string | null> {\n const installation = await resolveManagedSlackInstallation(incoming);\n if (!installation) return null;\n const bundle = await resolveIntegrationTokenBundle(\n \"slack\",\n installation.installationKey,\n );\n return bundle?.accessToken ?? null;\n}\n\nfunction formatTelegramLinkRequiredMessage(): string {\n const identitiesUrl = configuredDispatchIdentitiesUrl();\n const linkStep = identitiesUrl\n ? `Tap ${identitiesUrl}, create a Telegram link token, then send \\`/link <token>\\` here.`\n : \"Open Dispatch while signed in, create a Telegram link token, then send `/link <token>` here.\";\n return `Telegram is connected, but this Telegram account is not linked to an Agent-Native user yet. ${linkStep} After that I can use your Builder.io org and connected apps.`;\n}\n\nfunction formatSlackLinkRequiredMessage(): string {\n const identitiesUrl = configuredDispatchIdentitiesUrl();\n const linkStep = identitiesUrl\n ? `Open ${identitiesUrl}, create a Slack link token, then send \\`/link <token>\\` in this DM.`\n : \"Open Dispatch while signed in, create a Slack link token, then send `/link <token>` in this DM.\";\n return `Agent Native is ready, but this Slack account is not linked to an Agent Native user yet. ${linkStep}`;\n}\n\nasync function resolveSlackSenderProfile(\n incoming: IncomingMessage,\n): Promise<SlackSenderProfile> {\n if (incoming.platform !== \"slack\") {\n return { email: null, name: null, trust: \"unknown\" };\n }\n const token = await resolveSlackBotTokenForIncoming(incoming);\n const userId = contextString(incoming.senderId);\n const teamId = contextString(incoming.platformContext.teamId);\n if (!token || !userId) {\n return { email: null, name: null, trust: \"unknown\" };\n }\n\n // Slack user IDs are scoped per workspace, so without a teamId we can't\n // safely cache: two installs of the bot in different workspaces could\n // share user-id strings and collide on a single \"default\" key. Skip the\n // cache (and lookup on every request) when teamId is missing.\n const cacheKey = teamId ? `${teamId}:${userId}` : null;\n if (cacheKey) {\n const cached = slackProfileCache.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) return cached.profile;\n }\n\n try {\n const params = new URLSearchParams({ user: userId });\n const res = await fetch(`https://slack.com/api/users.info?${params}`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n const data = (await res.json()) as {\n ok?: boolean;\n user?: {\n real_name?: string;\n name?: string;\n profile?: {\n email?: string;\n real_name?: string;\n display_name?: string;\n };\n is_restricted?: boolean;\n is_ultra_restricted?: boolean;\n };\n };\n const profile = data.ok\n ? {\n email: data.user?.profile?.email?.trim().toLowerCase() || null,\n name:\n data.user?.profile?.real_name?.trim() ||\n data.user?.profile?.display_name?.trim() ||\n data.user?.real_name?.trim() ||\n data.user?.name?.trim() ||\n null,\n trust:\n data.user?.is_ultra_restricted === true\n ? (\"external_shared\" as const)\n : data.user?.is_restricted === true\n ? (\"guest\" as const)\n : (\"trusted\" as const),\n }\n : { email: null, name: null, trust: \"unknown\" as const };\n if (cacheKey) {\n slackProfileCache.set(cacheKey, {\n profile,\n expiresAt: Date.now() + SLACK_PROFILE_CACHE_TTL,\n });\n }\n return profile;\n } catch {\n return { email: null, name: null, trust: \"unknown\" };\n }\n}\n\nasync function resolveSlackOwnerFromVerifiedEmail(\n incoming: IncomingMessage,\n): Promise<string | null> {\n const profile = await resolveSlackSenderProfile(incoming);\n if (!profile.email) return null;\n\n incoming.senderEmail = profile.email;\n incoming.platformContext.senderEmail = profile.email;\n if (profile.name) {\n incoming.senderName = profile.name;\n incoming.platformContext.senderName = profile.name;\n }\n\n const orgId = await resolveOrgIdForEmail(profile.email);\n return orgId ? profile.email : null;\n}\n\nasync function resolveSlackConversationTrust(\n incoming: IncomingMessage,\n actorTrust: SlackSenderProfile[\"trust\"],\n): Promise<{\n trust: SlackSenderProfile[\"trust\"];\n conversationType: \"channel\" | \"direct_message\" | \"group_direct_message\";\n}> {\n if (incoming.triggerKind === \"dm\") {\n return { trust: actorTrust, conversationType: \"direct_message\" };\n }\n const token = await resolveManagedSlackToken(incoming);\n const channel = contextString(incoming.platformContext.channelId);\n if (!token || !channel) {\n return { trust: \"unknown\", conversationType: \"channel\" };\n }\n try {\n const params = new URLSearchParams({ channel });\n const response = await fetch(\n `https://slack.com/api/conversations.info?${params}`,\n { headers: { Authorization: `Bearer ${token}` } },\n );\n const data = (await response.json()) as {\n ok?: boolean;\n channel?: {\n is_ext_shared?: boolean;\n is_im?: boolean;\n is_mpim?: boolean;\n };\n };\n if (!data.ok) {\n return { trust: \"unknown\", conversationType: \"channel\" };\n }\n return {\n trust: data.channel?.is_ext_shared ? \"external_shared\" : actorTrust,\n conversationType: data.channel?.is_im\n ? \"direct_message\"\n : data.channel?.is_mpim\n ? \"group_direct_message\"\n : \"channel\",\n };\n } catch {\n return { trust: \"unknown\", conversationType: \"channel\" };\n }\n}\n\nexport async function resolveDispatchOwner(\n incoming: IncomingMessage,\n): Promise<string> {\n try {\n const externalUserId = identityKeyForIncoming(incoming);\n\n // Webhooks do not have the browser request's org context, so allow a safe\n // cross-org fallback when the linked platform identity maps to one owner.\n const owner = await resolveLinkedOwner(incoming.platform, externalUserId, {\n allowAnyOrgFallback: true,\n });\n if (owner) return owner;\n\n // For email, the sender's `From:` address is attacker-settable: SMTP lets\n // anyone claim any From, and our inbound webhook secret only authenticates\n // the provider→app hop, not the original sender. So we must NOT grant a\n // real user's identity (their API keys, org secrets, personal\n // instructions, ownable data) off the bare From. Mirror the Slack gate:\n // only return the sender email as the acting owner when BOTH\n // (a) the message is DKIM/SPF-verified for the From domain, AND\n // (b) that email maps to a real org member.\n // Otherwise fall through to the synthetic, credential-less fallback owner.\n // (A linked identity, handled by resolveLinkedOwner above, remains an\n // always-allowed way to bind an address regardless of verification.)\n //\n // Escape hatch: set DISPATCH_TRUST_UNVERIFIED_EMAIL_SENDER=1 to restore\n // the legacy \"trust the From header\" behavior. OFF by default; only use\n // this if you fully control the inbound mail path and accept that a\n // spoofed From can act as any org member. See FINDING 3 (inbound-email\n // impersonation) in the webhook security audit.\n if (\n incoming.platform === \"email\" &&\n incoming.senderId &&\n incoming.senderId.includes(\"@\")\n ) {\n if (process.env.DISPATCH_TRUST_UNVERIFIED_EMAIL_SENDER === \"1\") {\n return incoming.senderId;\n }\n if (incoming.senderVerified) {\n const orgId = await resolveOrgIdForEmail(incoming.senderId);\n if (orgId) return incoming.senderId;\n }\n // Unverified or not an org member — do not impersonate. Fall through to\n // the synthetic fallback owner below.\n }\n\n // Slack gives us a user id in the event payload. Resolve it to a verified\n // workspace email and use that user's own org context when they are an\n // Agent-Native member, so artifacts created via @agent-native are visible\n // when they open the target app.\n if (incoming.platform === \"slack\") {\n const slackOwner = await resolveSlackOwnerFromVerifiedEmail(incoming);\n if (slackOwner) return slackOwner;\n }\n\n const defaultOwner = configuredDefaultOwnerForIncoming(incoming);\n if (defaultOwner) return defaultOwner;\n\n return fallbackOwnerForIncoming(incoming);\n } catch {\n const defaultOwner = configuredDefaultOwnerForIncoming(incoming);\n if (defaultOwner) return defaultOwner;\n return fallbackOwnerForIncoming(incoming);\n }\n}\n\n/**\n * Resolve a personal DM user or a workspace-qualified channel service\n * principal. Managed Slack channels never silently inherit one requester's\n * personal credentials or memory.\n */\nexport async function resolveDispatchExecutionContext(\n incoming: IncomingMessage,\n): Promise<IntegrationExecutionContext> {\n if (incoming.platform !== \"slack\" || incoming.triggerKind === \"dm\") {\n const ownerEmail = await resolveDispatchOwner(incoming);\n if (\n incoming.platform === \"slack\" &&\n ownerEmail.endsWith(\"@integration.local\")\n ) {\n // Preserve a credential-less principal long enough for beforeProcess to\n // deliver linking guidance or consume `/link <token>`. Never run the\n // agent under this synthetic owner.\n incoming.platformContext.identityLinkRequired = true;\n }\n return {\n ownerEmail,\n orgId: (await resolveOrgIdForEmail(ownerEmail)) ?? null,\n principalType: \"user\",\n };\n }\n\n const installation = await resolveManagedSlackInstallation(incoming);\n if (!installation) {\n // Preserve the legacy manually configured app path while managed installs\n // roll out. Its behavior remains explicit and visible in Settings.\n const ownerEmail = await resolveDispatchOwner(incoming);\n return {\n ownerEmail,\n orgId: (await resolveOrgIdForEmail(ownerEmail)) ?? null,\n principalType: \"user\",\n };\n }\n\n const teamId = contextString(incoming.platformContext.teamId);\n const channelId = contextString(incoming.platformContext.channelId);\n if (!teamId || !channelId) {\n throw new Error(\"Slack channel identity is incomplete\");\n }\n const profile = await resolveSlackSenderProfile(incoming);\n const conversation = await resolveSlackConversationTrust(\n incoming,\n profile.trust,\n );\n const access = {\n ownerEmail: installation.ownerEmail,\n orgId: installation.orgId,\n };\n const key = {\n platform: \"slack\",\n tenantId: teamId,\n conversationId: channelId,\n };\n let scope = await getIntegrationScope(key, access);\n if (!scope && incoming.triggerKind === \"mention\") {\n scope = await saveIntegrationScope(\n {\n ...key,\n conversationType: conversation.conversationType,\n trust: conversation.trust,\n orgId: installation.orgId,\n installationId: installation.id,\n },\n access,\n );\n }\n if (!scope) throw new Error(\"Slack channel is not enabled for Agent Native\");\n const decision = evaluateIntegrationScopePolicy(scope, {\n // Thread replies reached this point only after the adapter's active-task\n // gate, so they are continuation steering rather than ambient chatter.\n mentioned:\n incoming.triggerKind === \"mention\" ||\n incoming.triggerKind === \"thread_reply\",\n });\n if (!decision.allowed) {\n throw new Error(`Slack channel policy denied: ${decision.reason}`);\n }\n incoming.integrationScopeId = scope.id;\n if (scope.defaultModel) {\n incoming.platformContext.defaultModel = scope.defaultModel;\n }\n incoming.actorTrust = {\n memberType:\n conversation.trust === \"guest\"\n ? \"guest\"\n : conversation.trust === \"external_shared\"\n ? \"external\"\n : conversation.trust === \"trusted\"\n ? \"member\"\n : \"unknown\",\n verified: conversation.trust !== \"unknown\",\n };\n return {\n ownerEmail: scope.serviceOwnerEmail,\n orgId: scope.orgId,\n principalType: \"service\",\n installationId: installation.id,\n scopeId: scope.id,\n };\n}\n\nexport async function beforeDispatchProcess(\n incoming: IncomingMessage,\n adapter: PlatformAdapter,\n): Promise<{ handled: true; responseText?: string } | { handled: false }> {\n const trimmed = incoming.text.trim();\n const commandText =\n contextString(incoming.platformContext.rawText) || trimmed;\n const match = commandText.match(/^\\/link(?:@\\w+)?\\s+([a-zA-Z0-9_-]+)$/);\n if (!match) {\n const routedIncoming = incoming as IncomingMessage & {\n routingHint?: DispatchIntegrationRoutingHint;\n };\n routedIncoming.routingHint ??= dispatchIntegrationRoutingHint(trimmed);\n if (\n incoming.platform === \"slack\" &&\n incoming.triggerKind === \"dm\" &&\n incoming.platformContext.identityLinkRequired === true\n ) {\n return {\n handled: true,\n responseText: formatSlackLinkRequiredMessage(),\n };\n }\n if (platformRequiresExplicitLink(incoming)) {\n const owner = await resolveLinkedOwner(\n incoming.platform,\n identityKeyForIncoming(incoming),\n { allowAnyOrgFallback: true },\n );\n if (!owner) {\n return {\n handled: true,\n responseText: formatTelegramLinkRequiredMessage(),\n };\n }\n }\n return handleRemoteCodeCommand(incoming, adapter, {\n resolveOwner: () => resolveDispatchOwner(incoming),\n });\n }\n\n try {\n const owner = await consumeLinkToken({\n platform: incoming.platform,\n token: match[1],\n externalUserId: identityKeyForIncoming(incoming),\n externalUserName: incoming.senderName || null,\n });\n return {\n handled: true,\n responseText: `Linked successfully. Future ${incoming.platform} messages will use ${owner}'s personal dispatch context.`,\n };\n } catch (error) {\n return {\n handled: true,\n responseText:\n error instanceof Error ? error.message : \"Failed to link this account.\",\n };\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/dispatch",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.13",
|
|
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": {
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"tailwind-merge": "^3.5.0",
|
|
87
87
|
"vaul": "^1.1.2",
|
|
88
88
|
"zod": "^4.3.6",
|
|
89
|
-
"@agent-native/toolkit": "0.
|
|
89
|
+
"@agent-native/toolkit": "0.10.1"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
92
|
"@react-router/dev": "^8.1.0",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"typescript-7": "npm:typescript@^7.0.2",
|
|
101
101
|
"vite": "8.1.0",
|
|
102
102
|
"vitest": "^4.1.5",
|
|
103
|
-
"@agent-native/core": "0.
|
|
103
|
+
"@agent-native/core": "0.118.1"
|
|
104
104
|
},
|
|
105
105
|
"peerDependencies": {
|
|
106
106
|
"@agent-native/core": ">=0.8.0",
|
|
@@ -105,4 +105,25 @@ describe("send-platform-message tenant scoping", () => {
|
|
|
105
105
|
expect(mocks.slackAdapter).not.toHaveBeenCalled();
|
|
106
106
|
expect(mocks.sendMessageToTarget).not.toHaveBeenCalled();
|
|
107
107
|
});
|
|
108
|
+
|
|
109
|
+
it("does not use the deployment token for an unconnected workspace", async () => {
|
|
110
|
+
mocks.getInstallation.mockResolvedValue([]);
|
|
111
|
+
mocks.resolveSecret.mockResolvedValue("fusion-token");
|
|
112
|
+
|
|
113
|
+
await expect(
|
|
114
|
+
action.run(
|
|
115
|
+
{
|
|
116
|
+
platform: "slack",
|
|
117
|
+
destination: "C1",
|
|
118
|
+
tenantId: "T-agent-native",
|
|
119
|
+
text: "hello",
|
|
120
|
+
},
|
|
121
|
+
{} as never,
|
|
122
|
+
),
|
|
123
|
+
).rejects.toThrow("That Slack workspace is not connected");
|
|
124
|
+
|
|
125
|
+
expect(mocks.resolveSecret).not.toHaveBeenCalledWith("SLACK_BOT_TOKEN");
|
|
126
|
+
expect(mocks.slackAdapter).not.toHaveBeenCalled();
|
|
127
|
+
expect(mocks.sendMessageToTarget).not.toHaveBeenCalled();
|
|
128
|
+
});
|
|
108
129
|
});
|
|
@@ -50,8 +50,9 @@ async function assertOutboundConfigured(
|
|
|
50
50
|
installation.installationKey,
|
|
51
51
|
)
|
|
52
52
|
: null;
|
|
53
|
-
const token =
|
|
54
|
-
managed?.accessToken
|
|
53
|
+
const token = tenantId
|
|
54
|
+
? managed?.accessToken
|
|
55
|
+
: (managed?.accessToken ?? (await resolveSecret("SLACK_BOT_TOKEN")));
|
|
55
56
|
if (!token) {
|
|
56
57
|
throw new Error(
|
|
57
58
|
tenantId
|
|
@@ -5,6 +5,7 @@ const mocks = vi.hoisted(() => ({
|
|
|
5
5
|
resolveLinkedOwner: vi.fn(),
|
|
6
6
|
resolveOrgIdForEmail: vi.fn(),
|
|
7
7
|
resolveSecret: vi.fn(),
|
|
8
|
+
resolveSlackBotTokenForIncoming: vi.fn(),
|
|
8
9
|
}));
|
|
9
10
|
|
|
10
11
|
vi.mock("./dispatch-store.js", () => ({
|
|
@@ -12,6 +13,16 @@ vi.mock("./dispatch-store.js", () => ({
|
|
|
12
13
|
resolveLinkedOwner: mocks.resolveLinkedOwner,
|
|
13
14
|
}));
|
|
14
15
|
|
|
16
|
+
vi.mock("@agent-native/core/integrations", async () => {
|
|
17
|
+
const actual = await vi.importActual<
|
|
18
|
+
typeof import("@agent-native/core/integrations")
|
|
19
|
+
>("@agent-native/core/integrations");
|
|
20
|
+
return {
|
|
21
|
+
...actual,
|
|
22
|
+
resolveSlackBotTokenForIncoming: mocks.resolveSlackBotTokenForIncoming,
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
|
|
15
26
|
vi.mock("@agent-native/core/org", () => ({
|
|
16
27
|
resolveOrgIdForEmail: mocks.resolveOrgIdForEmail,
|
|
17
28
|
}));
|
|
@@ -106,6 +117,7 @@ beforeEach(() => {
|
|
|
106
117
|
mocks.resolveLinkedOwner.mockResolvedValue(null);
|
|
107
118
|
mocks.consumeLinkToken.mockResolvedValue("owner@example.test");
|
|
108
119
|
mocks.resolveOrgIdForEmail.mockResolvedValue(null);
|
|
120
|
+
mocks.resolveSlackBotTokenForIncoming.mockResolvedValue(null);
|
|
109
121
|
mocks.resolveSecret.mockImplementation(
|
|
110
122
|
async (key: string) => process.env[key] ?? null,
|
|
111
123
|
);
|
|
@@ -145,6 +157,7 @@ describe("resolveDispatchOwner", () => {
|
|
|
145
157
|
|
|
146
158
|
it("uses the verified Slack email for org members", async () => {
|
|
147
159
|
vi.stubEnv("SLACK_BOT_TOKEN", "xoxb-token");
|
|
160
|
+
mocks.resolveSlackBotTokenForIncoming.mockResolvedValueOnce("xoxb-token");
|
|
148
161
|
mocks.resolveSecret.mockResolvedValueOnce(null);
|
|
149
162
|
mocks.resolveOrgIdForEmail.mockResolvedValueOnce("org_123");
|
|
150
163
|
vi.mocked(globalThis.fetch).mockResolvedValueOnce(
|
|
@@ -170,6 +183,9 @@ describe("resolveDispatchOwner", () => {
|
|
|
170
183
|
});
|
|
171
184
|
|
|
172
185
|
it("uses the request-scoped Slack token when no env token exists", async () => {
|
|
186
|
+
mocks.resolveSlackBotTokenForIncoming.mockResolvedValueOnce(
|
|
187
|
+
"configured-slack-token",
|
|
188
|
+
);
|
|
173
189
|
mocks.resolveSecret.mockResolvedValueOnce("configured-slack-token");
|
|
174
190
|
mocks.resolveOrgIdForEmail.mockResolvedValueOnce("org_123");
|
|
175
191
|
vi.mocked(globalThis.fetch).mockResolvedValueOnce(
|
|
@@ -191,7 +207,9 @@ describe("resolveDispatchOwner", () => {
|
|
|
191
207
|
}),
|
|
192
208
|
),
|
|
193
209
|
).resolves.toBe("member@example.test");
|
|
194
|
-
expect(mocks.
|
|
210
|
+
expect(mocks.resolveSlackBotTokenForIncoming).toHaveBeenCalledWith(
|
|
211
|
+
expect.objectContaining({ senderId: "U999" }),
|
|
212
|
+
);
|
|
195
213
|
expect(globalThis.fetch).toHaveBeenCalledWith(
|
|
196
214
|
"https://slack.com/api/users.info?user=U999",
|
|
197
215
|
{
|
|
@@ -200,6 +218,26 @@ describe("resolveDispatchOwner", () => {
|
|
|
200
218
|
);
|
|
201
219
|
});
|
|
202
220
|
|
|
221
|
+
it("does not resolve a sender with a legacy token from another Slack app", async () => {
|
|
222
|
+
mocks.resolveSlackBotTokenForIncoming.mockResolvedValueOnce(null);
|
|
223
|
+
|
|
224
|
+
const incoming = slackIncoming({
|
|
225
|
+
platformContext: {
|
|
226
|
+
teamId: "T123",
|
|
227
|
+
apiAppId: "A123",
|
|
228
|
+
channelId: "C1",
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const owner = await resolveDispatchOwner(incoming);
|
|
233
|
+
|
|
234
|
+
expect(owner).toMatch(/@integration\.local$/);
|
|
235
|
+
expect(globalThis.fetch).not.toHaveBeenCalledWith(
|
|
236
|
+
"https://slack.com/api/users.info?user=U123",
|
|
237
|
+
expect.anything(),
|
|
238
|
+
);
|
|
239
|
+
});
|
|
240
|
+
|
|
203
241
|
it("falls back to the configured Slack owner when the sender is not an org member", async () => {
|
|
204
242
|
vi.stubEnv("SLACK_BOT_TOKEN", "xoxb-token");
|
|
205
243
|
vi.stubEnv("DISPATCH_DEFAULT_OWNER_EMAIL", "default@example.test");
|
|
@@ -5,15 +5,12 @@ import {
|
|
|
5
5
|
getActiveIntegrationInstallationByKey,
|
|
6
6
|
getIntegrationScope,
|
|
7
7
|
resolveIntegrationTokenBundle,
|
|
8
|
+
resolveSlackBotTokenForIncoming,
|
|
8
9
|
saveIntegrationScope,
|
|
9
10
|
slackInstallationKey,
|
|
10
11
|
} from "@agent-native/core/integrations";
|
|
11
12
|
import { resolveOrgIdForEmail } from "@agent-native/core/org";
|
|
12
|
-
import {
|
|
13
|
-
readDeployCredentialEnv,
|
|
14
|
-
resolveSecret,
|
|
15
|
-
withConfiguredAppBasePath,
|
|
16
|
-
} from "@agent-native/core/server";
|
|
13
|
+
import { withConfiguredAppBasePath } from "@agent-native/core/server";
|
|
17
14
|
import type {
|
|
18
15
|
IncomingMessage,
|
|
19
16
|
IntegrationExecutionContext,
|
|
@@ -171,11 +168,7 @@ async function resolveSlackSenderProfile(
|
|
|
171
168
|
if (incoming.platform !== "slack") {
|
|
172
169
|
return { email: null, name: null, trust: "unknown" };
|
|
173
170
|
}
|
|
174
|
-
const
|
|
175
|
-
const token =
|
|
176
|
-
managedToken ??
|
|
177
|
-
(await resolveSecret("SLACK_BOT_TOKEN")) ??
|
|
178
|
-
readDeployCredentialEnv("SLACK_BOT_TOKEN");
|
|
171
|
+
const token = await resolveSlackBotTokenForIncoming(incoming);
|
|
179
172
|
const userId = contextString(incoming.senderId);
|
|
180
173
|
const teamId = contextString(incoming.platformContext.teamId);
|
|
181
174
|
if (!token || !userId) {
|