mcp-trellis 0.2.1 → 1.0.0

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 (131) hide show
  1. package/README.md +41 -561
  2. package/dist/adapters/node.d.ts +14 -5
  3. package/dist/adapters/node.d.ts.map +1 -1
  4. package/dist/adapters/node.js +56 -29
  5. package/dist/adapters/node.js.map +1 -1
  6. package/dist/adapters/origins.d.ts.map +1 -1
  7. package/dist/adapters/origins.js +1 -4
  8. package/dist/adapters/origins.js.map +1 -1
  9. package/dist/app.d.ts +27 -4
  10. package/dist/app.d.ts.map +1 -1
  11. package/dist/app.js +31 -18
  12. package/dist/app.js.map +1 -1
  13. package/dist/auth/bearer.d.ts.map +1 -1
  14. package/dist/auth/bearer.js +6 -1
  15. package/dist/auth/bearer.js.map +1 -1
  16. package/dist/body.d.ts +48 -0
  17. package/dist/body.d.ts.map +1 -0
  18. package/dist/body.js +145 -0
  19. package/dist/body.js.map +1 -0
  20. package/dist/clients.d.ts.map +1 -1
  21. package/dist/clients.js +2 -5
  22. package/dist/clients.js.map +1 -1
  23. package/dist/dispatch.d.ts +1 -1
  24. package/dist/dispatch.d.ts.map +1 -1
  25. package/dist/dispatch.js +58 -18
  26. package/dist/dispatch.js.map +1 -1
  27. package/dist/http.d.ts.map +1 -1
  28. package/dist/http.js.map +1 -1
  29. package/dist/jsonrpc.d.ts +1 -0
  30. package/dist/jsonrpc.d.ts.map +1 -1
  31. package/dist/jsonrpc.js +1 -0
  32. package/dist/jsonrpc.js.map +1 -1
  33. package/dist/methods.d.ts +38 -15
  34. package/dist/methods.d.ts.map +1 -1
  35. package/dist/methods.js +38 -22
  36. package/dist/methods.js.map +1 -1
  37. package/dist/oauth/authorize.d.ts.map +1 -1
  38. package/dist/oauth/authorize.js +100 -68
  39. package/dist/oauth/authorize.js.map +1 -1
  40. package/dist/oauth/base64url.d.ts +1 -1
  41. package/dist/oauth/base64url.d.ts.map +1 -1
  42. package/dist/oauth/base64url.js +1 -4
  43. package/dist/oauth/base64url.js.map +1 -1
  44. package/dist/oauth/clientauth.d.ts +7 -2
  45. package/dist/oauth/clientauth.d.ts.map +1 -1
  46. package/dist/oauth/clientauth.js +59 -16
  47. package/dist/oauth/clientauth.js.map +1 -1
  48. package/dist/oauth/codes.d.ts +4 -4
  49. package/dist/oauth/codes.d.ts.map +1 -1
  50. package/dist/oauth/codes.js +43 -51
  51. package/dist/oauth/codes.js.map +1 -1
  52. package/dist/oauth/consent.d.ts +65 -0
  53. package/dist/oauth/consent.d.ts.map +1 -0
  54. package/dist/oauth/consent.js +173 -0
  55. package/dist/oauth/consent.js.map +1 -0
  56. package/dist/oauth/constants.d.ts +4 -0
  57. package/dist/oauth/constants.d.ts.map +1 -1
  58. package/dist/oauth/constants.js +4 -0
  59. package/dist/oauth/constants.js.map +1 -1
  60. package/dist/oauth/metadata.d.ts +6 -6
  61. package/dist/oauth/metadata.d.ts.map +1 -1
  62. package/dist/oauth/metadata.js.map +1 -1
  63. package/dist/oauth/pkce.d.ts.map +1 -1
  64. package/dist/oauth/pkce.js +1 -1
  65. package/dist/oauth/pkce.js.map +1 -1
  66. package/dist/oauth/redirect.d.ts +6 -1
  67. package/dist/oauth/redirect.d.ts.map +1 -1
  68. package/dist/oauth/redirect.js +23 -10
  69. package/dist/oauth/redirect.js.map +1 -1
  70. package/dist/oauth/reqbody.d.ts +10 -0
  71. package/dist/oauth/reqbody.d.ts.map +1 -0
  72. package/dist/oauth/reqbody.js +29 -0
  73. package/dist/oauth/reqbody.js.map +1 -0
  74. package/dist/oauth/resource.d.ts +30 -0
  75. package/dist/oauth/resource.d.ts.map +1 -1
  76. package/dist/oauth/resource.js +38 -8
  77. package/dist/oauth/resource.js.map +1 -1
  78. package/dist/oauth/revoke.d.ts.map +1 -1
  79. package/dist/oauth/revoke.js +15 -3
  80. package/dist/oauth/revoke.js.map +1 -1
  81. package/dist/oauth/router.d.ts +14 -11
  82. package/dist/oauth/router.d.ts.map +1 -1
  83. package/dist/oauth/router.js +62 -22
  84. package/dist/oauth/router.js.map +1 -1
  85. package/dist/oauth/scope.d.ts +11 -2
  86. package/dist/oauth/scope.d.ts.map +1 -1
  87. package/dist/oauth/scope.js +18 -7
  88. package/dist/oauth/scope.js.map +1 -1
  89. package/dist/oauth/sealed.d.ts +17 -0
  90. package/dist/oauth/sealed.d.ts.map +1 -0
  91. package/dist/oauth/sealed.js +57 -0
  92. package/dist/oauth/sealed.js.map +1 -0
  93. package/dist/oauth/secrethash.d.ts +44 -0
  94. package/dist/oauth/secrethash.d.ts.map +1 -0
  95. package/dist/oauth/secrethash.js +66 -0
  96. package/dist/oauth/secrethash.js.map +1 -0
  97. package/dist/oauth/token.d.ts.map +1 -1
  98. package/dist/oauth/token.js +13 -34
  99. package/dist/oauth/token.js.map +1 -1
  100. package/dist/oauth/types.d.ts +106 -9
  101. package/dist/oauth/types.d.ts.map +1 -1
  102. package/dist/oauth/types.js +67 -4
  103. package/dist/oauth/types.js.map +1 -1
  104. package/dist/oauth/wellknown.d.ts.map +1 -1
  105. package/dist/oauth/wellknown.js +6 -4
  106. package/dist/oauth/wellknown.js.map +1 -1
  107. package/dist/protocol.d.ts +15 -1
  108. package/dist/protocol.d.ts.map +1 -1
  109. package/dist/protocol.js +16 -6
  110. package/dist/protocol.js.map +1 -1
  111. package/dist/registry.d.ts +4 -4
  112. package/dist/registry.d.ts.map +1 -1
  113. package/dist/registry.js +15 -7
  114. package/dist/registry.js.map +1 -1
  115. package/dist/server.d.ts +14 -13
  116. package/dist/server.d.ts.map +1 -1
  117. package/dist/server.js +8 -8
  118. package/dist/server.js.map +1 -1
  119. package/dist/tools.d.ts +11 -2
  120. package/dist/tools.d.ts.map +1 -1
  121. package/dist/tools.js +14 -13
  122. package/dist/tools.js.map +1 -1
  123. package/dist/validate.d.ts +16 -1
  124. package/dist/validate.d.ts.map +1 -1
  125. package/dist/validate.js +46 -8
  126. package/dist/validate.js.map +1 -1
  127. package/docs/ROADMAP.md +295 -0
  128. package/docs/guide.md +417 -0
  129. package/docs/reference.md +178 -0
  130. package/docs/security.md +63 -0
  131. package/package.json +6 -3
package/dist/methods.js CHANGED
@@ -1,7 +1,8 @@
1
- import { JSONRPC_METHOD_NOT_FOUND, JSONRPC_UNAUTHORIZED, rpcError, rpcResult, } from "./jsonrpc.js";
1
+ import { wwwAuthenticateHeader } from "./auth/bearer.js";
2
2
  import { emptyResponse, jsonResponse } from "./http.js";
3
+ import { JSONRPC_METHOD_NOT_FOUND, JSONRPC_UNAUTHORIZED, rpcError, rpcResult, } from "./jsonrpc.js";
3
4
  import { pickProtocolVersion } from "./protocol.js";
4
- import { wwwAuthenticateHeader, } from "./auth/bearer.js";
5
+ const DEFAULT_AUDIT_TIMEOUT_MS = 1000;
5
6
  export const DEFAULT_PUBLIC_METHODS = new Set([
6
7
  "initialize",
7
8
  "ping",
@@ -17,21 +18,38 @@ export const isNotification = (body) => NOTIFICATION_PREDICATES.some((predicate)
17
18
  export const resolveWww = (options, req) => typeof options.wwwAuthenticate === "function"
18
19
  ? options.wwwAuthenticate(req)
19
20
  : options.wwwAuthenticate;
20
- export const unauthorized = (www, message = "Unauthorized") => jsonResponse(rpcError(null, JSONRPC_UNAUTHORIZED, message), 401, {
21
+ /**
22
+ * `id` defaults to `null` for the transport-level call sites in
23
+ * `dispatch.ts` — a body hasn't been parsed yet there, so there's no real
24
+ * id to echo. Call sites past that point (inside `dispatchRpc` and the
25
+ * method handlers) have one and must pass it, or a client correlating
26
+ * responses by id sees `null` on every 401 regardless of what it sent.
27
+ */
28
+ export const unauthorized = (www, message = "Unauthorized", id = null) => jsonResponse(rpcError(id, JSONRPC_UNAUTHORIZED, message), 401, {
21
29
  "WWW-Authenticate": wwwAuthenticateHeader(www),
22
30
  });
23
31
  /**
24
- * Invoke the audit metrics hook, swallowing any failure.
25
- * Telemetry must never turn a served response into a transport error —
26
- * this is the only call path to `ports.audit`.
32
+ * Invoke the audit metrics hook, swallowing any failure and racing it
33
+ * against `auditTimeoutMs` so a hanging sink can't stall the response
34
+ * either — "can't fail a request" was already true; this adds "can't
35
+ * delay one" past a bound. The audit call keeps running in the background
36
+ * if the timer wins; its own `catch` below means it can never surface as
37
+ * an unhandled rejection whenever it does finish.
27
38
  */
28
39
  export const safeAudit = async (options, entry) => {
29
- try {
30
- await options.ports.audit?.(entry);
31
- }
32
- catch {
33
- // Intentionally ignored.
34
- }
40
+ const audit = options.ports.audit;
41
+ if (!audit)
42
+ return;
43
+ const settled = (async () => {
44
+ try {
45
+ await audit(entry);
46
+ }
47
+ catch {
48
+ // Intentionally ignored.
49
+ }
50
+ })();
51
+ const timeoutMs = options.auditTimeoutMs ?? DEFAULT_AUDIT_TIMEOUT_MS;
52
+ await Promise.race([settled, new Promise((resolve) => setTimeout(resolve, timeoutMs))]);
35
53
  };
36
54
  export const hasScope = (principal, scope) => {
37
55
  if (!scope)
@@ -47,13 +65,11 @@ const METHODS = {
47
65
  })),
48
66
  ping: async ({ id }) => jsonResponse(rpcResult(id, {})),
49
67
  "tools/list": async ({ id, options }) => jsonResponse(rpcResult(id, { tools: options.registry.list() })),
50
- "tools/call": async ({ req, body, id, principal, ctx, options }) => {
68
+ "tools/call": async ({ req, body, id, principal, ctx, options, startedAt }) => {
51
69
  const params = body.params ?? {};
52
70
  const name = String(params.name ?? "");
53
71
  const rawArgs = params.arguments;
54
- const args = rawArgs !== null &&
55
- typeof rawArgs === "object" &&
56
- !Array.isArray(rawArgs)
72
+ const args = rawArgs !== null && typeof rawArgs === "object" && !Array.isArray(rawArgs)
57
73
  ? rawArgs
58
74
  : {};
59
75
  const tool = options.registry.get(name);
@@ -64,9 +80,9 @@ const METHODS = {
64
80
  principalId: principal?.id,
65
81
  ok: false,
66
82
  error: "missing_scope",
67
- durationMs: 0,
83
+ durationMs: Date.now() - startedAt,
68
84
  });
69
- return unauthorized(resolveWww(options, req), `Missing scope: ${tool.scope}`);
85
+ return unauthorized(resolveWww(options, req), `Missing scope: ${tool.scope}`, id);
70
86
  }
71
87
  const started = Date.now();
72
88
  const result = await options.registry.call(name, ctx, args);
@@ -82,7 +98,7 @@ const METHODS = {
82
98
  },
83
99
  };
84
100
  export const dispatchRpc = async (input) => {
85
- const { req, body, options, publicMethods } = input;
101
+ const { req, body, options, publicMethods, startedAt } = input;
86
102
  const method = body.method ?? "";
87
103
  // Notifications omit `id`; explicit null is a valid request id (JSON-RPC).
88
104
  const id = body.id === undefined ? null : body.id;
@@ -97,9 +113,9 @@ export const dispatchRpc = async (input) => {
97
113
  tool: toolName,
98
114
  ok: false,
99
115
  error: "unauthorized",
100
- durationMs: 0,
116
+ durationMs: Date.now() - startedAt,
101
117
  });
102
- return unauthorized(resolveWww(options, req));
118
+ return unauthorized(resolveWww(options, req), undefined, id);
103
119
  }
104
120
  }
105
121
  const handler = METHODS[method];
@@ -109,6 +125,6 @@ export const dispatchRpc = async (input) => {
109
125
  return jsonResponse(rpcError(body.id, JSONRPC_METHOD_NOT_FOUND, `Method not found: ${method}`));
110
126
  }
111
127
  const ctx = await options.ports.context(req, principal);
112
- return handler({ req, body, id, principal, ctx, options });
128
+ return handler({ req, body, id, principal, ctx, options, startedAt });
113
129
  };
114
130
  //# sourceMappingURL=methods.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"methods.js","sourceRoot":"","sources":["../src/methods.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"methods.js","sourceRoot":"","sources":["../src/methods.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EAGpB,QAAQ,EACR,SAAS,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AA2DpD,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAEtC,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC;IAC5C,YAAY;IACZ,MAAM;IACN,2BAA2B;IAC3B,aAAa;CACd,CAAC,CAAC;AAEH,MAAM,uBAAuB,GAA6C;IACxE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC;IACrF,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa;IACvC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,IAAI,IAAI;CACjF,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAoB,EAAW,EAAE,CAC9D,uBAAuB,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AAE/D,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,OAAgC,EAChC,GAAY,EACY,EAAE,CAC1B,OAAO,OAAO,CAAC,eAAe,KAAK,UAAU;IAC3C,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC;IAC9B,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC;AAE9B;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,GAA2B,EAC3B,OAAO,GAAG,cAAc,EACxB,KAAgB,IAAI,EACV,EAAE,CACZ,YAAY,CAAC,QAAQ,CAAC,EAAE,EAAE,oBAAoB,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE;IAC7D,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,CAAC;CAC/C,CAAC,CAAC;AAEL;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,OAAgC,EAChC,KAAiB,EACF,EAAE;IACjB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;IAClC,IAAI,CAAC,KAAK;QAAE,OAAO;IAEnB,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;QAC1B,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IAEL,MAAM,SAAS,GAAG,OAAO,CAAC,cAAc,IAAI,wBAAwB,CAAC;IACrE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAChG,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,SAAoB,EAAE,KAAyB,EAAW,EAAE;IACnF,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC5E,CAAC,CAAC;AAaF,MAAM,OAAO,GAAG;IACd,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAC1C,YAAY,CACV,SAAS,CAAC,EAAE,EAAE;QACZ,eAAe,EAAE,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC;QACjD,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAC3B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,EAAE;KACzC,CAAC,CACH;IAEH,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAEvD,YAAY,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CACtC,YAAY,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAEjE,YAAY,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE;QAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC;QACjC,MAAM,IAAI,GACR,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YACxE,CAAC,CAAE,OAAmC;YACtC,CAAC,CAAC,EAAE,CAAC;QAET,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACpE,MAAM,SAAS,CAAC,OAAO,EAAE;gBACvB,MAAM,EAAE,YAAY;gBACpB,IAAI,EAAE,IAAI;gBACV,WAAW,EAAE,SAAS,EAAE,EAAE;gBAC1B,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,eAAe;gBACtB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACnC,CAAC,CAAC;YACH,OAAO,YAAY,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,kBAAkB,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QACpF,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5D,MAAM,SAAS,CAAC,OAAO,EAAE;YACvB,MAAM,EAAE,YAAY;YACpB,IAAI,EAAE,IAAI;YACV,WAAW,EAAE,SAAS,EAAE,EAAE;YAC1B,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO;YACnB,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS;YAC3D,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;SACjC,CAAC,CAAC;QACH,OAAO,YAAY,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,CAAC;CACmD,CAAC;AAEvD,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAQ,KAOvC,EAAqB,EAAE;IACtB,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IACjC,2EAA2E;IAC3E,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;IAClD,MAAM,QAAQ,GAAG,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEvF,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAClF,IAAI,SAAS,GAAqB,IAAI,CAAC;IAEvC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,SAAS,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACpE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,SAAS,CAAC,OAAO,EAAE;gBACvB,MAAM;gBACN,IAAI,EAAE,QAAQ;gBACd,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,cAAc;gBACrB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACnC,CAAC,CAAC;YACH,OAAO,YAAY,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAI,OAAsD,CAAC,MAAM,CAAC,CAAC;IAChF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,IAAI,IAAI,CAAC,EAAE,KAAK,SAAS;YAAE,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;QACrD,OAAO,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,wBAAwB,EAAE,qBAAqB,MAAM,EAAE,CAAC,CAAC,CAAC;IAClG,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACxD,OAAO,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;AACxE,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/oauth/authorize.ts"],"names":[],"mappings":"AAYA,OAAO,EAKL,KAAK,kBAAkB,EAExB,MAAM,YAAY,CAAC;AAmDpB,eAAO,MAAM,eAAe,GAC1B,SAAS,OAAO,EAChB,SAAS,kBAAkB,KAC1B,OAAO,CAAC,QAAQ,CAoFlB,CAAC"}
1
+ {"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/oauth/authorize.ts"],"names":[],"mappings":"AAeA,OAAO,EAIL,KAAK,kBAAkB,EAKxB,MAAM,YAAY,CAAC;AA6CpB,eAAO,MAAM,eAAe,GAC1B,SAAS,OAAO,EAChB,SAAS,kBAAkB,KAC1B,OAAO,CAAC,QAAQ,CAqHlB,CAAC"}
@@ -1,41 +1,42 @@
1
1
  import { requireHttpMethod } from "../http.js";
2
2
  import { issueAuthCode } from "./codes.js";
3
+ import { buildCodeRedirectUrl, buildErrorRedirectUrl, isPreApproved, issueConsentTicket, renderConsent, secureRedirect, } from "./consent.js";
3
4
  import { OAUTH_ERRORS } from "./constants.js";
4
- import { isAllowedRedirectUri, } from "./redirect.js";
5
- import { canonicalResource, firstResourceError, } from "./resource.js";
6
- import { firstScopeError, formatScope, requestedScopes } from "./scope.js";
7
- import { advertisedScopes, oauthError, unregisteredClientError, resolveSecret, } from "./types.js";
5
+ import { isAllowedRedirectUri } from "./redirect.js";
6
+ import { canonicalResource, resourceErrorInfo } from "./resource.js";
7
+ import { formatScope, requestedScopes, scopeErrorInfo } from "./scope.js";
8
+ import { unseal } from "./sealed.js";
9
+ import { advertisedScopes, defaultScopes, oauthError, registeredClientsRequired, resolveSecret, unregisteredClientError, } from "./types.js";
8
10
  const GET_ONLY = new Set(["GET"]);
11
+ /** Reflected into `Location` on denial — an unbounded `state` is a header-size DoS knob. */
12
+ const MAX_STATE_LENGTH = 2048;
9
13
  /**
10
- * A pre-registered client is bound to its own redirect URIs.
11
- * Only unknown (dynamic / public) clients fall back to the global allowlist.
14
+ * A client bound to a known redirect-URI list — either pre-registered via
15
+ * `clientStore`, or a sealed assertion this server itself issued via
16
+ * `/register` (see `sealed.ts`). Unbound clients fall back to the global
17
+ * allowlist, unless `requireRegisteredClients` forbids that entirely.
12
18
  */
13
- const redirectAllowed = (redirectUri, registered, allowlist) => {
19
+ const redirectAllowed = (redirectUri, boundRedirectUris, allowlist) => {
14
20
  if (!redirectUri)
15
21
  return false;
16
- if (registered)
17
- return registered.redirectUris.includes(redirectUri);
22
+ if (boundRedirectUris)
23
+ return boundRedirectUris.includes(redirectUri);
18
24
  return isAllowedRedirectUri(redirectUri, allowlist);
19
25
  };
20
- const firstAuthzError = (input) => {
21
- const rule = [
22
- {
23
- ok: input.responseType === "code",
24
- description: "response_type must be code",
25
- },
26
- {
27
- ok: redirectAllowed(input.redirectUri, input.registered, input.redirect),
28
- description: "invalid redirect_uri",
29
- },
30
- {
31
- ok: Boolean(input.codeChallenge) && input.challengeMethod === "S256",
32
- description: "PKCE S256 code_challenge required",
33
- },
34
- ].find((entry) => !entry.ok);
35
- if (rule) {
36
- return oauthError(OAUTH_ERRORS.invalidRequest, 400, rule.description);
26
+ const redirectToLogin = (request, url, options) => {
27
+ const next = `${url.pathname}${url.search}`;
28
+ const login = options.ports.loginUrl(request, next);
29
+ let loginTarget;
30
+ try {
31
+ loginTarget = new URL(login, url.origin);
37
32
  }
38
- return firstResourceError(input.resource, input.expectedResource);
33
+ catch {
34
+ return oauthError(OAUTH_ERRORS.invalidRequest, 500, "loginUrl must be absolute or same-origin relative");
35
+ }
36
+ if (loginTarget.protocol !== "http:" && loginTarget.protocol !== "https:") {
37
+ return oauthError(OAUTH_ERRORS.invalidRequest, 500, "loginUrl must be absolute or same-origin relative");
38
+ }
39
+ return secureRedirect(loginTarget.toString());
39
40
  };
40
41
  export const handleAuthorize = async (request, options) => {
41
42
  const methodError = requireHttpMethod(request, GET_ONLY);
@@ -48,62 +49,93 @@ export const handleAuthorize = async (request, options) => {
48
49
  return oauthError(OAUTH_ERRORS.invalidRequest, 400, "client_id required");
49
50
  }
50
51
  const registered = (await options.ports.clientStore?.get(clientId)) ?? null;
51
- if (!registered) {
52
+ const secret = await resolveSecret(options.ports, request);
53
+ // Additive: a `client_id` this server itself sealed via `/register` is
54
+ // bound to its own redirect_uris exactly like a pre-registered client,
55
+ // without ever being written to storage. Non-sealed ids unseal to null
56
+ // and keep today's behavior.
57
+ const assertion = registered ? null : await unseal(secret, "client", clientId);
58
+ if (!registered && !assertion) {
52
59
  const unregistered = unregisteredClientError(options, {
53
60
  code: OAUTH_ERRORS.unauthorizedClient,
54
61
  status: 400,
55
62
  });
56
63
  if (unregistered)
57
64
  return unregistered;
65
+ if (registeredClientsRequired(options)) {
66
+ return oauthError(OAUTH_ERRORS.unauthorizedClient, 400, "client_id must come from clientStore or this server's own /register");
67
+ }
58
68
  }
59
- const authzError = firstAuthzError({
60
- responseType: url.searchParams.get("response_type") ?? "",
61
- redirectUri: url.searchParams.get("redirect_uri") ?? "",
62
- codeChallenge: url.searchParams.get("code_challenge") ?? "",
63
- challengeMethod: url.searchParams.get("code_challenge_method") ?? "S256",
64
- resource: url.searchParams.get("resource") ?? "",
65
- expectedResource,
66
- registered,
67
- redirect: options.redirect,
68
- });
69
- if (authzError)
70
- return authzError;
69
+ const boundRedirectUris = registered?.redirectUris ?? assertion?.redirectUris ?? null;
70
+ const redirectUri = url.searchParams.get("redirect_uri") ?? "";
71
+ const state = url.searchParams.get("state") ?? "";
72
+ // --- Pre-trust tier: redirect_uri is not yet verified as belonging to a
73
+ // legitimate party, so these two stay direct JSON responses. Redirecting
74
+ // here is exactly the open-redirect risk RFC 6749 §4.1.2.1 exists to
75
+ // avoid — the URI itself is what's in question. An oversized `state` is
76
+ // included in this tier too, for a narrower reason: reflecting it back
77
+ // into the error redirect it would otherwise trigger recreates the
78
+ // header-size DoS the cap exists to prevent, on the one input the cap
79
+ // can't safely echo.
80
+ if (!redirectAllowed(redirectUri, boundRedirectUris, options.redirect)) {
81
+ return oauthError(OAUTH_ERRORS.invalidRequest, 400, "invalid redirect_uri");
82
+ }
83
+ if (state.length > MAX_STATE_LENGTH) {
84
+ return oauthError(OAUTH_ERRORS.invalidRequest, 400, `state must be at most ${MAX_STATE_LENGTH} characters`);
85
+ }
86
+ // --- Post-trust tier: redirect_uri is now trusted, so every remaining
87
+ // error goes back to the client's own callback per RFC 6749 §4.1.2.1
88
+ // instead of a bare JSON body the connector never parses.
89
+ const redirectError = (code, description) => secureRedirect(buildErrorRedirectUrl(redirectUri, code, description, state));
90
+ const responseType = url.searchParams.get("response_type") ?? "";
91
+ if (responseType !== "code") {
92
+ return redirectError(OAUTH_ERRORS.unsupportedResponseType, "response_type must be code");
93
+ }
94
+ const codeChallenge = url.searchParams.get("code_challenge") ?? "";
95
+ const challengeMethod = url.searchParams.get("code_challenge_method") ?? "S256";
96
+ if (!codeChallenge || challengeMethod !== "S256") {
97
+ return redirectError(OAUTH_ERRORS.invalidRequest, "PKCE S256 code_challenge required");
98
+ }
99
+ const resourceIssue = resourceErrorInfo(url.searchParams.get("resource") ?? "", expectedResource);
100
+ if (resourceIssue)
101
+ return redirectError(resourceIssue.code, resourceIssue.description);
71
102
  const advertised = advertisedScopes(options);
72
- const granted = requestedScopes(url.searchParams.get("scope") ?? "", advertised);
73
- const scopeError = firstScopeError(granted, advertised);
74
- if (scopeError)
75
- return scopeError;
103
+ const granted = requestedScopes(url.searchParams.get("scope") ?? "", defaultScopes(options));
104
+ const scopeIssue = scopeErrorInfo(granted, advertised);
105
+ if (scopeIssue)
106
+ return redirectError(scopeIssue.code, scopeIssue.description);
76
107
  const user = await options.ports.resolveUser(request);
77
- if (!user) {
78
- const next = `${url.pathname}${url.search}`;
79
- const login = options.ports.loginUrl(request, next);
80
- let loginTarget;
81
- try {
82
- loginTarget = new URL(login, url.origin);
83
- }
84
- catch {
85
- return oauthError(OAUTH_ERRORS.invalidRequest, 500, "loginUrl must be absolute or same-origin relative");
86
- }
87
- if (loginTarget.protocol !== "http:" && loginTarget.protocol !== "https:") {
88
- return oauthError(OAUTH_ERRORS.invalidRequest, 500, "loginUrl must be absolute or same-origin relative");
89
- }
90
- return Response.redirect(loginTarget.toString(), 302);
108
+ if (!user)
109
+ return redirectToLogin(request, url, options);
110
+ if (isPreApproved(options, clientId, registered)) {
111
+ const code = await issueAuthCode(secret, {
112
+ clientId,
113
+ redirectUri,
114
+ codeChallenge,
115
+ userId: user.id,
116
+ resource: expectedResource,
117
+ scope: formatScope(granted),
118
+ });
119
+ return secureRedirect(buildCodeRedirectUrl(redirectUri, code, state));
91
120
  }
92
- const redirectUri = url.searchParams.get("redirect_uri") ?? "";
93
- const secret = await resolveSecret(options.ports, request);
94
- const code = await issueAuthCode(secret, {
121
+ const ticket = await issueConsentTicket(secret, {
95
122
  clientId,
96
123
  redirectUri,
97
- codeChallenge: url.searchParams.get("code_challenge") ?? "",
124
+ codeChallenge,
98
125
  userId: user.id,
99
126
  resource: expectedResource,
100
127
  scope: formatScope(granted),
128
+ state,
129
+ });
130
+ return renderConsent(options, {
131
+ clientId,
132
+ registeredClient: registered,
133
+ redirectUri,
134
+ scope: granted,
135
+ resource: expectedResource,
136
+ user,
137
+ ticket,
138
+ oauthPath: options.oauthPath ?? "/mcp/oauth",
101
139
  });
102
- const target = new URL(redirectUri);
103
- target.searchParams.set("code", code);
104
- const state = url.searchParams.get("state") ?? "";
105
- if (state)
106
- target.searchParams.set("state", state);
107
- return Response.redirect(target.toString(), 302);
108
140
  };
109
141
  //# sourceMappingURL=authorize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/oauth/authorize.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/oauth/authorize.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /** Shared base64url helpers (WebCrypto / DOM — no Node Buffer). */
2
2
  export declare const bytesToBase64Url: (bytes: ArrayBuffer | Uint8Array) => string;
3
3
  export declare const textToBase64Url: (text: string) => string;
4
- export declare const fromBase64Url: (text: string) => Uint8Array;
4
+ export declare const fromBase64Url: (text: string) => Uint8Array<ArrayBuffer>;
5
5
  //# sourceMappingURL=base64url.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base64url.d.ts","sourceRoot":"","sources":["../../src/oauth/base64url.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAEnE,eAAO,MAAM,gBAAgB,GAAI,OAAO,WAAW,GAAG,UAAU,KAAG,MAOlE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,MACG,CAAC;AAEnD,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,UAM5C,CAAC"}
1
+ {"version":3,"file":"base64url.d.ts","sourceRoot":"","sources":["../../src/oauth/base64url.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAEnE,eAAO,MAAM,gBAAgB,GAAI,OAAO,WAAW,GAAG,UAAU,KAAG,MAIlE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,MACG,CAAC;AAEnD,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,UAAU,CAAC,WAAW,CAKlE,CAAC"}
@@ -2,10 +2,7 @@
2
2
  export const bytesToBase64Url = (bytes) => {
3
3
  const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
4
4
  const binary = Array.from(u8, (byte) => String.fromCharCode(byte)).join("");
5
- return btoa(binary)
6
- .replace(/\+/g, "-")
7
- .replace(/\//g, "_")
8
- .replace(/=+$/, "");
5
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
9
6
  };
10
7
  export const textToBase64Url = (text) => bytesToBase64Url(new TextEncoder().encode(text));
11
8
  export const fromBase64Url = (text) => {
@@ -1 +1 @@
1
- {"version":3,"file":"base64url.js","sourceRoot":"","sources":["../../src/oauth/base64url.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAEnE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAA+B,EAAU,EAAE;IAC1E,MAAM,EAAE,GAAG,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5E,OAAO,IAAI,CAAC,MAAM,CAAC;SAChB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACxB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAU,EAAE,CACtD,gBAAgB,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAEnD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAc,EAAE;IACxD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,GAAG,GACP,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IAC/B,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC,CAAC"}
1
+ {"version":3,"file":"base64url.js","sourceRoot":"","sources":["../../src/oauth/base64url.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAEnE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAA+B,EAAU,EAAE;IAC1E,MAAM,EAAE,GAAG,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5E,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACjF,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAU,EAAE,CACtD,gBAAgB,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAEnD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAY,EAA2B,EAAE;IACrE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IAC/B,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC,CAAC"}
@@ -13,7 +13,12 @@ export declare const readClientAuth: (request: Request, body: Record<string, str
13
13
  *
14
14
  * An unknown client_id is treated as public — PKCE is its only proof —
15
15
  * unless `allowUnregisteredClients` is false, in which case it is rejected
16
- * rather than silently falling back to "no auth required".
16
+ * rather than silently falling back to "no auth required". On that
17
+ * locked-down path, a dummy secret comparison runs even for a client_id
18
+ * this server has never heard of, so the crypto-verification cost can't be
19
+ * used to distinguish "unknown" from "known, wrong secret" by timing. This
20
+ * only runs on the non-default, already-more-expensive path — public
21
+ * clients (the common case) never pay it.
17
22
  */
18
- export declare const firstClientAuthError: (auth: ClientAuth, options: OAuthRouterOptions) => Promise<Response | null>;
23
+ export declare const firstClientAuthError: (auth: ClientAuth, options: OAuthRouterOptions, request: Request) => Promise<Response | null>;
19
24
  //# sourceMappingURL=clientauth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"clientauth.d.ts","sourceRoot":"","sources":["../../src/oauth/clientauth.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAE9D,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,uBAAuB,CAAC;CACjC,CAAC;AAqBF,qEAAqE;AACrE,eAAO,MAAM,cAAc,GACzB,SAAS,OAAO,EAChB,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC3B,UAAU,GAAG,IAef,CAAC;AAKF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC/B,MAAM,UAAU,EAChB,SAAS,kBAAkB,KAC1B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAwBzB,CAAC"}
1
+ {"version":3,"file":"clientauth.d.ts","sourceRoot":"","sources":["../../src/oauth/clientauth.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAE9D,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,uBAAuB,CAAC;CACjC,CAAC;AAqBF,qEAAqE;AACrE,eAAO,MAAM,cAAc,GACzB,SAAS,OAAO,EAChB,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC3B,UAAU,GAAG,IAaf,CAAC;AAuCF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAC/B,MAAM,UAAU,EAChB,SAAS,kBAAkB,EAC3B,SAAS,OAAO,KACf,OAAO,CAAC,QAAQ,GAAG,IAAI,CAkDzB,CAAC"}
@@ -1,6 +1,7 @@
1
1
  /** Token-endpoint client authentication (RFC 6749 §2.3.1). */
2
2
  import { OAUTH_ERRORS, TOKEN_ENDPOINT_AUTH_METHODS, } from "./constants.js";
3
- import { oauthError, unregisteredClientError, } from "./types.js";
3
+ import { verifyClientSecret } from "./secrethash.js";
4
+ import { oauthError, resolveSecret, safeOAuthAudit, unregisteredClientsAllowed, } from "./types.js";
4
5
  /** `Authorization: Basic base64(urlencode(id):urlencode(secret))`. */
5
6
  const parseBasicAuth = (header) => {
6
7
  if (!header?.startsWith("Basic "))
@@ -35,41 +36,83 @@ export const readClientAuth = (request, body) => {
35
36
  return {
36
37
  clientId,
37
38
  secret: secret.length > 0 ? secret : null,
38
- method: secret.length > 0
39
- ? TOKEN_ENDPOINT_AUTH_METHODS.post
40
- : TOKEN_ENDPOINT_AUTH_METHODS.none,
39
+ method: secret.length > 0 ? TOKEN_ENDPOINT_AUTH_METHODS.post : TOKEN_ENDPOINT_AUTH_METHODS.none,
41
40
  };
42
41
  };
43
- const invalidClient = (description) => oauthError(OAUTH_ERRORS.invalidClient, 401, description);
42
+ /**
43
+ * Every failure below returns the same code, status, and description.
44
+ * Distinguishable messages here ("client requires client_secret_basic" vs.
45
+ * "unknown client_id" vs. "client_secret required" vs. …) let an
46
+ * unauthenticated caller enumerate which client_ids this server actually
47
+ * knows about and how each is configured, just by reading error text —
48
+ * a real information leak on the one endpoint whose entire job is to
49
+ * reject an untrusted caller. `/authorize`'s `unauthorized_client` stays
50
+ * descriptive on purpose: it's a human debugging an OAuth flow in a
51
+ * browser, not a bare API response, and a locked-down server already
52
+ * announces the same fact by omitting `registration_endpoint` from its
53
+ * metadata.
54
+ */
55
+ const CLIENT_AUTH_FAILED = "client authentication failed";
56
+ /** The generic response every failure below returns to the caller. */
57
+ const invalidClient = () => oauthError(OAUTH_ERRORS.invalidClient, 401, CLIENT_AUTH_FAILED);
58
+ /** The response above, plus the real reason to `ports.audit` — never to the caller. */
59
+ const invalidClientAudited = async (options, clientId, reason) => {
60
+ await safeOAuthAudit(options, { event: "client_auth_failed", clientId, reason });
61
+ return invalidClient();
62
+ };
63
+ /**
64
+ * Never a real credential — exists only so the locked-down branch below
65
+ * does the same amount of comparison work whether or not a secret was
66
+ * actually presented, and whether or not a stored hash actually exists.
67
+ */
68
+ const DUMMY_SECRET = "dummy-secret-for-constant-time-padding";
69
+ const DUMMY_STORED_HASH = "hmac-sha256$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
44
70
  /**
45
71
  * Enforce the registered auth method for known clients.
46
72
  *
47
73
  * An unknown client_id is treated as public — PKCE is its only proof —
48
74
  * unless `allowUnregisteredClients` is false, in which case it is rejected
49
- * rather than silently falling back to "no auth required".
75
+ * rather than silently falling back to "no auth required". On that
76
+ * locked-down path, a dummy secret comparison runs even for a client_id
77
+ * this server has never heard of, so the crypto-verification cost can't be
78
+ * used to distinguish "unknown" from "known, wrong secret" by timing. This
79
+ * only runs on the non-default, already-more-expensive path — public
80
+ * clients (the common case) never pay it.
50
81
  */
51
- export const firstClientAuthError = async (auth, options) => {
82
+ export const firstClientAuthError = async (auth, options, request) => {
52
83
  const store = options.ports.clientStore;
53
84
  const registered = (await store?.get(auth.clientId)) ?? null;
54
85
  if (!registered) {
55
- return unregisteredClientError(options, {
56
- code: OAUTH_ERRORS.invalidClient,
57
- status: 401,
58
- });
86
+ if (unregisteredClientsAllowed(options))
87
+ return null;
88
+ const codeSecretValue = await resolveSecret(options.ports, request);
89
+ await verifyClientSecret(auth.secret ?? DUMMY_SECRET, DUMMY_STORED_HASH, codeSecretValue);
90
+ return invalidClientAudited(options, auth.clientId, "unknown client_id");
59
91
  }
60
92
  const expected = registered.tokenEndpointAuthMethod;
61
93
  if (expected === TOKEN_ENDPOINT_AUTH_METHODS.none)
62
94
  return null;
63
95
  if (auth.method !== expected) {
64
- return invalidClient(`client requires ${expected}`);
96
+ return invalidClientAudited(options, auth.clientId, `client requires ${expected}, got ${auth.method}`);
97
+ }
98
+ if (!auth.secret) {
99
+ return invalidClientAudited(options, auth.clientId, "client_secret required");
100
+ }
101
+ if (store?.secretHash) {
102
+ const codeSecretValue = await resolveSecret(options.ports, request);
103
+ const stored = await store.secretHash(auth.clientId);
104
+ // Constant path whether a hash is on file or not — same reasoning as
105
+ // the unregistered-client branch above.
106
+ const ok = await verifyClientSecret(auth.secret, stored ?? DUMMY_STORED_HASH, codeSecretValue);
107
+ if (ok && stored !== null)
108
+ return null;
109
+ return invalidClientAudited(options, auth.clientId, stored === null ? "no secretHash on file for this client" : "secretHash mismatch");
65
110
  }
66
- if (!auth.secret)
67
- return invalidClient("client_secret required");
68
111
  if (!store?.verifySecret) {
69
- return invalidClient("clientStore.verifySecret is not configured");
112
+ return invalidClientAudited(options, auth.clientId, "clientStore.verifySecret is not configured");
70
113
  }
71
114
  if (!(await store.verifySecret(auth.clientId, auth.secret))) {
72
- return invalidClient("client authentication failed");
115
+ return invalidClientAudited(options, auth.clientId, "verifySecret returned false");
73
116
  }
74
117
  return null;
75
118
  };
@@ -1 +1 @@
1
- {"version":3,"file":"clientauth.js","sourceRoot":"","sources":["../../src/oauth/clientauth.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAE9D,OAAO,EACL,YAAY,EACZ,2BAA2B,GAE5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,UAAU,EACV,uBAAuB,GAExB,MAAM,YAAY,CAAC;AAQpB,sEAAsE;AACtE,MAAM,cAAc,GAAG,CAAC,MAAqB,EAAqB,EAAE;IAClE,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,SAAS,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAC/B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC3B,OAAO;YACL,QAAQ;YACR,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;YACxD,MAAM,EAAE,2BAA2B,CAAC,KAAK;SAC1C,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,qEAAqE;AACrE,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,OAAgB,EAChB,IAA4B,EACT,EAAE;IACrB,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;IACnE,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IAExB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;IACtC,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC;IACxC,OAAO;QACL,QAAQ;QACR,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;QACzC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC;YACvB,CAAC,CAAC,2BAA2B,CAAC,IAAI;YAClC,CAAC,CAAC,2BAA2B,CAAC,IAAI;KACrC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,WAAmB,EAAY,EAAE,CACtD,UAAU,CAAC,YAAY,CAAC,aAAa,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;AAE3D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACvC,IAAgB,EAChB,OAA2B,EACD,EAAE;IAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC;IACxC,MAAM,UAAU,GAAG,CAAC,MAAM,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC;IAC7D,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,uBAAuB,CAAC,OAAO,EAAE;YACtC,IAAI,EAAE,YAAY,CAAC,aAAa;YAChC,MAAM,EAAE,GAAG;SACZ,CAAC,CAAC;IACL,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,uBAAuB,CAAC;IACpD,IAAI,QAAQ,KAAK,2BAA2B,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAE/D,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,aAAa,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,aAAa,CAAC,wBAAwB,CAAC,CAAC;IACjE,IAAI,CAAC,KAAK,EAAE,YAAY,EAAE,CAAC;QACzB,OAAO,aAAa,CAAC,4CAA4C,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAC5D,OAAO,aAAa,CAAC,8BAA8B,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
1
+ {"version":3,"file":"clientauth.js","sourceRoot":"","sources":["../../src/oauth/clientauth.ts"],"names":[],"mappings":"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"}
@@ -18,13 +18,13 @@ export type CodeStore = {
18
18
  consume: (jti: string, expMs: number) => Promise<boolean> | boolean;
19
19
  };
20
20
  /**
21
- * Issue an HMAC-signed auth code.
22
- * Single-use via codeStore, or pruning in-memory Map when omitted.
21
+ * Issue an AES-GCM sealed auth code (v2). Single-use via codeStore, or
22
+ * pruning in-memory Map when omitted.
23
23
  */
24
24
  export declare const issueAuthCode: (secret: string, record: Omit<AuthCodeRecord, "exp">, nowMs?: number) => Promise<string>;
25
25
  export declare const consumeAuthCode: (secret: string, code: string, options?: {
26
- codeStore?: CodeStore;
27
- nowMs?: number;
26
+ codeStore?: CodeStore | undefined;
27
+ nowMs?: number | undefined;
28
28
  }) => Promise<AuthCodeRecord | null>;
29
29
  export declare const newClientId: () => string;
30
30
  //# sourceMappingURL=codes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"codes.d.ts","sourceRoot":"","sources":["../../src/oauth/codes.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB;;;OAGG;IACH,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACrE,CAAC;AAkCF;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,QAAQ,MAAM,EACd,QAAQ,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,EACnC,cAAkB,KACjB,OAAO,CAAC,MAAM,CAShB,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,QAAQ,MAAM,EACd,MAAM,MAAM,EACZ,UAAS;IAAE,SAAS,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,KACtD,OAAO,CAAC,cAAc,GAAG,IAAI,CA8C/B,CAAC;AAEF,eAAO,MAAM,WAAW,QAAO,MAA6B,CAAC"}
1
+ {"version":3,"file":"codes.d.ts","sourceRoot":"","sources":["../../src/oauth/codes.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB;;;OAGG;IACH,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACrE,CAAC;AAkBF;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,QAAQ,MAAM,EACd,QAAQ,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,EACnC,cAAkB,KACjB,OAAO,CAAC,MAAM,CAOhB,CAAC;AAmCF,eAAO,MAAM,eAAe,GAC1B,QAAQ,MAAM,EACd,MAAM,MAAM,EACZ,UAAS;IAAE,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,KAC9E,OAAO,CAAC,cAAc,GAAG,IAAI,CAkB/B,CAAC;AAEF,eAAO,MAAM,WAAW,QAAO,MAA6B,CAAC"}