@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.
Files changed (69) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +130 -0
  3. package/build/authorize_controller-CUdEDNEi.js +136 -0
  4. package/build/client_info_controller-DeIVcW8B.js +18 -0
  5. package/build/client_service-B9fD3ZGe.js +53 -0
  6. package/build/commands/commands.json +1 -0
  7. package/build/commands/main.d.ts +4 -0
  8. package/build/commands/main.js +36 -0
  9. package/build/commands/sesame_purge.d.ts +21 -0
  10. package/build/commands/sesame_purge.js +28 -0
  11. package/build/configure.d.ts +2 -0
  12. package/build/configure.js +16 -0
  13. package/build/consent_controller-DFfx7qVs.js +87 -0
  14. package/build/decorate-2_8Ex77k.js +15 -0
  15. package/build/index.d.ts +14 -0
  16. package/build/index.js +27 -0
  17. package/build/introspect_controller-BzwfaUUE.js +63 -0
  18. package/build/main-kn40V-hF.js +2 -0
  19. package/build/metadata_controller-BSRRElQX.js +51 -0
  20. package/build/oauth_access_token-BpG8sq-c.js +18 -0
  21. package/build/oauth_client-eh0e5ql-.js +24 -0
  22. package/build/oauth_error-BQPqV-MV.js +78 -0
  23. package/build/providers/sesame_provider.d.ts +21 -0
  24. package/build/providers/sesame_provider.js +19 -0
  25. package/build/register_controller-BA7uQAgt.js +139 -0
  26. package/build/revoke_controller-CNIgNKH3.js +50 -0
  27. package/build/rolldown-runtime-BASaM9lw.js +12 -0
  28. package/build/routes-D6QCu0Pz.js +43 -0
  29. package/build/sesame_manager-B4tO2PLO.js +116 -0
  30. package/build/src/controllers/authorize_controller.d.ts +53 -0
  31. package/build/src/controllers/client_info_controller.d.ts +22 -0
  32. package/build/src/controllers/consent_controller.d.ts +27 -0
  33. package/build/src/controllers/introspect_controller.d.ts +28 -0
  34. package/build/src/controllers/metadata_controller.d.ts +64 -0
  35. package/build/src/controllers/register_controller.d.ts +91 -0
  36. package/build/src/controllers/revoke_controller.d.ts +16 -0
  37. package/build/src/controllers/token_controller.d.ts +24 -0
  38. package/build/src/decorators.d.ts +10 -0
  39. package/build/src/define_config.d.ts +16 -0
  40. package/build/src/grants/authorization_code_grant.d.ts +27 -0
  41. package/build/src/grants/refresh_token_grant.d.ts +27 -0
  42. package/build/src/guard/guard.d.ts +30 -0
  43. package/build/src/guard/main.d.ts +20 -0
  44. package/build/src/guard/main.js +17 -0
  45. package/build/src/guard/types.d.ts +46 -0
  46. package/build/src/guard/user_provider.d.ts +14 -0
  47. package/build/src/models/oauth_access_token.d.ts +23 -0
  48. package/build/src/models/oauth_authorization_code.d.ts +30 -0
  49. package/build/src/models/oauth_client.d.ts +33 -0
  50. package/build/src/models/oauth_consent.d.ts +22 -0
  51. package/build/src/models/oauth_refresh_token.d.ts +29 -0
  52. package/build/src/oauth_error.d.ts +359 -0
  53. package/build/src/routes.d.ts +28 -0
  54. package/build/src/rules.d.ts +12 -0
  55. package/build/src/services/client_service.d.ts +67 -0
  56. package/build/src/services/token_service.d.ts +42 -0
  57. package/build/src/sesame_manager.d.ts +66 -0
  58. package/build/src/types.d.ts +141 -0
  59. package/build/stubs/config/sesame.stub +30 -0
  60. package/build/stubs/main.d.ts +5 -0
  61. package/build/stubs/migrations/create_oauth_access_tokens_table.stub +25 -0
  62. package/build/stubs/migrations/create_oauth_authorization_codes_table.stub +27 -0
  63. package/build/stubs/migrations/create_oauth_clients_table.stub +31 -0
  64. package/build/stubs/migrations/create_oauth_consents_table.stub +24 -0
  65. package/build/stubs/migrations/create_oauth_refresh_tokens_table.stub +26 -0
  66. package/build/token_controller-C9wh813f.js +172 -0
  67. package/build/token_service-Czz9v5GI.js +30 -0
  68. package/build/user_provider-B3rXEUT3.js +150 -0
  69. 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
+ }