@agent-native/core 0.44.4 → 0.45.1

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 (165) hide show
  1. package/dist/action.d.ts +8 -1
  2. package/dist/action.d.ts.map +1 -1
  3. package/dist/action.js +20 -10
  4. package/dist/action.js.map +1 -1
  5. package/dist/cli/app-skill.d.ts +3 -1
  6. package/dist/cli/app-skill.d.ts.map +1 -1
  7. package/dist/cli/app-skill.js +50 -8
  8. package/dist/cli/app-skill.js.map +1 -1
  9. package/dist/cli/connect.d.ts +2 -1
  10. package/dist/cli/connect.d.ts.map +1 -1
  11. package/dist/cli/connect.js +224 -10
  12. package/dist/cli/connect.js.map +1 -1
  13. package/dist/cli/create.d.ts.map +1 -1
  14. package/dist/cli/create.js +9 -7
  15. package/dist/cli/create.js.map +1 -1
  16. package/dist/cli/index.js +69 -10
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/cli/mcp-config-writers.d.ts +10 -0
  19. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  20. package/dist/cli/mcp-config-writers.js +60 -6
  21. package/dist/cli/mcp-config-writers.js.map +1 -1
  22. package/dist/cli/mcp.d.ts.map +1 -1
  23. package/dist/cli/mcp.js +4 -6
  24. package/dist/cli/mcp.js.map +1 -1
  25. package/dist/cli/plan-local.d.ts +43 -0
  26. package/dist/cli/plan-local.d.ts.map +1 -0
  27. package/dist/cli/plan-local.js +490 -0
  28. package/dist/cli/plan-local.js.map +1 -0
  29. package/dist/cli/plan-publish-store.d.ts +17 -7
  30. package/dist/cli/plan-publish-store.d.ts.map +1 -1
  31. package/dist/cli/plan-publish-store.js +33 -8
  32. package/dist/cli/plan-publish-store.js.map +1 -1
  33. package/dist/cli/pr-visual-recap-workflow.d.ts +1 -1
  34. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
  35. package/dist/cli/pr-visual-recap-workflow.js +1 -1
  36. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  37. package/dist/cli/recap.d.ts +225 -3
  38. package/dist/cli/recap.d.ts.map +1 -1
  39. package/dist/cli/recap.js +1267 -27
  40. package/dist/cli/recap.js.map +1 -1
  41. package/dist/cli/skills.d.ts +26 -11
  42. package/dist/cli/skills.d.ts.map +1 -1
  43. package/dist/cli/skills.js +810 -1365
  44. package/dist/cli/skills.js.map +1 -1
  45. package/dist/cli/templates-meta.d.ts.map +1 -1
  46. package/dist/cli/templates-meta.js +3 -2
  47. package/dist/cli/templates-meta.js.map +1 -1
  48. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  49. package/dist/client/blocks/library/AnnotatedCodeBlock.js +41 -10
  50. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  51. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
  52. package/dist/client/blocks/library/DiffBlock.js +54 -23
  53. package/dist/client/blocks/library/DiffBlock.js.map +1 -1
  54. package/dist/client/blocks/library/annotation-rail.d.ts +27 -8
  55. package/dist/client/blocks/library/annotation-rail.d.ts.map +1 -1
  56. package/dist/client/blocks/library/annotation-rail.js +64 -27
  57. package/dist/client/blocks/library/annotation-rail.js.map +1 -1
  58. package/dist/client/blocks/library/code-filename-label.d.ts +8 -0
  59. package/dist/client/blocks/library/code-filename-label.d.ts.map +1 -0
  60. package/dist/client/blocks/library/code-filename-label.js +15 -0
  61. package/dist/client/blocks/library/code-filename-label.js.map +1 -0
  62. package/dist/client/blocks/library/code.d.ts.map +1 -1
  63. package/dist/client/blocks/library/code.js +3 -2
  64. package/dist/client/blocks/library/code.js.map +1 -1
  65. package/dist/client/blocks/library/diff.config.d.ts +1 -1
  66. package/dist/client/blocks/library/diff.config.js.map +1 -1
  67. package/dist/client/blocks/library/html.d.ts.map +1 -1
  68. package/dist/client/blocks/library/html.js +3 -1
  69. package/dist/client/blocks/library/html.js.map +1 -1
  70. package/dist/client/blocks/library/narrow-container.d.ts +4 -4
  71. package/dist/client/blocks/library/narrow-container.d.ts.map +1 -1
  72. package/dist/client/blocks/library/narrow-container.js +10 -10
  73. package/dist/client/blocks/library/narrow-container.js.map +1 -1
  74. package/dist/client/blocks/library/question-form.d.ts.map +1 -1
  75. package/dist/client/blocks/library/question-form.js +4 -1
  76. package/dist/client/blocks/library/question-form.js.map +1 -1
  77. package/dist/client/blocks/library/tabs.d.ts.map +1 -1
  78. package/dist/client/blocks/library/tabs.js +7 -2
  79. package/dist/client/blocks/library/tabs.js.map +1 -1
  80. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  81. package/dist/client/composer/TiptapComposer.js +4 -1
  82. package/dist/client/composer/TiptapComposer.js.map +1 -1
  83. package/dist/client/db-admin/TableEditor.d.ts.map +1 -1
  84. package/dist/client/db-admin/TableEditor.js +3 -1
  85. package/dist/client/db-admin/TableEditor.js.map +1 -1
  86. package/dist/db/client.d.ts +8 -0
  87. package/dist/db/client.d.ts.map +1 -1
  88. package/dist/db/client.js +23 -2
  89. package/dist/db/client.js.map +1 -1
  90. package/dist/db/migrations.d.ts.map +1 -1
  91. package/dist/db/migrations.js +2 -1
  92. package/dist/db/migrations.js.map +1 -1
  93. package/dist/deploy/build.d.ts.map +1 -1
  94. package/dist/deploy/build.js +8 -0
  95. package/dist/deploy/build.js.map +1 -1
  96. package/dist/extensions/html-shell.js +1 -1
  97. package/dist/extensions/html-shell.js.map +1 -1
  98. package/dist/extensions/routes.d.ts +18 -0
  99. package/dist/extensions/routes.d.ts.map +1 -1
  100. package/dist/extensions/routes.js +30 -8
  101. package/dist/extensions/routes.js.map +1 -1
  102. package/dist/jobs/scheduler.d.ts.map +1 -1
  103. package/dist/jobs/scheduler.js +5 -1
  104. package/dist/jobs/scheduler.js.map +1 -1
  105. package/dist/mcp/build-server.d.ts +1 -0
  106. package/dist/mcp/build-server.d.ts.map +1 -1
  107. package/dist/mcp/build-server.js +7 -3
  108. package/dist/mcp/build-server.js.map +1 -1
  109. package/dist/mcp/oauth-route.d.ts.map +1 -1
  110. package/dist/mcp/oauth-route.js +56 -19
  111. package/dist/mcp/oauth-route.js.map +1 -1
  112. package/dist/mcp/oauth-store.d.ts +1 -0
  113. package/dist/mcp/oauth-store.d.ts.map +1 -1
  114. package/dist/mcp/oauth-store.js +9 -0
  115. package/dist/mcp/oauth-store.js.map +1 -1
  116. package/dist/mcp/server.d.ts.map +1 -1
  117. package/dist/mcp/server.js +9 -4
  118. package/dist/mcp/server.js.map +1 -1
  119. package/dist/mcp-client/errors.js +3 -3
  120. package/dist/mcp-client/errors.js.map +1 -1
  121. package/dist/oauth-tokens/store.d.ts.map +1 -1
  122. package/dist/oauth-tokens/store.js +42 -5
  123. package/dist/oauth-tokens/store.js.map +1 -1
  124. package/dist/scripts/db/index.d.ts.map +1 -1
  125. package/dist/scripts/db/index.js +1 -0
  126. package/dist/scripts/db/index.js.map +1 -1
  127. package/dist/scripts/db/migrate-encrypt-oauth-tokens.d.ts +28 -0
  128. package/dist/scripts/db/migrate-encrypt-oauth-tokens.d.ts.map +1 -0
  129. package/dist/scripts/db/migrate-encrypt-oauth-tokens.js +164 -0
  130. package/dist/scripts/db/migrate-encrypt-oauth-tokens.js.map +1 -0
  131. package/dist/scripts/db/scoping.d.ts.map +1 -1
  132. package/dist/scripts/db/scoping.js +7 -5
  133. package/dist/scripts/db/scoping.js.map +1 -1
  134. package/dist/secrets/index.d.ts +1 -0
  135. package/dist/secrets/index.d.ts.map +1 -1
  136. package/dist/secrets/index.js +4 -0
  137. package/dist/secrets/index.js.map +1 -1
  138. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  139. package/dist/server/agent-chat-plugin.js +3 -1
  140. package/dist/server/agent-chat-plugin.js.map +1 -1
  141. package/dist/server/agent-teams.d.ts.map +1 -1
  142. package/dist/server/agent-teams.js +10 -2
  143. package/dist/server/agent-teams.js.map +1 -1
  144. package/dist/server/auth.d.ts.map +1 -1
  145. package/dist/server/auth.js +7 -3
  146. package/dist/server/auth.js.map +1 -1
  147. package/dist/server/recap-image-route.d.ts.map +1 -1
  148. package/dist/server/recap-image-route.js +3 -6
  149. package/dist/server/recap-image-route.js.map +1 -1
  150. package/dist/server/sentry.d.ts.map +1 -1
  151. package/dist/server/sentry.js +12 -5
  152. package/dist/server/sentry.js.map +1 -1
  153. package/dist/server/social-og-image.d.ts.map +1 -1
  154. package/dist/server/social-og-image.js +3 -1
  155. package/dist/server/social-og-image.js.map +1 -1
  156. package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
  157. package/dist/sharing/actions/set-resource-visibility.js +4 -1
  158. package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
  159. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +22 -6
  160. package/docs/content/plan-plugin.md +39 -7
  161. package/docs/content/pr-visual-recap.md +89 -13
  162. package/docs/content/skills-guide.md +13 -0
  163. package/docs/content/template-plan.md +62 -7
  164. package/package.json +5 -1
  165. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +22 -6
@@ -13,7 +13,7 @@ import { readBody } from "../server/h3-helpers.js";
13
13
  import { getConfiguredLoginHtml, getSession } from "../server/auth.js";
14
14
  import { getAuthSecret } from "../server/better-auth-instance.js";
15
15
  import { getOrgDomain } from "../org/context.js";
16
- import { createOAuthCode, createOAuthRefreshToken, consumeOAuthCode, generateOpaqueToken, getOAuthClient, getOAuthCode, getOAuthRefreshToken, registerOAuthClient, rotateOAuthRefreshToken, } from "./oauth-store.js";
16
+ import { createOAuthCode, createOAuthRefreshToken, consumeOAuthCode, generateOpaqueToken, getOAuthClient, getOAuthCode, getOAuthRefreshToken, registerOAuthClient, touchOAuthRefreshToken, } from "./oauth-store.js";
17
17
  import { MCP_OAUTH_DEFAULT_SCOPE, MCP_OAUTH_SCOPES, normalizeOAuthScope, signMcpOAuthAccessToken, } from "./oauth-token.js";
18
18
  function json(body, status = 200) {
19
19
  return new Response(JSON.stringify(body), {
@@ -74,6 +74,49 @@ function normalizeBasePath(raw) {
74
74
  function configuredBasePath() {
75
75
  return normalizeBasePath(process.env.APP_BASE_PATH || process.env.VITE_APP_BASE_PATH);
76
76
  }
77
+ function stripTrailingSlash(value) {
78
+ return value.replace(/\/+$/, "");
79
+ }
80
+ function configuredPublicBaseUrl() {
81
+ for (const key of [
82
+ "WORKSPACE_OAUTH_ORIGIN",
83
+ "VITE_WORKSPACE_OAUTH_ORIGIN",
84
+ "APP_URL",
85
+ "VITE_APP_URL",
86
+ "BETTER_AUTH_URL",
87
+ "VITE_BETTER_AUTH_URL",
88
+ ]) {
89
+ const raw = process.env[key]?.trim();
90
+ if (!raw)
91
+ continue;
92
+ try {
93
+ const url = new URL(raw);
94
+ url.search = "";
95
+ url.hash = "";
96
+ return stripTrailingSlash(`${url.origin}${url.pathname}`);
97
+ }
98
+ catch {
99
+ // Ignore invalid operator-provided URL values and fall back to headers.
100
+ }
101
+ }
102
+ return undefined;
103
+ }
104
+ function appendConfiguredBasePath(baseUrl) {
105
+ const basePath = configuredBasePath();
106
+ if (!basePath)
107
+ return stripTrailingSlash(baseUrl);
108
+ try {
109
+ const url = new URL(baseUrl);
110
+ const pathname = normalizeBasePath(url.pathname);
111
+ if (pathname === basePath || pathname.endsWith(`${basePath}`)) {
112
+ return stripTrailingSlash(`${url.origin}${pathname}`);
113
+ }
114
+ return stripTrailingSlash(`${url.origin}${pathname}${basePath}`);
115
+ }
116
+ catch {
117
+ return `${stripTrailingSlash(baseUrl)}${basePath}`;
118
+ }
119
+ }
77
120
  function deriveOrigin(event) {
78
121
  const forwardedProto = getHeader(event, "x-forwarded-proto");
79
122
  const host = getHeader(event, "x-forwarded-host") || getHeader(event, "host");
@@ -84,10 +127,10 @@ function deriveOrigin(event) {
84
127
  return host ? `${proto}://${host}` : "";
85
128
  }
86
129
  export function getMcpOAuthIssuer(event) {
87
- const origin = deriveOrigin(event);
88
- if (!origin)
130
+ const baseUrl = configuredPublicBaseUrl() || deriveOrigin(event);
131
+ if (!baseUrl)
89
132
  return undefined;
90
- return `${origin}${configuredBasePath()}`;
133
+ return appendConfiguredBasePath(baseUrl);
91
134
  }
92
135
  export function getMcpOAuthResource(event) {
93
136
  const issuer = getMcpOAuthIssuer(event);
@@ -559,31 +602,25 @@ async function handleRefreshTokenGrant(event, body) {
559
602
  if (existing.clientId !== clientId) {
560
603
  return oauthError("invalid_grant", "Refresh token belongs to another client");
561
604
  }
562
- const nextRefreshToken = generateOpaqueToken();
563
- const row = await rotateOAuthRefreshToken({
564
- oldRefreshToken: refreshToken,
565
- newRefreshToken: nextRefreshToken,
566
- });
567
- if (!row)
568
- return oauthError("invalid_grant", "Invalid refresh token");
605
+ await touchOAuthRefreshToken(refreshToken).catch(() => undefined);
569
606
  const issuer = getMcpOAuthIssuer(event);
570
607
  if (!issuer)
571
608
  return oauthError("server_error", "Unable to derive issuer", 500);
572
609
  const accessToken = await signMcpOAuthAccessToken({
573
- ownerEmail: row.ownerEmail,
574
- orgId: row.orgId,
575
- orgDomain: row.orgDomain,
576
- clientId: row.clientId,
577
- scope: row.scope,
578
- resource: row.resource,
610
+ ownerEmail: existing.ownerEmail,
611
+ orgId: existing.orgId,
612
+ orgDomain: existing.orgDomain,
613
+ clientId: existing.clientId,
614
+ scope: existing.scope,
615
+ resource: existing.resource,
579
616
  issuer,
580
617
  });
581
618
  return json({
582
619
  access_token: accessToken,
583
620
  token_type: "Bearer",
584
621
  expires_in: 3600,
585
- refresh_token: nextRefreshToken,
586
- scope: row.scope,
622
+ refresh_token: refreshToken,
623
+ scope: existing.scope,
587
624
  });
588
625
  }
589
626
  async function handleToken(event) {
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-route.js","sourceRoot":"","sources":["../../src/mcp/oauth-route.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Standard remote MCP OAuth 2.1 endpoints.\n *\n * These routes let MCP hosts such as Claude Code and ChatGPT authenticate\n * through their native remote-MCP OAuth flow instead of pasting bearer tokens.\n * The issued access tokens are audience-bound to `/_agent-native/mcp`, carry\n * the same user/org identity as the existing connect flow, and are mediated by\n * `verifyAuth` before any MCP tool/resource request runs.\n */\n\nimport type { H3Event } from \"h3\";\nimport { getHeader, getMethod, getQuery, setResponseStatus } from \"h3\";\nimport { createHash, createHmac, timingSafeEqual } from \"node:crypto\";\nimport { readBody } from \"../server/h3-helpers.js\";\nimport { getConfiguredLoginHtml, getSession } from \"../server/auth.js\";\nimport { getAuthSecret } from \"../server/better-auth-instance.js\";\nimport { getOrgDomain } from \"../org/context.js\";\nimport {\n createOAuthCode,\n createOAuthRefreshToken,\n consumeOAuthCode,\n generateOpaqueToken,\n getOAuthClient,\n getOAuthCode,\n getOAuthRefreshToken,\n registerOAuthClient,\n rotateOAuthRefreshToken,\n} from \"./oauth-store.js\";\nimport {\n MCP_OAUTH_DEFAULT_SCOPE,\n MCP_OAUTH_SCOPES,\n normalizeOAuthScope,\n signMcpOAuthAccessToken,\n} from \"./oauth-token.js\";\n\nexport interface McpOAuthRouteOptions {\n appId?: string;\n appName?: string;\n}\n\nfunction json(body: unknown, status = 200): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": \"no-store\",\n Pragma: \"no-cache\",\n },\n });\n}\n\nfunction html(body: string, status = 200): Response {\n return new Response(body, {\n status,\n headers: {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n },\n });\n}\n\nfunction redirect(location: string): Response {\n return new Response(null, {\n status: 302,\n headers: { Location: location, \"Cache-Control\": \"no-store\" },\n });\n}\n\nfunction isSameOriginPost(event: H3Event): boolean {\n const origin = getHeader(event, \"origin\");\n if (!origin) return true;\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer) return false;\n try {\n return new URL(origin).origin === new URL(issuer).origin;\n } catch {\n return false;\n }\n}\n\nfunction oauthError(\n error: string,\n description: string,\n status = 400,\n): Response {\n return json({ error, error_description: description }, status);\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nfunction normalizeBasePath(raw: string | undefined): string {\n const trimmed = (raw ?? \"\").trim();\n if (!trimmed || trimmed === \"/\") return \"\";\n const withSlash = trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n return withSlash.replace(/\\/+$/, \"\");\n}\n\nfunction configuredBasePath(): string {\n return normalizeBasePath(\n process.env.APP_BASE_PATH || process.env.VITE_APP_BASE_PATH,\n );\n}\n\nfunction deriveOrigin(event: H3Event): string {\n const forwardedProto = getHeader(event, \"x-forwarded-proto\");\n const host = getHeader(event, \"x-forwarded-host\") || getHeader(event, \"host\");\n const proto =\n forwardedProto?.split(\",\")[0]?.trim() ||\n (host && /^(localhost|127\\.0\\.0\\.1|\\[::1\\])(:|$)/.test(host)\n ? \"http\"\n : \"https\");\n return host ? `${proto}://${host}` : \"\";\n}\n\nexport function getMcpOAuthIssuer(event: H3Event): string | undefined {\n const origin = deriveOrigin(event);\n if (!origin) return undefined;\n return `${origin}${configuredBasePath()}`;\n}\n\nexport function getMcpOAuthResource(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer) return undefined;\n return `${issuer}/_agent-native/mcp`;\n}\n\nexport function getMcpOAuthProtectedResourceMetadataUrl(\n event: H3Event,\n): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer) return undefined;\n return `${issuer}/.well-known/oauth-protected-resource`;\n}\n\nexport function buildMcpOAuthChallenge(event: H3Event): string {\n const metadata = getMcpOAuthProtectedResourceMetadataUrl(event);\n const scope = MCP_OAUTH_DEFAULT_SCOPE;\n return metadata\n ? `Bearer resource_metadata=\"${metadata}\", scope=\"${scope}\"`\n : `Bearer scope=\"${scope}\"`;\n}\n\nfunction authorizationEndpoint(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n return issuer ? `${issuer}/_agent-native/mcp/oauth/authorize` : undefined;\n}\n\nfunction tokenEndpoint(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n return issuer ? `${issuer}/_agent-native/mcp/oauth/token` : undefined;\n}\n\nfunction registrationEndpoint(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n return issuer ? `${issuer}/_agent-native/mcp/oauth/register` : undefined;\n}\n\nexport function handleMcpOAuthProtectedResourceMetadata(\n event: H3Event,\n): Response {\n if (getMethod(event) !== \"GET\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const resource = getMcpOAuthResource(event);\n const issuer = getMcpOAuthIssuer(event);\n if (!resource || !issuer) {\n return oauthError(\"server_error\", \"Unable to derive MCP resource\", 500);\n }\n return json({\n resource,\n authorization_servers: [issuer],\n scopes_supported: MCP_OAUTH_SCOPES,\n resource_documentation: issuer,\n });\n}\n\nexport function handleMcpOAuthAuthorizationServerMetadata(\n event: H3Event,\n): Response {\n if (getMethod(event) !== \"GET\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const issuer = getMcpOAuthIssuer(event);\n const authorize = authorizationEndpoint(event);\n const token = tokenEndpoint(event);\n const register = registrationEndpoint(event);\n if (!issuer || !authorize || !token || !register) {\n return oauthError(\"server_error\", \"Unable to derive OAuth endpoints\", 500);\n }\n return json({\n issuer,\n authorization_endpoint: authorize,\n token_endpoint: token,\n registration_endpoint: register,\n response_types_supported: [\"code\"],\n grant_types_supported: [\"authorization_code\", \"refresh_token\"],\n code_challenge_methods_supported: [\"S256\"],\n token_endpoint_auth_methods_supported: [\"none\"],\n scopes_supported: MCP_OAUTH_SCOPES,\n });\n}\n\nfunction isAllowedRedirectUri(value: unknown): value is string {\n if (typeof value !== \"string\" || value.length > 2048) return false;\n try {\n const url = new URL(value);\n if (url.hash) return false;\n if (url.username || url.password) return false;\n if (url.protocol === \"https:\") return true;\n if (url.protocol !== \"http:\") return false;\n return (\n url.hostname === \"localhost\" ||\n url.hostname === \"127.0.0.1\" ||\n url.hostname === \"::1\" ||\n url.hostname === \"[::1]\"\n );\n } catch {\n return false;\n }\n}\n\nfunction parseStringArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === \"string\")\n : [];\n}\n\nasync function handleRegister(event: H3Event): Promise<Response> {\n if (getMethod(event) !== \"POST\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const body = ((await readBody(event).catch(() => ({}))) ?? {}) as Record<\n string,\n unknown\n >;\n const redirectUris = parseStringArray(body.redirect_uris);\n if (\n redirectUris.length === 0 ||\n redirectUris.length > 20 ||\n !redirectUris.every(isAllowedRedirectUri)\n ) {\n return oauthError(\n \"invalid_client_metadata\",\n \"redirect_uris must contain valid HTTPS or localhost callback URLs\",\n );\n }\n\n const grantTypes = parseStringArray(body.grant_types);\n if (\n grantTypes.length &&\n !grantTypes.every(\n (g) => g === \"authorization_code\" || g === \"refresh_token\",\n )\n ) {\n return oauthError(\"invalid_client_metadata\", \"Unsupported grant_type\");\n }\n const responseTypes = parseStringArray(body.response_types);\n if (responseTypes.length && !responseTypes.every((r) => r === \"code\")) {\n return oauthError(\"invalid_client_metadata\", \"Unsupported response_type\");\n }\n const method =\n typeof body.token_endpoint_auth_method === \"string\"\n ? body.token_endpoint_auth_method\n : \"none\";\n if (method !== \"none\") {\n return oauthError(\n \"invalid_client_metadata\",\n \"Only public OAuth clients are supported\",\n );\n }\n\n const clientName =\n typeof body.client_name === \"string\"\n ? body.client_name.trim().slice(0, 120)\n : null;\n let client;\n try {\n client = await registerOAuthClient({\n clientName,\n redirectUris: [...new Set(redirectUris)],\n grantTypes: grantTypes.length ? grantTypes : undefined,\n responseTypes: responseTypes.length ? responseTypes : undefined,\n tokenEndpointAuthMethod: method,\n });\n } catch (err: any) {\n if (err?.message === \"RATE_LIMITED\") {\n return oauthError(\"slow_down\", \"Too many client registrations\", 429);\n }\n throw err;\n }\n return json(\n {\n client_id: client.clientId,\n client_id_issued_at: Math.floor((client.createdAt ?? Date.now()) / 1000),\n client_name: client.clientName ?? undefined,\n redirect_uris: client.redirectUris,\n grant_types: client.grantTypes,\n response_types: client.responseTypes,\n token_endpoint_auth_method: client.tokenEndpointAuthMethod,\n },\n 201,\n );\n}\n\nfunction redirectWithOAuthError(params: {\n redirectUri: string;\n state?: string;\n error: string;\n description?: string;\n}): Response {\n const url = new URL(params.redirectUri);\n url.searchParams.set(\"error\", params.error);\n if (params.description) {\n url.searchParams.set(\"error_description\", params.description);\n }\n if (params.state) url.searchParams.set(\"state\", params.state);\n return redirect(url.toString());\n}\n\nfunction redirectWithCode(params: {\n redirectUri: string;\n code: string;\n state?: string;\n}): Response {\n const url = new URL(params.redirectUri);\n url.searchParams.set(\"code\", params.code);\n if (params.state) url.searchParams.set(\"state\", params.state);\n return redirect(url.toString());\n}\n\nfunction codeChallengeForVerifier(verifier: string): string {\n return createHash(\"sha256\").update(verifier).digest(\"base64url\");\n}\n\nfunction safeEqual(a: string, b: string): boolean {\n const aa = Buffer.from(a);\n const bb = Buffer.from(b);\n return aa.length === bb.length && timingSafeEqual(aa, bb);\n}\n\nfunction base64UrlEncode(value: Buffer | string): string {\n const buf = typeof value === \"string\" ? Buffer.from(value, \"utf8\") : value;\n return buf.toString(\"base64url\");\n}\n\nfunction base64UrlDecode(value: string): Buffer {\n return Buffer.from(value, \"base64url\");\n}\n\nfunction consentSigningKey(): string {\n return process.env.A2A_SECRET?.trim() || getAuthSecret();\n}\n\nfunction consentPayload(params: {\n email: string;\n clientId: string;\n redirectUri: string;\n resource: string;\n scope: string;\n codeChallenge: string;\n}): string {\n return JSON.stringify({\n ...params,\n exp: Math.floor(Date.now() / 1000) + 10 * 60,\n });\n}\n\nfunction signConsentToken(params: {\n email: string;\n clientId: string;\n redirectUri: string;\n resource: string;\n scope: string;\n codeChallenge: string;\n}): string {\n const payload = base64UrlEncode(consentPayload(params));\n const sig = base64UrlEncode(\n createHmac(\"sha256\", consentSigningKey()).update(payload).digest(),\n );\n return `${payload}.${sig}`;\n}\n\nfunction verifyConsentToken(\n token: string | undefined,\n expected: {\n email: string;\n clientId: string;\n redirectUri: string;\n resource: string;\n scope: string;\n codeChallenge: string;\n },\n): boolean {\n if (!token || !token.includes(\".\")) return false;\n const [payload, sig] = token.split(\".\", 2);\n if (!payload || !sig) return false;\n const expectedSig = base64UrlEncode(\n createHmac(\"sha256\", consentSigningKey()).update(payload).digest(),\n );\n if (!safeEqual(sig, expectedSig)) return false;\n try {\n const parsed = JSON.parse(base64UrlDecode(payload).toString(\"utf8\"));\n return (\n parsed.email === expected.email &&\n parsed.clientId === expected.clientId &&\n parsed.redirectUri === expected.redirectUri &&\n parsed.resource === expected.resource &&\n parsed.scope === expected.scope &&\n parsed.codeChallenge === expected.codeChallenge &&\n typeof parsed.exp === \"number\" &&\n parsed.exp * 1000 >= Date.now()\n );\n } catch {\n return false;\n }\n}\n\nfunction isValidCodeVerifier(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length >= 43 &&\n value.length <= 128 &&\n /^[A-Za-z0-9._~-]+$/.test(value)\n );\n}\n\nfunction renderConsentPage(params: {\n appName: string;\n email: string;\n clientName: string;\n scopes: string[];\n fields: Record<string, string>;\n}): string {\n const hidden = Object.entries(params.fields)\n .map(\n ([key, value]) =>\n `<input type=\"hidden\" name=\"${escapeHtml(key)}\" value=\"${escapeHtml(value)}\">`,\n )\n .join(\"\\n\");\n const scopes = params.scopes\n .map((scope) => `<li><code>${escapeHtml(scope)}</code></li>`)\n .join(\"\");\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Authorize ${escapeHtml(params.appName)}</title>\n<style>\n :root { color-scheme: dark; font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif; background: #09090b; color: #f4f4f5; }\n body { min-height: 100vh; display: grid; place-items: center; margin: 0; padding: 24px; }\n main { width: min(520px, 100%); border: 1px solid #27272a; border-radius: 8px; background: #111113; padding: 24px; box-shadow: 0 24px 80px rgba(0,0,0,.35); }\n h1 { font-size: 22px; line-height: 1.2; margin: 0 0 10px; }\n p { color: #a1a1aa; line-height: 1.5; margin: 0 0 18px; }\n ul { margin: 0 0 22px; padding-left: 22px; color: #d4d4d8; }\n code { color: #67e8f9; }\n .actions { display: flex; gap: 10px; justify-content: flex-end; }\n button { border: 0; border-radius: 6px; padding: 10px 14px; font-weight: 650; cursor: pointer; }\n .primary { background: #f4f4f5; color: #09090b; }\n .secondary { background: #27272a; color: #f4f4f5; }\n</style>\n</head>\n<body>\n<main>\n <h1>Authorize ${escapeHtml(params.clientName)}</h1>\n <p>${escapeHtml(params.appName)} will let this MCP client act as ${escapeHtml(params.email)} for these scopes:</p>\n <ul>${scopes}</ul>\n <form method=\"post\">\n ${hidden}\n <div class=\"actions\">\n <button class=\"secondary\" type=\"submit\" name=\"decision\" value=\"deny\">Deny</button>\n <button class=\"primary\" type=\"submit\" name=\"decision\" value=\"approve\">Authorize</button>\n </div>\n </form>\n</main>\n</body>\n</html>`;\n}\n\nasync function resolveOrgDomain(\n orgId: string | undefined,\n): Promise<string | undefined> {\n if (!orgId) return undefined;\n try {\n return (await getOrgDomain(orgId)) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function readOAuthParams(\n event: H3Event,\n): Promise<Record<string, string>> {\n if (getMethod(event) === \"GET\") {\n const query = getQuery(event);\n return Object.fromEntries(\n Object.entries(query).flatMap(([key, value]) =>\n typeof value === \"string\" ? [[key, value]] : [],\n ),\n );\n }\n const body = await readBody(event).catch(() => ({}));\n if (typeof body === \"string\") {\n return Object.fromEntries(new URLSearchParams(body));\n }\n if (body && typeof body === \"object\") {\n return Object.fromEntries(\n Object.entries(body as Record<string, unknown>).flatMap(([key, value]) =>\n typeof value === \"string\" ? [[key, value]] : [],\n ),\n );\n }\n return {};\n}\n\nasync function handleAuthorize(\n event: H3Event,\n options: McpOAuthRouteOptions,\n): Promise<Response> {\n const method = getMethod(event);\n if (method !== \"GET\" && method !== \"POST\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n if (method === \"POST\" && !isSameOriginPost(event)) {\n return oauthError(\n \"invalid_request\",\n \"Cross-origin authorize POST rejected\",\n 403,\n );\n }\n const params = await readOAuthParams(event);\n const state = params.state;\n const clientId = params.client_id;\n const redirectUri = params.redirect_uri;\n const resource = params.resource || getMcpOAuthResource(event);\n const expectedResource = getMcpOAuthResource(event);\n\n if (params.response_type !== \"code\") {\n return oauthError(\n \"unsupported_response_type\",\n \"response_type must be code\",\n );\n }\n if (!clientId || !redirectUri || !resource || resource !== expectedResource) {\n return oauthError(\"invalid_request\", \"Invalid OAuth authorization request\");\n }\n if (params.code_challenge_method !== \"S256\" || !params.code_challenge) {\n return oauthError(\"invalid_request\", \"PKCE S256 is required\");\n }\n\n const client = await getOAuthClient(clientId);\n if (!client || !client.redirectUris.includes(redirectUri)) {\n return oauthError(\"invalid_client\", \"Unknown client or redirect_uri\");\n }\n\n const session = await getSession(event);\n if (!session?.email) {\n if (params.prompt === \"none\") {\n return redirectWithOAuthError({\n redirectUri,\n state,\n error: \"login_required\",\n });\n }\n const loginHtml = getConfiguredLoginHtml(event);\n return loginHtml\n ? html(loginHtml, 200)\n : oauthError(\"login_required\", \"Sign in required\", 401);\n }\n\n const scope = normalizeOAuthScope(params.scope);\n if (!scope) {\n return redirectWithOAuthError({\n redirectUri,\n state,\n error: \"invalid_scope\",\n });\n }\n if (method === \"GET\") {\n return html(\n renderConsentPage({\n appName: options.appName || options.appId || \"Agent Native\",\n email: session.email,\n clientName: client.clientName || client.clientId,\n scopes: scope.split(/\\s+/),\n fields: {\n response_type: \"code\",\n client_id: clientId,\n redirect_uri: redirectUri,\n resource,\n scope,\n state: state ?? \"\",\n code_challenge: params.code_challenge,\n code_challenge_method: \"S256\",\n consent_token: signConsentToken({\n email: session.email,\n clientId,\n redirectUri,\n resource,\n scope,\n codeChallenge: params.code_challenge,\n }),\n },\n }),\n );\n }\n\n if (\n !verifyConsentToken(params.consent_token, {\n email: session.email,\n clientId,\n redirectUri,\n resource,\n scope,\n codeChallenge: params.code_challenge,\n })\n ) {\n return oauthError(\"invalid_request\", \"Invalid authorization consent token\");\n }\n\n if (params.decision !== \"approve\") {\n return redirectWithOAuthError({\n redirectUri,\n state,\n error: \"access_denied\",\n });\n }\n\n const orgDomain = await resolveOrgDomain(session.orgId);\n const code = await createOAuthCode({\n clientId,\n redirectUri,\n codeChallenge: params.code_challenge,\n codeChallengeMethod: \"S256\",\n ownerEmail: session.email,\n orgId: session.orgId ?? null,\n orgDomain: orgDomain ?? null,\n scope,\n resource,\n });\n return redirectWithCode({ redirectUri, state, code: code.code });\n}\n\nasync function issueTokenSet(params: {\n ownerEmail: string;\n orgId?: string | null;\n orgDomain?: string | null;\n clientId: string;\n scope: string;\n resource: string;\n issuer: string;\n}): Promise<Record<string, unknown>> {\n const refreshToken = generateOpaqueToken();\n await createOAuthRefreshToken({\n refreshToken,\n clientId: params.clientId,\n ownerEmail: params.ownerEmail,\n orgId: params.orgId ?? null,\n orgDomain: params.orgDomain ?? null,\n scope: params.scope,\n resource: params.resource,\n });\n const accessToken = await signMcpOAuthAccessToken(params);\n return {\n access_token: accessToken,\n token_type: \"Bearer\",\n expires_in: 3600,\n refresh_token: refreshToken,\n scope: params.scope,\n };\n}\n\nasync function handleAuthorizationCodeGrant(\n event: H3Event,\n body: Record<string, string>,\n): Promise<Response> {\n const code = body.code;\n const clientId = body.client_id;\n const redirectUri = body.redirect_uri;\n const verifier = body.code_verifier;\n if (!code || !clientId || !redirectUri || !isValidCodeVerifier(verifier)) {\n return oauthError(\"invalid_request\", \"Missing authorization-code fields\");\n }\n const row = await getOAuthCode(code);\n if (!row) return oauthError(\"invalid_grant\", \"Invalid or expired code\");\n if (row.clientId !== clientId || row.redirectUri !== redirectUri) {\n return oauthError(\"invalid_grant\", \"Code was issued to another client\");\n }\n const expectedChallenge = codeChallengeForVerifier(verifier);\n if (!safeEqual(expectedChallenge, row.codeChallenge)) {\n return oauthError(\"invalid_grant\", \"PKCE verification failed\");\n }\n const consumed = await consumeOAuthCode(code);\n if (!consumed) return oauthError(\"invalid_grant\", \"Invalid or expired code\");\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer)\n return oauthError(\"server_error\", \"Unable to derive issuer\", 500);\n return json(\n await issueTokenSet({\n ownerEmail: row.ownerEmail,\n orgId: row.orgId,\n orgDomain: row.orgDomain,\n clientId,\n scope: row.scope,\n resource: row.resource,\n issuer,\n }),\n );\n}\n\nasync function handleRefreshTokenGrant(\n event: H3Event,\n body: Record<string, string>,\n): Promise<Response> {\n const refreshToken = body.refresh_token;\n const clientId = body.client_id;\n if (!refreshToken) {\n return oauthError(\"invalid_request\", \"refresh_token is required\");\n }\n if (!clientId) {\n return oauthError(\"invalid_request\", \"client_id is required\");\n }\n const existing = await getOAuthRefreshToken(refreshToken);\n if (!existing) return oauthError(\"invalid_grant\", \"Invalid refresh token\");\n if (existing.clientId !== clientId) {\n return oauthError(\n \"invalid_grant\",\n \"Refresh token belongs to another client\",\n );\n }\n const nextRefreshToken = generateOpaqueToken();\n const row = await rotateOAuthRefreshToken({\n oldRefreshToken: refreshToken,\n newRefreshToken: nextRefreshToken,\n });\n if (!row) return oauthError(\"invalid_grant\", \"Invalid refresh token\");\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer)\n return oauthError(\"server_error\", \"Unable to derive issuer\", 500);\n const accessToken = await signMcpOAuthAccessToken({\n ownerEmail: row.ownerEmail,\n orgId: row.orgId,\n orgDomain: row.orgDomain,\n clientId: row.clientId,\n scope: row.scope,\n resource: row.resource,\n issuer,\n });\n return json({\n access_token: accessToken,\n token_type: \"Bearer\",\n expires_in: 3600,\n refresh_token: nextRefreshToken,\n scope: row.scope,\n });\n}\n\nasync function handleToken(event: H3Event): Promise<Response> {\n if (getMethod(event) !== \"POST\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const body = await readOAuthParams(event);\n switch (body.grant_type) {\n case \"authorization_code\":\n return handleAuthorizationCodeGrant(event, body);\n case \"refresh_token\":\n return handleRefreshTokenGrant(event, body);\n default:\n return oauthError(\"unsupported_grant_type\", \"Unsupported grant_type\");\n }\n}\n\nexport async function handleMcpOAuth(\n event: H3Event,\n subpath: string,\n options: McpOAuthRouteOptions = {},\n): Promise<Response> {\n const path = subpath.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n try {\n if (path === \"authorize\") return await handleAuthorize(event, options);\n if (path === \"token\") return await handleToken(event);\n if (path === \"register\") return await handleRegister(event);\n setResponseStatus(event, 404);\n return json({ error: \"Not found\" }, 404);\n } catch (err: any) {\n return oauthError(\n \"server_error\",\n err?.message || \"OAuth request failed\",\n 500,\n );\n }\n}\n"]}
1
+ {"version":3,"file":"oauth-route.js","sourceRoot":"","sources":["../../src/mcp/oauth-route.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Standard remote MCP OAuth 2.1 endpoints.\n *\n * These routes let MCP hosts such as Claude Code and ChatGPT authenticate\n * through their native remote-MCP OAuth flow instead of pasting bearer tokens.\n * The issued access tokens are audience-bound to `/_agent-native/mcp`, carry\n * the same user/org identity as the existing connect flow, and are mediated by\n * `verifyAuth` before any MCP tool/resource request runs.\n */\n\nimport type { H3Event } from \"h3\";\nimport { getHeader, getMethod, getQuery, setResponseStatus } from \"h3\";\nimport { createHash, createHmac, timingSafeEqual } from \"node:crypto\";\nimport { readBody } from \"../server/h3-helpers.js\";\nimport { getConfiguredLoginHtml, getSession } from \"../server/auth.js\";\nimport { getAuthSecret } from \"../server/better-auth-instance.js\";\nimport { getOrgDomain } from \"../org/context.js\";\nimport {\n createOAuthCode,\n createOAuthRefreshToken,\n consumeOAuthCode,\n generateOpaqueToken,\n getOAuthClient,\n getOAuthCode,\n getOAuthRefreshToken,\n registerOAuthClient,\n touchOAuthRefreshToken,\n} from \"./oauth-store.js\";\nimport {\n MCP_OAUTH_DEFAULT_SCOPE,\n MCP_OAUTH_SCOPES,\n normalizeOAuthScope,\n signMcpOAuthAccessToken,\n} from \"./oauth-token.js\";\n\nexport interface McpOAuthRouteOptions {\n appId?: string;\n appName?: string;\n}\n\nfunction json(body: unknown, status = 200): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": \"no-store\",\n Pragma: \"no-cache\",\n },\n });\n}\n\nfunction html(body: string, status = 200): Response {\n return new Response(body, {\n status,\n headers: {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n },\n });\n}\n\nfunction redirect(location: string): Response {\n return new Response(null, {\n status: 302,\n headers: { Location: location, \"Cache-Control\": \"no-store\" },\n });\n}\n\nfunction isSameOriginPost(event: H3Event): boolean {\n const origin = getHeader(event, \"origin\");\n if (!origin) return true;\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer) return false;\n try {\n return new URL(origin).origin === new URL(issuer).origin;\n } catch {\n return false;\n }\n}\n\nfunction oauthError(\n error: string,\n description: string,\n status = 400,\n): Response {\n return json({ error, error_description: description }, status);\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nfunction normalizeBasePath(raw: string | undefined): string {\n const trimmed = (raw ?? \"\").trim();\n if (!trimmed || trimmed === \"/\") return \"\";\n const withSlash = trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n return withSlash.replace(/\\/+$/, \"\");\n}\n\nfunction configuredBasePath(): string {\n return normalizeBasePath(\n process.env.APP_BASE_PATH || process.env.VITE_APP_BASE_PATH,\n );\n}\n\nfunction stripTrailingSlash(value: string): string {\n return value.replace(/\\/+$/, \"\");\n}\n\nfunction configuredPublicBaseUrl(): string | undefined {\n for (const key of [\n \"WORKSPACE_OAUTH_ORIGIN\",\n \"VITE_WORKSPACE_OAUTH_ORIGIN\",\n \"APP_URL\",\n \"VITE_APP_URL\",\n \"BETTER_AUTH_URL\",\n \"VITE_BETTER_AUTH_URL\",\n ]) {\n const raw = process.env[key]?.trim();\n if (!raw) continue;\n try {\n const url = new URL(raw);\n url.search = \"\";\n url.hash = \"\";\n return stripTrailingSlash(`${url.origin}${url.pathname}`);\n } catch {\n // Ignore invalid operator-provided URL values and fall back to headers.\n }\n }\n return undefined;\n}\n\nfunction appendConfiguredBasePath(baseUrl: string): string {\n const basePath = configuredBasePath();\n if (!basePath) return stripTrailingSlash(baseUrl);\n try {\n const url = new URL(baseUrl);\n const pathname = normalizeBasePath(url.pathname);\n if (pathname === basePath || pathname.endsWith(`${basePath}`)) {\n return stripTrailingSlash(`${url.origin}${pathname}`);\n }\n return stripTrailingSlash(`${url.origin}${pathname}${basePath}`);\n } catch {\n return `${stripTrailingSlash(baseUrl)}${basePath}`;\n }\n}\n\nfunction deriveOrigin(event: H3Event): string {\n const forwardedProto = getHeader(event, \"x-forwarded-proto\");\n const host = getHeader(event, \"x-forwarded-host\") || getHeader(event, \"host\");\n const proto =\n forwardedProto?.split(\",\")[0]?.trim() ||\n (host && /^(localhost|127\\.0\\.0\\.1|\\[::1\\])(:|$)/.test(host)\n ? \"http\"\n : \"https\");\n return host ? `${proto}://${host}` : \"\";\n}\n\nexport function getMcpOAuthIssuer(event: H3Event): string | undefined {\n const baseUrl = configuredPublicBaseUrl() || deriveOrigin(event);\n if (!baseUrl) return undefined;\n return appendConfiguredBasePath(baseUrl);\n}\n\nexport function getMcpOAuthResource(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer) return undefined;\n return `${issuer}/_agent-native/mcp`;\n}\n\nexport function getMcpOAuthProtectedResourceMetadataUrl(\n event: H3Event,\n): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer) return undefined;\n return `${issuer}/.well-known/oauth-protected-resource`;\n}\n\nexport function buildMcpOAuthChallenge(event: H3Event): string {\n const metadata = getMcpOAuthProtectedResourceMetadataUrl(event);\n const scope = MCP_OAUTH_DEFAULT_SCOPE;\n return metadata\n ? `Bearer resource_metadata=\"${metadata}\", scope=\"${scope}\"`\n : `Bearer scope=\"${scope}\"`;\n}\n\nfunction authorizationEndpoint(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n return issuer ? `${issuer}/_agent-native/mcp/oauth/authorize` : undefined;\n}\n\nfunction tokenEndpoint(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n return issuer ? `${issuer}/_agent-native/mcp/oauth/token` : undefined;\n}\n\nfunction registrationEndpoint(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n return issuer ? `${issuer}/_agent-native/mcp/oauth/register` : undefined;\n}\n\nexport function handleMcpOAuthProtectedResourceMetadata(\n event: H3Event,\n): Response {\n if (getMethod(event) !== \"GET\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const resource = getMcpOAuthResource(event);\n const issuer = getMcpOAuthIssuer(event);\n if (!resource || !issuer) {\n return oauthError(\"server_error\", \"Unable to derive MCP resource\", 500);\n }\n return json({\n resource,\n authorization_servers: [issuer],\n scopes_supported: MCP_OAUTH_SCOPES,\n resource_documentation: issuer,\n });\n}\n\nexport function handleMcpOAuthAuthorizationServerMetadata(\n event: H3Event,\n): Response {\n if (getMethod(event) !== \"GET\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const issuer = getMcpOAuthIssuer(event);\n const authorize = authorizationEndpoint(event);\n const token = tokenEndpoint(event);\n const register = registrationEndpoint(event);\n if (!issuer || !authorize || !token || !register) {\n return oauthError(\"server_error\", \"Unable to derive OAuth endpoints\", 500);\n }\n return json({\n issuer,\n authorization_endpoint: authorize,\n token_endpoint: token,\n registration_endpoint: register,\n response_types_supported: [\"code\"],\n grant_types_supported: [\"authorization_code\", \"refresh_token\"],\n code_challenge_methods_supported: [\"S256\"],\n token_endpoint_auth_methods_supported: [\"none\"],\n scopes_supported: MCP_OAUTH_SCOPES,\n });\n}\n\nfunction isAllowedRedirectUri(value: unknown): value is string {\n if (typeof value !== \"string\" || value.length > 2048) return false;\n try {\n const url = new URL(value);\n if (url.hash) return false;\n if (url.username || url.password) return false;\n if (url.protocol === \"https:\") return true;\n if (url.protocol !== \"http:\") return false;\n return (\n url.hostname === \"localhost\" ||\n url.hostname === \"127.0.0.1\" ||\n url.hostname === \"::1\" ||\n url.hostname === \"[::1]\"\n );\n } catch {\n return false;\n }\n}\n\nfunction parseStringArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === \"string\")\n : [];\n}\n\nasync function handleRegister(event: H3Event): Promise<Response> {\n if (getMethod(event) !== \"POST\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const body = ((await readBody(event).catch(() => ({}))) ?? {}) as Record<\n string,\n unknown\n >;\n const redirectUris = parseStringArray(body.redirect_uris);\n if (\n redirectUris.length === 0 ||\n redirectUris.length > 20 ||\n !redirectUris.every(isAllowedRedirectUri)\n ) {\n return oauthError(\n \"invalid_client_metadata\",\n \"redirect_uris must contain valid HTTPS or localhost callback URLs\",\n );\n }\n\n const grantTypes = parseStringArray(body.grant_types);\n if (\n grantTypes.length &&\n !grantTypes.every(\n (g) => g === \"authorization_code\" || g === \"refresh_token\",\n )\n ) {\n return oauthError(\"invalid_client_metadata\", \"Unsupported grant_type\");\n }\n const responseTypes = parseStringArray(body.response_types);\n if (responseTypes.length && !responseTypes.every((r) => r === \"code\")) {\n return oauthError(\"invalid_client_metadata\", \"Unsupported response_type\");\n }\n const method =\n typeof body.token_endpoint_auth_method === \"string\"\n ? body.token_endpoint_auth_method\n : \"none\";\n if (method !== \"none\") {\n return oauthError(\n \"invalid_client_metadata\",\n \"Only public OAuth clients are supported\",\n );\n }\n\n const clientName =\n typeof body.client_name === \"string\"\n ? body.client_name.trim().slice(0, 120)\n : null;\n let client;\n try {\n client = await registerOAuthClient({\n clientName,\n redirectUris: [...new Set(redirectUris)],\n grantTypes: grantTypes.length ? grantTypes : undefined,\n responseTypes: responseTypes.length ? responseTypes : undefined,\n tokenEndpointAuthMethod: method,\n });\n } catch (err: any) {\n if (err?.message === \"RATE_LIMITED\") {\n return oauthError(\"slow_down\", \"Too many client registrations\", 429);\n }\n throw err;\n }\n return json(\n {\n client_id: client.clientId,\n client_id_issued_at: Math.floor((client.createdAt ?? Date.now()) / 1000),\n client_name: client.clientName ?? undefined,\n redirect_uris: client.redirectUris,\n grant_types: client.grantTypes,\n response_types: client.responseTypes,\n token_endpoint_auth_method: client.tokenEndpointAuthMethod,\n },\n 201,\n );\n}\n\nfunction redirectWithOAuthError(params: {\n redirectUri: string;\n state?: string;\n error: string;\n description?: string;\n}): Response {\n const url = new URL(params.redirectUri);\n url.searchParams.set(\"error\", params.error);\n if (params.description) {\n url.searchParams.set(\"error_description\", params.description);\n }\n if (params.state) url.searchParams.set(\"state\", params.state);\n return redirect(url.toString());\n}\n\nfunction redirectWithCode(params: {\n redirectUri: string;\n code: string;\n state?: string;\n}): Response {\n const url = new URL(params.redirectUri);\n url.searchParams.set(\"code\", params.code);\n if (params.state) url.searchParams.set(\"state\", params.state);\n return redirect(url.toString());\n}\n\nfunction codeChallengeForVerifier(verifier: string): string {\n return createHash(\"sha256\").update(verifier).digest(\"base64url\");\n}\n\nfunction safeEqual(a: string, b: string): boolean {\n const aa = Buffer.from(a);\n const bb = Buffer.from(b);\n return aa.length === bb.length && timingSafeEqual(aa, bb);\n}\n\nfunction base64UrlEncode(value: Buffer | string): string {\n const buf = typeof value === \"string\" ? Buffer.from(value, \"utf8\") : value;\n return buf.toString(\"base64url\");\n}\n\nfunction base64UrlDecode(value: string): Buffer {\n return Buffer.from(value, \"base64url\");\n}\n\nfunction consentSigningKey(): string {\n return process.env.A2A_SECRET?.trim() || getAuthSecret();\n}\n\nfunction consentPayload(params: {\n email: string;\n clientId: string;\n redirectUri: string;\n resource: string;\n scope: string;\n codeChallenge: string;\n}): string {\n return JSON.stringify({\n ...params,\n exp: Math.floor(Date.now() / 1000) + 10 * 60,\n });\n}\n\nfunction signConsentToken(params: {\n email: string;\n clientId: string;\n redirectUri: string;\n resource: string;\n scope: string;\n codeChallenge: string;\n}): string {\n const payload = base64UrlEncode(consentPayload(params));\n const sig = base64UrlEncode(\n createHmac(\"sha256\", consentSigningKey()).update(payload).digest(),\n );\n return `${payload}.${sig}`;\n}\n\nfunction verifyConsentToken(\n token: string | undefined,\n expected: {\n email: string;\n clientId: string;\n redirectUri: string;\n resource: string;\n scope: string;\n codeChallenge: string;\n },\n): boolean {\n if (!token || !token.includes(\".\")) return false;\n const [payload, sig] = token.split(\".\", 2);\n if (!payload || !sig) return false;\n const expectedSig = base64UrlEncode(\n createHmac(\"sha256\", consentSigningKey()).update(payload).digest(),\n );\n if (!safeEqual(sig, expectedSig)) return false;\n try {\n const parsed = JSON.parse(base64UrlDecode(payload).toString(\"utf8\"));\n return (\n parsed.email === expected.email &&\n parsed.clientId === expected.clientId &&\n parsed.redirectUri === expected.redirectUri &&\n parsed.resource === expected.resource &&\n parsed.scope === expected.scope &&\n parsed.codeChallenge === expected.codeChallenge &&\n typeof parsed.exp === \"number\" &&\n parsed.exp * 1000 >= Date.now()\n );\n } catch {\n return false;\n }\n}\n\nfunction isValidCodeVerifier(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length >= 43 &&\n value.length <= 128 &&\n /^[A-Za-z0-9._~-]+$/.test(value)\n );\n}\n\nfunction renderConsentPage(params: {\n appName: string;\n email: string;\n clientName: string;\n scopes: string[];\n fields: Record<string, string>;\n}): string {\n const hidden = Object.entries(params.fields)\n .map(\n ([key, value]) =>\n `<input type=\"hidden\" name=\"${escapeHtml(key)}\" value=\"${escapeHtml(value)}\">`,\n )\n .join(\"\\n\");\n const scopes = params.scopes\n .map((scope) => `<li><code>${escapeHtml(scope)}</code></li>`)\n .join(\"\");\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Authorize ${escapeHtml(params.appName)}</title>\n<style>\n :root { color-scheme: dark; font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif; background: #09090b; color: #f4f4f5; }\n body { min-height: 100vh; display: grid; place-items: center; margin: 0; padding: 24px; }\n main { width: min(520px, 100%); border: 1px solid #27272a; border-radius: 8px; background: #111113; padding: 24px; box-shadow: 0 24px 80px rgba(0,0,0,.35); }\n h1 { font-size: 22px; line-height: 1.2; margin: 0 0 10px; }\n p { color: #a1a1aa; line-height: 1.5; margin: 0 0 18px; }\n ul { margin: 0 0 22px; padding-left: 22px; color: #d4d4d8; }\n code { color: #67e8f9; }\n .actions { display: flex; gap: 10px; justify-content: flex-end; }\n button { border: 0; border-radius: 6px; padding: 10px 14px; font-weight: 650; cursor: pointer; }\n .primary { background: #f4f4f5; color: #09090b; }\n .secondary { background: #27272a; color: #f4f4f5; }\n</style>\n</head>\n<body>\n<main>\n <h1>Authorize ${escapeHtml(params.clientName)}</h1>\n <p>${escapeHtml(params.appName)} will let this MCP client act as ${escapeHtml(params.email)} for these scopes:</p>\n <ul>${scopes}</ul>\n <form method=\"post\">\n ${hidden}\n <div class=\"actions\">\n <button class=\"secondary\" type=\"submit\" name=\"decision\" value=\"deny\">Deny</button>\n <button class=\"primary\" type=\"submit\" name=\"decision\" value=\"approve\">Authorize</button>\n </div>\n </form>\n</main>\n</body>\n</html>`;\n}\n\nasync function resolveOrgDomain(\n orgId: string | undefined,\n): Promise<string | undefined> {\n if (!orgId) return undefined;\n try {\n return (await getOrgDomain(orgId)) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function readOAuthParams(\n event: H3Event,\n): Promise<Record<string, string>> {\n if (getMethod(event) === \"GET\") {\n const query = getQuery(event);\n return Object.fromEntries(\n Object.entries(query).flatMap(([key, value]) =>\n typeof value === \"string\" ? [[key, value]] : [],\n ),\n );\n }\n const body = await readBody(event).catch(() => ({}));\n if (typeof body === \"string\") {\n return Object.fromEntries(new URLSearchParams(body));\n }\n if (body && typeof body === \"object\") {\n return Object.fromEntries(\n Object.entries(body as Record<string, unknown>).flatMap(([key, value]) =>\n typeof value === \"string\" ? [[key, value]] : [],\n ),\n );\n }\n return {};\n}\n\nasync function handleAuthorize(\n event: H3Event,\n options: McpOAuthRouteOptions,\n): Promise<Response> {\n const method = getMethod(event);\n if (method !== \"GET\" && method !== \"POST\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n if (method === \"POST\" && !isSameOriginPost(event)) {\n return oauthError(\n \"invalid_request\",\n \"Cross-origin authorize POST rejected\",\n 403,\n );\n }\n const params = await readOAuthParams(event);\n const state = params.state;\n const clientId = params.client_id;\n const redirectUri = params.redirect_uri;\n const resource = params.resource || getMcpOAuthResource(event);\n const expectedResource = getMcpOAuthResource(event);\n\n if (params.response_type !== \"code\") {\n return oauthError(\n \"unsupported_response_type\",\n \"response_type must be code\",\n );\n }\n if (!clientId || !redirectUri || !resource || resource !== expectedResource) {\n return oauthError(\"invalid_request\", \"Invalid OAuth authorization request\");\n }\n if (params.code_challenge_method !== \"S256\" || !params.code_challenge) {\n return oauthError(\"invalid_request\", \"PKCE S256 is required\");\n }\n\n const client = await getOAuthClient(clientId);\n if (!client || !client.redirectUris.includes(redirectUri)) {\n return oauthError(\"invalid_client\", \"Unknown client or redirect_uri\");\n }\n\n const session = await getSession(event);\n if (!session?.email) {\n if (params.prompt === \"none\") {\n return redirectWithOAuthError({\n redirectUri,\n state,\n error: \"login_required\",\n });\n }\n const loginHtml = getConfiguredLoginHtml(event);\n return loginHtml\n ? html(loginHtml, 200)\n : oauthError(\"login_required\", \"Sign in required\", 401);\n }\n\n const scope = normalizeOAuthScope(params.scope);\n if (!scope) {\n return redirectWithOAuthError({\n redirectUri,\n state,\n error: \"invalid_scope\",\n });\n }\n if (method === \"GET\") {\n return html(\n renderConsentPage({\n appName: options.appName || options.appId || \"Agent Native\",\n email: session.email,\n clientName: client.clientName || client.clientId,\n scopes: scope.split(/\\s+/),\n fields: {\n response_type: \"code\",\n client_id: clientId,\n redirect_uri: redirectUri,\n resource,\n scope,\n state: state ?? \"\",\n code_challenge: params.code_challenge,\n code_challenge_method: \"S256\",\n consent_token: signConsentToken({\n email: session.email,\n clientId,\n redirectUri,\n resource,\n scope,\n codeChallenge: params.code_challenge,\n }),\n },\n }),\n );\n }\n\n if (\n !verifyConsentToken(params.consent_token, {\n email: session.email,\n clientId,\n redirectUri,\n resource,\n scope,\n codeChallenge: params.code_challenge,\n })\n ) {\n return oauthError(\"invalid_request\", \"Invalid authorization consent token\");\n }\n\n if (params.decision !== \"approve\") {\n return redirectWithOAuthError({\n redirectUri,\n state,\n error: \"access_denied\",\n });\n }\n\n const orgDomain = await resolveOrgDomain(session.orgId);\n const code = await createOAuthCode({\n clientId,\n redirectUri,\n codeChallenge: params.code_challenge,\n codeChallengeMethod: \"S256\",\n ownerEmail: session.email,\n orgId: session.orgId ?? null,\n orgDomain: orgDomain ?? null,\n scope,\n resource,\n });\n return redirectWithCode({ redirectUri, state, code: code.code });\n}\n\nasync function issueTokenSet(params: {\n ownerEmail: string;\n orgId?: string | null;\n orgDomain?: string | null;\n clientId: string;\n scope: string;\n resource: string;\n issuer: string;\n}): Promise<Record<string, unknown>> {\n const refreshToken = generateOpaqueToken();\n await createOAuthRefreshToken({\n refreshToken,\n clientId: params.clientId,\n ownerEmail: params.ownerEmail,\n orgId: params.orgId ?? null,\n orgDomain: params.orgDomain ?? null,\n scope: params.scope,\n resource: params.resource,\n });\n const accessToken = await signMcpOAuthAccessToken(params);\n return {\n access_token: accessToken,\n token_type: \"Bearer\",\n expires_in: 3600,\n refresh_token: refreshToken,\n scope: params.scope,\n };\n}\n\nasync function handleAuthorizationCodeGrant(\n event: H3Event,\n body: Record<string, string>,\n): Promise<Response> {\n const code = body.code;\n const clientId = body.client_id;\n const redirectUri = body.redirect_uri;\n const verifier = body.code_verifier;\n if (!code || !clientId || !redirectUri || !isValidCodeVerifier(verifier)) {\n return oauthError(\"invalid_request\", \"Missing authorization-code fields\");\n }\n const row = await getOAuthCode(code);\n if (!row) return oauthError(\"invalid_grant\", \"Invalid or expired code\");\n if (row.clientId !== clientId || row.redirectUri !== redirectUri) {\n return oauthError(\"invalid_grant\", \"Code was issued to another client\");\n }\n const expectedChallenge = codeChallengeForVerifier(verifier);\n if (!safeEqual(expectedChallenge, row.codeChallenge)) {\n return oauthError(\"invalid_grant\", \"PKCE verification failed\");\n }\n const consumed = await consumeOAuthCode(code);\n if (!consumed) return oauthError(\"invalid_grant\", \"Invalid or expired code\");\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer)\n return oauthError(\"server_error\", \"Unable to derive issuer\", 500);\n return json(\n await issueTokenSet({\n ownerEmail: row.ownerEmail,\n orgId: row.orgId,\n orgDomain: row.orgDomain,\n clientId,\n scope: row.scope,\n resource: row.resource,\n issuer,\n }),\n );\n}\n\nasync function handleRefreshTokenGrant(\n event: H3Event,\n body: Record<string, string>,\n): Promise<Response> {\n const refreshToken = body.refresh_token;\n const clientId = body.client_id;\n if (!refreshToken) {\n return oauthError(\"invalid_request\", \"refresh_token is required\");\n }\n if (!clientId) {\n return oauthError(\"invalid_request\", \"client_id is required\");\n }\n const existing = await getOAuthRefreshToken(refreshToken);\n if (!existing) return oauthError(\"invalid_grant\", \"Invalid refresh token\");\n if (existing.clientId !== clientId) {\n return oauthError(\n \"invalid_grant\",\n \"Refresh token belongs to another client\",\n );\n }\n await touchOAuthRefreshToken(refreshToken).catch(() => undefined);\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer)\n return oauthError(\"server_error\", \"Unable to derive issuer\", 500);\n const accessToken = await signMcpOAuthAccessToken({\n ownerEmail: existing.ownerEmail,\n orgId: existing.orgId,\n orgDomain: existing.orgDomain,\n clientId: existing.clientId,\n scope: existing.scope,\n resource: existing.resource,\n issuer,\n });\n return json({\n access_token: accessToken,\n token_type: \"Bearer\",\n expires_in: 3600,\n refresh_token: refreshToken,\n scope: existing.scope,\n });\n}\n\nasync function handleToken(event: H3Event): Promise<Response> {\n if (getMethod(event) !== \"POST\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const body = await readOAuthParams(event);\n switch (body.grant_type) {\n case \"authorization_code\":\n return handleAuthorizationCodeGrant(event, body);\n case \"refresh_token\":\n return handleRefreshTokenGrant(event, body);\n default:\n return oauthError(\"unsupported_grant_type\", \"Unsupported grant_type\");\n }\n}\n\nexport async function handleMcpOAuth(\n event: H3Event,\n subpath: string,\n options: McpOAuthRouteOptions = {},\n): Promise<Response> {\n const path = subpath.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n try {\n if (path === \"authorize\") return await handleAuthorize(event, options);\n if (path === \"token\") return await handleToken(event);\n if (path === \"register\") return await handleRegister(event);\n setResponseStatus(event, 404);\n return json({ error: \"Not found\" }, 404);\n } catch (err: any) {\n return oauthError(\n \"server_error\",\n err?.message || \"OAuth request failed\",\n 500,\n );\n }\n}\n"]}
@@ -86,4 +86,5 @@ export declare function rotateOAuthRefreshToken(params: {
86
86
  newRefreshToken: string;
87
87
  }): Promise<OAuthRefreshTokenRow | null>;
88
88
  export declare function getOAuthRefreshToken(refreshToken: string): Promise<OAuthRefreshTokenRow | null>;
89
+ export declare function touchOAuthRefreshToken(refreshToken: string): Promise<void>;
89
90
  //# sourceMappingURL=oauth-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-store.d.ts","sourceRoot":"","sources":["../../src/mcp/oauth-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"oauth-store.d.ts","sourceRoot":"","sources":["../../src/mcp/oauth-store.ts"],"names":[],"mappings":"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"}
@@ -388,4 +388,13 @@ export async function getOAuthRefreshToken(refreshToken) {
388
388
  }
389
389
  return row;
390
390
  }
391
+ export async function touchOAuthRefreshToken(refreshToken) {
392
+ await ensureTable();
393
+ const client = getDbExec();
394
+ const tokenHash = hashOAuthToken(refreshToken);
395
+ await client.execute({
396
+ sql: `UPDATE mcp_oauth_refresh_tokens SET last_used_at = ? WHERE token_hash = ? AND revoked_at IS NULL`,
397
+ args: [Date.now(), tokenHash],
398
+ });
399
+ }
391
400
  //# sourceMappingURL=oauth-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-store.js","sourceRoot":"","sources":["../../src/mcp/oauth-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SQL-backed storage for standard remote MCP OAuth.\n *\n * Additive framework tables only. We store OAuth client registrations,\n * short-lived authorization codes, and hashed refresh tokens. Access tokens\n * are signed JWTs and are never persisted.\n */\n\nimport { getDbExec, isConnectionError, intType } from \"../db/client.js\";\nimport { randomBytes, randomUUID, createHash } from \"node:crypto\";\n\nlet _initPromise: Promise<void> | undefined;\n\nexport const MCP_OAUTH_CODE_TTL_MS = 10 * 60_000;\nexport const MCP_OAUTH_ACCESS_TOKEN_TTL = \"1h\";\nexport const MCP_OAUTH_REFRESH_TOKEN_TTL_MS = 90 * 24 * 60 * 60_000;\nexport const MCP_OAUTH_REGISTER_MAX = 60;\nexport const MCP_OAUTH_REGISTER_WINDOW_MS = 60_000;\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n await client.execute(`\n CREATE TABLE IF NOT EXISTS mcp_oauth_clients (\n client_id TEXT PRIMARY KEY,\n client_name TEXT,\n redirect_uris TEXT NOT NULL,\n grant_types TEXT,\n response_types TEXT,\n token_endpoint_auth_method TEXT,\n created_at ${intType()}\n )\n `);\n await client.execute(`\n CREATE TABLE IF NOT EXISTS mcp_oauth_codes (\n code TEXT PRIMARY KEY,\n client_id TEXT NOT NULL,\n redirect_uri TEXT NOT NULL,\n code_challenge TEXT NOT NULL,\n code_challenge_method TEXT NOT NULL,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n org_domain TEXT,\n scope TEXT NOT NULL,\n resource TEXT NOT NULL,\n created_at ${intType()},\n expires_at ${intType()},\n consumed_at ${intType()}\n )\n `);\n await client.execute(`\n CREATE TABLE IF NOT EXISTS mcp_oauth_refresh_tokens (\n id TEXT PRIMARY KEY,\n token_hash TEXT UNIQUE NOT NULL,\n client_id TEXT NOT NULL,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n org_domain TEXT,\n scope TEXT NOT NULL,\n resource TEXT NOT NULL,\n created_at ${intType()},\n expires_at ${intType()},\n last_used_at ${intType()},\n revoked_at ${intType()},\n replaced_by_hash TEXT\n )\n `);\n })().catch((err) => {\n _initPromise = undefined;\n throw err;\n });\n }\n return _initPromise;\n}\n\nexport interface OAuthClientRow {\n clientId: string;\n clientName: string | null;\n redirectUris: string[];\n grantTypes: string[];\n responseTypes: string[];\n tokenEndpointAuthMethod: string;\n createdAt: number | null;\n}\n\nexport interface OAuthCodeRow {\n code: string;\n clientId: string;\n redirectUri: string;\n codeChallenge: string;\n codeChallengeMethod: string;\n ownerEmail: string;\n orgId: string | null;\n orgDomain: string | null;\n scope: string;\n resource: string;\n createdAt: number | null;\n expiresAt: number | null;\n consumedAt: number | null;\n}\n\nexport interface OAuthRefreshTokenRow {\n id: string;\n tokenHash: string;\n clientId: string;\n ownerEmail: string;\n orgId: string | null;\n orgDomain: string | null;\n scope: string;\n resource: string;\n createdAt: number | null;\n expiresAt: number | null;\n lastUsedAt: number | null;\n revokedAt: number | null;\n replacedByHash: string | null;\n}\n\nexport function generateOpaqueToken(): string {\n return randomBytes(32).toString(\"base64url\");\n}\n\nexport function hashOAuthToken(token: string): string {\n return createHash(\"sha256\").update(token).digest(\"base64url\");\n}\n\nfunction parseJsonStringArray(\n value: unknown,\n fallback: string[] = [],\n): string[] {\n if (typeof value !== \"string\") return fallback;\n try {\n const parsed = JSON.parse(value);\n return Array.isArray(parsed)\n ? parsed.filter((item): item is string => typeof item === \"string\")\n : fallback;\n } catch {\n return fallback;\n }\n}\n\nfunction numOrNull(v: unknown): number | null {\n if (v == null) return null;\n const n = Number(v);\n return Number.isFinite(n) ? n : null;\n}\n\nfunction mapClientRow(row: any): OAuthClientRow {\n return {\n clientId: row.client_id ?? row.clientId,\n clientName: row.client_name ?? row.clientName ?? null,\n redirectUris: parseJsonStringArray(row.redirect_uris ?? row.redirectUris),\n grantTypes: parseJsonStringArray(row.grant_types ?? row.grantTypes, [\n \"authorization_code\",\n \"refresh_token\",\n ]),\n responseTypes: parseJsonStringArray(\n row.response_types ?? row.responseTypes,\n [\"code\"],\n ),\n tokenEndpointAuthMethod:\n row.token_endpoint_auth_method ?? row.tokenEndpointAuthMethod ?? \"none\",\n createdAt: numOrNull(row.created_at ?? row.createdAt),\n };\n}\n\nfunction mapCodeRow(row: any): OAuthCodeRow {\n return {\n code: row.code,\n clientId: row.client_id ?? row.clientId,\n redirectUri: row.redirect_uri ?? row.redirectUri,\n codeChallenge: row.code_challenge ?? row.codeChallenge,\n codeChallengeMethod: row.code_challenge_method ?? row.codeChallengeMethod,\n ownerEmail: row.owner_email ?? row.ownerEmail,\n orgId: row.org_id ?? row.orgId ?? null,\n orgDomain: row.org_domain ?? row.orgDomain ?? null,\n scope: row.scope,\n resource: row.resource,\n createdAt: numOrNull(row.created_at ?? row.createdAt),\n expiresAt: numOrNull(row.expires_at ?? row.expiresAt),\n consumedAt: numOrNull(row.consumed_at ?? row.consumedAt),\n };\n}\n\nfunction mapRefreshRow(row: any): OAuthRefreshTokenRow {\n return {\n id: row.id,\n tokenHash: row.token_hash ?? row.tokenHash,\n clientId: row.client_id ?? row.clientId,\n ownerEmail: row.owner_email ?? row.ownerEmail,\n orgId: row.org_id ?? row.orgId ?? null,\n orgDomain: row.org_domain ?? row.orgDomain ?? null,\n scope: row.scope,\n resource: row.resource,\n createdAt: numOrNull(row.created_at ?? row.createdAt),\n expiresAt: numOrNull(row.expires_at ?? row.expiresAt),\n lastUsedAt: numOrNull(row.last_used_at ?? row.lastUsedAt),\n revokedAt: numOrNull(row.revoked_at ?? row.revokedAt),\n replacedByHash: row.replaced_by_hash ?? row.replacedByHash ?? null,\n };\n}\n\nexport async function registerOAuthClient(params: {\n clientName?: string | null;\n redirectUris: string[];\n grantTypes?: string[];\n responseTypes?: string[];\n tokenEndpointAuthMethod?: string;\n}): Promise<OAuthClientRow> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n try {\n const { rows } = await client.execute({\n sql: `SELECT COUNT(*) AS n FROM mcp_oauth_clients WHERE created_at > ?`,\n args: [now - MCP_OAUTH_REGISTER_WINDOW_MS],\n });\n const n = Number(rows[0]?.n ?? rows[0]?.[\"COUNT(*)\"] ?? 0);\n if (Number.isFinite(n) && n >= MCP_OAUTH_REGISTER_MAX) {\n throw new Error(\"RATE_LIMITED\");\n }\n } catch (err: any) {\n if (err?.message === \"RATE_LIMITED\") throw err;\n // Registration stays possible through transient count-read failures; the\n // exact redirect URI allowlist remains the primary safety gate.\n }\n const clientId = `agent-native-oauth-client-${randomUUID()}`;\n const grantTypes = params.grantTypes?.length\n ? params.grantTypes\n : [\"authorization_code\", \"refresh_token\"];\n const responseTypes = params.responseTypes?.length\n ? params.responseTypes\n : [\"code\"];\n const tokenEndpointAuthMethod = params.tokenEndpointAuthMethod || \"none\";\n await client.execute({\n sql: `INSERT INTO mcp_oauth_clients (client_id, client_name, redirect_uris, grant_types, response_types, token_endpoint_auth_method, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)`,\n args: [\n clientId,\n params.clientName ?? null,\n JSON.stringify(params.redirectUris),\n JSON.stringify(grantTypes),\n JSON.stringify(responseTypes),\n tokenEndpointAuthMethod,\n now,\n ],\n });\n return {\n clientId,\n clientName: params.clientName ?? null,\n redirectUris: params.redirectUris,\n grantTypes,\n responseTypes,\n tokenEndpointAuthMethod,\n createdAt: now,\n };\n}\n\nexport async function getOAuthClient(\n clientId: string,\n): Promise<OAuthClientRow | null> {\n try {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM mcp_oauth_clients WHERE client_id = ?`,\n args: [clientId],\n });\n return rows.length ? mapClientRow(rows[0]) : null;\n } catch (err) {\n if (isConnectionError(err)) return null;\n throw err;\n }\n}\n\nexport async function createOAuthCode(params: {\n clientId: string;\n redirectUri: string;\n codeChallenge: string;\n codeChallengeMethod: string;\n ownerEmail: string;\n orgId?: string | null;\n orgDomain?: string | null;\n scope: string;\n resource: string;\n}): Promise<OAuthCodeRow> {\n await ensureTable();\n const client = getDbExec();\n const code = generateOpaqueToken();\n const now = Date.now();\n const expiresAt = now + MCP_OAUTH_CODE_TTL_MS;\n await client.execute({\n sql: `INSERT INTO mcp_oauth_codes (code, client_id, redirect_uri, code_challenge, code_challenge_method, owner_email, org_id, org_domain, scope, resource, created_at, expires_at, consumed_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n code,\n params.clientId,\n params.redirectUri,\n params.codeChallenge,\n params.codeChallengeMethod,\n params.ownerEmail,\n params.orgId ?? null,\n params.orgDomain ?? null,\n params.scope,\n params.resource,\n now,\n expiresAt,\n null,\n ],\n });\n return {\n code,\n clientId: params.clientId,\n redirectUri: params.redirectUri,\n codeChallenge: params.codeChallenge,\n codeChallengeMethod: params.codeChallengeMethod,\n ownerEmail: params.ownerEmail,\n orgId: params.orgId ?? null,\n orgDomain: params.orgDomain ?? null,\n scope: params.scope,\n resource: params.resource,\n createdAt: now,\n expiresAt,\n consumedAt: null,\n };\n}\n\nexport async function getOAuthCode(code: string): Promise<OAuthCodeRow | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM mcp_oauth_codes WHERE code = ?`,\n args: [code],\n });\n if (rows.length === 0) return null;\n const row = mapCodeRow(rows[0]);\n if (row.consumedAt != null || (row.expiresAt ?? 0) < Date.now()) {\n return null;\n }\n return row;\n}\n\nexport async function consumeOAuthCode(\n code: string,\n): Promise<OAuthCodeRow | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM mcp_oauth_codes WHERE code = ?`,\n args: [code],\n });\n if (rows.length === 0) return null;\n const row = mapCodeRow(rows[0]);\n if (row.consumedAt != null || (row.expiresAt ?? 0) < Date.now()) {\n return null;\n }\n const result = await client.execute({\n sql: `UPDATE mcp_oauth_codes SET consumed_at = ? WHERE code = ? AND consumed_at IS NULL`,\n args: [Date.now(), code],\n });\n return result.rowsAffected > 0 ? row : null;\n}\n\nexport async function createOAuthRefreshToken(params: {\n refreshToken: string;\n clientId: string;\n ownerEmail: string;\n orgId?: string | null;\n orgDomain?: string | null;\n scope: string;\n resource: string;\n}): Promise<OAuthRefreshTokenRow> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const row: OAuthRefreshTokenRow = {\n id: randomUUID(),\n tokenHash: hashOAuthToken(params.refreshToken),\n clientId: params.clientId,\n ownerEmail: params.ownerEmail,\n orgId: params.orgId ?? null,\n orgDomain: params.orgDomain ?? null,\n scope: params.scope,\n resource: params.resource,\n createdAt: now,\n expiresAt: now + MCP_OAUTH_REFRESH_TOKEN_TTL_MS,\n lastUsedAt: null,\n revokedAt: null,\n replacedByHash: null,\n };\n await client.execute({\n sql: `INSERT INTO mcp_oauth_refresh_tokens (id, token_hash, client_id, owner_email, org_id, org_domain, scope, resource, created_at, expires_at, last_used_at, revoked_at, replaced_by_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n row.id,\n row.tokenHash,\n row.clientId,\n row.ownerEmail,\n row.orgId,\n row.orgDomain,\n row.scope,\n row.resource,\n row.createdAt,\n row.expiresAt,\n row.lastUsedAt,\n row.revokedAt,\n row.replacedByHash,\n ],\n });\n return row;\n}\n\nexport async function rotateOAuthRefreshToken(params: {\n oldRefreshToken: string;\n newRefreshToken: string;\n}): Promise<OAuthRefreshTokenRow | null> {\n await ensureTable();\n const client = getDbExec();\n const oldHash = hashOAuthToken(params.oldRefreshToken);\n const newHash = hashOAuthToken(params.newRefreshToken);\n const { rows } = await client.execute({\n sql: `SELECT * FROM mcp_oauth_refresh_tokens WHERE token_hash = ?`,\n args: [oldHash],\n });\n if (rows.length === 0) return null;\n const old = mapRefreshRow(rows[0]);\n if (old.revokedAt != null || (old.expiresAt ?? 0) < Date.now()) return null;\n\n const now = Date.now();\n const update = await client.execute({\n sql: `UPDATE mcp_oauth_refresh_tokens SET revoked_at = ?, last_used_at = ?, replaced_by_hash = ? WHERE token_hash = ? AND revoked_at IS NULL`,\n args: [now, now, newHash, oldHash],\n });\n if (update.rowsAffected === 0) return null;\n\n const next: OAuthRefreshTokenRow = {\n ...old,\n id: randomUUID(),\n tokenHash: newHash,\n createdAt: now,\n expiresAt: now + MCP_OAUTH_REFRESH_TOKEN_TTL_MS,\n lastUsedAt: null,\n revokedAt: null,\n replacedByHash: null,\n };\n await client.execute({\n sql: `INSERT INTO mcp_oauth_refresh_tokens (id, token_hash, client_id, owner_email, org_id, org_domain, scope, resource, created_at, expires_at, last_used_at, revoked_at, replaced_by_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n next.id,\n next.tokenHash,\n next.clientId,\n next.ownerEmail,\n next.orgId,\n next.orgDomain,\n next.scope,\n next.resource,\n next.createdAt,\n next.expiresAt,\n next.lastUsedAt,\n next.revokedAt,\n next.replacedByHash,\n ],\n });\n return next;\n}\n\nexport async function getOAuthRefreshToken(\n refreshToken: string,\n): Promise<OAuthRefreshTokenRow | null> {\n await ensureTable();\n const client = getDbExec();\n const tokenHash = hashOAuthToken(refreshToken);\n const { rows } = await client.execute({\n sql: `SELECT * FROM mcp_oauth_refresh_tokens WHERE token_hash = ?`,\n args: [tokenHash],\n });\n if (rows.length === 0) return null;\n const row = mapRefreshRow(rows[0]);\n if (row.revokedAt != null || (row.expiresAt ?? 0) < Date.now()) {\n return null;\n }\n return row;\n}\n"]}
1
+ {"version":3,"file":"oauth-store.js","sourceRoot":"","sources":["../../src/mcp/oauth-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SQL-backed storage for standard remote MCP OAuth.\n *\n * Additive framework tables only. We store OAuth client registrations,\n * short-lived authorization codes, and hashed refresh tokens. Access tokens\n * are signed JWTs and are never persisted.\n */\n\nimport { getDbExec, isConnectionError, intType } from \"../db/client.js\";\nimport { randomBytes, randomUUID, createHash } from \"node:crypto\";\n\nlet _initPromise: Promise<void> | undefined;\n\nexport const MCP_OAUTH_CODE_TTL_MS = 10 * 60_000;\nexport const MCP_OAUTH_ACCESS_TOKEN_TTL = \"1h\";\nexport const MCP_OAUTH_REFRESH_TOKEN_TTL_MS = 90 * 24 * 60 * 60_000;\nexport const MCP_OAUTH_REGISTER_MAX = 60;\nexport const MCP_OAUTH_REGISTER_WINDOW_MS = 60_000;\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n await client.execute(`\n CREATE TABLE IF NOT EXISTS mcp_oauth_clients (\n client_id TEXT PRIMARY KEY,\n client_name TEXT,\n redirect_uris TEXT NOT NULL,\n grant_types TEXT,\n response_types TEXT,\n token_endpoint_auth_method TEXT,\n created_at ${intType()}\n )\n `);\n await client.execute(`\n CREATE TABLE IF NOT EXISTS mcp_oauth_codes (\n code TEXT PRIMARY KEY,\n client_id TEXT NOT NULL,\n redirect_uri TEXT NOT NULL,\n code_challenge TEXT NOT NULL,\n code_challenge_method TEXT NOT NULL,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n org_domain TEXT,\n scope TEXT NOT NULL,\n resource TEXT NOT NULL,\n created_at ${intType()},\n expires_at ${intType()},\n consumed_at ${intType()}\n )\n `);\n await client.execute(`\n CREATE TABLE IF NOT EXISTS mcp_oauth_refresh_tokens (\n id TEXT PRIMARY KEY,\n token_hash TEXT UNIQUE NOT NULL,\n client_id TEXT NOT NULL,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n org_domain TEXT,\n scope TEXT NOT NULL,\n resource TEXT NOT NULL,\n created_at ${intType()},\n expires_at ${intType()},\n last_used_at ${intType()},\n revoked_at ${intType()},\n replaced_by_hash TEXT\n )\n `);\n })().catch((err) => {\n _initPromise = undefined;\n throw err;\n });\n }\n return _initPromise;\n}\n\nexport interface OAuthClientRow {\n clientId: string;\n clientName: string | null;\n redirectUris: string[];\n grantTypes: string[];\n responseTypes: string[];\n tokenEndpointAuthMethod: string;\n createdAt: number | null;\n}\n\nexport interface OAuthCodeRow {\n code: string;\n clientId: string;\n redirectUri: string;\n codeChallenge: string;\n codeChallengeMethod: string;\n ownerEmail: string;\n orgId: string | null;\n orgDomain: string | null;\n scope: string;\n resource: string;\n createdAt: number | null;\n expiresAt: number | null;\n consumedAt: number | null;\n}\n\nexport interface OAuthRefreshTokenRow {\n id: string;\n tokenHash: string;\n clientId: string;\n ownerEmail: string;\n orgId: string | null;\n orgDomain: string | null;\n scope: string;\n resource: string;\n createdAt: number | null;\n expiresAt: number | null;\n lastUsedAt: number | null;\n revokedAt: number | null;\n replacedByHash: string | null;\n}\n\nexport function generateOpaqueToken(): string {\n return randomBytes(32).toString(\"base64url\");\n}\n\nexport function hashOAuthToken(token: string): string {\n return createHash(\"sha256\").update(token).digest(\"base64url\");\n}\n\nfunction parseJsonStringArray(\n value: unknown,\n fallback: string[] = [],\n): string[] {\n if (typeof value !== \"string\") return fallback;\n try {\n const parsed = JSON.parse(value);\n return Array.isArray(parsed)\n ? parsed.filter((item): item is string => typeof item === \"string\")\n : fallback;\n } catch {\n return fallback;\n }\n}\n\nfunction numOrNull(v: unknown): number | null {\n if (v == null) return null;\n const n = Number(v);\n return Number.isFinite(n) ? n : null;\n}\n\nfunction mapClientRow(row: any): OAuthClientRow {\n return {\n clientId: row.client_id ?? row.clientId,\n clientName: row.client_name ?? row.clientName ?? null,\n redirectUris: parseJsonStringArray(row.redirect_uris ?? row.redirectUris),\n grantTypes: parseJsonStringArray(row.grant_types ?? row.grantTypes, [\n \"authorization_code\",\n \"refresh_token\",\n ]),\n responseTypes: parseJsonStringArray(\n row.response_types ?? row.responseTypes,\n [\"code\"],\n ),\n tokenEndpointAuthMethod:\n row.token_endpoint_auth_method ?? row.tokenEndpointAuthMethod ?? \"none\",\n createdAt: numOrNull(row.created_at ?? row.createdAt),\n };\n}\n\nfunction mapCodeRow(row: any): OAuthCodeRow {\n return {\n code: row.code,\n clientId: row.client_id ?? row.clientId,\n redirectUri: row.redirect_uri ?? row.redirectUri,\n codeChallenge: row.code_challenge ?? row.codeChallenge,\n codeChallengeMethod: row.code_challenge_method ?? row.codeChallengeMethod,\n ownerEmail: row.owner_email ?? row.ownerEmail,\n orgId: row.org_id ?? row.orgId ?? null,\n orgDomain: row.org_domain ?? row.orgDomain ?? null,\n scope: row.scope,\n resource: row.resource,\n createdAt: numOrNull(row.created_at ?? row.createdAt),\n expiresAt: numOrNull(row.expires_at ?? row.expiresAt),\n consumedAt: numOrNull(row.consumed_at ?? row.consumedAt),\n };\n}\n\nfunction mapRefreshRow(row: any): OAuthRefreshTokenRow {\n return {\n id: row.id,\n tokenHash: row.token_hash ?? row.tokenHash,\n clientId: row.client_id ?? row.clientId,\n ownerEmail: row.owner_email ?? row.ownerEmail,\n orgId: row.org_id ?? row.orgId ?? null,\n orgDomain: row.org_domain ?? row.orgDomain ?? null,\n scope: row.scope,\n resource: row.resource,\n createdAt: numOrNull(row.created_at ?? row.createdAt),\n expiresAt: numOrNull(row.expires_at ?? row.expiresAt),\n lastUsedAt: numOrNull(row.last_used_at ?? row.lastUsedAt),\n revokedAt: numOrNull(row.revoked_at ?? row.revokedAt),\n replacedByHash: row.replaced_by_hash ?? row.replacedByHash ?? null,\n };\n}\n\nexport async function registerOAuthClient(params: {\n clientName?: string | null;\n redirectUris: string[];\n grantTypes?: string[];\n responseTypes?: string[];\n tokenEndpointAuthMethod?: string;\n}): Promise<OAuthClientRow> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n try {\n const { rows } = await client.execute({\n sql: `SELECT COUNT(*) AS n FROM mcp_oauth_clients WHERE created_at > ?`,\n args: [now - MCP_OAUTH_REGISTER_WINDOW_MS],\n });\n const n = Number(rows[0]?.n ?? rows[0]?.[\"COUNT(*)\"] ?? 0);\n if (Number.isFinite(n) && n >= MCP_OAUTH_REGISTER_MAX) {\n throw new Error(\"RATE_LIMITED\");\n }\n } catch (err: any) {\n if (err?.message === \"RATE_LIMITED\") throw err;\n // Registration stays possible through transient count-read failures; the\n // exact redirect URI allowlist remains the primary safety gate.\n }\n const clientId = `agent-native-oauth-client-${randomUUID()}`;\n const grantTypes = params.grantTypes?.length\n ? params.grantTypes\n : [\"authorization_code\", \"refresh_token\"];\n const responseTypes = params.responseTypes?.length\n ? params.responseTypes\n : [\"code\"];\n const tokenEndpointAuthMethod = params.tokenEndpointAuthMethod || \"none\";\n await client.execute({\n sql: `INSERT INTO mcp_oauth_clients (client_id, client_name, redirect_uris, grant_types, response_types, token_endpoint_auth_method, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)`,\n args: [\n clientId,\n params.clientName ?? null,\n JSON.stringify(params.redirectUris),\n JSON.stringify(grantTypes),\n JSON.stringify(responseTypes),\n tokenEndpointAuthMethod,\n now,\n ],\n });\n return {\n clientId,\n clientName: params.clientName ?? null,\n redirectUris: params.redirectUris,\n grantTypes,\n responseTypes,\n tokenEndpointAuthMethod,\n createdAt: now,\n };\n}\n\nexport async function getOAuthClient(\n clientId: string,\n): Promise<OAuthClientRow | null> {\n try {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM mcp_oauth_clients WHERE client_id = ?`,\n args: [clientId],\n });\n return rows.length ? mapClientRow(rows[0]) : null;\n } catch (err) {\n if (isConnectionError(err)) return null;\n throw err;\n }\n}\n\nexport async function createOAuthCode(params: {\n clientId: string;\n redirectUri: string;\n codeChallenge: string;\n codeChallengeMethod: string;\n ownerEmail: string;\n orgId?: string | null;\n orgDomain?: string | null;\n scope: string;\n resource: string;\n}): Promise<OAuthCodeRow> {\n await ensureTable();\n const client = getDbExec();\n const code = generateOpaqueToken();\n const now = Date.now();\n const expiresAt = now + MCP_OAUTH_CODE_TTL_MS;\n await client.execute({\n sql: `INSERT INTO mcp_oauth_codes (code, client_id, redirect_uri, code_challenge, code_challenge_method, owner_email, org_id, org_domain, scope, resource, created_at, expires_at, consumed_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n code,\n params.clientId,\n params.redirectUri,\n params.codeChallenge,\n params.codeChallengeMethod,\n params.ownerEmail,\n params.orgId ?? null,\n params.orgDomain ?? null,\n params.scope,\n params.resource,\n now,\n expiresAt,\n null,\n ],\n });\n return {\n code,\n clientId: params.clientId,\n redirectUri: params.redirectUri,\n codeChallenge: params.codeChallenge,\n codeChallengeMethod: params.codeChallengeMethod,\n ownerEmail: params.ownerEmail,\n orgId: params.orgId ?? null,\n orgDomain: params.orgDomain ?? null,\n scope: params.scope,\n resource: params.resource,\n createdAt: now,\n expiresAt,\n consumedAt: null,\n };\n}\n\nexport async function getOAuthCode(code: string): Promise<OAuthCodeRow | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM mcp_oauth_codes WHERE code = ?`,\n args: [code],\n });\n if (rows.length === 0) return null;\n const row = mapCodeRow(rows[0]);\n if (row.consumedAt != null || (row.expiresAt ?? 0) < Date.now()) {\n return null;\n }\n return row;\n}\n\nexport async function consumeOAuthCode(\n code: string,\n): Promise<OAuthCodeRow | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM mcp_oauth_codes WHERE code = ?`,\n args: [code],\n });\n if (rows.length === 0) return null;\n const row = mapCodeRow(rows[0]);\n if (row.consumedAt != null || (row.expiresAt ?? 0) < Date.now()) {\n return null;\n }\n const result = await client.execute({\n sql: `UPDATE mcp_oauth_codes SET consumed_at = ? WHERE code = ? AND consumed_at IS NULL`,\n args: [Date.now(), code],\n });\n return result.rowsAffected > 0 ? row : null;\n}\n\nexport async function createOAuthRefreshToken(params: {\n refreshToken: string;\n clientId: string;\n ownerEmail: string;\n orgId?: string | null;\n orgDomain?: string | null;\n scope: string;\n resource: string;\n}): Promise<OAuthRefreshTokenRow> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const row: OAuthRefreshTokenRow = {\n id: randomUUID(),\n tokenHash: hashOAuthToken(params.refreshToken),\n clientId: params.clientId,\n ownerEmail: params.ownerEmail,\n orgId: params.orgId ?? null,\n orgDomain: params.orgDomain ?? null,\n scope: params.scope,\n resource: params.resource,\n createdAt: now,\n expiresAt: now + MCP_OAUTH_REFRESH_TOKEN_TTL_MS,\n lastUsedAt: null,\n revokedAt: null,\n replacedByHash: null,\n };\n await client.execute({\n sql: `INSERT INTO mcp_oauth_refresh_tokens (id, token_hash, client_id, owner_email, org_id, org_domain, scope, resource, created_at, expires_at, last_used_at, revoked_at, replaced_by_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n row.id,\n row.tokenHash,\n row.clientId,\n row.ownerEmail,\n row.orgId,\n row.orgDomain,\n row.scope,\n row.resource,\n row.createdAt,\n row.expiresAt,\n row.lastUsedAt,\n row.revokedAt,\n row.replacedByHash,\n ],\n });\n return row;\n}\n\nexport async function rotateOAuthRefreshToken(params: {\n oldRefreshToken: string;\n newRefreshToken: string;\n}): Promise<OAuthRefreshTokenRow | null> {\n await ensureTable();\n const client = getDbExec();\n const oldHash = hashOAuthToken(params.oldRefreshToken);\n const newHash = hashOAuthToken(params.newRefreshToken);\n const { rows } = await client.execute({\n sql: `SELECT * FROM mcp_oauth_refresh_tokens WHERE token_hash = ?`,\n args: [oldHash],\n });\n if (rows.length === 0) return null;\n const old = mapRefreshRow(rows[0]);\n if (old.revokedAt != null || (old.expiresAt ?? 0) < Date.now()) return null;\n\n const now = Date.now();\n const update = await client.execute({\n sql: `UPDATE mcp_oauth_refresh_tokens SET revoked_at = ?, last_used_at = ?, replaced_by_hash = ? WHERE token_hash = ? AND revoked_at IS NULL`,\n args: [now, now, newHash, oldHash],\n });\n if (update.rowsAffected === 0) return null;\n\n const next: OAuthRefreshTokenRow = {\n ...old,\n id: randomUUID(),\n tokenHash: newHash,\n createdAt: now,\n expiresAt: now + MCP_OAUTH_REFRESH_TOKEN_TTL_MS,\n lastUsedAt: null,\n revokedAt: null,\n replacedByHash: null,\n };\n await client.execute({\n sql: `INSERT INTO mcp_oauth_refresh_tokens (id, token_hash, client_id, owner_email, org_id, org_domain, scope, resource, created_at, expires_at, last_used_at, revoked_at, replaced_by_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n next.id,\n next.tokenHash,\n next.clientId,\n next.ownerEmail,\n next.orgId,\n next.orgDomain,\n next.scope,\n next.resource,\n next.createdAt,\n next.expiresAt,\n next.lastUsedAt,\n next.revokedAt,\n next.replacedByHash,\n ],\n });\n return next;\n}\n\nexport async function getOAuthRefreshToken(\n refreshToken: string,\n): Promise<OAuthRefreshTokenRow | null> {\n await ensureTable();\n const client = getDbExec();\n const tokenHash = hashOAuthToken(refreshToken);\n const { rows } = await client.execute({\n sql: `SELECT * FROM mcp_oauth_refresh_tokens WHERE token_hash = ?`,\n args: [tokenHash],\n });\n if (rows.length === 0) return null;\n const row = mapRefreshRow(rows[0]);\n if (row.revokedAt != null || (row.expiresAt ?? 0) < Date.now()) {\n return null;\n }\n return row;\n}\n\nexport async function touchOAuthRefreshToken(\n refreshToken: string,\n): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const tokenHash = hashOAuthToken(refreshToken);\n await client.execute({\n sql: `UPDATE mcp_oauth_refresh_tokens SET last_used_at = ? WHERE token_hash = ? AND revoked_at IS NULL`,\n args: [Date.now(), tokenHash],\n });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAYlC,OAAO,EACL,yBAAyB,EACzB,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAW3B,OAAO,EACL,yBAAyB,EACzB,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,kBAAkB,GACnB,CAAC;AACF,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,cAAc,EAAE,CAAC;AA8L7D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,SAAS,GAChB,OAAO,CACR,QAAQ,GAAG,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAC5E,CA+JA;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,GAAG,EACb,MAAM,EAAE,SAAS,EACjB,WAAW,SAAmB,GAC7B,IAAI,CAYN"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAYlC,OAAO,EACL,yBAAyB,EACzB,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAW3B,OAAO,EACL,yBAAyB,EACzB,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,kBAAkB,GACnB,CAAC;AACF,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,cAAc,EAAE,CAAC;AAoM7D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,SAAS,GAChB,OAAO,CACR,QAAQ,GAAG,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAC5E,CA+JA;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,GAAG,EACb,MAAM,EAAE,SAAS,EACjB,WAAW,SAAmB,GAC7B,IAAI,CAYN"}
@@ -137,14 +137,18 @@ function buildUnauthorizedBody(event) {
137
137
  const issuer = getMcpOAuthIssuer(event);
138
138
  const mcpUrl = getMcpOAuthResource(event);
139
139
  const resourceMetadataUrl = getMcpOAuthProtectedResourceMetadataUrl(event);
140
- const command = issuer ? `agent-native connect ${issuer}` : undefined;
140
+ const command = issuer ? `agent-native reconnect ${issuer}` : undefined;
141
+ const firstTimeCommand = issuer
142
+ ? `agent-native connect ${issuer}`
143
+ : undefined;
141
144
  const authorizeUrl = issuer
142
145
  ? `${issuer}/_agent-native/mcp/oauth/authorize`
143
146
  : undefined;
144
147
  const message = command
145
- ? `Authentication required. Run \`${command}\` to authenticate this MCP ` +
146
- `connector (or, in an OAuth-capable host, re-run /mcp and choose ` +
147
- `Authenticate), then retry.`
148
+ ? `Authentication required. Run \`${command}\` to re-authenticate this ` +
149
+ `MCP connector without reinstalling it (or, in an OAuth-capable host, ` +
150
+ `re-run /mcp and choose Authenticate), then retry. For first-time ` +
151
+ `setup, run \`${firstTimeCommand}\`.`
148
152
  : "Authentication required. Authenticate the MCP connector in your host, " +
149
153
  "then retry.";
150
154
  return {
@@ -152,6 +156,7 @@ function buildUnauthorizedBody(event) {
152
156
  message,
153
157
  authenticate: {
154
158
  ...(command ? { command } : {}),
159
+ ...(firstTimeCommand ? { firstTimeCommand } : {}),
155
160
  ...(authorizeUrl ? { authorizeUrl } : {}),
156
161
  ...(resourceMetadataUrl ? { resourceMetadataUrl } : {}),
157
162
  ...(mcpUrl ? { mcpUrl } : {}),