@adonisjs/auth 9.0.0-9 → 9.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 (125) hide show
  1. package/build/chunk-3HZHOWKL.js +8 -0
  2. package/build/chunk-3HZHOWKL.js.map +1 -0
  3. package/build/chunk-52DVKHJR.js +246 -0
  4. package/build/chunk-52DVKHJR.js.map +1 -0
  5. package/build/chunk-BHB55PBJ.js +197 -0
  6. package/build/chunk-BHB55PBJ.js.map +1 -0
  7. package/build/chunk-CZCFTIBB.js +21 -0
  8. package/build/chunk-CZCFTIBB.js.map +1 -0
  9. package/build/index.d.ts +7 -6
  10. package/build/index.js +146 -15
  11. package/build/index.js.map +1 -0
  12. package/build/modules/access_tokens_guard/access_token.d.ts +137 -0
  13. package/build/modules/access_tokens_guard/crc32.d.ts +16 -0
  14. package/build/modules/access_tokens_guard/define_config.d.ts +17 -0
  15. package/build/modules/access_tokens_guard/guard.d.ts +81 -0
  16. package/build/modules/access_tokens_guard/main.d.ts +5 -0
  17. package/build/modules/access_tokens_guard/main.js +929 -0
  18. package/build/modules/access_tokens_guard/main.js.map +1 -0
  19. package/build/modules/access_tokens_guard/token_providers/db.d.ts +76 -0
  20. package/build/modules/access_tokens_guard/types.d.ts +208 -0
  21. package/build/modules/access_tokens_guard/types.js +1 -0
  22. package/build/modules/access_tokens_guard/types.js.map +1 -0
  23. package/build/modules/access_tokens_guard/user_providers/lucid.d.ts +53 -0
  24. package/build/modules/session_guard/define_config.d.ts +17 -0
  25. package/build/modules/session_guard/guard.d.ts +98 -0
  26. package/build/modules/session_guard/main.d.ts +5 -0
  27. package/build/modules/session_guard/main.js +741 -0
  28. package/build/modules/session_guard/main.js.map +1 -0
  29. package/build/modules/session_guard/remember_me_token.d.ts +88 -0
  30. package/build/modules/session_guard/token_providers/db.d.ts +69 -0
  31. package/build/modules/session_guard/types.d.ts +243 -0
  32. package/build/modules/session_guard/types.js +1 -0
  33. package/build/modules/session_guard/types.js.map +1 -0
  34. package/build/modules/session_guard/user_providers/lucid.d.ts +57 -0
  35. package/build/providers/auth_provider.d.ts +1 -1
  36. package/build/providers/auth_provider.js +31 -27
  37. package/build/providers/auth_provider.js.map +1 -0
  38. package/build/services/auth.d.ts +1 -1
  39. package/build/services/auth.js +10 -15
  40. package/build/services/auth.js.map +1 -0
  41. package/build/src/{auth/auth_manager.d.ts → auth_manager.d.ts} +8 -3
  42. package/build/src/authenticator.d.ts +81 -0
  43. package/build/src/{auth/authenticator_client.d.ts → authenticator_client.d.ts} +4 -4
  44. package/build/src/{auth/define_config.d.ts → define_config.d.ts} +0 -10
  45. package/build/src/errors.d.ts +105 -0
  46. package/build/src/{auth/middleware → middleware}/initialize_auth_middleware.d.ts +3 -2
  47. package/build/src/middleware/initialize_auth_middleware.js +17 -0
  48. package/build/src/middleware/initialize_auth_middleware.js.map +1 -0
  49. package/build/src/mixins/with_auth_finder.d.ts +156 -0
  50. package/build/src/{auth/plugins → plugins}/japa/api_client.d.ts +8 -8
  51. package/build/src/plugins/japa/api_client.js +59 -0
  52. package/build/src/plugins/japa/api_client.js.map +1 -0
  53. package/build/src/{auth/plugins → plugins}/japa/browser_client.d.ts +10 -7
  54. package/build/src/plugins/japa/browser_client.js +67 -0
  55. package/build/src/plugins/japa/browser_client.js.map +1 -0
  56. package/build/src/{auth/types.d.ts → types.d.ts} +31 -26
  57. package/build/src/types.js +1 -0
  58. package/build/src/types.js.map +1 -0
  59. package/package.json +88 -68
  60. package/build/configure.js +0 -47
  61. package/build/factories/basic_auth_guard_factory.d.ts +0 -12
  62. package/build/factories/basic_auth_guard_factory.js +0 -22
  63. package/build/factories/database_token_factory.d.ts +0 -36
  64. package/build/factories/database_token_factory.js +0 -54
  65. package/build/factories/database_user_provider.d.ts +0 -14
  66. package/build/factories/database_user_provider.js +0 -27
  67. package/build/factories/lucid_user_provider.d.ts +0 -28
  68. package/build/factories/lucid_user_provider.js +0 -68
  69. package/build/factories/main.d.ts +0 -4
  70. package/build/factories/main.js +0 -12
  71. package/build/factories/session_guard_factory.d.ts +0 -13
  72. package/build/factories/session_guard_factory.js +0 -24
  73. package/build/src/auth/auth_manager.js +0 -41
  74. package/build/src/auth/authenticator.d.ts +0 -63
  75. package/build/src/auth/authenticator.js +0 -129
  76. package/build/src/auth/authenticator_client.js +0 -59
  77. package/build/src/auth/debug.js +0 -10
  78. package/build/src/auth/define_config.js +0 -54
  79. package/build/src/auth/errors.d.ts +0 -90
  80. package/build/src/auth/errors.js +0 -201
  81. package/build/src/auth/middleware/initialize_auth_middleware.js +0 -25
  82. package/build/src/auth/plugins/japa/api_client.js +0 -63
  83. package/build/src/auth/plugins/japa/browser_client.js +0 -64
  84. package/build/src/auth/symbols.js +0 -17
  85. package/build/src/auth/types.js +0 -9
  86. package/build/src/auth/user_providers/main.d.ts +0 -15
  87. package/build/src/auth/user_providers/main.js +0 -22
  88. package/build/src/core/guard_user.d.ts +0 -26
  89. package/build/src/core/guard_user.js +0 -29
  90. package/build/src/core/token.d.ts +0 -89
  91. package/build/src/core/token.js +0 -114
  92. package/build/src/core/token_providers/database.d.ts +0 -77
  93. package/build/src/core/token_providers/database.js +0 -113
  94. package/build/src/core/types.d.ts +0 -178
  95. package/build/src/core/types.js +0 -9
  96. package/build/src/core/user_providers/database.d.ts +0 -78
  97. package/build/src/core/user_providers/database.js +0 -117
  98. package/build/src/core/user_providers/lucid.d.ts +0 -61
  99. package/build/src/core/user_providers/lucid.js +0 -122
  100. package/build/src/guards/basic_auth/define_config.d.ts +0 -16
  101. package/build/src/guards/basic_auth/define_config.js +0 -38
  102. package/build/src/guards/basic_auth/guard.d.ts +0 -70
  103. package/build/src/guards/basic_auth/guard.js +0 -190
  104. package/build/src/guards/basic_auth/main.d.ts +0 -2
  105. package/build/src/guards/basic_auth/main.js +0 -10
  106. package/build/src/guards/basic_auth/types.d.ts +0 -35
  107. package/build/src/guards/basic_auth/types.js +0 -9
  108. package/build/src/guards/session/define_config.d.ts +0 -23
  109. package/build/src/guards/session/define_config.js +0 -56
  110. package/build/src/guards/session/guard.d.ts +0 -123
  111. package/build/src/guards/session/guard.js +0 -510
  112. package/build/src/guards/session/main.d.ts +0 -3
  113. package/build/src/guards/session/main.js +0 -11
  114. package/build/src/guards/session/token.d.ts +0 -57
  115. package/build/src/guards/session/token.js +0 -58
  116. package/build/src/guards/session/token_providers/main.d.ts +0 -33
  117. package/build/src/guards/session/token_providers/main.js +0 -42
  118. package/build/src/guards/session/types.d.ts +0 -104
  119. package/build/src/guards/session/types.js +0 -9
  120. package/build/stubs/main.d.ts +0 -1
  121. package/build/stubs/main.js +0 -10
  122. package/build/stubs/middleware/auth_middleware.stub +0 -30
  123. package/build/stubs/middleware/guest_middleware.stub +0 -36
  124. /package/build/src/{auth/debug.d.ts → debug.d.ts} +0 -0
  125. /package/build/src/{auth/symbols.d.ts → symbols.d.ts} +0 -0
@@ -0,0 +1,741 @@
1
+ import {
2
+ E_UNAUTHORIZED_ACCESS
3
+ } from "../../chunk-BHB55PBJ.js";
4
+ import "../../chunk-CZCFTIBB.js";
5
+
6
+ // modules/session_guard/remember_me_token.ts
7
+ import { createHash } from "node:crypto";
8
+ import string from "@adonisjs/core/helpers/string";
9
+ import { Secret, base64, safeEqual } from "@adonisjs/core/helpers";
10
+ var RememberMeToken = class {
11
+ /**
12
+ * Decodes a publicly shared token and return the series
13
+ * and the token value from it.
14
+ *
15
+ * Returns null when unable to decode the token because of
16
+ * invalid format or encoding.
17
+ */
18
+ static decode(value) {
19
+ if (typeof value !== "string") {
20
+ return null;
21
+ }
22
+ if (!value) {
23
+ return null;
24
+ }
25
+ const [identifier, ...tokenValue] = value.split(".");
26
+ if (!identifier || tokenValue.length === 0) {
27
+ return null;
28
+ }
29
+ const decodedIdentifier = base64.urlDecode(identifier);
30
+ const decodedSecret = base64.urlDecode(tokenValue.join("."));
31
+ if (!decodedIdentifier || !decodedSecret) {
32
+ return null;
33
+ }
34
+ return {
35
+ identifier: decodedIdentifier,
36
+ secret: new Secret(decodedSecret)
37
+ };
38
+ }
39
+ /**
40
+ * Creates a transient token that can be shared with the persistence
41
+ * layer.
42
+ */
43
+ static createTransientToken(userId, size, expiresIn) {
44
+ const expiresAt = /* @__PURE__ */ new Date();
45
+ expiresAt.setSeconds(expiresAt.getSeconds() + string.seconds.parse(expiresIn));
46
+ return {
47
+ userId,
48
+ expiresAt,
49
+ ...this.seed(size)
50
+ };
51
+ }
52
+ /**
53
+ * Creates a secret opaque token and its hash.
54
+ */
55
+ static seed(size) {
56
+ const seed = string.random(size);
57
+ const secret = new Secret(seed);
58
+ const hash = createHash("sha256").update(secret.release()).digest("hex");
59
+ return { secret, hash };
60
+ }
61
+ /**
62
+ * Identifer is a unique sequence to identify the
63
+ * token within database. It should be the
64
+ * primary/unique key
65
+ */
66
+ identifier;
67
+ /**
68
+ * Reference to the user id for whom the token
69
+ * is generated.
70
+ */
71
+ tokenableId;
72
+ /**
73
+ * The value is a public representation of a token. It is created
74
+ * by combining the "identifier"."secret"
75
+ */
76
+ value;
77
+ /**
78
+ * Hash is computed from the seed to later verify the validity
79
+ * of seed
80
+ */
81
+ hash;
82
+ /**
83
+ * Date/time when the token instance was created
84
+ */
85
+ createdAt;
86
+ /**
87
+ * Date/time when the token was updated
88
+ */
89
+ updatedAt;
90
+ /**
91
+ * Timestamp at which the token will expire
92
+ */
93
+ expiresAt;
94
+ constructor(attributes) {
95
+ this.identifier = attributes.identifier;
96
+ this.tokenableId = attributes.tokenableId;
97
+ this.hash = attributes.hash;
98
+ this.createdAt = attributes.createdAt;
99
+ this.updatedAt = attributes.updatedAt;
100
+ this.expiresAt = attributes.expiresAt;
101
+ if (attributes.secret) {
102
+ this.value = new Secret(
103
+ `${base64.urlEncode(String(this.identifier))}.${base64.urlEncode(
104
+ attributes.secret.release()
105
+ )}`
106
+ );
107
+ }
108
+ }
109
+ /**
110
+ * Check if the token has been expired. Verifies
111
+ * the "expiresAt" timestamp with the current
112
+ * date.
113
+ */
114
+ isExpired() {
115
+ return this.expiresAt < /* @__PURE__ */ new Date();
116
+ }
117
+ /**
118
+ * Verifies the value of a token against the pre-defined hash
119
+ */
120
+ verify(secret) {
121
+ const newHash = createHash("sha256").update(secret.release()).digest("hex");
122
+ return safeEqual(this.hash, newHash);
123
+ }
124
+ };
125
+
126
+ // modules/session_guard/guard.ts
127
+ import { Secret as Secret2 } from "@adonisjs/core/helpers";
128
+ import { RuntimeException } from "@adonisjs/core/exceptions";
129
+ var SessionGuard = class {
130
+ /**
131
+ * A unique name for the guard.
132
+ */
133
+ #name;
134
+ /**
135
+ * Reference to the current HTTP context
136
+ */
137
+ #ctx;
138
+ /**
139
+ * Options accepted by the session guard
140
+ */
141
+ #options;
142
+ /**
143
+ * Provider to lookup user details
144
+ */
145
+ #userProvider;
146
+ /**
147
+ * Emitter to emit events
148
+ */
149
+ #emitter;
150
+ /**
151
+ * Driver name of the guard
152
+ */
153
+ driverName = "session";
154
+ /**
155
+ * Whether or not the authentication has been attempted
156
+ * during the current request.
157
+ */
158
+ authenticationAttempted = false;
159
+ /**
160
+ * A boolean to know if a remember me token was used in attempt
161
+ * to login a user.
162
+ */
163
+ attemptedViaRemember = false;
164
+ /**
165
+ * A boolean to know if the current request has
166
+ * been authenticated
167
+ */
168
+ isAuthenticated = false;
169
+ /**
170
+ * A boolean to know if the current request is authenticated
171
+ * using the "rememember_me" token.
172
+ */
173
+ viaRemember = false;
174
+ /**
175
+ * Find if the user has been logged out during
176
+ * the current request
177
+ */
178
+ isLoggedOut = false;
179
+ /**
180
+ * Reference to an instance of the authenticated user.
181
+ * The value only exists after calling one of the
182
+ * following methods.
183
+ *
184
+ * - authenticate
185
+ * - check
186
+ *
187
+ * You can use the "getUserOrFail" method to throw an exception if
188
+ * the request is not authenticated.
189
+ */
190
+ user;
191
+ /**
192
+ * The key used to store the logged-in user id inside
193
+ * session
194
+ */
195
+ get sessionKeyName() {
196
+ return `auth_${this.#name}`;
197
+ }
198
+ /**
199
+ * The key used to store the remember me token cookie
200
+ */
201
+ get rememberMeKeyName() {
202
+ return `remember_${this.#name}`;
203
+ }
204
+ constructor(name, ctx, options, emitter, userProvider) {
205
+ this.#name = name;
206
+ this.#ctx = ctx;
207
+ this.#options = { rememberMeTokensAge: "2 years", ...options };
208
+ this.#emitter = emitter;
209
+ this.#userProvider = userProvider;
210
+ }
211
+ /**
212
+ * Returns the session instance for the given request,
213
+ * ensuring the property exists
214
+ */
215
+ #getSession() {
216
+ if (!("session" in this.#ctx)) {
217
+ throw new RuntimeException(
218
+ 'Cannot authenticate user. Install and configure "@adonisjs/session" package'
219
+ );
220
+ }
221
+ return this.#ctx.session;
222
+ }
223
+ /**
224
+ * Emits authentication failure, updates the local state,
225
+ * and returns an exception to end the authentication
226
+ * cycle.
227
+ */
228
+ #authenticationFailed(sessionId) {
229
+ this.isAuthenticated = false;
230
+ this.viaRemember = false;
231
+ this.user = void 0;
232
+ this.isLoggedOut = false;
233
+ const error = new E_UNAUTHORIZED_ACCESS("Invalid or expired user session", {
234
+ guardDriverName: this.driverName
235
+ });
236
+ this.#emitter.emit("session_auth:authentication_failed", {
237
+ ctx: this.#ctx,
238
+ guardName: this.#name,
239
+ error,
240
+ sessionId
241
+ });
242
+ return error;
243
+ }
244
+ /**
245
+ * Emits the authentication succeeded event and updates
246
+ * the local state to reflect successful authentication
247
+ */
248
+ #authenticationSucceeded(sessionId, user, rememberMeToken) {
249
+ this.isAuthenticated = true;
250
+ this.viaRemember = !!rememberMeToken;
251
+ this.user = user;
252
+ this.isLoggedOut = false;
253
+ this.#emitter.emit("session_auth:authentication_succeeded", {
254
+ ctx: this.#ctx,
255
+ guardName: this.#name,
256
+ sessionId,
257
+ user,
258
+ rememberMeToken
259
+ });
260
+ }
261
+ /**
262
+ * Emits the login succeeded event and updates the login
263
+ * state
264
+ */
265
+ #loginSucceeded(sessionId, user, rememberMeToken) {
266
+ this.user = user;
267
+ this.isLoggedOut = false;
268
+ this.#emitter.emit("session_auth:login_succeeded", {
269
+ ctx: this.#ctx,
270
+ guardName: this.#name,
271
+ sessionId,
272
+ user,
273
+ rememberMeToken
274
+ });
275
+ }
276
+ /**
277
+ * Creates session for a given user by their user id.
278
+ */
279
+ #createSessionForUser(userId) {
280
+ const session = this.#getSession();
281
+ session.put(this.sessionKeyName, userId);
282
+ session.regenerate();
283
+ }
284
+ /**
285
+ * Creates the remember me cookie
286
+ */
287
+ #createRememberMeCookie(value) {
288
+ this.#ctx.response.encryptedCookie(this.rememberMeKeyName, value.release(), {
289
+ maxAge: this.#options.rememberMeTokensAge,
290
+ httpOnly: true
291
+ });
292
+ }
293
+ /**
294
+ * Authenticates the user using its id read from the session
295
+ * store.
296
+ *
297
+ * - We check the user exists in the db
298
+ * - If not, throw exception.
299
+ * - Otherwise, update local state to mark the user as logged-in
300
+ */
301
+ async #authenticateViaId(userId, sessionId) {
302
+ const providerUser = await this.#userProvider.findById(userId);
303
+ if (!providerUser) {
304
+ throw this.#authenticationFailed(sessionId);
305
+ }
306
+ this.#authenticationSucceeded(sessionId, providerUser.getOriginal());
307
+ return this.user;
308
+ }
309
+ /**
310
+ * Authenticates user from the remember me cookie. Creates a fresh
311
+ * session for them and recycles the remember me token as well.
312
+ */
313
+ async #authenticateViaRememberCookie(rememberMeCookie, sessionId) {
314
+ const userProvider = this.#userProvider;
315
+ const token = await userProvider.verifyRememberToken(new Secret2(rememberMeCookie));
316
+ if (!token) {
317
+ throw this.#authenticationFailed(sessionId);
318
+ }
319
+ const providerUser = await userProvider.findById(token.tokenableId);
320
+ if (!providerUser) {
321
+ throw this.#authenticationFailed(sessionId);
322
+ }
323
+ const recycledToken = await userProvider.recycleRememberToken(
324
+ providerUser.getOriginal(),
325
+ token.identifier,
326
+ this.#options.rememberMeTokensAge
327
+ );
328
+ this.#createRememberMeCookie(recycledToken.value);
329
+ this.#createSessionForUser(providerUser.getId());
330
+ this.#authenticationSucceeded(sessionId, providerUser.getOriginal(), token);
331
+ return this.user;
332
+ }
333
+ /**
334
+ * Returns an instance of the authenticated user. Or throws
335
+ * an exception if the request is not authenticated.
336
+ */
337
+ getUserOrFail() {
338
+ if (!this.user) {
339
+ throw new E_UNAUTHORIZED_ACCESS("Invalid or expired user session", {
340
+ guardDriverName: this.driverName
341
+ });
342
+ }
343
+ return this.user;
344
+ }
345
+ /**
346
+ * Login user using sessions. Optionally, you can also create
347
+ * a remember me token to automatically login user when their
348
+ * session expires.
349
+ */
350
+ async login(user, remember = false) {
351
+ const session = this.#getSession();
352
+ const providerUser = await this.#userProvider.createUserForGuard(user);
353
+ this.#emitter.emit("session_auth:login_attempted", {
354
+ ctx: this.#ctx,
355
+ user,
356
+ guardName: this.#name
357
+ });
358
+ let token;
359
+ if (remember) {
360
+ if (!this.#options.useRememberMeTokens) {
361
+ throw new RuntimeException('Cannot use "rememberMe" feature. It has been disabled');
362
+ }
363
+ const userProvider = this.#userProvider;
364
+ token = await userProvider.createRememberToken(
365
+ providerUser.getOriginal(),
366
+ this.#options.rememberMeTokensAge
367
+ );
368
+ }
369
+ if (token) {
370
+ this.#createRememberMeCookie(token.value);
371
+ } else {
372
+ this.#ctx.response.clearCookie(this.rememberMeKeyName);
373
+ }
374
+ this.#createSessionForUser(providerUser.getId());
375
+ this.#loginSucceeded(session.sessionId, providerUser.getOriginal(), token);
376
+ }
377
+ /**
378
+ * Logout a user by removing its state from the session
379
+ * store and delete the remember me cookie (if any).
380
+ */
381
+ async logout() {
382
+ const session = this.#getSession();
383
+ const rememberMeCookie = this.#ctx.request.encryptedCookie(this.rememberMeKeyName);
384
+ session.forget(this.sessionKeyName);
385
+ this.#ctx.response.clearCookie(this.rememberMeKeyName);
386
+ if (this.user && rememberMeCookie && this.#options.useRememberMeTokens) {
387
+ const userProvider = this.#userProvider;
388
+ const token = await userProvider.verifyRememberToken(new Secret2(rememberMeCookie));
389
+ if (token) {
390
+ await userProvider.deleteRemeberToken(this.user, token.identifier);
391
+ }
392
+ }
393
+ this.user = void 0;
394
+ this.viaRemember = false;
395
+ this.isAuthenticated = false;
396
+ this.isLoggedOut = true;
397
+ this.#emitter.emit("session_auth:logged_out", {
398
+ ctx: this.#ctx,
399
+ guardName: this.#name,
400
+ user: this.user || null,
401
+ sessionId: session.sessionId
402
+ });
403
+ }
404
+ /**
405
+ * Authenticate the current HTTP request by verifying the bearer
406
+ * token or fails with an exception
407
+ */
408
+ async authenticate() {
409
+ if (this.authenticationAttempted) {
410
+ return this.getUserOrFail();
411
+ }
412
+ this.authenticationAttempted = true;
413
+ const session = this.#getSession();
414
+ this.#emitter.emit("session_auth:authentication_attempted", {
415
+ ctx: this.#ctx,
416
+ sessionId: session.sessionId,
417
+ guardName: this.#name
418
+ });
419
+ const authUserId = session.get(this.sessionKeyName);
420
+ if (authUserId) {
421
+ return this.#authenticateViaId(authUserId, session.sessionId);
422
+ }
423
+ const rememberMeCookie = this.#ctx.request.encryptedCookie(this.rememberMeKeyName);
424
+ if (rememberMeCookie && this.#options.useRememberMeTokens) {
425
+ this.attemptedViaRemember = true;
426
+ return this.#authenticateViaRememberCookie(rememberMeCookie, session.sessionId);
427
+ }
428
+ throw this.#authenticationFailed(session.sessionId);
429
+ }
430
+ /**
431
+ * Silently check if the user is authenticated or not, without
432
+ * throwing any exceptions
433
+ */
434
+ async check() {
435
+ try {
436
+ await this.authenticate();
437
+ return true;
438
+ } catch (error) {
439
+ if (error instanceof E_UNAUTHORIZED_ACCESS) {
440
+ return false;
441
+ }
442
+ throw error;
443
+ }
444
+ }
445
+ /**
446
+ * Returns the session info for the clients to send during
447
+ * an HTTP request to mark the user as logged-in.
448
+ */
449
+ async authenticateAsClient(user) {
450
+ const providerUser = await this.#userProvider.createUserForGuard(user);
451
+ const userId = providerUser.getId();
452
+ return {
453
+ session: {
454
+ [this.sessionKeyName]: userId
455
+ }
456
+ };
457
+ }
458
+ };
459
+
460
+ // modules/session_guard/token_providers/db.ts
461
+ import { RuntimeException as RuntimeException2 } from "@adonisjs/core/exceptions";
462
+ var DbRememberMeTokensProvider = class _DbRememberMeTokensProvider {
463
+ constructor(options) {
464
+ this.options = options;
465
+ this.table = options.table || "remember_me_tokens";
466
+ this.tokenSecretLength = options.tokenSecretLength || 40;
467
+ }
468
+ /**
469
+ * Create tokens provider instance for a given Lucid model
470
+ */
471
+ static forModel(model, options) {
472
+ return new _DbRememberMeTokensProvider({
473
+ tokenableModel: model,
474
+ ...options || {}
475
+ });
476
+ }
477
+ /**
478
+ * Database table to use for querying remember me tokens
479
+ */
480
+ table;
481
+ /**
482
+ * The length for the token secret. A secret is a cryptographically
483
+ * secure random string.
484
+ */
485
+ tokenSecretLength;
486
+ /**
487
+ * Ensure the provided user is an instance of the user model and
488
+ * has a primary key
489
+ */
490
+ #ensureIsPersisted(user) {
491
+ const model = this.options.tokenableModel;
492
+ if (user instanceof model === false) {
493
+ throw new RuntimeException2(
494
+ `Invalid user object. It must be an instance of the "${model.name}" model`
495
+ );
496
+ }
497
+ if (!user.$primaryKeyValue) {
498
+ throw new RuntimeException2(
499
+ `Cannot use "${model.name}" model for managing remember me tokens. The value of column "${model.primaryKey}" is undefined or null`
500
+ );
501
+ }
502
+ }
503
+ /**
504
+ * Maps a database row to an instance token instance
505
+ */
506
+ dbRowToRememberMeToken(dbRow) {
507
+ return new RememberMeToken({
508
+ identifier: dbRow.id,
509
+ tokenableId: dbRow.tokenable_id,
510
+ hash: dbRow.hash,
511
+ createdAt: typeof dbRow.created_at === "number" ? new Date(dbRow.created_at) : dbRow.created_at,
512
+ updatedAt: typeof dbRow.updated_at === "number" ? new Date(dbRow.updated_at) : dbRow.updated_at,
513
+ expiresAt: typeof dbRow.expires_at === "number" ? new Date(dbRow.expires_at) : dbRow.expires_at
514
+ });
515
+ }
516
+ /**
517
+ * Returns a query client instance from the parent model
518
+ */
519
+ async getDb() {
520
+ const model = this.options.tokenableModel;
521
+ return model.$adapter.query(model).client;
522
+ }
523
+ /**
524
+ * Create a token for a user
525
+ */
526
+ async create(user, expiresIn) {
527
+ this.#ensureIsPersisted(user);
528
+ const queryClient = await this.getDb();
529
+ const transientToken = RememberMeToken.createTransientToken(
530
+ user.$primaryKeyValue,
531
+ this.tokenSecretLength,
532
+ expiresIn
533
+ );
534
+ const dbRow = {
535
+ tokenable_id: transientToken.userId,
536
+ hash: transientToken.hash,
537
+ created_at: /* @__PURE__ */ new Date(),
538
+ updated_at: /* @__PURE__ */ new Date(),
539
+ expires_at: transientToken.expiresAt
540
+ };
541
+ const [id] = await queryClient.table(this.table).insert(dbRow);
542
+ return new RememberMeToken({
543
+ identifier: id,
544
+ tokenableId: dbRow.tokenable_id,
545
+ secret: transientToken.secret,
546
+ hash: dbRow.hash,
547
+ createdAt: dbRow.created_at,
548
+ updatedAt: dbRow.updated_at,
549
+ expiresAt: dbRow.expires_at
550
+ });
551
+ }
552
+ /**
553
+ * Find a token for a user by the token id
554
+ */
555
+ async find(user, identifier) {
556
+ this.#ensureIsPersisted(user);
557
+ const queryClient = await this.getDb();
558
+ const dbRow = await queryClient.query().from(this.table).where({ id: identifier, tokenable_id: user.$primaryKeyValue }).limit(1).first();
559
+ if (!dbRow) {
560
+ return null;
561
+ }
562
+ return this.dbRowToRememberMeToken(dbRow);
563
+ }
564
+ /**
565
+ * Delete a token by its id
566
+ */
567
+ async delete(user, identifier) {
568
+ this.#ensureIsPersisted(user);
569
+ const queryClient = await this.getDb();
570
+ const affectedRows = await queryClient.query().from(this.table).where({ id: identifier, tokenable_id: user.$primaryKeyValue }).del().exec();
571
+ return affectedRows;
572
+ }
573
+ /**
574
+ * Returns all the tokens a given user
575
+ */
576
+ async all(user) {
577
+ this.#ensureIsPersisted(user);
578
+ const queryClient = await this.getDb();
579
+ const dbRows = await queryClient.query().from(this.table).where({ tokenable_id: user.$primaryKeyValue }).orderBy("id", "desc").exec();
580
+ return dbRows.map((dbRow) => {
581
+ return this.dbRowToRememberMeToken(dbRow);
582
+ });
583
+ }
584
+ /**
585
+ * Verifies a publicly shared remember me token and returns an
586
+ * RememberMeToken for it.
587
+ *
588
+ * Returns null when unable to verify the token or find it
589
+ * inside the storage
590
+ */
591
+ async verify(tokenValue) {
592
+ const decodedToken = RememberMeToken.decode(tokenValue.release());
593
+ if (!decodedToken) {
594
+ return null;
595
+ }
596
+ const db = await this.getDb();
597
+ const dbRow = await db.query().from(this.table).where({ id: decodedToken.identifier }).limit(1).first();
598
+ if (!dbRow) {
599
+ return null;
600
+ }
601
+ const rememberMeToken = this.dbRowToRememberMeToken(dbRow);
602
+ if (!rememberMeToken.verify(decodedToken.secret) || rememberMeToken.isExpired()) {
603
+ return null;
604
+ }
605
+ return rememberMeToken;
606
+ }
607
+ /**
608
+ * Recycles a remember me token by deleting the old one and
609
+ * creates a new one.
610
+ *
611
+ * Ideally, the recycle should update the existing token, but we
612
+ * skip that for now and come back to it later and handle race
613
+ * conditions as well.
614
+ */
615
+ async recycle(user, identifier, expiresIn) {
616
+ await this.delete(user, identifier);
617
+ return this.create(user, expiresIn);
618
+ }
619
+ };
620
+
621
+ // modules/session_guard/user_providers/lucid.ts
622
+ import { RuntimeException as RuntimeException3 } from "@adonisjs/core/exceptions";
623
+ var SessionLucidUserProvider = class {
624
+ constructor(options) {
625
+ this.options = options;
626
+ }
627
+ /**
628
+ * Reference to the lazily imported model
629
+ */
630
+ model;
631
+ /**
632
+ * Imports the model from the provider, returns and caches it
633
+ * for further operations.
634
+ */
635
+ async getModel() {
636
+ if (this.model) {
637
+ return this.model;
638
+ }
639
+ const importedModel = await this.options.model();
640
+ this.model = importedModel.default;
641
+ return this.model;
642
+ }
643
+ /**
644
+ * Returns the tokens provider associated with the user model
645
+ */
646
+ async getTokensProvider() {
647
+ const model = await this.getModel();
648
+ if (!model.rememberMeTokens) {
649
+ throw new RuntimeException3(
650
+ `Cannot use "${model.name}" model for verifying remember me tokens. Make sure to assign a token provider to the model.`
651
+ );
652
+ }
653
+ return model.rememberMeTokens;
654
+ }
655
+ /**
656
+ * Creates an adapter user for the guard
657
+ */
658
+ async createUserForGuard(user) {
659
+ const model = await this.getModel();
660
+ if (user instanceof model === false) {
661
+ throw new RuntimeException3(
662
+ `Invalid user object. It must be an instance of the "${model.name}" model`
663
+ );
664
+ }
665
+ return {
666
+ getId() {
667
+ if (!user.$primaryKeyValue) {
668
+ throw new RuntimeException3(
669
+ `Cannot use "${model.name}" model for authentication. The value of column "${model.primaryKey}" is undefined or null`
670
+ );
671
+ }
672
+ return user.$primaryKeyValue;
673
+ },
674
+ getOriginal() {
675
+ return user;
676
+ }
677
+ };
678
+ }
679
+ /**
680
+ * Finds a user by their primary key value
681
+ */
682
+ async findById(identifier) {
683
+ const model = await this.getModel();
684
+ const user = await model.find(identifier);
685
+ if (!user) {
686
+ return null;
687
+ }
688
+ return this.createUserForGuard(user);
689
+ }
690
+ /**
691
+ * Creates a remember token for a given user
692
+ */
693
+ async createRememberToken(user, expiresIn) {
694
+ const tokensProvider = await this.getTokensProvider();
695
+ return tokensProvider.create(user, expiresIn);
696
+ }
697
+ /**
698
+ * Verify a token by its publicly shared value
699
+ */
700
+ async verifyRememberToken(tokenValue) {
701
+ const tokensProvider = await this.getTokensProvider();
702
+ return tokensProvider.verify(tokenValue);
703
+ }
704
+ /**
705
+ * Delete a token for a user by the token identifier
706
+ */
707
+ async deleteRemeberToken(user, identifier) {
708
+ const tokensProvider = await this.getTokensProvider();
709
+ return tokensProvider.delete(user, identifier);
710
+ }
711
+ /**
712
+ * Recycle a token for a user by the token identifier
713
+ */
714
+ async recycleRememberToken(user, identifier, expiresIn) {
715
+ const tokensProvider = await this.getTokensProvider();
716
+ return tokensProvider.recycle(user, identifier, expiresIn);
717
+ }
718
+ };
719
+
720
+ // modules/session_guard/define_config.ts
721
+ function sessionGuard(config) {
722
+ return {
723
+ async resolver(name, app) {
724
+ const emitter = await app.container.make("emitter");
725
+ const provider = "resolver" in config.provider ? await config.provider.resolver(app) : config.provider;
726
+ return (ctx) => new SessionGuard(name, ctx, config, emitter, provider);
727
+ }
728
+ };
729
+ }
730
+ function sessionUserProvider(config) {
731
+ return new SessionLucidUserProvider(config);
732
+ }
733
+ export {
734
+ DbRememberMeTokensProvider,
735
+ RememberMeToken,
736
+ SessionGuard,
737
+ SessionLucidUserProvider,
738
+ sessionGuard,
739
+ sessionUserProvider
740
+ };
741
+ //# sourceMappingURL=main.js.map