@julr/sesame 0.5.1 → 0.7.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.
- package/LICENSE.md +1 -1
- package/README.md +470 -64
- package/build/authorize_controller-sCZIjnc-.js +251 -0
- package/build/{client_info_controller-BucHGx4u.js → client_info_controller-B5A3tpbk.js} +11 -4
- package/build/commands/sesame_client.d.ts +20 -0
- package/build/commands/sesame_key.d.ts +12 -0
- package/build/commands/sesame_purge.d.ts +0 -2
- package/build/commands/sesame_purge.js +12 -3
- package/build/configure-t9q3KonY.js +31 -0
- package/build/configure.js +1 -24
- package/build/consent_controller-ChBboaSd.js +96 -0
- package/build/consent_retry-DMkfhmk9.js +41 -0
- package/build/{decorate-BKZEjPRg.js → decorate-RQD1h28J.js} +3 -9
- package/build/id_token_service-BtBUiL_n.js +54 -0
- package/build/index.d.ts +2 -8
- package/build/index.js +59 -10
- package/build/{introspect_controller-6bRt9sZt.js → introspect_controller-LVYGWhMj.js} +28 -10
- package/build/issue_authorization_code-Dr4-bbMp.js +39 -0
- package/build/jwks_controller-4HUVS_HC.js +22 -0
- package/build/{main-EbeMS5S9.js → main-Dx9kZv07.js} +35 -43
- package/build/{metadata_controller-DeaMRnUr.js → metadata_controller-hwfmxlF7.js} +81 -6
- package/build/oauth_error-CvxtZvjp.js +189 -0
- package/build/providers/sesame_provider.d.ts +1 -1
- package/build/providers/sesame_provider.js +17 -6
- package/build/{register_controller-sIJ1rxdM.js → register_controller-Cdk3c32j.js} +44 -8
- package/build/revoke_controller-Daz4Yqfs.js +48 -0
- package/build/services/main.js +3 -3
- package/build/sesame_manager-CeEmlzba.js +515 -0
- package/build/sesame_manager-DQxvsTEq.js +2 -0
- package/build/src/actions/authorize.d.ts +46 -0
- package/build/src/actions/exchange_authorization_code.d.ts +34 -0
- package/build/src/actions/exchange_client_credentials.d.ts +28 -0
- package/build/src/actions/exchange_refresh_token.d.ts +59 -0
- package/build/src/actions/issue_authorization_code.d.ts +26 -0
- package/build/src/controllers/authorize_controller.d.ts +18 -17
- package/build/src/controllers/consent_controller.d.ts +5 -0
- package/build/src/controllers/jwks_controller.d.ts +14 -0
- package/build/src/controllers/metadata_controller.d.ts +10 -3
- package/build/src/controllers/register_controller.d.ts +30 -30
- package/build/src/controllers/token_controller.d.ts +8 -5
- package/build/src/controllers/userinfo_controller.d.ts +14 -0
- package/build/src/guard/guard.d.ts +1 -1
- package/build/src/guard/lucid.d.ts +8 -0
- package/build/src/guard/lucid.js +46 -0
- package/build/src/guard/main.d.ts +2 -9
- package/build/src/guard/main.js +2 -6
- package/build/src/guard/types.d.ts +0 -9
- package/build/src/guard/user_provider.d.ts +9 -1
- package/build/src/middleware/any_scope_middleware.js +10 -1
- package/build/src/middleware/scope_middleware.js +10 -1
- package/build/src/models/oauth_authorization_code.d.ts +1 -0
- package/build/src/models/oauth_pending_authorization_request.d.ts +1 -0
- package/build/src/oauth_error.d.ts +74 -74
- package/build/src/routes.d.ts +3 -1
- package/build/src/services/client_service.d.ts +5 -2
- package/build/src/services/id_token_service.d.ts +30 -0
- package/build/src/services/key_service.d.ts +20 -0
- package/build/src/sesame_manager.d.ts +56 -4
- package/build/src/storage/consent_retry.d.ts +4 -0
- package/build/src/storage/drivers/kysely.d.ts +166 -0
- package/build/src/storage/drivers/kysely.js +480 -0
- package/build/src/storage/drivers/lucid.d.ts +162 -0
- package/build/src/storage/drivers/lucid.js +549 -0
- package/build/src/storage/migrations/kysely.d.ts +6 -0
- package/build/src/storage/types.d.ts +197 -0
- package/build/src/storage/types.js +1 -0
- package/build/src/stores.d.ts +21 -0
- package/build/src/types.d.ts +120 -0
- package/build/src/types.js +2 -0
- package/build/stubs/config/sesame.stub +4 -1
- package/build/stubs/config/sesame_kysely.stub +35 -0
- package/build/stubs/main.ts +5 -0
- package/build/stubs/migrations/create_oauth_authorization_codes_table.stub +1 -0
- package/build/stubs/migrations/create_oauth_pending_authorization_requests_table.stub +1 -0
- package/build/stubs/migrations/create_oauth_refresh_tokens_table.stub +1 -1
- package/build/stubs/migrations/kysely/create_oauth_tables.stub +151 -0
- package/build/taze.config.d.ts +2 -0
- package/build/token_controller-DRatCQNT.js +492 -0
- package/build/token_service-DDQ3Dxaj.js +59 -0
- package/build/types-DEtn2Zdb.js +75 -0
- package/build/userinfo_controller-YwN26wK-.js +37 -0
- package/build/vite.config.d.ts +2 -0
- package/package.json +55 -54
- package/build/authorize_controller-YUfAy-R2.js +0 -138
- package/build/client_service-WTNMqWzY.js +0 -65
- package/build/consent_controller-Dprwd1ed.js +0 -85
- package/build/oauth_access_token-bsoM5KeU.js +0 -18
- package/build/oauth_client-BIoY5jBR.js +0 -24
- package/build/oauth_error-CnJ3L8tf.js +0 -94
- package/build/revoke_controller-D6isoQCi.js +0 -41
- package/build/sesame_manager-Bu4MHqZV.js +0 -4
- package/build/sesame_manager-DwDZy5Vy.js +0 -167
- package/build/src/grants/authorization_code_grant.d.ts +0 -23
- package/build/src/grants/client_credentials_grant.d.ts +0 -23
- package/build/src/grants/refresh_token_grant.d.ts +0 -27
- package/build/token_controller-DzcrLMyS.js +0 -194
- package/build/token_service-fhoA4slP.js +0 -31
|
@@ -1,14 +1,25 @@
|
|
|
1
|
-
import { t as SesameManager } from "../sesame_manager-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { t as SesameManager } from "../sesame_manager-CeEmlzba.js";
|
|
2
|
+
//#region providers/sesame_provider.ts
|
|
3
|
+
/**
|
|
4
|
+
* AdonisJS service provider for the Sésame OAuth 2.1 server.
|
|
5
|
+
*/
|
|
4
6
|
var SesameProvider = class {
|
|
7
|
+
#app;
|
|
5
8
|
constructor(app) {
|
|
6
|
-
this
|
|
9
|
+
this.#app = app;
|
|
7
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Register `SesameManager` as a singleton binding.
|
|
13
|
+
* The manager is resolved from the `sesame` config key.
|
|
14
|
+
*/
|
|
8
15
|
register() {
|
|
9
|
-
this
|
|
10
|
-
|
|
16
|
+
this.#app.container.singleton(SesameManager, async () => {
|
|
17
|
+
const config = this.#app.config.get("sesame");
|
|
18
|
+
const router = await this.#app.container.make("router");
|
|
19
|
+
const store = await config.store.resolver(this.#app);
|
|
20
|
+
return new SesameManager(config, router, store);
|
|
11
21
|
});
|
|
12
22
|
}
|
|
13
23
|
};
|
|
24
|
+
//#endregion
|
|
14
25
|
export { SesameProvider as default };
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import "./
|
|
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 { i as E_INVALID_CLIENT_METADATA, o as E_INVALID_REQUEST, s as E_INVALID_SCOPE, t as E_ACCESS_DENIED } from "./oauth_error-CvxtZvjp.js";
|
|
2
|
+
import { n as ClientService, t as SesameManager } from "./sesame_manager-CeEmlzba.js";
|
|
7
3
|
import vine from "@vinejs/vine";
|
|
4
|
+
//#region src/rules.ts
|
|
8
5
|
const DANGEROUS_SCHEMES = [
|
|
9
6
|
"javascript:",
|
|
10
7
|
"data:",
|
|
@@ -15,6 +12,10 @@ const LOCALHOST_HOSTS = [
|
|
|
15
12
|
"127.0.0.1",
|
|
16
13
|
"[::1]"
|
|
17
14
|
];
|
|
15
|
+
/**
|
|
16
|
+
* Validates a redirect URI per OAuth 2.1 / RFC 8252 rules.
|
|
17
|
+
* Blocks fragments, dangerous schemes, and requires HTTPS for non-localhost hosts.
|
|
18
|
+
*/
|
|
18
19
|
const redirectUriRule = vine.createRule((value, _options, field) => {
|
|
19
20
|
let parsed;
|
|
20
21
|
try {
|
|
@@ -33,11 +34,40 @@ const redirectUriRule = vine.createRule((value, _options, field) => {
|
|
|
33
34
|
}
|
|
34
35
|
if (parsed.protocol === "http:" && !LOCALHOST_HOSTS.includes(parsed.hostname)) field.report("Redirect URI must use HTTPS for non-localhost hosts", "redirectUri", field);
|
|
35
36
|
});
|
|
37
|
+
/**
|
|
38
|
+
* Blocks dangerous URI schemes for metadata URIs (client_uri, logo_uri, etc.).
|
|
39
|
+
*
|
|
40
|
+
* RFC 7591 §5 says the server MAY verify that metadata URIs match the
|
|
41
|
+
* host+scheme of redirect_uris, but this is NOT required.
|
|
42
|
+
*
|
|
43
|
+
* We intentionally skip this check because it breaks legitimate CLI/desktop clients
|
|
44
|
+
* (e.g. OpenCode, Claude Code) that use localhost redirect URIs but have a
|
|
45
|
+
* different `client_uri` pointing to their website.
|
|
46
|
+
*
|
|
47
|
+
* Maybe we can add an option to enable this check in the future if needed.
|
|
48
|
+
*
|
|
49
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7591#section-5
|
|
50
|
+
*/
|
|
36
51
|
const metadataUriRule = vine.createRule((value, _options, field) => {
|
|
37
52
|
const parsed = new URL(value);
|
|
38
53
|
if (DANGEROUS_SCHEMES.includes(parsed.protocol)) field.report("{{ field }} uses a disallowed scheme", "metadataUri", field);
|
|
39
54
|
});
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/controllers/register_controller.ts
|
|
40
57
|
const metadataUrl = vine.string().url({ require_protocol: true }).use(metadataUriRule()).optional();
|
|
58
|
+
/**
|
|
59
|
+
* Handles the OAuth 2.0 Dynamic Client Registration Endpoint (RFC 7591).
|
|
60
|
+
*
|
|
61
|
+
* Allows clients to register themselves with the authorization server
|
|
62
|
+
* by providing metadata such as `redirect_uris`, `grant_types`, and
|
|
63
|
+
* `token_endpoint_auth_method`. Returns the assigned `client_id` and
|
|
64
|
+
* optionally a `client_secret` for confidential clients.
|
|
65
|
+
*
|
|
66
|
+
* Can be configured to require authentication or allow public
|
|
67
|
+
* registration (useful for MCP where clients self-register).
|
|
68
|
+
*
|
|
69
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7591
|
|
70
|
+
*/
|
|
41
71
|
var RegisterController = class RegisterController {
|
|
42
72
|
static validator = vine.create(vine.object({
|
|
43
73
|
redirect_uris: vine.array(vine.string().use(redirectUriRule())).minLength(1),
|
|
@@ -72,11 +102,12 @@ var RegisterController = class RegisterController {
|
|
|
72
102
|
const clientService = new ClientService();
|
|
73
103
|
const tokenEndpointAuthMethod = body.token_endpoint_auth_method ?? "client_secret_basic";
|
|
74
104
|
const isPublic = tokenEndpointAuthMethod === "none";
|
|
75
|
-
const grantTypes = body.grant_types ?? ["authorization_code"];
|
|
105
|
+
const grantTypes = body.grant_types ?? ["authorization_code", "refresh_token"];
|
|
76
106
|
const responseTypes = body.response_types ?? ["code"];
|
|
77
107
|
const scopes = body.scope ? body.scope.split(" ") : manager.config.defaultScopes;
|
|
78
108
|
const invalidScopes = manager.validateScopes(scopes);
|
|
79
109
|
if (invalidScopes.length > 0) throw new E_INVALID_SCOPE(`Unknown scopes: ${invalidScopes.join(", ")}`);
|
|
110
|
+
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
111
|
const clientName = body.client_name ?? "Unnamed Client";
|
|
81
112
|
for (const gt of grantTypes) if (!manager.isGrantTypeEnabled(gt)) throw new E_INVALID_CLIENT_METADATA(`Unsupported grant type: ${gt}`);
|
|
82
113
|
if (responseTypes.some((rt) => rt !== "code")) throw new E_INVALID_CLIENT_METADATA("Only \"code\" response type is supported");
|
|
@@ -94,7 +125,7 @@ var RegisterController = class RegisterController {
|
|
|
94
125
|
...body.software_id ? { software_id: body.software_id } : {},
|
|
95
126
|
...body.software_version ? { software_version: body.software_version } : {}
|
|
96
127
|
};
|
|
97
|
-
await
|
|
128
|
+
await manager.store.createClient({
|
|
98
129
|
id: crypto.randomUUID(),
|
|
99
130
|
clientId,
|
|
100
131
|
clientSecret: hashedSecret,
|
|
@@ -111,6 +142,10 @@ var RegisterController = class RegisterController {
|
|
|
111
142
|
});
|
|
112
143
|
ctx.response.header("Cache-Control", "no-store");
|
|
113
144
|
ctx.response.status(201);
|
|
145
|
+
/**
|
|
146
|
+
* RFC 7591 §3.2.1 requires the response to include ALL registered
|
|
147
|
+
* metadata about this client, including fields provisioned by the server.
|
|
148
|
+
*/
|
|
114
149
|
return {
|
|
115
150
|
client_id: clientId,
|
|
116
151
|
...clientSecret ? { client_secret: clientSecret } : {},
|
|
@@ -123,4 +158,5 @@ var RegisterController = class RegisterController {
|
|
|
123
158
|
};
|
|
124
159
|
}
|
|
125
160
|
};
|
|
161
|
+
//#endregion
|
|
126
162
|
export { RegisterController as default };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { n as ClientService, t as SesameManager } from "./sesame_manager-CeEmlzba.js";
|
|
2
|
+
import { t as TokenService } from "./token_service-DDQ3Dxaj.js";
|
|
3
|
+
import { DateTime } from "luxon";
|
|
4
|
+
//#region src/controllers/revoke_controller.ts
|
|
5
|
+
/**
|
|
6
|
+
* Handles the OAuth 2.0 Token Revocation Endpoint (RFC 7009).
|
|
7
|
+
*
|
|
8
|
+
* Allows an authenticated client to revoke an access token or
|
|
9
|
+
* refresh token. Always responds with HTTP 200, even if the token
|
|
10
|
+
* was already revoked or not found (to prevent information leakage).
|
|
11
|
+
*
|
|
12
|
+
* When revoking a refresh token, the associated access token is
|
|
13
|
+
* also revoked as recommended by RFC 7009 §2.1.
|
|
14
|
+
*
|
|
15
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7009
|
|
16
|
+
*/
|
|
17
|
+
var RevokeController = class {
|
|
18
|
+
async handle(ctx) {
|
|
19
|
+
const manager = await ctx.containerResolver.make(SesameManager);
|
|
20
|
+
const clientService = new ClientService(manager);
|
|
21
|
+
const store = manager.store;
|
|
22
|
+
const client = await clientService.authenticateClient({
|
|
23
|
+
authorizationHeader: ctx.request.header("authorization"),
|
|
24
|
+
bodyClientId: ctx.request.body().client_id,
|
|
25
|
+
bodyClientSecret: ctx.request.body().client_secret
|
|
26
|
+
});
|
|
27
|
+
const token = ctx.request.body().token;
|
|
28
|
+
if (!token) return ctx.response.ok({});
|
|
29
|
+
const tokenTypeHint = ctx.request.body().token_type_hint;
|
|
30
|
+
const hashed = new TokenService(manager).hashToken(token);
|
|
31
|
+
if (!tokenTypeHint || tokenTypeHint === "access_token") {
|
|
32
|
+
if (await store.revokeAccessToken({
|
|
33
|
+
hash: hashed,
|
|
34
|
+
clientId: client.clientId,
|
|
35
|
+
now: DateTime.now()
|
|
36
|
+
})) return ctx.response.ok({});
|
|
37
|
+
if (tokenTypeHint === "access_token") return ctx.response.ok({});
|
|
38
|
+
}
|
|
39
|
+
if (!tokenTypeHint || tokenTypeHint === "refresh_token") await store.revokeRefreshToken({
|
|
40
|
+
hash: hashed,
|
|
41
|
+
clientId: client.clientId,
|
|
42
|
+
now: DateTime.now()
|
|
43
|
+
});
|
|
44
|
+
return ctx.response.ok({});
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
//#endregion
|
|
48
|
+
export { RevokeController as default };
|
package/build/services/main.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { t as SesameManager } from "../sesame_manager-
|
|
2
|
-
import "../decorate-BKZEjPRg.js";
|
|
3
|
-
import "../oauth_access_token-bsoM5KeU.js";
|
|
1
|
+
import { t as SesameManager } from "../sesame_manager-CeEmlzba.js";
|
|
4
2
|
import app from "@adonisjs/core/services/app";
|
|
3
|
+
//#region services/main.ts
|
|
5
4
|
let sesame;
|
|
6
5
|
await app.booted(async () => {
|
|
7
6
|
sesame = await app.container.make(SesameManager);
|
|
8
7
|
});
|
|
8
|
+
//#endregion
|
|
9
9
|
export { sesame as default };
|