@julr/sesame 0.5.0 → 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.
- package/LICENSE.md +1 -1
- package/README.md +405 -62
- package/build/authorize_controller-BiycO4be.js +251 -0
- package/build/chunk-DF48asd8.js +9 -0
- package/build/{client_info_controller-BucHGx4u.js → client_info_controller-AcOG8lWu.js} +11 -3
- 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 +15 -3
- package/build/configure-DkDkIlt8.js +27 -0
- package/build/configure.js +2 -24
- package/build/consent_controller-Dsdhv6-f.js +108 -0
- package/build/id_token_service-CpTzOUDe.js +54 -0
- package/build/index.d.ts +1 -1
- package/build/index.js +30 -10
- package/build/{introspect_controller-un95fs4y.js → introspect_controller-DvOp9scr.js} +21 -7
- package/build/issue_authorization_code-B9ERu1uO.js +40 -0
- package/build/jwks_controller-keo4kBZc.js +26 -0
- package/build/{main-B3M6ihoS.js → main-DGBJhq3E.js} +34 -4
- package/build/metadata_controller-BVsTo0Gp.js +158 -0
- package/build/{oauth_access_token-bsoM5KeU.js → oauth_access_token-Cz_5gNBx.js} +12 -1
- package/build/oauth_client-BSanvSql.js +63 -0
- package/build/oauth_error-C7UhDb2q.js +189 -0
- package/build/providers/sesame_provider.js +14 -3
- package/build/{register_controller-Dch4ecyD.js → register_controller-gbq7p8a5.js} +46 -7
- package/build/{revoke_controller-DnPmzYMd.js → revoke_controller-z_ghrEB7.js} +21 -8
- package/build/services/main.js +7 -3
- package/build/sesame_manager-B1Jgq1v2.js +6 -0
- package/build/sesame_manager-DYUSZ0NC.js +693 -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 +13 -12
- 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 +9 -2
- package/build/src/controllers/token_controller.d.ts +8 -5
- package/build/src/controllers/userinfo_controller.d.ts +14 -0
- package/build/src/guard/main.js +5 -5
- package/build/src/middleware/any_scope_middleware.js +11 -1
- package/build/src/middleware/scope_middleware.js +11 -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 +1 -1
- package/build/src/routes.d.ts +3 -1
- 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 +54 -3
- package/build/src/types.d.ts +124 -3
- 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/token_controller-DyI7oy-U.js +481 -0
- package/build/token_service-DwnfAR9F.js +59 -0
- package/build/userinfo_controller-RLk8cN_o.js +40 -0
- package/build/vite.config.d.ts +2 -0
- package/package.json +26 -41
- package/build/authorize_controller-BGzxPvYU.js +0 -138
- package/build/client_service-C3rfXGk_.js +0 -65
- package/build/consent_controller-BHoB9mip.js +0 -85
- package/build/decorate-BKZEjPRg.js +0 -15
- package/build/metadata_controller-CJeZG93_.js +0 -81
- package/build/oauth_client-BIoY5jBR.js +0 -24
- package/build/oauth_error-CnJ3L8tf.js +0 -94
- package/build/sesame_manager-BQIW2mqt.js +0 -4
- package/build/sesame_manager-C-eEFFHM.js +0 -167
- package/build/src/grants/authorization_code_grant.d.ts +0 -27
- 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-hGDAYuBS.js +0 -194
- package/build/token_service-fhoA4slP.js +0 -31
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { SesameManager } from '../sesame_manager.ts';
|
|
2
|
+
export interface AuthorizeInput {
|
|
3
|
+
clientId: string;
|
|
4
|
+
responseType: string;
|
|
5
|
+
redirectUri: string;
|
|
6
|
+
scope?: string;
|
|
7
|
+
state?: string;
|
|
8
|
+
codeChallenge?: string;
|
|
9
|
+
codeChallengeMethod?: string;
|
|
10
|
+
nonce?: string;
|
|
11
|
+
userId?: string;
|
|
12
|
+
}
|
|
13
|
+
export type AuthorizeResult = {
|
|
14
|
+
type: 'redirect_error';
|
|
15
|
+
error: string;
|
|
16
|
+
description: string;
|
|
17
|
+
} | {
|
|
18
|
+
type: 'login_required';
|
|
19
|
+
} | {
|
|
20
|
+
type: 'consent_required';
|
|
21
|
+
authToken: string;
|
|
22
|
+
scopes: string[];
|
|
23
|
+
} | {
|
|
24
|
+
type: 'authorized';
|
|
25
|
+
code: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Handles the OAuth 2.0 authorization request business logic.
|
|
29
|
+
*
|
|
30
|
+
* Validates the client, scopes, and PKCE parameters, checks
|
|
31
|
+
* existing consent, and either issues an authorization code
|
|
32
|
+
* or signals that login/consent is required.
|
|
33
|
+
*
|
|
34
|
+
* Errors before redirect_uri validation are thrown as exceptions.
|
|
35
|
+
* Errors after are returned as `redirect_error` results so the
|
|
36
|
+
* controller can redirect back to the client per spec.
|
|
37
|
+
*/
|
|
38
|
+
export declare class AuthorizeAction {
|
|
39
|
+
#private;
|
|
40
|
+
/**
|
|
41
|
+
* Process an authorization request. Returns a discriminated
|
|
42
|
+
* union that the controller interprets as the appropriate
|
|
43
|
+
* HTTP redirect.
|
|
44
|
+
*/
|
|
45
|
+
execute(manager: SesameManager, input: AuthorizeInput): Promise<AuthorizeResult>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { SesameManager } from '../sesame_manager.ts';
|
|
2
|
+
import type { OAuthClient } from '../models/oauth_client.ts';
|
|
3
|
+
export interface ExchangeAuthorizationCodeInput {
|
|
4
|
+
client: OAuthClient;
|
|
5
|
+
code: string;
|
|
6
|
+
redirectUri: string;
|
|
7
|
+
codeVerifier: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Handle the Authorization Code Grant (RFC 6749 §4.1.3).
|
|
11
|
+
*
|
|
12
|
+
* Exchanges an authorization code for an access token and
|
|
13
|
+
* optionally a refresh token and id_token. Verifies PKCE,
|
|
14
|
+
* validates scopes, and atomically consumes the code to
|
|
15
|
+
* prevent replay.
|
|
16
|
+
*
|
|
17
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
|
|
18
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.6
|
|
19
|
+
*/
|
|
20
|
+
export declare class ExchangeAuthorizationCodeAction {
|
|
21
|
+
#private;
|
|
22
|
+
/**
|
|
23
|
+
* Exchange an authorization code for tokens. The code is
|
|
24
|
+
* consumed atomically inside a transaction.
|
|
25
|
+
*/
|
|
26
|
+
execute(manager: SesameManager, input: ExchangeAuthorizationCodeInput): Promise<{
|
|
27
|
+
id_token?: string | undefined;
|
|
28
|
+
refresh_token?: string | undefined;
|
|
29
|
+
access_token: string;
|
|
30
|
+
token_type: "Bearer";
|
|
31
|
+
expires_in: number;
|
|
32
|
+
scope: string;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SesameManager } from '../sesame_manager.ts';
|
|
2
|
+
import type { OAuthClient } from '../models/oauth_client.ts';
|
|
3
|
+
export interface ExchangeClientCredentialsInput {
|
|
4
|
+
client: OAuthClient;
|
|
5
|
+
scope?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Handle the Client Credentials Grant (RFC 6749 §4.4).
|
|
9
|
+
*
|
|
10
|
+
* Issues an access token directly to a confidential client
|
|
11
|
+
* for machine-to-machine communication. No refresh token
|
|
12
|
+
* is issued. User-centric OIDC scopes are rejected.
|
|
13
|
+
*
|
|
14
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.4
|
|
15
|
+
*/
|
|
16
|
+
export declare class ExchangeClientCredentialsAction {
|
|
17
|
+
#private;
|
|
18
|
+
/**
|
|
19
|
+
* Validate the client, resolve scopes, and issue an
|
|
20
|
+
* access token for M2M usage.
|
|
21
|
+
*/
|
|
22
|
+
execute(manager: SesameManager, input: ExchangeClientCredentialsInput): Promise<{
|
|
23
|
+
access_token: string;
|
|
24
|
+
token_type: "Bearer";
|
|
25
|
+
expires_in: number;
|
|
26
|
+
scope: string;
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { SesameManager } from '../sesame_manager.ts';
|
|
2
|
+
import type { OAuthClient } from '../models/oauth_client.ts';
|
|
3
|
+
export interface ExchangeRefreshTokenInput {
|
|
4
|
+
client: OAuthClient;
|
|
5
|
+
refreshToken: string;
|
|
6
|
+
scope?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Handle the Refresh Token Grant (RFC 6749 §6).
|
|
10
|
+
*
|
|
11
|
+
* Exchanges a refresh token for a new access token and a new
|
|
12
|
+
* refresh token (rotation). The old refresh token is revoked
|
|
13
|
+
* immediately after use.
|
|
14
|
+
*
|
|
15
|
+
* ## Replay detection
|
|
16
|
+
*
|
|
17
|
+
* If a revoked refresh token is presented **outside** the grace
|
|
18
|
+
* period, all tokens for that client+user pair are nuked to
|
|
19
|
+
* mitigate stolen-token reuse (RFC 6819 §5.2.2.3, RFC 9700 §4.14.2).
|
|
20
|
+
*
|
|
21
|
+
* ## Grace period (rotation reuse window)
|
|
22
|
+
*
|
|
23
|
+
* OAuth 2.1 requires that rotated refresh tokens be single-use.
|
|
24
|
+
* However, that requirement conflicts with the realities of
|
|
25
|
+
* distributed systems: if the server rotates the token but the
|
|
26
|
+
* client never receives (or persists) the new token — due to a
|
|
27
|
+
* network failure, a concurrent refresh from another process, or
|
|
28
|
+
* a retry after timeout — the client loses its grant permanently.
|
|
29
|
+
*
|
|
30
|
+
* To handle this, we allow a recently-rotated refresh token to be
|
|
31
|
+
* reused within a short configurable window (`refreshTokenRotationGracePeriod`,
|
|
32
|
+
* defaults to 120 s). During that window the old token issues fresh
|
|
33
|
+
* tokens without triggering replay-attack revocation.
|
|
34
|
+
*
|
|
35
|
+
* This is the same approach used by Auth0 ("reuse interval") and
|
|
36
|
+
* Cloudflare workers-oauth-provider ("previous token"). It provides
|
|
37
|
+
* most of the security benefits of strict rotation while remaining
|
|
38
|
+
* reliable for real-world clients (MCP SDK, multi-process CLIs, etc.).
|
|
39
|
+
*
|
|
40
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-6
|
|
41
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6819#section-5.2.2.3
|
|
42
|
+
* @see https://datatracker.ietf.org/doc/html/rfc9700#section-4.14.2
|
|
43
|
+
*/
|
|
44
|
+
export declare class ExchangeRefreshTokenAction {
|
|
45
|
+
#private;
|
|
46
|
+
/**
|
|
47
|
+
* Rotate the refresh token, issue a new access token,
|
|
48
|
+
* and optionally reissue an id_token if openid scope
|
|
49
|
+
* is present.
|
|
50
|
+
*/
|
|
51
|
+
execute(manager: SesameManager, input: ExchangeRefreshTokenInput): Promise<{
|
|
52
|
+
id_token?: string | undefined;
|
|
53
|
+
access_token: string;
|
|
54
|
+
token_type: "Bearer";
|
|
55
|
+
expires_in: number;
|
|
56
|
+
scope: string;
|
|
57
|
+
refresh_token: string;
|
|
58
|
+
}>;
|
|
59
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SesameManager } from '../sesame_manager.ts';
|
|
2
|
+
import type { OAuthClient } from '../models/oauth_client.ts';
|
|
3
|
+
export interface AuthorizationCodeInput {
|
|
4
|
+
client: OAuthClient;
|
|
5
|
+
userId: string;
|
|
6
|
+
scopes: string[];
|
|
7
|
+
redirectUri: string;
|
|
8
|
+
codeChallenge?: string;
|
|
9
|
+
codeChallengeMethod?: string;
|
|
10
|
+
nonce?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Create and persist an authorization code in the database.
|
|
14
|
+
* Returns the raw (unhashed) code to be sent to the client.
|
|
15
|
+
*
|
|
16
|
+
* Shared between the authorize and consent flows to avoid
|
|
17
|
+
* duplicating the code-issuance logic.
|
|
18
|
+
*/
|
|
19
|
+
export declare class IssueAuthorizationCodeAction {
|
|
20
|
+
/**
|
|
21
|
+
* Generate an opaque authorization code, store its SHA-256
|
|
22
|
+
* hash in the database, and return the raw value for the
|
|
23
|
+
* client redirect.
|
|
24
|
+
*/
|
|
25
|
+
execute(manager: SesameManager, input: AuthorizationCodeInput): Promise<string>;
|
|
26
|
+
}
|
|
@@ -2,17 +2,10 @@ import type { HttpContext } from '@adonisjs/core/http';
|
|
|
2
2
|
/**
|
|
3
3
|
* Handles the OAuth 2.0 Authorization Endpoint (RFC 6749 §3.1).
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* either redirects the user to the login/consent page or directly
|
|
8
|
-
* issues an authorization code if consent was already granted.
|
|
9
|
-
*
|
|
10
|
-
* The `iss` response parameter is included per RFC 9207 to prevent
|
|
11
|
-
* mix-up attacks.
|
|
5
|
+
* Validates HTTP parameters, delegates business logic to
|
|
6
|
+
* AuthorizeAction, and interprets the result as redirects.
|
|
12
7
|
*
|
|
13
8
|
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-3.1
|
|
14
|
-
* @see https://datatracker.ietf.org/doc/html/rfc7636
|
|
15
|
-
* @see https://datatracker.ietf.org/doc/html/rfc9207
|
|
16
9
|
*/
|
|
17
10
|
export default class AuthorizeController {
|
|
18
11
|
#private;
|
|
@@ -24,30 +17,38 @@ export default class AuthorizeController {
|
|
|
24
17
|
state: import("@vinejs/vine/schema/base/literal").OptionalModifier<import("@vinejs/vine").VineString>;
|
|
25
18
|
code_challenge: import("@vinejs/vine/schema/base/literal").OptionalModifier<import("@vinejs/vine").VineString>;
|
|
26
19
|
code_challenge_method: import("@vinejs/vine/schema/base/literal").OptionalModifier<import("@vinejs/vine").VineString>;
|
|
20
|
+
nonce: import("@vinejs/vine/schema/base/literal").OptionalModifier<import("@vinejs/vine").VineString>;
|
|
27
21
|
}, {
|
|
22
|
+
nonce?: string | null | undefined;
|
|
28
23
|
scope?: string | null | undefined;
|
|
29
24
|
state?: string | null | undefined;
|
|
30
25
|
code_challenge?: string | null | undefined;
|
|
31
26
|
code_challenge_method?: string | null | undefined;
|
|
32
|
-
redirect_uri: string;
|
|
33
27
|
client_id: string;
|
|
28
|
+
redirect_uri: string;
|
|
34
29
|
response_type: string;
|
|
35
30
|
}, {
|
|
31
|
+
nonce?: string | undefined;
|
|
36
32
|
scope?: string | undefined;
|
|
37
33
|
state?: string | undefined;
|
|
38
34
|
code_challenge?: string | undefined;
|
|
39
35
|
code_challenge_method?: string | undefined;
|
|
40
|
-
redirect_uri: string;
|
|
41
36
|
client_id: string;
|
|
37
|
+
redirect_uri: string;
|
|
42
38
|
response_type: string;
|
|
43
39
|
}, {
|
|
40
|
+
nonce?: string | undefined;
|
|
44
41
|
scope?: string | undefined;
|
|
45
42
|
state?: string | undefined;
|
|
46
43
|
code_challenge?: string | undefined;
|
|
47
44
|
code_challenge_method?: string | undefined;
|
|
48
|
-
redirect_uri: string;
|
|
49
45
|
client_id: string;
|
|
46
|
+
redirect_uri: string;
|
|
50
47
|
response_type: string;
|
|
51
48
|
}>, Record<string, any> | undefined>;
|
|
49
|
+
/**
|
|
50
|
+
* Validate the authorization request query params, run the
|
|
51
|
+
* authorize action, and redirect based on the result.
|
|
52
|
+
*/
|
|
52
53
|
handle(ctx: HttpContext): Promise<void>;
|
|
53
54
|
}
|
|
@@ -23,5 +23,10 @@ export default class ConsentController {
|
|
|
23
23
|
}, {
|
|
24
24
|
auth_token: string;
|
|
25
25
|
}>, Record<string, any> | undefined>;
|
|
26
|
+
/**
|
|
27
|
+
* Validate the consent submission, consume the pending
|
|
28
|
+
* request, and redirect back to the client with either
|
|
29
|
+
* an authorization code or an access_denied error.
|
|
30
|
+
*/
|
|
26
31
|
handle(ctx: HttpContext): Promise<void>;
|
|
27
32
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
2
|
+
/**
|
|
3
|
+
* Serves the JSON Web Key Set (JWKS) containing public keys
|
|
4
|
+
* used to verify ID token signatures.
|
|
5
|
+
*
|
|
6
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7517
|
|
7
|
+
*/
|
|
8
|
+
export default class JwksController {
|
|
9
|
+
handle(ctx: HttpContext): Promise<{
|
|
10
|
+
keys: import("jose").JWK[];
|
|
11
|
+
} | {
|
|
12
|
+
error: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HttpContext } from '@adonisjs/core/http';
|
|
2
|
-
import type
|
|
2
|
+
import { type AuthServerMetadata, type ResourceServerMetadata } from '../types.ts';
|
|
3
3
|
/**
|
|
4
4
|
* Serves OAuth 2.0 discovery metadata documents.
|
|
5
5
|
*
|
|
@@ -34,15 +34,21 @@ export default class MetadataController {
|
|
|
34
34
|
* @see https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
|
35
35
|
*/
|
|
36
36
|
oidc(ctx: HttpContext): Promise<{
|
|
37
|
+
error: string;
|
|
38
|
+
} | {
|
|
39
|
+
userinfo_endpoint: string;
|
|
40
|
+
jwks_uri: string;
|
|
37
41
|
subject_types_supported: string[];
|
|
42
|
+
id_token_signing_alg_values_supported: string[];
|
|
38
43
|
scopes_supported: string[];
|
|
44
|
+
claims_supported: string[];
|
|
45
|
+
response_types_supported: string[];
|
|
39
46
|
issuer: string;
|
|
40
47
|
authorization_endpoint: string;
|
|
41
48
|
token_endpoint: string;
|
|
42
49
|
registration_endpoint?: string;
|
|
43
50
|
introspection_endpoint?: string;
|
|
44
51
|
revocation_endpoint?: string;
|
|
45
|
-
response_types_supported: string[];
|
|
46
52
|
response_modes_supported: string[];
|
|
47
53
|
grant_types_supported: string[];
|
|
48
54
|
token_endpoint_auth_methods_supported: string[];
|
|
@@ -50,6 +56,7 @@ export default class MetadataController {
|
|
|
50
56
|
revocation_endpoint_auth_methods_supported?: string[];
|
|
51
57
|
code_challenge_methods_supported: string[];
|
|
52
58
|
authorization_response_iss_parameter_supported: boolean;
|
|
59
|
+
error?: undefined;
|
|
53
60
|
}>;
|
|
54
61
|
/**
|
|
55
62
|
* OAuth 2.0 Protected Resource Metadata (RFC 9728).
|
|
@@ -2,15 +2,14 @@ import type { HttpContext } from '@adonisjs/core/http';
|
|
|
2
2
|
/**
|
|
3
3
|
* Handles the OAuth 2.0 Token Endpoint (RFC 6749 §3.2).
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* by the spec.
|
|
5
|
+
* Authenticates the client, extracts grant-specific params,
|
|
6
|
+
* and dispatches to the appropriate action. Sets required
|
|
7
|
+
* cache headers on all token responses.
|
|
9
8
|
*
|
|
10
9
|
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-3.2
|
|
11
|
-
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.1
|
|
12
10
|
*/
|
|
13
11
|
export default class TokenController {
|
|
12
|
+
#private;
|
|
14
13
|
static validator: import("@vinejs/vine").VineValidator<import("@vinejs/vine").VineObject<{
|
|
15
14
|
grant_type: import("@vinejs/vine").VineString;
|
|
16
15
|
}, {
|
|
@@ -20,5 +19,9 @@ export default class TokenController {
|
|
|
20
19
|
}, {
|
|
21
20
|
grant_type: string;
|
|
22
21
|
}>, Record<string, any> | undefined>;
|
|
22
|
+
/**
|
|
23
|
+
* Validate the grant type, authenticate the client,
|
|
24
|
+
* and dispatch to the appropriate grant action.
|
|
25
|
+
*/
|
|
23
26
|
handle(ctx: HttpContext): Promise<any>;
|
|
24
27
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
2
|
+
/**
|
|
3
|
+
* OpenID Connect UserInfo endpoint (OIDC Core §5.3).
|
|
4
|
+
*
|
|
5
|
+
* Returns claims about the authenticated user based on the
|
|
6
|
+
* access token's scopes. Supports both GET and POST.
|
|
7
|
+
*
|
|
8
|
+
* @see https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
|
|
9
|
+
*/
|
|
10
|
+
export default class UserinfoController {
|
|
11
|
+
handle(ctx: HttpContext): Promise<{
|
|
12
|
+
sub: string | null;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
package/build/src/guard/main.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "../../
|
|
2
|
-
import "../../
|
|
3
|
-
import "../../
|
|
4
|
-
import "../../token_service-
|
|
5
|
-
import { i as OAuthGuard, n as oauthUserProvider, r as OAuthLucidUserProvider, t as oauthGuard } from "../../main-
|
|
1
|
+
import "../../chunk-DF48asd8.js";
|
|
2
|
+
import "../../oauth_client-BSanvSql.js";
|
|
3
|
+
import "../../oauth_access_token-Cz_5gNBx.js";
|
|
4
|
+
import "../../token_service-DwnfAR9F.js";
|
|
5
|
+
import { i as OAuthGuard, n as oauthUserProvider, r as OAuthLucidUserProvider, t as oauthGuard } from "../../main-DGBJhq3E.js";
|
|
6
6
|
export { OAuthGuard, OAuthLucidUserProvider, oauthGuard, oauthUserProvider };
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "../../chunk-DF48asd8.js";
|
|
2
|
+
import { n as E_INSUFFICIENT_SCOPE } from "../../oauth_error-C7UhDb2q.js";
|
|
3
|
+
//#region src/middleware/any_scope_middleware.ts
|
|
4
|
+
/**
|
|
5
|
+
* Any-scope middleware requires ANY of the listed scopes on the
|
|
6
|
+
* authenticated OAuth token. Throws 403 if none match.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* router.get('/data', [DataController]).use(middleware.anyScope({ scopes: ['read', 'read-all'] }))
|
|
10
|
+
*/
|
|
2
11
|
var AnyScopeMiddleware = class {
|
|
3
12
|
async handle(ctx, next, options) {
|
|
4
13
|
const guard = ctx.auth.use("oauth");
|
|
@@ -15,4 +24,5 @@ var AnyScopeMiddleware = class {
|
|
|
15
24
|
await guard.authenticate();
|
|
16
25
|
}
|
|
17
26
|
};
|
|
27
|
+
//#endregion
|
|
18
28
|
export { AnyScopeMiddleware as default };
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "../../chunk-DF48asd8.js";
|
|
2
|
+
import { n as E_INSUFFICIENT_SCOPE } from "../../oauth_error-C7UhDb2q.js";
|
|
3
|
+
//#region src/middleware/scope_middleware.ts
|
|
4
|
+
/**
|
|
5
|
+
* Scope middleware requires ALL listed scopes on the authenticated
|
|
6
|
+
* OAuth token. Throws 403 if any scope is missing.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* router.get('/admin', [AdminController]).use(middleware.scopes({ scopes: ['admin', 'manage'] }))
|
|
10
|
+
*/
|
|
2
11
|
var ScopeMiddleware = class {
|
|
3
12
|
async handle(ctx, next, options) {
|
|
4
13
|
const guard = ctx.auth.use("oauth");
|
|
@@ -15,4 +24,5 @@ var ScopeMiddleware = class {
|
|
|
15
24
|
await guard.authenticate();
|
|
16
25
|
}
|
|
17
26
|
};
|
|
27
|
+
//#endregion
|
|
18
28
|
export { ScopeMiddleware as default };
|
|
@@ -171,8 +171,8 @@ export declare const E_INVALID_TOKEN: {
|
|
|
171
171
|
code?: string;
|
|
172
172
|
status?: number;
|
|
173
173
|
}): {
|
|
174
|
-
get oauthCode(): string;
|
|
175
174
|
handle(error: /*elided*/ any, ctx: HttpContext): void;
|
|
175
|
+
get oauthCode(): string;
|
|
176
176
|
name: string;
|
|
177
177
|
help?: string;
|
|
178
178
|
code?: string;
|
package/build/src/routes.d.ts
CHANGED
|
@@ -26,4 +26,6 @@ export declare function registerOAuthRoutes(router: Router): void;
|
|
|
26
26
|
* - `GET /.well-known/openid-configuration` — OpenID Connect discovery
|
|
27
27
|
* - `GET /.well-known/oauth-protected-resource` — Protected resource metadata (RFC 9728)
|
|
28
28
|
*/
|
|
29
|
-
export declare function registerWellKnownRoutes(router: Router
|
|
29
|
+
export declare function registerWellKnownRoutes(router: Router, options?: {
|
|
30
|
+
jwksPath?: string;
|
|
31
|
+
}): void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { SesameManager } from '../sesame_manager.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Builds and signs OIDC `id_token` JWTs.
|
|
4
|
+
*/
|
|
5
|
+
export declare class IdTokenService {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(manager: SesameManager);
|
|
8
|
+
/**
|
|
9
|
+
* Compute `at_hash` — left half of SHA-256 hash of the access token, base64url-encoded.
|
|
10
|
+
* @see OIDC Core §3.1.3.6
|
|
11
|
+
*/
|
|
12
|
+
static computeAtHash(accessToken: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Filter out reserved claims that the server owns.
|
|
15
|
+
*/
|
|
16
|
+
static filterReservedClaims(claims: Record<string, unknown>): Record<string, unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve user OIDC claims by calling `getOidcClaims` if present,
|
|
19
|
+
* then filtering out reserved protocol claims.
|
|
20
|
+
*/
|
|
21
|
+
static resolveUserClaims(user: unknown, scopes: string[]): Promise<Record<string, unknown>>;
|
|
22
|
+
sign(options: {
|
|
23
|
+
sub: string;
|
|
24
|
+
clientId: string;
|
|
25
|
+
scopes: string[];
|
|
26
|
+
accessToken: string;
|
|
27
|
+
user: unknown;
|
|
28
|
+
nonce?: string;
|
|
29
|
+
}): Promise<string>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type JWK } from 'jose';
|
|
2
|
+
/**
|
|
3
|
+
* Manages the RSA key pair used to sign ID tokens.
|
|
4
|
+
* Accepts a JWK from config, caches the imported private key
|
|
5
|
+
* and public JWK for JWKS export.
|
|
6
|
+
*/
|
|
7
|
+
export declare class KeyService {
|
|
8
|
+
#private;
|
|
9
|
+
constructor(jwk: JWK);
|
|
10
|
+
/**
|
|
11
|
+
* Compute a `kid` from public key components (SHA-256, base64url).
|
|
12
|
+
* Same approach as node-oidc-provider.
|
|
13
|
+
*/
|
|
14
|
+
static computeKid(jwk: JWK): string;
|
|
15
|
+
sign(payload: Record<string, unknown>): Promise<string>;
|
|
16
|
+
getPublicJwks(): {
|
|
17
|
+
keys: JWK[];
|
|
18
|
+
};
|
|
19
|
+
get kid(): string;
|
|
20
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Router } from '@adonisjs/core/http';
|
|
2
|
-
import { type ResolvedSesameConfig, type Scope } from './types.ts';
|
|
2
|
+
import { type CreateClientOptions, type CreateClientResult, type ResolvedSesameConfig, type Scope, type UpdateClientOptions } from './types.ts';
|
|
3
|
+
import { KeyService } from './services/key_service.ts';
|
|
4
|
+
import { OAuthClient } from './models/oauth_client.ts';
|
|
3
5
|
export interface PurgeResult {
|
|
4
6
|
accessTokens: number;
|
|
5
7
|
refreshTokens: number;
|
|
@@ -16,12 +18,23 @@ export declare class SesameManager {
|
|
|
16
18
|
#private;
|
|
17
19
|
constructor(config: ResolvedSesameConfig, router: Router);
|
|
18
20
|
get config(): ResolvedSesameConfig;
|
|
21
|
+
get keyService(): KeyService;
|
|
22
|
+
get isOidcEnabled(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Load a user by ID using the configured user provider.
|
|
25
|
+
* Returns the original user model instance, or null if not found.
|
|
26
|
+
*/
|
|
27
|
+
findUserById(userId: string): Promise<unknown | null>;
|
|
19
28
|
/**
|
|
20
29
|
* Check if a scope is registered in the server configuration.
|
|
21
30
|
*
|
|
22
31
|
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-3.3
|
|
23
32
|
*/
|
|
24
33
|
hasScope(scope: Scope): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Check if the requested scope list uses any OIDC-specific scopes.
|
|
36
|
+
*/
|
|
37
|
+
usesOidcScopes(scopes: Scope[]): boolean;
|
|
25
38
|
/**
|
|
26
39
|
* Return the list of scopes that are not registered in the
|
|
27
40
|
* server configuration. When no scopes are configured, all
|
|
@@ -58,6 +71,36 @@ export declare class SesameManager {
|
|
|
58
71
|
expiredOnly?: boolean;
|
|
59
72
|
retentionHours?: number;
|
|
60
73
|
}): Promise<PurgeResult>;
|
|
74
|
+
/**
|
|
75
|
+
* Create a new OAuth client programmatically.
|
|
76
|
+
* Returns the client and the raw secret (only available at creation time).
|
|
77
|
+
*/
|
|
78
|
+
createClient(options: CreateClientOptions): Promise<CreateClientResult>;
|
|
79
|
+
/**
|
|
80
|
+
* Find a client by its public client_id.
|
|
81
|
+
*/
|
|
82
|
+
findClient(clientId: string): Promise<OAuthClient | null>;
|
|
83
|
+
/**
|
|
84
|
+
* List all clients, optionally filtered by userId.
|
|
85
|
+
*/
|
|
86
|
+
listClients(options?: {
|
|
87
|
+
userId?: string;
|
|
88
|
+
}): Promise<OAuthClient[]>;
|
|
89
|
+
/**
|
|
90
|
+
* Update an existing client by its public client_id.
|
|
91
|
+
* Returns the updated client, or null if not found.
|
|
92
|
+
*/
|
|
93
|
+
updateClient(clientId: string, options: UpdateClientOptions): Promise<OAuthClient | null>;
|
|
94
|
+
/**
|
|
95
|
+
* Delete a client and all its associated tokens, codes, and consents.
|
|
96
|
+
* Returns true if the client was found and deleted.
|
|
97
|
+
*/
|
|
98
|
+
deleteClient(clientId: string): Promise<boolean>;
|
|
99
|
+
/**
|
|
100
|
+
* Rotate the secret of a confidential client.
|
|
101
|
+
* Returns the new raw secret, or null if the client is public or not found.
|
|
102
|
+
*/
|
|
103
|
+
rotateClientSecret(clientId: string): Promise<string | null>;
|
|
61
104
|
/**
|
|
62
105
|
* Register OAuth 2.1 endpoint routes (token, authorize, consent, etc.).
|
|
63
106
|
*
|
|
@@ -77,12 +120,20 @@ export declare class SesameManager {
|
|
|
77
120
|
*/
|
|
78
121
|
registerRoutes(): void;
|
|
79
122
|
/**
|
|
80
|
-
* Register
|
|
123
|
+
* Register discovery routes at the root level.
|
|
81
124
|
*
|
|
82
125
|
* Must be called outside any prefix group so endpoints
|
|
83
126
|
* remain at `/.well-known/...`.
|
|
84
127
|
*/
|
|
85
|
-
|
|
128
|
+
registerDiscoveryRoutes(options?: {
|
|
129
|
+
jwksPath?: string;
|
|
130
|
+
}): void;
|
|
131
|
+
/**
|
|
132
|
+
* @deprecated Use `registerDiscoveryRoutes()` instead.
|
|
133
|
+
*/
|
|
134
|
+
registerWellKnownRoutes(options?: {
|
|
135
|
+
jwksPath?: string;
|
|
136
|
+
}): void;
|
|
86
137
|
/**
|
|
87
138
|
* Register a `/.well-known/oauth-protected-resource` endpoint
|
|
88
139
|
* for a specific resource path (RFC 9728). Useful for MCP
|