@julr/sesame 0.5.1 → 0.6.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 (73) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +405 -62
  3. package/build/authorize_controller-BiycO4be.js +251 -0
  4. package/build/chunk-DF48asd8.js +9 -0
  5. package/build/{client_info_controller-BucHGx4u.js → client_info_controller-AcOG8lWu.js} +11 -3
  6. package/build/commands/sesame_client.d.ts +20 -0
  7. package/build/commands/sesame_key.d.ts +12 -0
  8. package/build/commands/sesame_purge.d.ts +0 -2
  9. package/build/commands/sesame_purge.js +15 -3
  10. package/build/configure-DkDkIlt8.js +27 -0
  11. package/build/configure.js +2 -24
  12. package/build/consent_controller-Dsdhv6-f.js +108 -0
  13. package/build/id_token_service-CpTzOUDe.js +54 -0
  14. package/build/index.d.ts +1 -1
  15. package/build/index.js +30 -10
  16. package/build/{introspect_controller-6bRt9sZt.js → introspect_controller-DvOp9scr.js} +21 -7
  17. package/build/issue_authorization_code-B9ERu1uO.js +40 -0
  18. package/build/jwks_controller-keo4kBZc.js +26 -0
  19. package/build/{main-EbeMS5S9.js → main-DGBJhq3E.js} +34 -4
  20. package/build/{metadata_controller-DeaMRnUr.js → metadata_controller-BVsTo0Gp.js} +83 -6
  21. package/build/{oauth_access_token-bsoM5KeU.js → oauth_access_token-Cz_5gNBx.js} +12 -1
  22. package/build/oauth_client-BSanvSql.js +63 -0
  23. package/build/oauth_error-C7UhDb2q.js +189 -0
  24. package/build/providers/sesame_provider.js +14 -3
  25. package/build/{register_controller-sIJ1rxdM.js → register_controller-gbq7p8a5.js} +46 -7
  26. package/build/{revoke_controller-D6isoQCi.js → revoke_controller-z_ghrEB7.js} +21 -8
  27. package/build/services/main.js +7 -3
  28. package/build/sesame_manager-B1Jgq1v2.js +6 -0
  29. package/build/sesame_manager-DYUSZ0NC.js +693 -0
  30. package/build/src/actions/authorize.d.ts +46 -0
  31. package/build/src/actions/exchange_authorization_code.d.ts +34 -0
  32. package/build/src/actions/exchange_client_credentials.d.ts +28 -0
  33. package/build/src/actions/exchange_refresh_token.d.ts +59 -0
  34. package/build/src/actions/issue_authorization_code.d.ts +26 -0
  35. package/build/src/controllers/authorize_controller.d.ts +13 -12
  36. package/build/src/controllers/consent_controller.d.ts +5 -0
  37. package/build/src/controllers/jwks_controller.d.ts +14 -0
  38. package/build/src/controllers/metadata_controller.d.ts +8 -1
  39. package/build/src/controllers/token_controller.d.ts +8 -5
  40. package/build/src/controllers/userinfo_controller.d.ts +14 -0
  41. package/build/src/guard/main.js +5 -5
  42. package/build/src/middleware/any_scope_middleware.js +11 -1
  43. package/build/src/middleware/scope_middleware.js +11 -1
  44. package/build/src/models/oauth_authorization_code.d.ts +1 -0
  45. package/build/src/models/oauth_pending_authorization_request.d.ts +1 -0
  46. package/build/src/oauth_error.d.ts +1 -1
  47. package/build/src/routes.d.ts +3 -1
  48. package/build/src/services/id_token_service.d.ts +30 -0
  49. package/build/src/services/key_service.d.ts +20 -0
  50. package/build/src/sesame_manager.d.ts +54 -3
  51. package/build/src/types.d.ts +112 -0
  52. package/build/stubs/main.ts +5 -0
  53. package/build/stubs/migrations/create_oauth_authorization_codes_table.stub +1 -0
  54. package/build/stubs/migrations/create_oauth_pending_authorization_requests_table.stub +1 -0
  55. package/build/stubs/migrations/create_oauth_refresh_tokens_table.stub +1 -1
  56. package/build/token_controller-DyI7oy-U.js +481 -0
  57. package/build/token_service-DwnfAR9F.js +59 -0
  58. package/build/userinfo_controller-RLk8cN_o.js +40 -0
  59. package/build/vite.config.d.ts +2 -0
  60. package/package.json +26 -41
  61. package/build/authorize_controller-YUfAy-R2.js +0 -138
  62. package/build/client_service-WTNMqWzY.js +0 -65
  63. package/build/consent_controller-Dprwd1ed.js +0 -85
  64. package/build/decorate-BKZEjPRg.js +0 -15
  65. package/build/oauth_client-BIoY5jBR.js +0 -24
  66. package/build/oauth_error-CnJ3L8tf.js +0 -94
  67. package/build/sesame_manager-Bu4MHqZV.js +0 -4
  68. package/build/sesame_manager-DwDZy5Vy.js +0 -167
  69. package/build/src/grants/authorization_code_grant.d.ts +0 -23
  70. package/build/src/grants/client_credentials_grant.d.ts +0 -23
  71. package/build/src/grants/refresh_token_grant.d.ts +0 -27
  72. package/build/token_controller-DzcrLMyS.js +0 -194
  73. package/build/token_service-fhoA4slP.js +0 -31
@@ -1,10 +1,10 @@
1
- import { t as SesameManager } from "./sesame_manager-DwDZy5Vy.js";
2
- import "./decorate-BKZEjPRg.js";
3
- import "./oauth_access_token-bsoM5KeU.js";
4
- import { i as E_INVALID_CLIENT_METADATA, o as E_INVALID_REQUEST, s as E_INVALID_SCOPE, t as E_ACCESS_DENIED } from "./oauth_error-CnJ3L8tf.js";
5
- import { t as OAuthClient } from "./oauth_client-BIoY5jBR.js";
6
- import { t as ClientService } from "./client_service-WTNMqWzY.js";
1
+ import "./chunk-DF48asd8.js";
2
+ import { o as ClientService, t as SesameManager } from "./sesame_manager-DYUSZ0NC.js";
3
+ import { t as OAuthClient } from "./oauth_client-BSanvSql.js";
4
+ import { i as E_INVALID_CLIENT_METADATA, o as E_INVALID_REQUEST, s as E_INVALID_SCOPE, t as E_ACCESS_DENIED } from "./oauth_error-C7UhDb2q.js";
5
+ import "./oauth_access_token-Cz_5gNBx.js";
7
6
  import vine from "@vinejs/vine";
7
+ //#region src/rules.ts
8
8
  const DANGEROUS_SCHEMES = [
9
9
  "javascript:",
10
10
  "data:",
@@ -15,6 +15,10 @@ const LOCALHOST_HOSTS = [
15
15
  "127.0.0.1",
16
16
  "[::1]"
17
17
  ];
18
+ /**
19
+ * Validates a redirect URI per OAuth 2.1 / RFC 8252 rules.
20
+ * Blocks fragments, dangerous schemes, and requires HTTPS for non-localhost hosts.
21
+ */
18
22
  const redirectUriRule = vine.createRule((value, _options, field) => {
19
23
  let parsed;
20
24
  try {
@@ -33,11 +37,40 @@ const redirectUriRule = vine.createRule((value, _options, field) => {
33
37
  }
34
38
  if (parsed.protocol === "http:" && !LOCALHOST_HOSTS.includes(parsed.hostname)) field.report("Redirect URI must use HTTPS for non-localhost hosts", "redirectUri", field);
35
39
  });
40
+ /**
41
+ * Blocks dangerous URI schemes for metadata URIs (client_uri, logo_uri, etc.).
42
+ *
43
+ * RFC 7591 §5 says the server MAY verify that metadata URIs match the
44
+ * host+scheme of redirect_uris, but this is NOT required.
45
+ *
46
+ * We intentionally skip this check because it breaks legitimate CLI/desktop clients
47
+ * (e.g. OpenCode, Claude Code) that use localhost redirect URIs but have a
48
+ * different `client_uri` pointing to their website.
49
+ *
50
+ * Maybe we can add an option to enable this check in the future if needed.
51
+ *
52
+ * @see https://datatracker.ietf.org/doc/html/rfc7591#section-5
53
+ */
36
54
  const metadataUriRule = vine.createRule((value, _options, field) => {
37
55
  const parsed = new URL(value);
38
56
  if (DANGEROUS_SCHEMES.includes(parsed.protocol)) field.report("{{ field }} uses a disallowed scheme", "metadataUri", field);
39
57
  });
58
+ //#endregion
59
+ //#region src/controllers/register_controller.ts
40
60
  const metadataUrl = vine.string().url({ require_protocol: true }).use(metadataUriRule()).optional();
61
+ /**
62
+ * Handles the OAuth 2.0 Dynamic Client Registration Endpoint (RFC 7591).
63
+ *
64
+ * Allows clients to register themselves with the authorization server
65
+ * by providing metadata such as `redirect_uris`, `grant_types`, and
66
+ * `token_endpoint_auth_method`. Returns the assigned `client_id` and
67
+ * optionally a `client_secret` for confidential clients.
68
+ *
69
+ * Can be configured to require authentication or allow public
70
+ * registration (useful for MCP where clients self-register).
71
+ *
72
+ * @see https://datatracker.ietf.org/doc/html/rfc7591
73
+ */
41
74
  var RegisterController = class RegisterController {
42
75
  static validator = vine.create(vine.object({
43
76
  redirect_uris: vine.array(vine.string().use(redirectUriRule())).minLength(1),
@@ -72,11 +105,12 @@ var RegisterController = class RegisterController {
72
105
  const clientService = new ClientService();
73
106
  const tokenEndpointAuthMethod = body.token_endpoint_auth_method ?? "client_secret_basic";
74
107
  const isPublic = tokenEndpointAuthMethod === "none";
75
- const grantTypes = body.grant_types ?? ["authorization_code"];
108
+ const grantTypes = body.grant_types ?? ["authorization_code", "refresh_token"];
76
109
  const responseTypes = body.response_types ?? ["code"];
77
110
  const scopes = body.scope ? body.scope.split(" ") : manager.config.defaultScopes;
78
111
  const invalidScopes = manager.validateScopes(scopes);
79
112
  if (invalidScopes.length > 0) throw new E_INVALID_SCOPE(`Unknown scopes: ${invalidScopes.join(", ")}`);
113
+ if (manager.usesOidcScopes(scopes) && !manager.isOidcEnabled) throw new E_INVALID_SCOPE("OIDC scopes require OIDC to be configured (set jwk and oidcProvider in config)");
80
114
  const clientName = body.client_name ?? "Unnamed Client";
81
115
  for (const gt of grantTypes) if (!manager.isGrantTypeEnabled(gt)) throw new E_INVALID_CLIENT_METADATA(`Unsupported grant type: ${gt}`);
82
116
  if (responseTypes.some((rt) => rt !== "code")) throw new E_INVALID_CLIENT_METADATA("Only \"code\" response type is supported");
@@ -111,6 +145,10 @@ var RegisterController = class RegisterController {
111
145
  });
112
146
  ctx.response.header("Cache-Control", "no-store");
113
147
  ctx.response.status(201);
148
+ /**
149
+ * RFC 7591 §3.2.1 requires the response to include ALL registered
150
+ * metadata about this client, including fields provisioned by the server.
151
+ */
114
152
  return {
115
153
  client_id: clientId,
116
154
  ...clientSecret ? { client_secret: clientSecret } : {},
@@ -123,4 +161,5 @@ var RegisterController = class RegisterController {
123
161
  };
124
162
  }
125
163
  };
164
+ //#endregion
126
165
  export { RegisterController as default };
@@ -1,11 +1,23 @@
1
- import { a as OAuthRefreshToken, t as SesameManager } from "./sesame_manager-DwDZy5Vy.js";
2
- import "./decorate-BKZEjPRg.js";
3
- import { t as OAuthAccessToken } from "./oauth_access_token-bsoM5KeU.js";
4
- import "./oauth_error-CnJ3L8tf.js";
5
- import "./oauth_client-BIoY5jBR.js";
6
- import { t as TokenService } from "./token_service-fhoA4slP.js";
7
- import { t as ClientService } from "./client_service-WTNMqWzY.js";
1
+ import "./chunk-DF48asd8.js";
2
+ import { a as OAuthRefreshToken, o as ClientService, t as SesameManager } from "./sesame_manager-DYUSZ0NC.js";
3
+ import "./oauth_client-BSanvSql.js";
4
+ import "./oauth_error-C7UhDb2q.js";
5
+ import { t as OAuthAccessToken } from "./oauth_access_token-Cz_5gNBx.js";
6
+ import { t as TokenService } from "./token_service-DwnfAR9F.js";
8
7
  import { DateTime } from "luxon";
8
+ //#region src/controllers/revoke_controller.ts
9
+ /**
10
+ * Handles the OAuth 2.0 Token Revocation Endpoint (RFC 7009).
11
+ *
12
+ * Allows an authenticated client to revoke an access token or
13
+ * refresh token. Always responds with HTTP 200, even if the token
14
+ * was already revoked or not found (to prevent information leakage).
15
+ *
16
+ * When revoking a refresh token, the associated access token is
17
+ * also revoked as recommended by RFC 7009 §2.1.
18
+ *
19
+ * @see https://datatracker.ietf.org/doc/html/rfc7009
20
+ */
9
21
  var RevokeController = class {
10
22
  async handle(ctx) {
11
23
  const manager = await ctx.containerResolver.make(SesameManager);
@@ -32,10 +44,11 @@ var RevokeController = class {
32
44
  if (refreshToken && !refreshToken.revokedAt) {
33
45
  refreshToken.revokedAt = DateTime.now();
34
46
  await refreshToken.save();
35
- await OAuthAccessToken.query().where("tokenHash", refreshToken.accessTokenId).whereNull("revokedAt").update({ revokedAt: DateTime.now().toSQL() });
47
+ await OAuthAccessToken.query().where("id", refreshToken.accessTokenId).whereNull("revokedAt").update({ revokedAt: DateTime.now().toSQL() });
36
48
  }
37
49
  }
38
50
  return ctx.response.ok({});
39
51
  }
40
52
  };
53
+ //#endregion
41
54
  export { RevokeController as default };
@@ -1,9 +1,13 @@
1
- import { t as SesameManager } from "../sesame_manager-DwDZy5Vy.js";
2
- import "../decorate-BKZEjPRg.js";
3
- import "../oauth_access_token-bsoM5KeU.js";
1
+ import "../chunk-DF48asd8.js";
2
+ import { t as SesameManager } from "../sesame_manager-DYUSZ0NC.js";
3
+ import "../oauth_client-BSanvSql.js";
4
+ import "../oauth_error-C7UhDb2q.js";
5
+ import "../oauth_access_token-Cz_5gNBx.js";
4
6
  import app from "@adonisjs/core/services/app";
7
+ //#region services/main.ts
5
8
  let sesame;
6
9
  await app.booted(async () => {
7
10
  sesame = await app.container.make(SesameManager);
8
11
  });
12
+ //#endregion
9
13
  export { sesame as default };
@@ -0,0 +1,6 @@
1
+ import "./chunk-DF48asd8.js";
2
+ import { t as SesameManager } from "./sesame_manager-DYUSZ0NC.js";
3
+ import "./oauth_client-BSanvSql.js";
4
+ import "./oauth_error-C7UhDb2q.js";
5
+ import "./oauth_access_token-Cz_5gNBx.js";
6
+ export { SesameManager };