@agent-native/dispatch 0.30.1 → 0.30.3

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.
Files changed (32) hide show
  1. package/dist/actions/ask_app.d.ts +1 -0
  2. package/dist/actions/ask_app_status.d.ts +1 -0
  3. package/dist/routes/pages/$appId.d.ts.map +1 -1
  4. package/dist/routes/pages/$appId.js +4 -3
  5. package/dist/routes/pages/$appId.js.map +1 -1
  6. package/dist/routes/pages/_index.d.ts.map +1 -1
  7. package/dist/routes/pages/_index.js +7 -2
  8. package/dist/routes/pages/_index.js.map +1 -1
  9. package/dist/routes/pages/_index.test.d.ts +2 -0
  10. package/dist/routes/pages/_index.test.d.ts.map +1 -0
  11. package/dist/routes/pages/_index.test.js +29 -0
  12. package/dist/routes/pages/_index.test.js.map +1 -0
  13. package/dist/server/lib/dispatch-integrations.d.ts.map +1 -1
  14. package/dist/server/lib/dispatch-integrations.js +149 -7
  15. package/dist/server/lib/dispatch-integrations.js.map +1 -1
  16. package/dist/server/lib/dispatch-store.d.ts +1 -0
  17. package/dist/server/lib/dispatch-store.d.ts.map +1 -1
  18. package/dist/server/lib/dispatch-store.js +4 -0
  19. package/dist/server/lib/dispatch-store.js.map +1 -1
  20. package/dist/server/lib/mcp-gateway.d.ts +8 -2
  21. package/dist/server/lib/mcp-gateway.d.ts.map +1 -1
  22. package/dist/server/lib/mcp-gateway.js +39 -6
  23. package/dist/server/lib/mcp-gateway.js.map +1 -1
  24. package/package.json +2 -2
  25. package/src/routes/pages/$appId.tsx +4 -3
  26. package/src/routes/pages/_index.test.ts +34 -0
  27. package/src/routes/pages/_index.tsx +7 -2
  28. package/src/server/lib/dispatch-integrations.spec.ts +578 -7
  29. package/src/server/lib/dispatch-integrations.ts +186 -9
  30. package/src/server/lib/dispatch-store.ts +7 -0
  31. package/src/server/lib/mcp-gateway.spec.ts +328 -17
  32. package/src/server/lib/mcp-gateway.ts +59 -4
@@ -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 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 // Slack channel turns only arrive here after an explicit current-message\n // mention; keep the generic thread_reply trigger for other adapters.\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":"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","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 { isOrgMember, 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 enterpriseId = contextString(incoming.platformContext.enterpriseId);\n const apiAppId = contextString(incoming.platformContext.apiAppId);\n const isEnterpriseInstall =\n incoming.platformContext.isEnterpriseInstall === true;\n if ((!teamId && !enterpriseId) || (isEnterpriseInstall && !enterpriseId))\n return null;\n return getActiveIntegrationInstallationByKey(\n \"slack\",\n slackInstallationKey({\n teamId,\n enterpriseId,\n apiAppId,\n isEnterpriseInstall,\n }),\n );\n}\n\nclass ManagedSlackInstallationLookupError extends Error {\n constructor(options?: ErrorOptions) {\n super(\n \"Managed Slack installation identity is temporarily unavailable\",\n options,\n );\n this.name = \"ManagedSlackInstallationLookupError\";\n }\n}\n\nasync function resolveManagedSlackInstallationOrFail(\n incoming: IncomingMessage,\n) {\n try {\n return await resolveManagedSlackInstallation(incoming);\n } catch (cause) {\n throw new ManagedSlackInstallationLookupError({ cause });\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\nfunction formatSlackIdentityVerificationFailedMessage(): string {\n return \"I couldn't verify your Slack identity just now, so I can't run this request. Please try again in a moment.\";\n}\n\nfunction formatSlackIdentityDeniedMessage(): string {\n return \"This assistant is only available to members of this workspace's organization.\";\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 is_stranger?: 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_stranger === true ||\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 resolveManagedSlackDmExecutionContext(\n incoming: IncomingMessage,\n installation: NonNullable<\n Awaited<ReturnType<typeof resolveManagedSlackInstallation>>\n >,\n): Promise<IntegrationExecutionContext> {\n const profile = await resolveSlackSenderProfile(incoming);\n incoming.actorTrust = {\n memberType:\n profile.trust === \"guest\"\n ? \"guest\"\n : profile.trust === \"external_shared\"\n ? \"external\"\n : profile.trust === \"trusted\"\n ? \"member\"\n : \"unknown\",\n verified: profile.trust !== \"unknown\",\n };\n incoming.senderVerified = profile.email !== null;\n if (profile.email) {\n incoming.senderEmail = profile.email;\n incoming.platformContext.senderEmail = profile.email;\n }\n if (profile.name) {\n incoming.senderName = profile.name;\n incoming.platformContext.senderName = profile.name;\n }\n\n const deniedContext = (): IntegrationExecutionContext => ({\n ownerEmail: fallbackOwnerForIncoming(incoming),\n orgId: null,\n principalType: \"user\",\n installationId: installation.id,\n });\n\n if (profile.trust === \"unknown\") {\n incoming.platformContext.identityVerificationFailed = true;\n return deniedContext();\n }\n if (profile.trust === \"guest\" || profile.trust === \"external_shared\") {\n incoming.platformContext.identityAccessDenied = true;\n return deniedContext();\n }\n if (!installation.orgId) {\n incoming.platformContext.identityLinkRequired = true;\n return deniedContext();\n }\n incoming.platformContext.managedInstallationOrgId = installation.orgId;\n\n let linkedOwner: string | null;\n try {\n linkedOwner = await resolveLinkedOwner(\n \"slack\",\n identityKeyForIncoming(incoming),\n { orgId: installation.orgId },\n );\n } catch {\n incoming.platformContext.identityVerificationFailed = true;\n return deniedContext();\n }\n const candidates = [profile.email, linkedOwner].filter(\n (email, index, values): email is string =>\n !!email && values.indexOf(email) === index,\n );\n for (const ownerEmail of candidates) {\n try {\n if (await isOrgMember(installation.orgId, ownerEmail)) {\n return {\n ownerEmail,\n orgId: installation.orgId,\n principalType: \"user\",\n installationId: installation.id,\n };\n }\n } catch {\n incoming.platformContext.identityVerificationFailed = true;\n return deniedContext();\n }\n }\n\n incoming.platformContext.identityLinkRequired = true;\n return deniedContext();\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 let installation;\n try {\n installation = await resolveManagedSlackInstallationOrFail(incoming);\n } catch (error) {\n if (!(error instanceof ManagedSlackInstallationLookupError)) throw error;\n incoming.platformContext.identityVerificationFailed = true;\n return {\n ownerEmail: fallbackOwnerForIncoming(incoming),\n orgId: null,\n principalType: \"user\",\n };\n }\n if (installation) {\n return resolveManagedSlackDmExecutionContext(incoming, installation);\n }\n incoming.platformContext.identityVerificationFailed = true;\n return {\n ownerEmail: fallbackOwnerForIncoming(incoming),\n orgId: null,\n principalType: \"user\",\n };\n }\n\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 resolveManagedSlackInstallationOrFail(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 // Slack channel turns only arrive here after an explicit current-message\n // mention; keep the generic thread_reply trigger for other adapters.\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 (\n match &&\n incoming.platform === \"slack\" &&\n incoming.triggerKind === \"dm\" &&\n !contextString(incoming.platformContext.managedInstallationOrgId) &&\n incoming.platformContext.identityVerificationFailed !== true &&\n incoming.platformContext.identityAccessDenied !== true\n ) {\n await resolveDispatchExecutionContext(incoming);\n }\n if (\n incoming.platform === \"slack\" &&\n incoming.triggerKind === \"dm\" &&\n incoming.platformContext.identityVerificationFailed === true\n ) {\n return {\n handled: true,\n responseText: formatSlackIdentityVerificationFailedMessage(),\n };\n }\n if (\n incoming.platform === \"slack\" &&\n incoming.triggerKind === \"dm\" &&\n incoming.platformContext.identityAccessDenied === true\n ) {\n return {\n handled: true,\n responseText: formatSlackIdentityDeniedMessage(),\n };\n }\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 expectedOrgId = contextString(\n incoming.platformContext.managedInstallationOrgId,\n );\n const owner = await consumeLinkToken({\n platform: incoming.platform,\n token: match[1],\n externalUserId: identityKeyForIncoming(incoming),\n externalUserName: incoming.senderName || null,\n ...(expectedOrgId ? { expectedOrgId } : {}),\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"]}
@@ -286,6 +286,7 @@ export declare function consumeLinkToken(input: {
286
286
  token: string;
287
287
  externalUserId?: string | null;
288
288
  externalUserName?: string | null;
289
+ expectedOrgId?: string;
289
290
  }): Promise<string>;
290
291
  export declare function listOverview(): Promise<{
291
292
  counts: {
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch-store.d.ts","sourceRoot":"","sources":["../../../src/server/lib/dispatch-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dispatch-store.d.ts","sourceRoot":"","sources":["../../../src/server/lib/dispatch-store.ts"],"names":[],"mappings":"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"}
@@ -643,6 +643,10 @@ export async function consumeLinkToken(input) {
643
643
  recordLinkFailure(input.platform, input.externalUserId);
644
644
  throw new Error("Link token has expired");
645
645
  }
646
+ if (input.expectedOrgId && tokenRow.orgId !== input.expectedOrgId) {
647
+ recordLinkFailure(input.platform, input.externalUserId);
648
+ throw new Error("This link token belongs to a different organization. Create a token from this workspace and try again.");
649
+ }
646
650
  const timestamp = now();
647
651
  const [existing] = await db
648
652
  .select()
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch-store.js","sourceRoot":"","sources":["../../../src/server/lib/dispatch-store.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"node:crypto\";\n\nimport { and, desc, eq, isNull, or, sql } from \"@agent-native/core/db/schema\";\nimport {\n getRequestUserEmail,\n getRequestOrgId,\n} from \"@agent-native/core/server\";\nimport { getOrgSetting, putOrgSetting } from \"@agent-native/core/settings\";\n\nimport { getDb, schema } from \"../../db/index.js\";\n\nexport const SHARED_DISPATCH_OWNER = \"dispatch@shared\";\nconst APPROVAL_POLICY_KEY = \"dispatch-approval-policy\";\nconst APPROVAL_APPLY_LEASE_MS = 5 * 60 * 1000;\n\n// ─── /link rate limiting ──────────────────────────────────────────────────\n//\n// Failed `/link <token>` attempts are rate-limited per `(platform, externalUserId)`\n// to deter token brute-force after the H5 entropy bump. The window /\n// threshold are tuned so legitimate retries (typo, expired token) don't\n// trip the limit, while a scripted attacker burns out their per-account\n// budget quickly.\n//\n// State is process-local: works for the single-node dispatch deployment\n// we ship today. TODO: move to a SQL-backed counter table when dispatch\n// is sharded across multiple regions / processes — otherwise an\n// attacker can scale around the limit by hammering more than one node.\nconst LINK_FAIL_WINDOW_MS = 5 * 60 * 1000;\nconst LINK_FAIL_BLOCK_MS = 30 * 60 * 1000;\nconst LINK_FAIL_THRESHOLD = 5;\n\ninterface LinkFailureState {\n failures: number[]; // unix-ms timestamps of recent failures within the window\n blockedUntil: number; // unix-ms; 0 if not currently blocked\n}\n\nconst _linkFailureMap = new Map<string, LinkFailureState>();\n\nfunction linkFailureKey(\n platform: string,\n externalUserId: string | null | undefined,\n): string {\n return `${platform}::${externalUserId ?? \"\"}`;\n}\n\nfunction getLinkFailureState(key: string): LinkFailureState {\n let state = _linkFailureMap.get(key);\n if (!state) {\n state = { failures: [], blockedUntil: 0 };\n _linkFailureMap.set(key, state);\n }\n return state;\n}\n\nfunction isLinkAttemptBlocked(\n platform: string,\n externalUserId: string | null | undefined,\n): { blocked: true; retryAfterMs: number } | { blocked: false } {\n if (!externalUserId) return { blocked: false };\n const key = linkFailureKey(platform, externalUserId);\n const state = _linkFailureMap.get(key);\n if (!state) return { blocked: false };\n const nowMs = Date.now();\n if (state.blockedUntil > nowMs) {\n return { blocked: true, retryAfterMs: state.blockedUntil - nowMs };\n }\n return { blocked: false };\n}\n\nfunction recordLinkFailure(\n platform: string,\n externalUserId: string | null | undefined,\n): void {\n if (!externalUserId) return;\n const key = linkFailureKey(platform, externalUserId);\n const state = getLinkFailureState(key);\n const nowMs = Date.now();\n // Drop expired failure timestamps before counting.\n state.failures = state.failures.filter(\n (ts) => nowMs - ts < LINK_FAIL_WINDOW_MS,\n );\n state.failures.push(nowMs);\n if (state.failures.length >= LINK_FAIL_THRESHOLD) {\n state.blockedUntil = nowMs + LINK_FAIL_BLOCK_MS;\n state.failures = [];\n }\n}\n\nfunction clearLinkFailures(\n platform: string,\n externalUserId: string | null | undefined,\n): void {\n if (!externalUserId) return;\n _linkFailureMap.delete(linkFailureKey(platform, externalUserId));\n}\n\n/**\n * 429-style error returned when /link attempts are rate-limited. The\n * adapter layer can branch on `code === \"LINK_RATE_LIMITED\"` to send a\n * platform-appropriate message back to the user.\n */\nexport class LinkRateLimitError extends Error {\n readonly code = \"LINK_RATE_LIMITED\";\n constructor(public readonly retryAfterMs: number) {\n super(\n `Too many failed link attempts. Try again in ${Math.ceil(retryAfterMs / 60_000)} minute(s).`,\n );\n }\n}\n\nexport interface DispatchApprovalPolicy {\n enabled: boolean;\n approverEmails: string[];\n}\n\nexport interface DispatchDestinationInput {\n id?: string;\n name: string;\n platform: string;\n destination: string;\n threadRef?: string | null;\n notes?: string | null;\n}\n\ntype DispatchApprovalRequest =\n typeof schema.dispatchApprovalRequests.$inferSelect;\n\nexport function currentOwnerEmail(): string {\n const email = getRequestUserEmail();\n if (!email) throw new Error(\"no authenticated user\");\n return email;\n}\n\nexport function currentOrgId(): string | null {\n return getRequestOrgId() || null;\n}\n\n/**\n * Caller-supplied access context for dispatch operations that work by\n * id (destinations, etc.). Looking up a row by id alone is unsafe —\n * UUIDs are not authorization. A row matches the ctx if either the\n * caller owns it or it lives in the caller's active org.\n */\nexport interface DispatchCtx {\n ownerEmail: string;\n orgId: string | null;\n}\n\nexport function requireDispatchCtx(): DispatchCtx {\n return { ownerEmail: currentOwnerEmail(), orgId: currentOrgId() };\n}\n\nfunction ctxScope<T extends { ownerEmail: any; orgId: any }>(\n table: T,\n ctx: DispatchCtx,\n) {\n if (!ctx.orgId) {\n return and(eq(table.ownerEmail, ctx.ownerEmail), isNull(table.orgId));\n }\n return or(eq(table.ownerEmail, ctx.ownerEmail), eq(table.orgId, ctx.orgId));\n}\n\nfunction id() {\n return crypto.randomUUID();\n}\n\nfunction now() {\n return Date.now();\n}\n\nfunction safeJson(value: unknown) {\n return JSON.stringify(value ?? null);\n}\n\nexport async function getApprovalPolicy(): Promise<DispatchApprovalPolicy> {\n const orgId = currentOrgId();\n if (!orgId) return { enabled: false, approverEmails: [] };\n const raw = await getOrgSetting(orgId, APPROVAL_POLICY_KEY);\n return {\n enabled: raw?.enabled === true,\n approverEmails: Array.isArray(raw?.approverEmails)\n ? raw.approverEmails.filter(\n (value): value is string => typeof value === \"string\",\n )\n : [],\n };\n}\n\nasync function applyApprovalPolicy(\n input: DispatchApprovalPolicy,\n actor = currentOwnerEmail(),\n orgId = currentOrgId(),\n) {\n if (!orgId) {\n throw new Error(\n \"Dispatch approval settings require an active organization\",\n );\n }\n await putOrgSetting(orgId, APPROVAL_POLICY_KEY, {\n enabled: input.enabled,\n approverEmails: input.approverEmails,\n });\n await recordAudit({\n action: \"settings.updated\",\n targetType: \"dispatch-settings\",\n targetId: APPROVAL_POLICY_KEY,\n summary: input.enabled\n ? \"Enabled approval flow for durable dispatch changes\"\n : \"Disabled approval flow for durable dispatch changes\",\n metadata: input,\n actor,\n });\n return {\n enabled: input.enabled,\n approverEmails: input.approverEmails,\n };\n}\n\nexport async function setApprovalPolicy(input: DispatchApprovalPolicy) {\n const current = await getApprovalPolicy();\n if (!current.enabled) {\n return applyApprovalPolicy(input);\n }\n return createApprovalRequest({\n changeType: \"approval-policy.update\",\n targetType: \"dispatch-settings\",\n targetId: APPROVAL_POLICY_KEY,\n summary: input.enabled\n ? \"Update dispatch approval policy\"\n : \"Disable dispatch approval policy\",\n payload: input,\n beforeValue: current,\n afterValue: input,\n });\n}\n\nexport async function recordAudit(input: {\n action: string;\n targetType: string;\n targetId?: string | null;\n summary: string;\n metadata?: unknown;\n actor?: string;\n ownerEmail?: string;\n orgId?: string | null;\n}) {\n const db = getDb();\n const timestamp = now();\n await db.insert(schema.dispatchAuditEvents).values({\n id: id(),\n ownerEmail: input.ownerEmail || currentOwnerEmail(),\n orgId: input.orgId !== undefined ? input.orgId : currentOrgId(),\n actor: input.actor || currentOwnerEmail(),\n action: input.action,\n targetType: input.targetType,\n targetId: input.targetId || null,\n summary: input.summary,\n metadata: input.metadata ? safeJson(input.metadata) : null,\n createdAt: timestamp,\n });\n}\n\nexport async function listAuditEvents(limit = 50) {\n const db = getDb();\n const orgId = currentOrgId();\n return db\n .select()\n .from(schema.dispatchAuditEvents)\n .where(\n and(\n eq(schema.dispatchAuditEvents.ownerEmail, currentOwnerEmail()),\n orgId\n ? eq(schema.dispatchAuditEvents.orgId, orgId)\n : isNull(schema.dispatchAuditEvents.orgId),\n ),\n )\n .orderBy(desc(schema.dispatchAuditEvents.createdAt))\n .limit(limit);\n}\n\nexport async function listDestinations() {\n const db = getDb();\n const orgId = currentOrgId();\n return db\n .select()\n .from(schema.dispatchDestinations)\n .where(\n and(\n eq(schema.dispatchDestinations.ownerEmail, currentOwnerEmail()),\n orgId\n ? eq(schema.dispatchDestinations.orgId, orgId)\n : isNull(schema.dispatchDestinations.orgId),\n ),\n )\n .orderBy(desc(schema.dispatchDestinations.updatedAt));\n}\n\nexport async function getDestinationById(\n destinationId: string,\n ctx: DispatchCtx = requireDispatchCtx(),\n) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.dispatchDestinations)\n .where(\n and(\n eq(schema.dispatchDestinations.id, destinationId),\n ctxScope(schema.dispatchDestinations, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nasync function applyDestinationUpsert(\n input: DispatchDestinationInput,\n actor = currentOwnerEmail(),\n ctx: DispatchCtx = requireDispatchCtx(),\n) {\n const db = getDb();\n const timestamp = now();\n const destinationId = input.id || id();\n const existing = input.id ? await getDestinationById(input.id, ctx) : null;\n\n if (existing) {\n await db\n .update(schema.dispatchDestinations)\n .set({\n name: input.name,\n platform: input.platform,\n destination: input.destination,\n threadRef: input.threadRef || null,\n notes: input.notes || null,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.dispatchDestinations.id, destinationId),\n ctxScope(schema.dispatchDestinations, ctx),\n ),\n );\n } else {\n await db.insert(schema.dispatchDestinations).values({\n id: destinationId,\n ownerEmail: ctx.ownerEmail,\n orgId: ctx.orgId,\n name: input.name,\n platform: input.platform,\n destination: input.destination,\n threadRef: input.threadRef || null,\n notes: input.notes || null,\n createdBy: actor,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n }\n\n await recordAudit({\n actor,\n action: existing ? \"destination.updated\" : \"destination.created\",\n targetType: \"destination\",\n targetId: destinationId,\n summary: `${existing ? \"Updated\" : \"Created\"} ${input.platform} destination ${input.name}`,\n metadata: input,\n });\n\n return getDestinationById(destinationId, ctx);\n}\n\nasync function applyDestinationDelete(\n destinationId: string,\n actor = currentOwnerEmail(),\n ctx: DispatchCtx = requireDispatchCtx(),\n) {\n const db = getDb();\n const existing = await getDestinationById(destinationId, ctx);\n if (!existing) {\n throw new Error(\"Destination not found\");\n }\n await db\n .delete(schema.dispatchDestinations)\n .where(\n and(\n eq(schema.dispatchDestinations.id, destinationId),\n ctxScope(schema.dispatchDestinations, ctx),\n ),\n );\n await recordAudit({\n actor,\n action: \"destination.deleted\",\n targetType: \"destination\",\n targetId: destinationId,\n summary: `Deleted ${existing.platform} destination ${existing.name}`,\n metadata: existing,\n });\n return existing;\n}\n\nasync function notifyApprovers(requestId: string, summary: string) {\n const policy = await getApprovalPolicy();\n const apiKey = process.env.SENDGRID_API_KEY;\n const from = process.env.SENDGRID_FROM_EMAIL;\n const appUrl = process.env.APP_URL;\n if (!apiKey || !from || !appUrl || policy.approverEmails.length === 0) return;\n\n await fetch(\"https://api.sendgrid.com/v3/mail/send\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n personalizations: [\n {\n to: policy.approverEmails.map((email) => ({ email })),\n subject: \"Dispatch approval requested\",\n },\n ],\n from: { email: from },\n content: [\n {\n type: \"text/plain\",\n value: `${summary}\\n\\nReview it here: ${appUrl}/approvals`,\n },\n ],\n custom_args: { requestId },\n }),\n }).catch(() => {});\n}\n\nexport async function createApprovalRequest(input: {\n changeType: string;\n targetType: string;\n targetId?: string | null;\n summary: string;\n payload: unknown;\n beforeValue?: unknown;\n afterValue?: unknown;\n}) {\n const db = getDb();\n const timestamp = now();\n const requestId = id();\n await db.insert(schema.dispatchApprovalRequests).values({\n id: requestId,\n ownerEmail: currentOwnerEmail(),\n orgId: currentOrgId(),\n changeType: input.changeType,\n targetType: input.targetType,\n targetId: input.targetId || null,\n status: \"pending\",\n summary: input.summary,\n payload: safeJson(input.payload),\n beforeValue:\n input.beforeValue === undefined ? null : safeJson(input.beforeValue),\n afterValue:\n input.afterValue === undefined ? null : safeJson(input.afterValue),\n requestedBy: currentOwnerEmail(),\n reviewedBy: null,\n reviewedAt: null,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n await recordAudit({\n action: \"approval.requested\",\n targetType: input.targetType,\n targetId: input.targetId || requestId,\n summary: input.summary,\n metadata: input,\n });\n await notifyApprovers(requestId, input.summary);\n return getApprovalRequest(requestId);\n}\n\nexport async function upsertDestination(input: DispatchDestinationInput) {\n const policy = await getApprovalPolicy();\n if (policy.enabled) {\n const existing = input.id ? await getDestinationById(input.id) : null;\n return createApprovalRequest({\n changeType: \"destination.upsert\",\n targetType: \"destination\",\n targetId: input.id || null,\n summary: `${existing ? \"Update\" : \"Create\"} ${input.platform} destination ${input.name}`,\n payload: input,\n beforeValue: existing,\n afterValue: input,\n });\n }\n return applyDestinationUpsert(input);\n}\n\nexport async function deleteDestination(destinationId: string) {\n const policy = await getApprovalPolicy();\n const existing = await getDestinationById(destinationId);\n if (!existing) {\n throw new Error(\"Destination not found\");\n }\n if (policy.enabled) {\n return createApprovalRequest({\n changeType: \"destination.delete\",\n targetType: \"destination\",\n targetId: destinationId,\n summary: `Delete ${existing.platform} destination ${existing.name}`,\n payload: { id: destinationId },\n beforeValue: existing,\n afterValue: null,\n });\n }\n return applyDestinationDelete(destinationId);\n}\n\nexport async function listApprovalRequests() {\n const db = getDb();\n const orgId = currentOrgId();\n return db\n .select()\n .from(schema.dispatchApprovalRequests)\n .where(\n and(\n eq(schema.dispatchApprovalRequests.ownerEmail, currentOwnerEmail()),\n orgId\n ? eq(schema.dispatchApprovalRequests.orgId, orgId)\n : isNull(schema.dispatchApprovalRequests.orgId),\n ),\n )\n .orderBy(desc(schema.dispatchApprovalRequests.updatedAt));\n}\n\nasync function getApprovalRequest(\n requestId: string,\n ctx: DispatchCtx = requireDispatchCtx(),\n) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.dispatchApprovalRequests)\n .where(\n and(\n eq(schema.dispatchApprovalRequests.id, requestId),\n ctxScope(schema.dispatchApprovalRequests, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nasync function applyApprovedRequest(request: DispatchApprovalRequest) {\n const payload = JSON.parse(request.payload);\n const requestCtx = {\n ownerEmail: request.ownerEmail,\n orgId: request.orgId,\n };\n if (request.changeType === \"destination.upsert\") {\n return applyDestinationUpsert(\n payload,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n if (request.changeType === \"destination.delete\") {\n return applyDestinationDelete(\n payload.id,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n if (request.changeType === \"approval-policy.update\") {\n return applyApprovalPolicy(\n payload,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx.orgId,\n );\n }\n if (request.changeType === \"dream-proposal.apply\") {\n const { applyApprovedDreamProposal } = await import(\"./dreams-store.js\");\n return applyApprovedDreamProposal(\n payload.proposalId,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n if (request.changeType === \"workspace-resource.create\") {\n const { applyWorkspaceResourceCreate } =\n await import(\"./workspace-resources-store.js\");\n return applyWorkspaceResourceCreate(\n payload.input,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n if (request.changeType === \"workspace-agent-pack.create\") {\n const { applyAgentPackCreate } = await import(\"./agent-pack-store.js\");\n return applyAgentPackCreate(\n payload.inputs,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n if (request.changeType === \"workspace-resource.update\") {\n const { applyWorkspaceResourceUpdate } =\n await import(\"./workspace-resources-store.js\");\n return applyWorkspaceResourceUpdate(\n payload.id,\n payload.input,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n if (request.changeType === \"workspace-resource.delete\") {\n const { applyWorkspaceResourceDelete } =\n await import(\"./workspace-resources-store.js\");\n return applyWorkspaceResourceDelete(\n payload.id,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n throw new Error(`Unsupported approval request type: ${request.changeType}`);\n}\n\nexport async function approveRequest(requestId: string) {\n const db = getDb();\n const ctx = requireDispatchCtx();\n const request = await getApprovalRequest(requestId, ctx);\n if (!request) throw new Error(\"Approval request not found\");\n\n const timestamp = now();\n const staleApplyingBefore = timestamp - APPROVAL_APPLY_LEASE_MS;\n // Fence the transition on the current status so a concurrent approve can't\n // both win. A crashed worker can leave its lease in \"applying\", so reclaim\n // only a lease that has been idle for the full lease interval.\n const claimed = await db\n .update(schema.dispatchApprovalRequests)\n .set({\n status: \"applying\",\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.dispatchApprovalRequests.id, requestId),\n ctxScope(schema.dispatchApprovalRequests, ctx),\n or(\n eq(schema.dispatchApprovalRequests.status, \"pending\"),\n and(\n eq(schema.dispatchApprovalRequests.status, \"applying\"),\n sql`${schema.dispatchApprovalRequests.updatedAt} < ${staleApplyingBefore}`,\n ),\n ),\n ),\n )\n .returning();\n\n if (claimed.length === 0) {\n const current = (await getApprovalRequest(requestId, ctx)) ?? request;\n if (current.status === \"applying\") {\n throw new Error(\"Approval is already being applied\");\n }\n return current;\n }\n\n const applying = claimed[0];\n try {\n await applyApprovedRequest(applying);\n } catch (error) {\n // Applying a request can have succeeded partially before throwing. Do not\n // return it to pending: that would allow an immediate retry to duplicate a\n // non-idempotent effect. Keep the lease until it becomes stale, which\n // serializes any recovery attempt behind the same fencing rule.\n await db\n .update(schema.dispatchApprovalRequests)\n .set({ updatedAt: now() })\n .where(\n and(\n eq(schema.dispatchApprovalRequests.id, requestId),\n ctxScope(schema.dispatchApprovalRequests, ctx),\n eq(schema.dispatchApprovalRequests.status, \"applying\"),\n ),\n );\n throw error;\n }\n const [updated] = await db\n .update(schema.dispatchApprovalRequests)\n .set({\n status: \"approved\",\n reviewedBy: currentOwnerEmail(),\n reviewedAt: timestamp,\n updatedAt: now(),\n })\n .where(\n and(\n eq(schema.dispatchApprovalRequests.id, requestId),\n ctxScope(schema.dispatchApprovalRequests, ctx),\n eq(schema.dispatchApprovalRequests.status, \"applying\"),\n ),\n )\n .returning();\n if (!updated) throw new Error(\"Approval request disappeared\");\n await recordAudit({\n action: \"approval.approved\",\n targetType: updated.targetType,\n targetId: requestId,\n summary: `Approved ${updated.summary}`,\n metadata: updated,\n });\n return updated;\n}\n\nexport async function rejectRequest(requestId: string, reason?: string | null) {\n const db = getDb();\n const ctx = requireDispatchCtx();\n const request = await getApprovalRequest(requestId, ctx);\n if (!request) throw new Error(\"Approval request not found\");\n\n const timestamp = now();\n const claimed = await db\n .update(schema.dispatchApprovalRequests)\n .set({\n status: \"rejected\",\n reviewedBy: currentOwnerEmail(),\n reviewedAt: timestamp,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.dispatchApprovalRequests.id, requestId),\n ctxScope(schema.dispatchApprovalRequests, ctx),\n eq(schema.dispatchApprovalRequests.status, \"pending\"),\n ),\n )\n .returning();\n\n if (claimed.length === 0) {\n return (await getApprovalRequest(requestId, ctx)) ?? request;\n }\n\n const updated = claimed[0];\n await recordAudit({\n action: \"approval.rejected\",\n targetType: updated.targetType,\n targetId: requestId,\n summary: `Rejected ${updated.summary}`,\n metadata: { request: updated, reason: reason || null },\n });\n return updated;\n}\n\nexport async function createLinkToken(platform: string) {\n const db = getDb();\n const timestamp = now();\n // 16 bytes = 128 bits of entropy. Previous size was 4 bytes (32 bits,\n // ~4.29 billion keyspace) which is brute-forceable in well under an\n // hour given a 7-day expiry and no rate limiting on /link attempts.\n // Old 8-hex-char tokens minted before this change continue to verify\n // until they expire; we don't migrate retroactively. See\n // /tmp/security-audit/07-webhooks.md (H5).\n const token = crypto.randomBytes(16).toString(\"hex\");\n const recordId = id();\n const owner = currentOwnerEmail();\n await db.insert(schema.dispatchLinkTokens).values({\n id: recordId,\n token,\n ownerEmail: owner,\n orgId: currentOrgId(),\n platform,\n createdBy: owner,\n expiresAt: timestamp + 7 * 24 * 60 * 60 * 1000,\n claimedAt: null,\n claimedByExternalUserId: null,\n claimedByExternalUserName: null,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n await recordAudit({\n action: \"identity.link-token-created\",\n targetType: \"link-token\",\n targetId: recordId,\n summary: `Created ${platform} link token for ${owner}`,\n metadata: { token, platform },\n });\n return {\n token,\n command: `/link ${token}`,\n platform,\n expiresAt: timestamp + 7 * 24 * 60 * 60 * 1000,\n };\n}\n\nexport async function listIdentityState() {\n const db = getDb();\n const owner = currentOwnerEmail();\n const orgId = currentOrgId();\n const filters = and(\n eq(schema.dispatchIdentityLinks.ownerEmail, owner),\n orgId\n ? eq(schema.dispatchIdentityLinks.orgId, orgId)\n : isNull(schema.dispatchIdentityLinks.orgId),\n );\n const tokenFilters = and(\n eq(schema.dispatchLinkTokens.ownerEmail, owner),\n orgId\n ? eq(schema.dispatchLinkTokens.orgId, orgId)\n : isNull(schema.dispatchLinkTokens.orgId),\n );\n const [links, tokens] = await Promise.all([\n db\n .select()\n .from(schema.dispatchIdentityLinks)\n .where(filters)\n .orderBy(desc(schema.dispatchIdentityLinks.updatedAt)),\n db\n .select()\n .from(schema.dispatchLinkTokens)\n .where(tokenFilters)\n .orderBy(desc(schema.dispatchLinkTokens.updatedAt)),\n ]);\n return { links, tokens };\n}\n\nexport async function resolveLinkedOwner(\n platform: string,\n externalUserId?: string | null,\n options: {\n orgId?: string | null;\n allowAnyOrgFallback?: boolean;\n } = {},\n) {\n if (!externalUserId) return null;\n const db = getDb();\n const orgId = options.orgId !== undefined ? options.orgId : currentOrgId();\n const rows = await db\n .select()\n .from(schema.dispatchIdentityLinks)\n .where(\n and(\n eq(schema.dispatchIdentityLinks.platform, platform),\n eq(schema.dispatchIdentityLinks.externalUserId, externalUserId),\n orgId\n ? eq(schema.dispatchIdentityLinks.orgId, orgId)\n : isNull(schema.dispatchIdentityLinks.orgId),\n ),\n )\n .orderBy(desc(schema.dispatchIdentityLinks.updatedAt))\n .limit(1);\n if (rows[0]?.ownerEmail) return rows[0].ownerEmail;\n\n if (!options.allowAnyOrgFallback || orgId) return null;\n\n // Webhook processors run outside a normal request/org context. A linked\n // Slack/Telegram identity may still be scoped to an org, so fall back to any\n // org only when every matching link resolves to the same owner.\n const fallbackRows = await db\n .select()\n .from(schema.dispatchIdentityLinks)\n .where(\n and(\n eq(schema.dispatchIdentityLinks.platform, platform),\n eq(schema.dispatchIdentityLinks.externalUserId, externalUserId),\n ),\n )\n .orderBy(desc(schema.dispatchIdentityLinks.updatedAt))\n .limit(25);\n const owners = new Set(fallbackRows.map((row) => row.ownerEmail));\n return owners.size === 1 ? fallbackRows[0]?.ownerEmail || null : null;\n}\n\nexport async function consumeLinkToken(input: {\n platform: string;\n token: string;\n externalUserId?: string | null;\n externalUserName?: string | null;\n}) {\n if (!input.externalUserId) {\n throw new Error(\"Linking requires a platform user id\");\n }\n\n // Rate-limit failed attempts per (platform, externalUserId). Once\n // tripped, all further attempts are short-circuited until the block\n // window passes — including the lookup, so an attacker can't probe\n // for valid tokens during the block.\n const blockState = isLinkAttemptBlocked(input.platform, input.externalUserId);\n if (blockState.blocked) {\n throw new LinkRateLimitError(blockState.retryAfterMs);\n }\n\n const db = getDb();\n const tokenRows = await db\n .select()\n .from(schema.dispatchLinkTokens)\n .where(\n and(\n eq(schema.dispatchLinkTokens.platform, input.platform),\n eq(schema.dispatchLinkTokens.token, input.token),\n ),\n )\n .orderBy(desc(schema.dispatchLinkTokens.createdAt))\n .limit(2);\n if (tokenRows.length > 1) {\n recordLinkFailure(input.platform, input.externalUserId);\n throw new Error(\"Link token is ambiguous. Create a fresh token and retry.\");\n }\n const tokenRow = tokenRows[0];\n if (!tokenRow) {\n recordLinkFailure(input.platform, input.externalUserId);\n throw new Error(\"Link token not found\");\n }\n if (tokenRow.claimedAt) {\n recordLinkFailure(input.platform, input.externalUserId);\n throw new Error(\"Link token has already been claimed\");\n }\n if (tokenRow.expiresAt < now()) {\n recordLinkFailure(input.platform, input.externalUserId);\n throw new Error(\"Link token has expired\");\n }\n\n const timestamp = now();\n const [existing] = await db\n .select()\n .from(schema.dispatchIdentityLinks)\n .where(\n and(\n eq(schema.dispatchIdentityLinks.platform, input.platform),\n eq(schema.dispatchIdentityLinks.externalUserId, input.externalUserId),\n tokenRow.orgId\n ? eq(schema.dispatchIdentityLinks.orgId, tokenRow.orgId)\n : isNull(schema.dispatchIdentityLinks.orgId),\n ),\n )\n .limit(1);\n\n if (existing) {\n await db\n .update(schema.dispatchIdentityLinks)\n .set({\n ownerEmail: tokenRow.ownerEmail,\n orgId: tokenRow.orgId,\n externalUserName: input.externalUserName || null,\n linkedBy: tokenRow.createdBy,\n updatedAt: timestamp,\n })\n .where(eq(schema.dispatchIdentityLinks.id, existing.id));\n } else {\n await db.insert(schema.dispatchIdentityLinks).values({\n id: id(),\n ownerEmail: tokenRow.ownerEmail,\n orgId: tokenRow.orgId,\n platform: input.platform,\n externalUserId: input.externalUserId,\n externalUserName: input.externalUserName || null,\n linkedBy: tokenRow.createdBy,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n }\n\n await db\n .update(schema.dispatchLinkTokens)\n .set({\n claimedAt: timestamp,\n claimedByExternalUserId: input.externalUserId,\n claimedByExternalUserName: input.externalUserName || null,\n updatedAt: timestamp,\n })\n .where(eq(schema.dispatchLinkTokens.id, tokenRow.id));\n\n // Successful claim — reset the rate-limit budget so subsequent\n // links from this external user start fresh.\n clearLinkFailures(input.platform, input.externalUserId);\n\n await recordAudit({\n actor: tokenRow.createdBy,\n ownerEmail: tokenRow.ownerEmail,\n orgId: tokenRow.orgId,\n action: \"identity.linked\",\n targetType: \"identity-link\",\n targetId: input.externalUserId,\n summary: `Linked ${input.platform} user ${input.externalUserName || input.externalUserId}`,\n metadata: input,\n });\n\n return tokenRow.ownerEmail;\n}\n\nexport async function listOverview() {\n const [destinations, approvals, identities, audit, settings] =\n await Promise.all([\n listDestinations(),\n listApprovalRequests(),\n listIdentityState(),\n listAuditEvents(12),\n getApprovalPolicy(),\n ]);\n\n return {\n counts: {\n destinations: destinations.length,\n pendingApprovals: approvals.filter((item) => item.status === \"pending\")\n .length,\n linkedIdentities: identities.links.length,\n activeTokens: identities.tokens.filter(\n (item) => !item.claimedAt && item.expiresAt > now(),\n ).length,\n },\n recentDestinations: destinations.slice(0, 5),\n recentApprovals: approvals.slice(0, 5),\n recentAudit: audit.slice(0, 8),\n settings,\n };\n}\n"]}
1
+ {"version":3,"file":"dispatch-store.js","sourceRoot":"","sources":["../../../src/server/lib/dispatch-store.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"node:crypto\";\n\nimport { and, desc, eq, isNull, or, sql } from \"@agent-native/core/db/schema\";\nimport {\n getRequestUserEmail,\n getRequestOrgId,\n} from \"@agent-native/core/server\";\nimport { getOrgSetting, putOrgSetting } from \"@agent-native/core/settings\";\n\nimport { getDb, schema } from \"../../db/index.js\";\n\nexport const SHARED_DISPATCH_OWNER = \"dispatch@shared\";\nconst APPROVAL_POLICY_KEY = \"dispatch-approval-policy\";\nconst APPROVAL_APPLY_LEASE_MS = 5 * 60 * 1000;\n\n// ─── /link rate limiting ──────────────────────────────────────────────────\n//\n// Failed `/link <token>` attempts are rate-limited per `(platform, externalUserId)`\n// to deter token brute-force after the H5 entropy bump. The window /\n// threshold are tuned so legitimate retries (typo, expired token) don't\n// trip the limit, while a scripted attacker burns out their per-account\n// budget quickly.\n//\n// State is process-local: works for the single-node dispatch deployment\n// we ship today. TODO: move to a SQL-backed counter table when dispatch\n// is sharded across multiple regions / processes — otherwise an\n// attacker can scale around the limit by hammering more than one node.\nconst LINK_FAIL_WINDOW_MS = 5 * 60 * 1000;\nconst LINK_FAIL_BLOCK_MS = 30 * 60 * 1000;\nconst LINK_FAIL_THRESHOLD = 5;\n\ninterface LinkFailureState {\n failures: number[]; // unix-ms timestamps of recent failures within the window\n blockedUntil: number; // unix-ms; 0 if not currently blocked\n}\n\nconst _linkFailureMap = new Map<string, LinkFailureState>();\n\nfunction linkFailureKey(\n platform: string,\n externalUserId: string | null | undefined,\n): string {\n return `${platform}::${externalUserId ?? \"\"}`;\n}\n\nfunction getLinkFailureState(key: string): LinkFailureState {\n let state = _linkFailureMap.get(key);\n if (!state) {\n state = { failures: [], blockedUntil: 0 };\n _linkFailureMap.set(key, state);\n }\n return state;\n}\n\nfunction isLinkAttemptBlocked(\n platform: string,\n externalUserId: string | null | undefined,\n): { blocked: true; retryAfterMs: number } | { blocked: false } {\n if (!externalUserId) return { blocked: false };\n const key = linkFailureKey(platform, externalUserId);\n const state = _linkFailureMap.get(key);\n if (!state) return { blocked: false };\n const nowMs = Date.now();\n if (state.blockedUntil > nowMs) {\n return { blocked: true, retryAfterMs: state.blockedUntil - nowMs };\n }\n return { blocked: false };\n}\n\nfunction recordLinkFailure(\n platform: string,\n externalUserId: string | null | undefined,\n): void {\n if (!externalUserId) return;\n const key = linkFailureKey(platform, externalUserId);\n const state = getLinkFailureState(key);\n const nowMs = Date.now();\n // Drop expired failure timestamps before counting.\n state.failures = state.failures.filter(\n (ts) => nowMs - ts < LINK_FAIL_WINDOW_MS,\n );\n state.failures.push(nowMs);\n if (state.failures.length >= LINK_FAIL_THRESHOLD) {\n state.blockedUntil = nowMs + LINK_FAIL_BLOCK_MS;\n state.failures = [];\n }\n}\n\nfunction clearLinkFailures(\n platform: string,\n externalUserId: string | null | undefined,\n): void {\n if (!externalUserId) return;\n _linkFailureMap.delete(linkFailureKey(platform, externalUserId));\n}\n\n/**\n * 429-style error returned when /link attempts are rate-limited. The\n * adapter layer can branch on `code === \"LINK_RATE_LIMITED\"` to send a\n * platform-appropriate message back to the user.\n */\nexport class LinkRateLimitError extends Error {\n readonly code = \"LINK_RATE_LIMITED\";\n constructor(public readonly retryAfterMs: number) {\n super(\n `Too many failed link attempts. Try again in ${Math.ceil(retryAfterMs / 60_000)} minute(s).`,\n );\n }\n}\n\nexport interface DispatchApprovalPolicy {\n enabled: boolean;\n approverEmails: string[];\n}\n\nexport interface DispatchDestinationInput {\n id?: string;\n name: string;\n platform: string;\n destination: string;\n threadRef?: string | null;\n notes?: string | null;\n}\n\ntype DispatchApprovalRequest =\n typeof schema.dispatchApprovalRequests.$inferSelect;\n\nexport function currentOwnerEmail(): string {\n const email = getRequestUserEmail();\n if (!email) throw new Error(\"no authenticated user\");\n return email;\n}\n\nexport function currentOrgId(): string | null {\n return getRequestOrgId() || null;\n}\n\n/**\n * Caller-supplied access context for dispatch operations that work by\n * id (destinations, etc.). Looking up a row by id alone is unsafe —\n * UUIDs are not authorization. A row matches the ctx if either the\n * caller owns it or it lives in the caller's active org.\n */\nexport interface DispatchCtx {\n ownerEmail: string;\n orgId: string | null;\n}\n\nexport function requireDispatchCtx(): DispatchCtx {\n return { ownerEmail: currentOwnerEmail(), orgId: currentOrgId() };\n}\n\nfunction ctxScope<T extends { ownerEmail: any; orgId: any }>(\n table: T,\n ctx: DispatchCtx,\n) {\n if (!ctx.orgId) {\n return and(eq(table.ownerEmail, ctx.ownerEmail), isNull(table.orgId));\n }\n return or(eq(table.ownerEmail, ctx.ownerEmail), eq(table.orgId, ctx.orgId));\n}\n\nfunction id() {\n return crypto.randomUUID();\n}\n\nfunction now() {\n return Date.now();\n}\n\nfunction safeJson(value: unknown) {\n return JSON.stringify(value ?? null);\n}\n\nexport async function getApprovalPolicy(): Promise<DispatchApprovalPolicy> {\n const orgId = currentOrgId();\n if (!orgId) return { enabled: false, approverEmails: [] };\n const raw = await getOrgSetting(orgId, APPROVAL_POLICY_KEY);\n return {\n enabled: raw?.enabled === true,\n approverEmails: Array.isArray(raw?.approverEmails)\n ? raw.approverEmails.filter(\n (value): value is string => typeof value === \"string\",\n )\n : [],\n };\n}\n\nasync function applyApprovalPolicy(\n input: DispatchApprovalPolicy,\n actor = currentOwnerEmail(),\n orgId = currentOrgId(),\n) {\n if (!orgId) {\n throw new Error(\n \"Dispatch approval settings require an active organization\",\n );\n }\n await putOrgSetting(orgId, APPROVAL_POLICY_KEY, {\n enabled: input.enabled,\n approverEmails: input.approverEmails,\n });\n await recordAudit({\n action: \"settings.updated\",\n targetType: \"dispatch-settings\",\n targetId: APPROVAL_POLICY_KEY,\n summary: input.enabled\n ? \"Enabled approval flow for durable dispatch changes\"\n : \"Disabled approval flow for durable dispatch changes\",\n metadata: input,\n actor,\n });\n return {\n enabled: input.enabled,\n approverEmails: input.approverEmails,\n };\n}\n\nexport async function setApprovalPolicy(input: DispatchApprovalPolicy) {\n const current = await getApprovalPolicy();\n if (!current.enabled) {\n return applyApprovalPolicy(input);\n }\n return createApprovalRequest({\n changeType: \"approval-policy.update\",\n targetType: \"dispatch-settings\",\n targetId: APPROVAL_POLICY_KEY,\n summary: input.enabled\n ? \"Update dispatch approval policy\"\n : \"Disable dispatch approval policy\",\n payload: input,\n beforeValue: current,\n afterValue: input,\n });\n}\n\nexport async function recordAudit(input: {\n action: string;\n targetType: string;\n targetId?: string | null;\n summary: string;\n metadata?: unknown;\n actor?: string;\n ownerEmail?: string;\n orgId?: string | null;\n}) {\n const db = getDb();\n const timestamp = now();\n await db.insert(schema.dispatchAuditEvents).values({\n id: id(),\n ownerEmail: input.ownerEmail || currentOwnerEmail(),\n orgId: input.orgId !== undefined ? input.orgId : currentOrgId(),\n actor: input.actor || currentOwnerEmail(),\n action: input.action,\n targetType: input.targetType,\n targetId: input.targetId || null,\n summary: input.summary,\n metadata: input.metadata ? safeJson(input.metadata) : null,\n createdAt: timestamp,\n });\n}\n\nexport async function listAuditEvents(limit = 50) {\n const db = getDb();\n const orgId = currentOrgId();\n return db\n .select()\n .from(schema.dispatchAuditEvents)\n .where(\n and(\n eq(schema.dispatchAuditEvents.ownerEmail, currentOwnerEmail()),\n orgId\n ? eq(schema.dispatchAuditEvents.orgId, orgId)\n : isNull(schema.dispatchAuditEvents.orgId),\n ),\n )\n .orderBy(desc(schema.dispatchAuditEvents.createdAt))\n .limit(limit);\n}\n\nexport async function listDestinations() {\n const db = getDb();\n const orgId = currentOrgId();\n return db\n .select()\n .from(schema.dispatchDestinations)\n .where(\n and(\n eq(schema.dispatchDestinations.ownerEmail, currentOwnerEmail()),\n orgId\n ? eq(schema.dispatchDestinations.orgId, orgId)\n : isNull(schema.dispatchDestinations.orgId),\n ),\n )\n .orderBy(desc(schema.dispatchDestinations.updatedAt));\n}\n\nexport async function getDestinationById(\n destinationId: string,\n ctx: DispatchCtx = requireDispatchCtx(),\n) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.dispatchDestinations)\n .where(\n and(\n eq(schema.dispatchDestinations.id, destinationId),\n ctxScope(schema.dispatchDestinations, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nasync function applyDestinationUpsert(\n input: DispatchDestinationInput,\n actor = currentOwnerEmail(),\n ctx: DispatchCtx = requireDispatchCtx(),\n) {\n const db = getDb();\n const timestamp = now();\n const destinationId = input.id || id();\n const existing = input.id ? await getDestinationById(input.id, ctx) : null;\n\n if (existing) {\n await db\n .update(schema.dispatchDestinations)\n .set({\n name: input.name,\n platform: input.platform,\n destination: input.destination,\n threadRef: input.threadRef || null,\n notes: input.notes || null,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.dispatchDestinations.id, destinationId),\n ctxScope(schema.dispatchDestinations, ctx),\n ),\n );\n } else {\n await db.insert(schema.dispatchDestinations).values({\n id: destinationId,\n ownerEmail: ctx.ownerEmail,\n orgId: ctx.orgId,\n name: input.name,\n platform: input.platform,\n destination: input.destination,\n threadRef: input.threadRef || null,\n notes: input.notes || null,\n createdBy: actor,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n }\n\n await recordAudit({\n actor,\n action: existing ? \"destination.updated\" : \"destination.created\",\n targetType: \"destination\",\n targetId: destinationId,\n summary: `${existing ? \"Updated\" : \"Created\"} ${input.platform} destination ${input.name}`,\n metadata: input,\n });\n\n return getDestinationById(destinationId, ctx);\n}\n\nasync function applyDestinationDelete(\n destinationId: string,\n actor = currentOwnerEmail(),\n ctx: DispatchCtx = requireDispatchCtx(),\n) {\n const db = getDb();\n const existing = await getDestinationById(destinationId, ctx);\n if (!existing) {\n throw new Error(\"Destination not found\");\n }\n await db\n .delete(schema.dispatchDestinations)\n .where(\n and(\n eq(schema.dispatchDestinations.id, destinationId),\n ctxScope(schema.dispatchDestinations, ctx),\n ),\n );\n await recordAudit({\n actor,\n action: \"destination.deleted\",\n targetType: \"destination\",\n targetId: destinationId,\n summary: `Deleted ${existing.platform} destination ${existing.name}`,\n metadata: existing,\n });\n return existing;\n}\n\nasync function notifyApprovers(requestId: string, summary: string) {\n const policy = await getApprovalPolicy();\n const apiKey = process.env.SENDGRID_API_KEY;\n const from = process.env.SENDGRID_FROM_EMAIL;\n const appUrl = process.env.APP_URL;\n if (!apiKey || !from || !appUrl || policy.approverEmails.length === 0) return;\n\n await fetch(\"https://api.sendgrid.com/v3/mail/send\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n personalizations: [\n {\n to: policy.approverEmails.map((email) => ({ email })),\n subject: \"Dispatch approval requested\",\n },\n ],\n from: { email: from },\n content: [\n {\n type: \"text/plain\",\n value: `${summary}\\n\\nReview it here: ${appUrl}/approvals`,\n },\n ],\n custom_args: { requestId },\n }),\n }).catch(() => {});\n}\n\nexport async function createApprovalRequest(input: {\n changeType: string;\n targetType: string;\n targetId?: string | null;\n summary: string;\n payload: unknown;\n beforeValue?: unknown;\n afterValue?: unknown;\n}) {\n const db = getDb();\n const timestamp = now();\n const requestId = id();\n await db.insert(schema.dispatchApprovalRequests).values({\n id: requestId,\n ownerEmail: currentOwnerEmail(),\n orgId: currentOrgId(),\n changeType: input.changeType,\n targetType: input.targetType,\n targetId: input.targetId || null,\n status: \"pending\",\n summary: input.summary,\n payload: safeJson(input.payload),\n beforeValue:\n input.beforeValue === undefined ? null : safeJson(input.beforeValue),\n afterValue:\n input.afterValue === undefined ? null : safeJson(input.afterValue),\n requestedBy: currentOwnerEmail(),\n reviewedBy: null,\n reviewedAt: null,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n await recordAudit({\n action: \"approval.requested\",\n targetType: input.targetType,\n targetId: input.targetId || requestId,\n summary: input.summary,\n metadata: input,\n });\n await notifyApprovers(requestId, input.summary);\n return getApprovalRequest(requestId);\n}\n\nexport async function upsertDestination(input: DispatchDestinationInput) {\n const policy = await getApprovalPolicy();\n if (policy.enabled) {\n const existing = input.id ? await getDestinationById(input.id) : null;\n return createApprovalRequest({\n changeType: \"destination.upsert\",\n targetType: \"destination\",\n targetId: input.id || null,\n summary: `${existing ? \"Update\" : \"Create\"} ${input.platform} destination ${input.name}`,\n payload: input,\n beforeValue: existing,\n afterValue: input,\n });\n }\n return applyDestinationUpsert(input);\n}\n\nexport async function deleteDestination(destinationId: string) {\n const policy = await getApprovalPolicy();\n const existing = await getDestinationById(destinationId);\n if (!existing) {\n throw new Error(\"Destination not found\");\n }\n if (policy.enabled) {\n return createApprovalRequest({\n changeType: \"destination.delete\",\n targetType: \"destination\",\n targetId: destinationId,\n summary: `Delete ${existing.platform} destination ${existing.name}`,\n payload: { id: destinationId },\n beforeValue: existing,\n afterValue: null,\n });\n }\n return applyDestinationDelete(destinationId);\n}\n\nexport async function listApprovalRequests() {\n const db = getDb();\n const orgId = currentOrgId();\n return db\n .select()\n .from(schema.dispatchApprovalRequests)\n .where(\n and(\n eq(schema.dispatchApprovalRequests.ownerEmail, currentOwnerEmail()),\n orgId\n ? eq(schema.dispatchApprovalRequests.orgId, orgId)\n : isNull(schema.dispatchApprovalRequests.orgId),\n ),\n )\n .orderBy(desc(schema.dispatchApprovalRequests.updatedAt));\n}\n\nasync function getApprovalRequest(\n requestId: string,\n ctx: DispatchCtx = requireDispatchCtx(),\n) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.dispatchApprovalRequests)\n .where(\n and(\n eq(schema.dispatchApprovalRequests.id, requestId),\n ctxScope(schema.dispatchApprovalRequests, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nasync function applyApprovedRequest(request: DispatchApprovalRequest) {\n const payload = JSON.parse(request.payload);\n const requestCtx = {\n ownerEmail: request.ownerEmail,\n orgId: request.orgId,\n };\n if (request.changeType === \"destination.upsert\") {\n return applyDestinationUpsert(\n payload,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n if (request.changeType === \"destination.delete\") {\n return applyDestinationDelete(\n payload.id,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n if (request.changeType === \"approval-policy.update\") {\n return applyApprovalPolicy(\n payload,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx.orgId,\n );\n }\n if (request.changeType === \"dream-proposal.apply\") {\n const { applyApprovedDreamProposal } = await import(\"./dreams-store.js\");\n return applyApprovedDreamProposal(\n payload.proposalId,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n if (request.changeType === \"workspace-resource.create\") {\n const { applyWorkspaceResourceCreate } =\n await import(\"./workspace-resources-store.js\");\n return applyWorkspaceResourceCreate(\n payload.input,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n if (request.changeType === \"workspace-agent-pack.create\") {\n const { applyAgentPackCreate } = await import(\"./agent-pack-store.js\");\n return applyAgentPackCreate(\n payload.inputs,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n if (request.changeType === \"workspace-resource.update\") {\n const { applyWorkspaceResourceUpdate } =\n await import(\"./workspace-resources-store.js\");\n return applyWorkspaceResourceUpdate(\n payload.id,\n payload.input,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n if (request.changeType === \"workspace-resource.delete\") {\n const { applyWorkspaceResourceDelete } =\n await import(\"./workspace-resources-store.js\");\n return applyWorkspaceResourceDelete(\n payload.id,\n request.reviewedBy || currentOwnerEmail(),\n requestCtx,\n );\n }\n throw new Error(`Unsupported approval request type: ${request.changeType}`);\n}\n\nexport async function approveRequest(requestId: string) {\n const db = getDb();\n const ctx = requireDispatchCtx();\n const request = await getApprovalRequest(requestId, ctx);\n if (!request) throw new Error(\"Approval request not found\");\n\n const timestamp = now();\n const staleApplyingBefore = timestamp - APPROVAL_APPLY_LEASE_MS;\n // Fence the transition on the current status so a concurrent approve can't\n // both win. A crashed worker can leave its lease in \"applying\", so reclaim\n // only a lease that has been idle for the full lease interval.\n const claimed = await db\n .update(schema.dispatchApprovalRequests)\n .set({\n status: \"applying\",\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.dispatchApprovalRequests.id, requestId),\n ctxScope(schema.dispatchApprovalRequests, ctx),\n or(\n eq(schema.dispatchApprovalRequests.status, \"pending\"),\n and(\n eq(schema.dispatchApprovalRequests.status, \"applying\"),\n sql`${schema.dispatchApprovalRequests.updatedAt} < ${staleApplyingBefore}`,\n ),\n ),\n ),\n )\n .returning();\n\n if (claimed.length === 0) {\n const current = (await getApprovalRequest(requestId, ctx)) ?? request;\n if (current.status === \"applying\") {\n throw new Error(\"Approval is already being applied\");\n }\n return current;\n }\n\n const applying = claimed[0];\n try {\n await applyApprovedRequest(applying);\n } catch (error) {\n // Applying a request can have succeeded partially before throwing. Do not\n // return it to pending: that would allow an immediate retry to duplicate a\n // non-idempotent effect. Keep the lease until it becomes stale, which\n // serializes any recovery attempt behind the same fencing rule.\n await db\n .update(schema.dispatchApprovalRequests)\n .set({ updatedAt: now() })\n .where(\n and(\n eq(schema.dispatchApprovalRequests.id, requestId),\n ctxScope(schema.dispatchApprovalRequests, ctx),\n eq(schema.dispatchApprovalRequests.status, \"applying\"),\n ),\n );\n throw error;\n }\n const [updated] = await db\n .update(schema.dispatchApprovalRequests)\n .set({\n status: \"approved\",\n reviewedBy: currentOwnerEmail(),\n reviewedAt: timestamp,\n updatedAt: now(),\n })\n .where(\n and(\n eq(schema.dispatchApprovalRequests.id, requestId),\n ctxScope(schema.dispatchApprovalRequests, ctx),\n eq(schema.dispatchApprovalRequests.status, \"applying\"),\n ),\n )\n .returning();\n if (!updated) throw new Error(\"Approval request disappeared\");\n await recordAudit({\n action: \"approval.approved\",\n targetType: updated.targetType,\n targetId: requestId,\n summary: `Approved ${updated.summary}`,\n metadata: updated,\n });\n return updated;\n}\n\nexport async function rejectRequest(requestId: string, reason?: string | null) {\n const db = getDb();\n const ctx = requireDispatchCtx();\n const request = await getApprovalRequest(requestId, ctx);\n if (!request) throw new Error(\"Approval request not found\");\n\n const timestamp = now();\n const claimed = await db\n .update(schema.dispatchApprovalRequests)\n .set({\n status: \"rejected\",\n reviewedBy: currentOwnerEmail(),\n reviewedAt: timestamp,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.dispatchApprovalRequests.id, requestId),\n ctxScope(schema.dispatchApprovalRequests, ctx),\n eq(schema.dispatchApprovalRequests.status, \"pending\"),\n ),\n )\n .returning();\n\n if (claimed.length === 0) {\n return (await getApprovalRequest(requestId, ctx)) ?? request;\n }\n\n const updated = claimed[0];\n await recordAudit({\n action: \"approval.rejected\",\n targetType: updated.targetType,\n targetId: requestId,\n summary: `Rejected ${updated.summary}`,\n metadata: { request: updated, reason: reason || null },\n });\n return updated;\n}\n\nexport async function createLinkToken(platform: string) {\n const db = getDb();\n const timestamp = now();\n // 16 bytes = 128 bits of entropy. Previous size was 4 bytes (32 bits,\n // ~4.29 billion keyspace) which is brute-forceable in well under an\n // hour given a 7-day expiry and no rate limiting on /link attempts.\n // Old 8-hex-char tokens minted before this change continue to verify\n // until they expire; we don't migrate retroactively. See\n // /tmp/security-audit/07-webhooks.md (H5).\n const token = crypto.randomBytes(16).toString(\"hex\");\n const recordId = id();\n const owner = currentOwnerEmail();\n await db.insert(schema.dispatchLinkTokens).values({\n id: recordId,\n token,\n ownerEmail: owner,\n orgId: currentOrgId(),\n platform,\n createdBy: owner,\n expiresAt: timestamp + 7 * 24 * 60 * 60 * 1000,\n claimedAt: null,\n claimedByExternalUserId: null,\n claimedByExternalUserName: null,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n await recordAudit({\n action: \"identity.link-token-created\",\n targetType: \"link-token\",\n targetId: recordId,\n summary: `Created ${platform} link token for ${owner}`,\n metadata: { token, platform },\n });\n return {\n token,\n command: `/link ${token}`,\n platform,\n expiresAt: timestamp + 7 * 24 * 60 * 60 * 1000,\n };\n}\n\nexport async function listIdentityState() {\n const db = getDb();\n const owner = currentOwnerEmail();\n const orgId = currentOrgId();\n const filters = and(\n eq(schema.dispatchIdentityLinks.ownerEmail, owner),\n orgId\n ? eq(schema.dispatchIdentityLinks.orgId, orgId)\n : isNull(schema.dispatchIdentityLinks.orgId),\n );\n const tokenFilters = and(\n eq(schema.dispatchLinkTokens.ownerEmail, owner),\n orgId\n ? eq(schema.dispatchLinkTokens.orgId, orgId)\n : isNull(schema.dispatchLinkTokens.orgId),\n );\n const [links, tokens] = await Promise.all([\n db\n .select()\n .from(schema.dispatchIdentityLinks)\n .where(filters)\n .orderBy(desc(schema.dispatchIdentityLinks.updatedAt)),\n db\n .select()\n .from(schema.dispatchLinkTokens)\n .where(tokenFilters)\n .orderBy(desc(schema.dispatchLinkTokens.updatedAt)),\n ]);\n return { links, tokens };\n}\n\nexport async function resolveLinkedOwner(\n platform: string,\n externalUserId?: string | null,\n options: {\n orgId?: string | null;\n allowAnyOrgFallback?: boolean;\n } = {},\n) {\n if (!externalUserId) return null;\n const db = getDb();\n const orgId = options.orgId !== undefined ? options.orgId : currentOrgId();\n const rows = await db\n .select()\n .from(schema.dispatchIdentityLinks)\n .where(\n and(\n eq(schema.dispatchIdentityLinks.platform, platform),\n eq(schema.dispatchIdentityLinks.externalUserId, externalUserId),\n orgId\n ? eq(schema.dispatchIdentityLinks.orgId, orgId)\n : isNull(schema.dispatchIdentityLinks.orgId),\n ),\n )\n .orderBy(desc(schema.dispatchIdentityLinks.updatedAt))\n .limit(1);\n if (rows[0]?.ownerEmail) return rows[0].ownerEmail;\n\n if (!options.allowAnyOrgFallback || orgId) return null;\n\n // Webhook processors run outside a normal request/org context. A linked\n // Slack/Telegram identity may still be scoped to an org, so fall back to any\n // org only when every matching link resolves to the same owner.\n const fallbackRows = await db\n .select()\n .from(schema.dispatchIdentityLinks)\n .where(\n and(\n eq(schema.dispatchIdentityLinks.platform, platform),\n eq(schema.dispatchIdentityLinks.externalUserId, externalUserId),\n ),\n )\n .orderBy(desc(schema.dispatchIdentityLinks.updatedAt))\n .limit(25);\n const owners = new Set(fallbackRows.map((row) => row.ownerEmail));\n return owners.size === 1 ? fallbackRows[0]?.ownerEmail || null : null;\n}\n\nexport async function consumeLinkToken(input: {\n platform: string;\n token: string;\n externalUserId?: string | null;\n externalUserName?: string | null;\n expectedOrgId?: string;\n}) {\n if (!input.externalUserId) {\n throw new Error(\"Linking requires a platform user id\");\n }\n\n // Rate-limit failed attempts per (platform, externalUserId). Once\n // tripped, all further attempts are short-circuited until the block\n // window passes — including the lookup, so an attacker can't probe\n // for valid tokens during the block.\n const blockState = isLinkAttemptBlocked(input.platform, input.externalUserId);\n if (blockState.blocked) {\n throw new LinkRateLimitError(blockState.retryAfterMs);\n }\n\n const db = getDb();\n const tokenRows = await db\n .select()\n .from(schema.dispatchLinkTokens)\n .where(\n and(\n eq(schema.dispatchLinkTokens.platform, input.platform),\n eq(schema.dispatchLinkTokens.token, input.token),\n ),\n )\n .orderBy(desc(schema.dispatchLinkTokens.createdAt))\n .limit(2);\n if (tokenRows.length > 1) {\n recordLinkFailure(input.platform, input.externalUserId);\n throw new Error(\"Link token is ambiguous. Create a fresh token and retry.\");\n }\n const tokenRow = tokenRows[0];\n if (!tokenRow) {\n recordLinkFailure(input.platform, input.externalUserId);\n throw new Error(\"Link token not found\");\n }\n if (tokenRow.claimedAt) {\n recordLinkFailure(input.platform, input.externalUserId);\n throw new Error(\"Link token has already been claimed\");\n }\n if (tokenRow.expiresAt < now()) {\n recordLinkFailure(input.platform, input.externalUserId);\n throw new Error(\"Link token has expired\");\n }\n if (input.expectedOrgId && tokenRow.orgId !== input.expectedOrgId) {\n recordLinkFailure(input.platform, input.externalUserId);\n throw new Error(\n \"This link token belongs to a different organization. Create a token from this workspace and try again.\",\n );\n }\n\n const timestamp = now();\n const [existing] = await db\n .select()\n .from(schema.dispatchIdentityLinks)\n .where(\n and(\n eq(schema.dispatchIdentityLinks.platform, input.platform),\n eq(schema.dispatchIdentityLinks.externalUserId, input.externalUserId),\n tokenRow.orgId\n ? eq(schema.dispatchIdentityLinks.orgId, tokenRow.orgId)\n : isNull(schema.dispatchIdentityLinks.orgId),\n ),\n )\n .limit(1);\n\n if (existing) {\n await db\n .update(schema.dispatchIdentityLinks)\n .set({\n ownerEmail: tokenRow.ownerEmail,\n orgId: tokenRow.orgId,\n externalUserName: input.externalUserName || null,\n linkedBy: tokenRow.createdBy,\n updatedAt: timestamp,\n })\n .where(eq(schema.dispatchIdentityLinks.id, existing.id));\n } else {\n await db.insert(schema.dispatchIdentityLinks).values({\n id: id(),\n ownerEmail: tokenRow.ownerEmail,\n orgId: tokenRow.orgId,\n platform: input.platform,\n externalUserId: input.externalUserId,\n externalUserName: input.externalUserName || null,\n linkedBy: tokenRow.createdBy,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n }\n\n await db\n .update(schema.dispatchLinkTokens)\n .set({\n claimedAt: timestamp,\n claimedByExternalUserId: input.externalUserId,\n claimedByExternalUserName: input.externalUserName || null,\n updatedAt: timestamp,\n })\n .where(eq(schema.dispatchLinkTokens.id, tokenRow.id));\n\n // Successful claim — reset the rate-limit budget so subsequent\n // links from this external user start fresh.\n clearLinkFailures(input.platform, input.externalUserId);\n\n await recordAudit({\n actor: tokenRow.createdBy,\n ownerEmail: tokenRow.ownerEmail,\n orgId: tokenRow.orgId,\n action: \"identity.linked\",\n targetType: \"identity-link\",\n targetId: input.externalUserId,\n summary: `Linked ${input.platform} user ${input.externalUserName || input.externalUserId}`,\n metadata: input,\n });\n\n return tokenRow.ownerEmail;\n}\n\nexport async function listOverview() {\n const [destinations, approvals, identities, audit, settings] =\n await Promise.all([\n listDestinations(),\n listApprovalRequests(),\n listIdentityState(),\n listAuditEvents(12),\n getApprovalPolicy(),\n ]);\n\n return {\n counts: {\n destinations: destinations.length,\n pendingApprovals: approvals.filter((item) => item.status === \"pending\")\n .length,\n linkedIdentities: identities.links.length,\n activeTokens: identities.tokens.filter(\n (item) => !item.claimedAt && item.expiresAt > now(),\n ).length,\n },\n recentDestinations: destinations.slice(0, 5),\n recentApprovals: approvals.slice(0, 5),\n recentAudit: audit.slice(0, 8),\n settings,\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { type Task } from "@agent-native/core/a2a";
1
+ import { type A2APersistedMutationReceipt, type Task } from "@agent-native/core/a2a";
2
2
  import { type DispatchMcpAppAccessSettings } from "./mcp-access-store.js";
3
3
  export interface DispatchMcpAccessibleApp {
4
4
  id: string;
@@ -10,6 +10,7 @@ export interface DispatchMcpAccessibleApp {
10
10
  color: string;
11
11
  granted: boolean;
12
12
  }
13
+ type DispatchMutationReceipt = A2APersistedMutationReceipt;
13
14
  type DispatchAskAppStatusErrorCategory = "transport" | "timeout" | "upstream_5xx" | "rate_limited";
14
15
  type DispatchAskAppTaskResult = {
15
16
  app: string;
@@ -17,6 +18,7 @@ type DispatchAskAppTaskResult = {
17
18
  taskId: string;
18
19
  status: string;
19
20
  response?: string;
21
+ receipts?: DispatchMutationReceipt[];
20
22
  error?: string;
21
23
  inputRequired?: string;
22
24
  statusRead?: "unavailable";
@@ -33,7 +35,11 @@ type DispatchAskAppTaskResult = {
33
35
  };
34
36
  message?: string;
35
37
  };
36
- declare function dispatchAskAppTaskResult(app: string, task: Task): DispatchAskAppTaskResult;
38
+ declare function dispatchAskAppTaskResult(app: string, task: Task, identity: {
39
+ userEmail: string;
40
+ orgId: string | null;
41
+ orgSecret: string | null;
42
+ }): DispatchAskAppTaskResult;
37
43
  export declare function listDispatchMcpApps(): Promise<{
38
44
  settings: DispatchMcpAppAccessSettings;
39
45
  apps: DispatchMcpAccessibleApp[];
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-gateway.d.ts","sourceRoot":"","sources":["../../../src/server/lib/mcp-gateway.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-gateway.d.ts","sourceRoot":"","sources":["../../../src/server/lib/mcp-gateway.ts"],"names":[],"mappings":"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"}