@julr/sesame 0.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.
- package/LICENSE.md +9 -0
- package/README.md +130 -0
- package/build/authorize_controller-CUdEDNEi.js +136 -0
- package/build/client_info_controller-DeIVcW8B.js +18 -0
- package/build/client_service-B9fD3ZGe.js +53 -0
- package/build/commands/commands.json +1 -0
- package/build/commands/main.d.ts +4 -0
- package/build/commands/main.js +36 -0
- package/build/commands/sesame_purge.d.ts +21 -0
- package/build/commands/sesame_purge.js +28 -0
- package/build/configure.d.ts +2 -0
- package/build/configure.js +16 -0
- package/build/consent_controller-DFfx7qVs.js +87 -0
- package/build/decorate-2_8Ex77k.js +15 -0
- package/build/index.d.ts +14 -0
- package/build/index.js +27 -0
- package/build/introspect_controller-BzwfaUUE.js +63 -0
- package/build/main-kn40V-hF.js +2 -0
- package/build/metadata_controller-BSRRElQX.js +51 -0
- package/build/oauth_access_token-BpG8sq-c.js +18 -0
- package/build/oauth_client-eh0e5ql-.js +24 -0
- package/build/oauth_error-BQPqV-MV.js +78 -0
- package/build/providers/sesame_provider.d.ts +21 -0
- package/build/providers/sesame_provider.js +19 -0
- package/build/register_controller-BA7uQAgt.js +139 -0
- package/build/revoke_controller-CNIgNKH3.js +50 -0
- package/build/rolldown-runtime-BASaM9lw.js +12 -0
- package/build/routes-D6QCu0Pz.js +43 -0
- package/build/sesame_manager-B4tO2PLO.js +116 -0
- package/build/src/controllers/authorize_controller.d.ts +53 -0
- package/build/src/controllers/client_info_controller.d.ts +22 -0
- package/build/src/controllers/consent_controller.d.ts +27 -0
- package/build/src/controllers/introspect_controller.d.ts +28 -0
- package/build/src/controllers/metadata_controller.d.ts +64 -0
- package/build/src/controllers/register_controller.d.ts +91 -0
- package/build/src/controllers/revoke_controller.d.ts +16 -0
- package/build/src/controllers/token_controller.d.ts +24 -0
- package/build/src/decorators.d.ts +10 -0
- package/build/src/define_config.d.ts +16 -0
- package/build/src/grants/authorization_code_grant.d.ts +27 -0
- package/build/src/grants/refresh_token_grant.d.ts +27 -0
- package/build/src/guard/guard.d.ts +30 -0
- package/build/src/guard/main.d.ts +20 -0
- package/build/src/guard/main.js +17 -0
- package/build/src/guard/types.d.ts +46 -0
- package/build/src/guard/user_provider.d.ts +14 -0
- package/build/src/models/oauth_access_token.d.ts +23 -0
- package/build/src/models/oauth_authorization_code.d.ts +30 -0
- package/build/src/models/oauth_client.d.ts +33 -0
- package/build/src/models/oauth_consent.d.ts +22 -0
- package/build/src/models/oauth_refresh_token.d.ts +29 -0
- package/build/src/oauth_error.d.ts +359 -0
- package/build/src/routes.d.ts +28 -0
- package/build/src/rules.d.ts +12 -0
- package/build/src/services/client_service.d.ts +67 -0
- package/build/src/services/token_service.d.ts +42 -0
- package/build/src/sesame_manager.d.ts +66 -0
- package/build/src/types.d.ts +141 -0
- package/build/stubs/config/sesame.stub +30 -0
- package/build/stubs/main.d.ts +5 -0
- package/build/stubs/migrations/create_oauth_access_tokens_table.stub +25 -0
- package/build/stubs/migrations/create_oauth_authorization_codes_table.stub +27 -0
- package/build/stubs/migrations/create_oauth_clients_table.stub +31 -0
- package/build/stubs/migrations/create_oauth_consents_table.stub +24 -0
- package/build/stubs/migrations/create_oauth_refresh_tokens_table.stub +26 -0
- package/build/token_controller-C9wh813f.js +172 -0
- package/build/token_service-Czz9v5GI.js +30 -0
- package/build/user_provider-B3rXEUT3.js +150 -0
- package/package.json +144 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DateTime } from 'luxon';
|
|
2
|
+
import { BaseModel } from '@adonisjs/lucid/orm';
|
|
3
|
+
/**
|
|
4
|
+
* Tracks which scopes a user has approved for a given client.
|
|
5
|
+
*
|
|
6
|
+
* When a user grants consent during the authorization flow,
|
|
7
|
+
* the approved scopes are persisted here. On subsequent
|
|
8
|
+
* authorization requests, if the requested scopes are a subset
|
|
9
|
+
* of previously approved scopes, the user is not prompted again.
|
|
10
|
+
*
|
|
11
|
+
* New scopes are merged into the existing record when the user
|
|
12
|
+
* approves additional permissions.
|
|
13
|
+
*/
|
|
14
|
+
export declare class OAuthConsent extends BaseModel {
|
|
15
|
+
static table: string;
|
|
16
|
+
id: string;
|
|
17
|
+
clientId: string;
|
|
18
|
+
userId: string;
|
|
19
|
+
scopes: string[];
|
|
20
|
+
createdAt: DateTime;
|
|
21
|
+
updatedAt: DateTime;
|
|
22
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DateTime } from 'luxon';
|
|
2
|
+
import { BaseModel } from '@adonisjs/lucid/orm';
|
|
3
|
+
/**
|
|
4
|
+
* Database record for an OAuth 2.0 refresh token (RFC 6749 §6).
|
|
5
|
+
*
|
|
6
|
+
* The `token` column stores the SHA-256 hash of the raw refresh
|
|
7
|
+
* token value. Refresh token rotation is enforced: each use
|
|
8
|
+
* produces a new token and revokes the old one.
|
|
9
|
+
*
|
|
10
|
+
* Replay detection is implemented by checking `revokedAt` —
|
|
11
|
+
* if a revoked token is presented, all tokens for that
|
|
12
|
+
* client+user pair are deleted as a security measure.
|
|
13
|
+
*
|
|
14
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-6
|
|
15
|
+
* @see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.14.2
|
|
16
|
+
*/
|
|
17
|
+
export declare class OAuthRefreshToken extends BaseModel {
|
|
18
|
+
static table: string;
|
|
19
|
+
id: string;
|
|
20
|
+
token: string;
|
|
21
|
+
accessTokenId: string;
|
|
22
|
+
clientId: string;
|
|
23
|
+
userId: string;
|
|
24
|
+
scopes: string[];
|
|
25
|
+
expiresAt: DateTime;
|
|
26
|
+
revokedAt: DateTime | null;
|
|
27
|
+
createdAt: DateTime;
|
|
28
|
+
updatedAt: DateTime;
|
|
29
|
+
}
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 error classes following the error codes defined in
|
|
3
|
+
* RFC 6749 §5.2 (https://datatracker.ietf.org/doc/html/rfc6749#section-5.2)
|
|
4
|
+
* and RFC 7591 §3.2.2 (https://datatracker.ietf.org/doc/html/rfc7591#section-3.2.2).
|
|
5
|
+
*
|
|
6
|
+
* Each error class extends AdonisJS Exception and self-renders via
|
|
7
|
+
* the `handle()` method, producing a standard OAuth JSON error response.
|
|
8
|
+
*/
|
|
9
|
+
import { Exception } from '@adonisjs/core/exceptions';
|
|
10
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
11
|
+
/**
|
|
12
|
+
* Base class for all OAuth errors. Extends AdonisJS Exception
|
|
13
|
+
* and renders the standard OAuth error response format:
|
|
14
|
+
* `{ error: "<oauth_code>", error_description: "<message>" }`.
|
|
15
|
+
*
|
|
16
|
+
* Subclasses declare a static `oauthCode` matching the `error` field
|
|
17
|
+
* defined by the OAuth 2.0 spec (e.g. `invalid_request`, `invalid_client`).
|
|
18
|
+
*/
|
|
19
|
+
export declare class OAuthError extends Exception {
|
|
20
|
+
static oauthCode: string;
|
|
21
|
+
get oauthCode(): string;
|
|
22
|
+
handle(error: this, ctx: HttpContext): void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The request is missing a required parameter, includes an unsupported
|
|
26
|
+
* parameter value, repeats a parameter, or is otherwise malformed.
|
|
27
|
+
*
|
|
28
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
29
|
+
*/
|
|
30
|
+
export declare const E_INVALID_REQUEST: {
|
|
31
|
+
new (message?: string, options?: ErrorOptions & {
|
|
32
|
+
code?: string;
|
|
33
|
+
status?: number;
|
|
34
|
+
}): {
|
|
35
|
+
get oauthCode(): string;
|
|
36
|
+
handle(error: /*elided*/ any, ctx: HttpContext): void;
|
|
37
|
+
name: string;
|
|
38
|
+
help?: string;
|
|
39
|
+
code?: string;
|
|
40
|
+
status: number;
|
|
41
|
+
toString(): string;
|
|
42
|
+
get [Symbol.toStringTag](): string;
|
|
43
|
+
message: string;
|
|
44
|
+
stack?: string;
|
|
45
|
+
cause?: unknown;
|
|
46
|
+
};
|
|
47
|
+
readonly status: number;
|
|
48
|
+
readonly code: string;
|
|
49
|
+
readonly message: string;
|
|
50
|
+
readonly oauthCode: string;
|
|
51
|
+
help?: string;
|
|
52
|
+
isError(error: unknown): error is Error;
|
|
53
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
54
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
55
|
+
stackTraceLimit: number;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Client authentication failed (e.g. unknown client, no client
|
|
59
|
+
* authentication included, or unsupported authentication method).
|
|
60
|
+
*
|
|
61
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
62
|
+
*/
|
|
63
|
+
export declare const E_INVALID_CLIENT: {
|
|
64
|
+
new (message?: string, options?: ErrorOptions & {
|
|
65
|
+
code?: string;
|
|
66
|
+
status?: number;
|
|
67
|
+
}): {
|
|
68
|
+
/**
|
|
69
|
+
* If the client attempted to authenticate via the Authorization header
|
|
70
|
+
* (Basic auth), the server MUST include WWW-Authenticate: Basic.
|
|
71
|
+
*
|
|
72
|
+
* @see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-3.2.4
|
|
73
|
+
*/
|
|
74
|
+
handle(error: /*elided*/ any, ctx: HttpContext): void;
|
|
75
|
+
get oauthCode(): string;
|
|
76
|
+
name: string;
|
|
77
|
+
help?: string;
|
|
78
|
+
code?: string;
|
|
79
|
+
status: number;
|
|
80
|
+
toString(): string;
|
|
81
|
+
get [Symbol.toStringTag](): string;
|
|
82
|
+
message: string;
|
|
83
|
+
stack?: string;
|
|
84
|
+
cause?: unknown;
|
|
85
|
+
};
|
|
86
|
+
readonly status: number;
|
|
87
|
+
readonly code: string;
|
|
88
|
+
readonly message: string;
|
|
89
|
+
readonly oauthCode: string;
|
|
90
|
+
help?: string;
|
|
91
|
+
isError(error: unknown): error is Error;
|
|
92
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
93
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
94
|
+
stackTraceLimit: number;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* The provided authorization grant (authorization code, refresh token,
|
|
98
|
+
* resource owner credentials) is invalid, expired, revoked, or does
|
|
99
|
+
* not match the redirection URI used in the authorization request.
|
|
100
|
+
*
|
|
101
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
102
|
+
*/
|
|
103
|
+
export declare const E_INVALID_GRANT: {
|
|
104
|
+
new (message?: string, options?: ErrorOptions & {
|
|
105
|
+
code?: string;
|
|
106
|
+
status?: number;
|
|
107
|
+
}): {
|
|
108
|
+
get oauthCode(): string;
|
|
109
|
+
handle(error: /*elided*/ any, ctx: HttpContext): void;
|
|
110
|
+
name: string;
|
|
111
|
+
help?: string;
|
|
112
|
+
code?: string;
|
|
113
|
+
status: number;
|
|
114
|
+
toString(): string;
|
|
115
|
+
get [Symbol.toStringTag](): string;
|
|
116
|
+
message: string;
|
|
117
|
+
stack?: string;
|
|
118
|
+
cause?: unknown;
|
|
119
|
+
};
|
|
120
|
+
readonly status: number;
|
|
121
|
+
readonly code: string;
|
|
122
|
+
readonly message: string;
|
|
123
|
+
readonly oauthCode: string;
|
|
124
|
+
help?: string;
|
|
125
|
+
isError(error: unknown): error is Error;
|
|
126
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
127
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
128
|
+
stackTraceLimit: number;
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* The requested scope is invalid, unknown, malformed, or exceeds
|
|
132
|
+
* the scope granted by the resource owner.
|
|
133
|
+
*
|
|
134
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
135
|
+
*/
|
|
136
|
+
export declare const E_INVALID_SCOPE: {
|
|
137
|
+
new (message?: string, options?: ErrorOptions & {
|
|
138
|
+
code?: string;
|
|
139
|
+
status?: number;
|
|
140
|
+
}): {
|
|
141
|
+
get oauthCode(): string;
|
|
142
|
+
handle(error: /*elided*/ any, ctx: HttpContext): void;
|
|
143
|
+
name: string;
|
|
144
|
+
help?: string;
|
|
145
|
+
code?: string;
|
|
146
|
+
status: number;
|
|
147
|
+
toString(): string;
|
|
148
|
+
get [Symbol.toStringTag](): string;
|
|
149
|
+
message: string;
|
|
150
|
+
stack?: string;
|
|
151
|
+
cause?: unknown;
|
|
152
|
+
};
|
|
153
|
+
readonly status: number;
|
|
154
|
+
readonly code: string;
|
|
155
|
+
readonly message: string;
|
|
156
|
+
readonly oauthCode: string;
|
|
157
|
+
help?: string;
|
|
158
|
+
isError(error: unknown): error is Error;
|
|
159
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
160
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
161
|
+
stackTraceLimit: number;
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* The access token provided is expired, revoked, malformed,
|
|
165
|
+
* or invalid for other reasons.
|
|
166
|
+
*
|
|
167
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6750#section-3.1
|
|
168
|
+
*/
|
|
169
|
+
export declare const E_INVALID_TOKEN: {
|
|
170
|
+
new (message?: string, options?: ErrorOptions & {
|
|
171
|
+
code?: string;
|
|
172
|
+
status?: number;
|
|
173
|
+
}): {
|
|
174
|
+
get oauthCode(): string;
|
|
175
|
+
handle(error: /*elided*/ any, ctx: HttpContext): void;
|
|
176
|
+
name: string;
|
|
177
|
+
help?: string;
|
|
178
|
+
code?: string;
|
|
179
|
+
status: number;
|
|
180
|
+
toString(): string;
|
|
181
|
+
get [Symbol.toStringTag](): string;
|
|
182
|
+
message: string;
|
|
183
|
+
stack?: string;
|
|
184
|
+
cause?: unknown;
|
|
185
|
+
};
|
|
186
|
+
readonly status: number;
|
|
187
|
+
readonly code: string;
|
|
188
|
+
readonly message: string;
|
|
189
|
+
readonly oauthCode: string;
|
|
190
|
+
help?: string;
|
|
191
|
+
isError(error: unknown): error is Error;
|
|
192
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
193
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
194
|
+
stackTraceLimit: number;
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* The authorization grant type is not supported by the
|
|
198
|
+
* authorization server.
|
|
199
|
+
*
|
|
200
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
201
|
+
*/
|
|
202
|
+
export declare const E_UNSUPPORTED_GRANT_TYPE: {
|
|
203
|
+
new (message?: string, options?: ErrorOptions & {
|
|
204
|
+
code?: string;
|
|
205
|
+
status?: number;
|
|
206
|
+
}): {
|
|
207
|
+
get oauthCode(): string;
|
|
208
|
+
handle(error: /*elided*/ any, ctx: HttpContext): void;
|
|
209
|
+
name: string;
|
|
210
|
+
help?: string;
|
|
211
|
+
code?: string;
|
|
212
|
+
status: number;
|
|
213
|
+
toString(): string;
|
|
214
|
+
get [Symbol.toStringTag](): string;
|
|
215
|
+
message: string;
|
|
216
|
+
stack?: string;
|
|
217
|
+
cause?: unknown;
|
|
218
|
+
};
|
|
219
|
+
readonly status: number;
|
|
220
|
+
readonly code: string;
|
|
221
|
+
readonly message: string;
|
|
222
|
+
readonly oauthCode: string;
|
|
223
|
+
help?: string;
|
|
224
|
+
isError(error: unknown): error is Error;
|
|
225
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
226
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
227
|
+
stackTraceLimit: number;
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* The authorization server does not support obtaining an
|
|
231
|
+
* authorization code using this response type.
|
|
232
|
+
*
|
|
233
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
|
|
234
|
+
*/
|
|
235
|
+
export declare const E_UNSUPPORTED_RESPONSE_TYPE: {
|
|
236
|
+
new (message?: string, options?: ErrorOptions & {
|
|
237
|
+
code?: string;
|
|
238
|
+
status?: number;
|
|
239
|
+
}): {
|
|
240
|
+
get oauthCode(): string;
|
|
241
|
+
handle(error: /*elided*/ any, ctx: HttpContext): void;
|
|
242
|
+
name: string;
|
|
243
|
+
help?: string;
|
|
244
|
+
code?: string;
|
|
245
|
+
status: number;
|
|
246
|
+
toString(): string;
|
|
247
|
+
get [Symbol.toStringTag](): string;
|
|
248
|
+
message: string;
|
|
249
|
+
stack?: string;
|
|
250
|
+
cause?: unknown;
|
|
251
|
+
};
|
|
252
|
+
readonly status: number;
|
|
253
|
+
readonly code: string;
|
|
254
|
+
readonly message: string;
|
|
255
|
+
readonly oauthCode: string;
|
|
256
|
+
help?: string;
|
|
257
|
+
isError(error: unknown): error is Error;
|
|
258
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
259
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
260
|
+
stackTraceLimit: number;
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* The resource owner or authorization server denied the request.
|
|
264
|
+
*
|
|
265
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
|
|
266
|
+
*/
|
|
267
|
+
export declare const E_ACCESS_DENIED: {
|
|
268
|
+
new (message?: string, options?: ErrorOptions & {
|
|
269
|
+
code?: string;
|
|
270
|
+
status?: number;
|
|
271
|
+
}): {
|
|
272
|
+
get oauthCode(): string;
|
|
273
|
+
handle(error: /*elided*/ any, ctx: HttpContext): void;
|
|
274
|
+
name: string;
|
|
275
|
+
help?: string;
|
|
276
|
+
code?: string;
|
|
277
|
+
status: number;
|
|
278
|
+
toString(): string;
|
|
279
|
+
get [Symbol.toStringTag](): string;
|
|
280
|
+
message: string;
|
|
281
|
+
stack?: string;
|
|
282
|
+
cause?: unknown;
|
|
283
|
+
};
|
|
284
|
+
readonly status: number;
|
|
285
|
+
readonly code: string;
|
|
286
|
+
readonly message: string;
|
|
287
|
+
readonly oauthCode: string;
|
|
288
|
+
help?: string;
|
|
289
|
+
isError(error: unknown): error is Error;
|
|
290
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
291
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
292
|
+
stackTraceLimit: number;
|
|
293
|
+
};
|
|
294
|
+
/**
|
|
295
|
+
* The client metadata value is invalid, as defined in the dynamic
|
|
296
|
+
* client registration protocol.
|
|
297
|
+
*
|
|
298
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7591#section-3.2.2
|
|
299
|
+
*/
|
|
300
|
+
export declare const E_INVALID_CLIENT_METADATA: {
|
|
301
|
+
new (message?: string, options?: ErrorOptions & {
|
|
302
|
+
code?: string;
|
|
303
|
+
status?: number;
|
|
304
|
+
}): {
|
|
305
|
+
get oauthCode(): string;
|
|
306
|
+
handle(error: /*elided*/ any, ctx: HttpContext): void;
|
|
307
|
+
name: string;
|
|
308
|
+
help?: string;
|
|
309
|
+
code?: string;
|
|
310
|
+
status: number;
|
|
311
|
+
toString(): string;
|
|
312
|
+
get [Symbol.toStringTag](): string;
|
|
313
|
+
message: string;
|
|
314
|
+
stack?: string;
|
|
315
|
+
cause?: unknown;
|
|
316
|
+
};
|
|
317
|
+
readonly status: number;
|
|
318
|
+
readonly code: string;
|
|
319
|
+
readonly message: string;
|
|
320
|
+
readonly oauthCode: string;
|
|
321
|
+
help?: string;
|
|
322
|
+
isError(error: unknown): error is Error;
|
|
323
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
324
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
325
|
+
stackTraceLimit: number;
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* The authorization server encountered an unexpected condition
|
|
329
|
+
* that prevented it from fulfilling the request.
|
|
330
|
+
*
|
|
331
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
|
|
332
|
+
*/
|
|
333
|
+
export declare const E_SERVER_ERROR: {
|
|
334
|
+
new (message?: string, options?: ErrorOptions & {
|
|
335
|
+
code?: string;
|
|
336
|
+
status?: number;
|
|
337
|
+
}): {
|
|
338
|
+
get oauthCode(): string;
|
|
339
|
+
handle(error: /*elided*/ any, ctx: HttpContext): void;
|
|
340
|
+
name: string;
|
|
341
|
+
help?: string;
|
|
342
|
+
code?: string;
|
|
343
|
+
status: number;
|
|
344
|
+
toString(): string;
|
|
345
|
+
get [Symbol.toStringTag](): string;
|
|
346
|
+
message: string;
|
|
347
|
+
stack?: string;
|
|
348
|
+
cause?: unknown;
|
|
349
|
+
};
|
|
350
|
+
readonly status: number;
|
|
351
|
+
readonly code: string;
|
|
352
|
+
readonly message: string;
|
|
353
|
+
readonly oauthCode: string;
|
|
354
|
+
help?: string;
|
|
355
|
+
isError(error: unknown): error is Error;
|
|
356
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
357
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
358
|
+
stackTraceLimit: number;
|
|
359
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Router } from '@adonisjs/core/http';
|
|
2
|
+
/**
|
|
3
|
+
* Register all OAuth 2.1 routes on the given AdonisJS router.
|
|
4
|
+
*
|
|
5
|
+
* Endpoints registered:
|
|
6
|
+
* - `POST /oauth/token` — Token endpoint (RFC 6749 §3.2)
|
|
7
|
+
* - `GET /oauth/authorize` — Authorization endpoint (RFC 6749 §3.1)
|
|
8
|
+
* - `POST /oauth/consent` — User consent submission
|
|
9
|
+
* - `POST /oauth/introspect` — Token introspection (RFC 7662)
|
|
10
|
+
* - `POST /oauth/revoke` — Token revocation (RFC 7009)
|
|
11
|
+
* - `POST /oauth/register` — Dynamic client registration (RFC 7591)
|
|
12
|
+
* - `GET /oauth/client-info` — Public client information (RFC 6819 §4.4.1.4)
|
|
13
|
+
* - `GET /.well-known/oauth-authorization-server` — Server metadata (RFC 8414)
|
|
14
|
+
* - `GET /.well-known/openid-configuration` — OpenID Connect discovery
|
|
15
|
+
* - `GET /.well-known/oauth-protected-resource` — Protected resource metadata (RFC 9728)
|
|
16
|
+
*/
|
|
17
|
+
export declare function registerRoutes(router: Router): void;
|
|
18
|
+
/**
|
|
19
|
+
* Register a `/.well-known/oauth-protected-resource` endpoint for a
|
|
20
|
+
* specific resource path (RFC 9728). Useful for MCP servers that need
|
|
21
|
+
* per-resource discovery.
|
|
22
|
+
*
|
|
23
|
+
* @see https://datatracker.ietf.org/doc/html/rfc9728
|
|
24
|
+
*/
|
|
25
|
+
export declare function registerProtectedResource(router: Router, options: {
|
|
26
|
+
resource: string;
|
|
27
|
+
scopes?: string[];
|
|
28
|
+
}): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates a redirect URI per OAuth 2.1 / RFC 8252 rules.
|
|
3
|
+
* Blocks fragments, dangerous schemes, and requires HTTPS for non-localhost hosts.
|
|
4
|
+
*/
|
|
5
|
+
export declare const redirectUriRule: (options?: undefined) => import("@vinejs/vine/types").Validation<undefined>;
|
|
6
|
+
/**
|
|
7
|
+
* Blocks dangerous URI schemes and enforces same host+scheme
|
|
8
|
+
* matching with redirect_uris (RFC 7591 §5).
|
|
9
|
+
*
|
|
10
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7591#section-5
|
|
11
|
+
*/
|
|
12
|
+
export declare const metadataUriRule: (options?: undefined) => import("@vinejs/vine/types").Validation<undefined>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracted client credentials from a request.
|
|
3
|
+
*/
|
|
4
|
+
export interface ClientCredentials {
|
|
5
|
+
clientId: string;
|
|
6
|
+
clientSecret?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Handles OAuth client authentication and credential management.
|
|
10
|
+
*
|
|
11
|
+
* Supports the client authentication methods defined in RFC 6749 §2.3:
|
|
12
|
+
* - `client_secret_basic`: HTTP Basic auth with client_id:client_secret
|
|
13
|
+
* - `client_secret_post`: credentials in the request body
|
|
14
|
+
* - `none`: public clients (no secret)
|
|
15
|
+
*
|
|
16
|
+
* Client secrets are stored as SHA-256 hashes and compared using
|
|
17
|
+
* timing-safe equality to prevent timing attacks.
|
|
18
|
+
*
|
|
19
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-2.3
|
|
20
|
+
*/
|
|
21
|
+
export declare class ClientService {
|
|
22
|
+
/**
|
|
23
|
+
* Parse an HTTP Basic Authorization header into client credentials.
|
|
24
|
+
* Follows RFC 6749 §2.3.1 — the client_id and client_secret are
|
|
25
|
+
* URL-decoded after base64 decoding.
|
|
26
|
+
*
|
|
27
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1
|
|
28
|
+
*/
|
|
29
|
+
parseBasicAuth(header: string): ClientCredentials | null;
|
|
30
|
+
/**
|
|
31
|
+
* Extract client credentials from a request. Checks the
|
|
32
|
+
* Authorization header first (Basic auth), then falls back
|
|
33
|
+
* to POST body parameters (`client_id` / `client_secret`).
|
|
34
|
+
*/
|
|
35
|
+
extractCredentials(options: {
|
|
36
|
+
authorizationHeader?: string;
|
|
37
|
+
bodyClientId?: string;
|
|
38
|
+
bodyClientSecret?: string;
|
|
39
|
+
}): ClientCredentials | null;
|
|
40
|
+
/**
|
|
41
|
+
* Validate that requested scopes are within the client's
|
|
42
|
+
* allowed scopes. Throws `E_INVALID_SCOPE` if any scope
|
|
43
|
+
* is not permitted. An empty `clientScopes` array means the
|
|
44
|
+
* client has no scope permissions (RFC 6749 §2, §3.3).
|
|
45
|
+
*
|
|
46
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-3.3
|
|
47
|
+
*/
|
|
48
|
+
validateClientScopes(requestedScopes: string[], clientScopes: string[]): void;
|
|
49
|
+
/**
|
|
50
|
+
* Hash a client secret for storage using SHA-256
|
|
51
|
+
* (base64url-encoded).
|
|
52
|
+
*/
|
|
53
|
+
hashSecret(secret: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Verify a client secret against its stored hash using
|
|
56
|
+
* timing-safe comparison to prevent timing attacks.
|
|
57
|
+
*/
|
|
58
|
+
verifySecret(secret: string, storedHash: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Generate a random client ID (16 bytes, hex-encoded).
|
|
61
|
+
*/
|
|
62
|
+
generateClientId(): string;
|
|
63
|
+
/**
|
|
64
|
+
* Generate a random client secret (32 bytes, base64url-encoded).
|
|
65
|
+
*/
|
|
66
|
+
generateClientSecret(): string;
|
|
67
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { SesameManager } from '../sesame_manager.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Handles opaque token generation for access tokens, refresh tokens,
|
|
4
|
+
* and authorization codes.
|
|
5
|
+
*
|
|
6
|
+
* All tokens are random opaque values. Only their SHA-256 hashes
|
|
7
|
+
* are stored in the database, so the raw tokens cannot be
|
|
8
|
+
* reconstructed from a database leak.
|
|
9
|
+
*/
|
|
10
|
+
export declare class TokenService {
|
|
11
|
+
#private;
|
|
12
|
+
constructor(manager: SesameManager);
|
|
13
|
+
/**
|
|
14
|
+
* Create an opaque access token. Returns the raw token
|
|
15
|
+
* (sent to the client), its SHA-256 hash (stored in DB),
|
|
16
|
+
* and the computed expiration date.
|
|
17
|
+
*/
|
|
18
|
+
createAccessToken(): {
|
|
19
|
+
raw: string;
|
|
20
|
+
hash: string;
|
|
21
|
+
expiresAt: Date;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Create an opaque refresh token. Returns the raw token
|
|
25
|
+
* (sent to the client) and its SHA-256 hash (stored in DB).
|
|
26
|
+
*/
|
|
27
|
+
createRefreshToken(): {
|
|
28
|
+
raw: string;
|
|
29
|
+
hash: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Generate a cryptographically random opaque token
|
|
33
|
+
* (32 bytes, base64url-encoded).
|
|
34
|
+
*/
|
|
35
|
+
generateOpaqueToken(): string;
|
|
36
|
+
/**
|
|
37
|
+
* SHA-256 hash a token value for secure storage.
|
|
38
|
+
* All tokens (codes, access tokens, refresh tokens) are stored
|
|
39
|
+
* as hashes so raw values cannot be reconstructed from a DB leak.
|
|
40
|
+
*/
|
|
41
|
+
hashToken(token: string): string;
|
|
42
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ResolvedSesameConfig } from './types.ts';
|
|
2
|
+
export interface PurgeResult {
|
|
3
|
+
accessTokens: number;
|
|
4
|
+
refreshTokens: number;
|
|
5
|
+
authorizationCodes: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Central manager for the Sésame OAuth 2.1 server.
|
|
9
|
+
*
|
|
10
|
+
* Holds the resolved configuration. Registered as a singleton
|
|
11
|
+
* in the AdonisJS IoC container by `SesameProvider`.
|
|
12
|
+
*/
|
|
13
|
+
export declare class SesameManager {
|
|
14
|
+
#private;
|
|
15
|
+
constructor(config: ResolvedSesameConfig);
|
|
16
|
+
get config(): ResolvedSesameConfig;
|
|
17
|
+
/**
|
|
18
|
+
* Check if a scope is registered in the server configuration.
|
|
19
|
+
*
|
|
20
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-3.3
|
|
21
|
+
*/
|
|
22
|
+
hasScope(scope: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Return the list of scopes that are not registered in the
|
|
25
|
+
* server configuration. When no scopes are configured, all
|
|
26
|
+
* requested scopes are considered unknown per RFC 6749 §3.3
|
|
27
|
+
* (`invalid_scope` — "The requested scope is invalid, unknown,
|
|
28
|
+
* or malformed").
|
|
29
|
+
*
|
|
30
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-3.3
|
|
31
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
|
|
32
|
+
*/
|
|
33
|
+
validateScopes(scopes: string[]): string[];
|
|
34
|
+
/**
|
|
35
|
+
* Check if a grant type is enabled in the server configuration.
|
|
36
|
+
*/
|
|
37
|
+
isGrantTypeEnabled(grantType: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Revoke all OAuth artifacts for a given user.
|
|
40
|
+
*
|
|
41
|
+
* Call this when a user is deleted or deactivated to ensure
|
|
42
|
+
* none of their tokens remain usable. Revokes access tokens
|
|
43
|
+
* and refresh tokens, and deletes authorization codes and
|
|
44
|
+
* consent records.
|
|
45
|
+
*/
|
|
46
|
+
revokeAllForUser(userId: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Purge revoked and/or expired tokens and authorization codes.
|
|
49
|
+
*
|
|
50
|
+
* Returns the total number of deleted records. Expired tokens are
|
|
51
|
+
* retained for `retentionHours` (default 168 = 7 days) to allow
|
|
52
|
+
* for debugging and audit trails.
|
|
53
|
+
*
|
|
54
|
+
* Inspired by Laravel Passport's `passport:purge` command.
|
|
55
|
+
*/
|
|
56
|
+
purgeTokens(options?: {
|
|
57
|
+
revokedOnly?: boolean;
|
|
58
|
+
expiredOnly?: boolean;
|
|
59
|
+
retentionHours?: number;
|
|
60
|
+
}): Promise<PurgeResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Parse a duration string like '1h', '30m', '10d' into seconds.
|
|
63
|
+
* Supported units: `s` (seconds), `m` (minutes), `h` (hours), `d` (days).
|
|
64
|
+
*/
|
|
65
|
+
parseTtl(ttl: string): number;
|
|
66
|
+
}
|