@arkstack/auth 0.12.6 → 0.12.7

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 (2) hide show
  1. package/dist/index.d.ts +422 -0
  2. package/package.json +4 -4
package/dist/index.d.ts CHANGED
@@ -18,10 +18,25 @@ declare abstract class PersonalAccessToken extends Model {
18
18
  }
19
19
  //#endregion
20
20
  //#region src/Session.d.ts
21
+ /**
22
+ * Represents an authenticated user session.
23
+ *
24
+ * @author 3m1n3nc3
25
+ */
21
26
  declare class Session extends Session$1 {
22
27
  private auth;
23
28
  constructor(auth: AuthContract, current?: Session$1 | undefined);
29
+ /**
30
+ * Destroy the current session
31
+ *
32
+ * @returns
33
+ */
24
34
  destroy(): Promise<this>;
35
+ /**
36
+ * Get the current auth session token
37
+ *
38
+ * @returns
39
+ */
25
40
  token(): Promise<PersonalAccessToken | null>;
26
41
  }
27
42
  //#endregion
@@ -37,51 +52,277 @@ declare abstract class User extends Model {
37
52
  }
38
53
  //#endregion
39
54
  //#region src/Contracts/AuthContract.d.ts
55
+ /**
56
+ * The Auth class provides methods for user authentication, including verifying
57
+ * credentials, logging in, logging out, and managing personal access tokens.
58
+ *
59
+ * @author Legacy (3m1n3nc3)
60
+ */
40
61
  declare abstract class AuthContract {
62
+ /**
63
+ * Set the current HTTP request instance being processed.
64
+ *
65
+ * @param req The HTTP request instance to be set.
66
+ * @returns The Auth instance itself for method chaining.
67
+ */
41
68
  abstract setRequest(req: Request<User> | RequestSource<User>): this;
69
+ /**
70
+ * Get the current HTTP request instance being processed, which may contain
71
+ * user information and other request-specific data relevant to authentication operations.
72
+ *
73
+ * @returns The current HTTP request instance or undefined if not set.
74
+ */
42
75
  abstract getRequest(): Request<User> | undefined;
76
+ /**
77
+ * Get the currently authenticated user
78
+ *
79
+ * @returns The currently authenticated user or null if not authenticated.
80
+ */
43
81
  abstract user(): User | null;
82
+ /**
83
+ * Verify user credentials
84
+ *
85
+ * @param email The email address of the user.
86
+ * @param password The password of the user.
87
+ * @returns A boolean indicating whether the credentials are valid.
88
+ */
44
89
  abstract verify(email: string, password: string): Promise<boolean>;
90
+ /**
91
+ * Attempt to authenticate a user with the given email and password.
92
+ *
93
+ * @param email
94
+ * @param password
95
+ * @returns
96
+ */
45
97
  abstract attempt(email: string, password: string): Promise<User>;
98
+ /**
99
+ * Login a user and create a personal access token
100
+ *
101
+ * @param email
102
+ * @param password
103
+ * @returns
104
+ */
46
105
  abstract login(email: string, password: string): Promise<PersonalAccessToken>;
106
+ /**
107
+ * Create a temporary token for a user with a specific purpose, such as
108
+ * two-factor authentication.
109
+ *
110
+ * @param user
111
+ * @param purpose
112
+ * @param expiresIn
113
+ * @returns
114
+ */
47
115
  abstract createTemporaryToken(user: User, purpose: string, expiresIn?: string): Promise<string>;
116
+ /**
117
+ * Authorize a temporary token and return the associated user if the token is
118
+ * valid and matches the expected purpose.
119
+ *
120
+ * @param token
121
+ * @param purpose
122
+ * @returns
123
+ */
48
124
  abstract authorizeTemporaryToken(token: string, purpose: string): Promise<User>;
125
+ /**
126
+ * Logout the currently authenticated user and delete all their personal access tokens
127
+ *
128
+ * @param token
129
+ * @returns
130
+ */
49
131
  abstract logout(token?: string | PersonalAccessToken): Promise<void>;
132
+ /**
133
+ * Check if the user is authenticated
134
+ *
135
+ * @returns
136
+ */
50
137
  abstract check(): Promise<boolean>;
138
+ /**
139
+ * Get the current session's personal access token
140
+ *
141
+ * @returns
142
+ */
51
143
  abstract session(): Session;
144
+ /**
145
+ * Create a personal access token for a user
146
+ *
147
+ * @param user
148
+ * @returns
149
+ */
52
150
  abstract create(user: User): Promise<PersonalAccessToken>;
151
+ /**
152
+ * Authorize a token and return the associated user
153
+ *
154
+ * @param token
155
+ * @returns
156
+ */
53
157
  abstract authorizeToken(token: string): Promise<User>;
54
158
  }
55
159
  //#endregion
56
160
  //#region src/Auth.d.ts
161
+ /**
162
+ * The Auth class provides methods for user authentication, including verifying
163
+ * credentials, logging in, logging out, and managing personal access tokens.
164
+ *
165
+ * @author Legacy (3m1n3nc3)
166
+ */
57
167
  declare class Auth extends AuthContract {
58
168
  #private;
59
169
  protected static req?: Request<User>;
60
170
  private configuredSecret?;
61
171
  constructor(secret?: string, req?: Request<User> | RequestSource<User>);
172
+ /**
173
+ * Create a new instance of the Auth class with an optional secret for JWT
174
+ * signing and verification.
175
+ *
176
+ * @param secret The secret key used for signing and verifying JWTs.
177
+ * @returns A new instance of the Auth class.
178
+ */
62
179
  static make(secret?: string): Auth;
180
+ /**
181
+ * Set the current HTTP request instance being processed.
182
+ *
183
+ * @param req The HTTP request instance to be set.
184
+ * @returns The Auth class itself for method chaining.
185
+ */
63
186
  static setRequest(req: Request<User> | RequestSource<User>): typeof Auth;
187
+ /**
188
+ * Set the current HTTP request instance being processed.
189
+ *
190
+ * @param req The HTTP request instance to be set.
191
+ * @returns The Auth instance itself for method chaining.
192
+ */
64
193
  setRequest(req: Request<User> | RequestSource<User>): this;
194
+ /**
195
+ * Get the current HTTP request instance being processed, which may contain
196
+ * user information and other request-specific data relevant to authentication operations.
197
+ *
198
+ * @returns The current HTTP request instance or undefined if not set.
199
+ */
65
200
  getRequest(): Request<User> | undefined;
201
+ /**
202
+ * Get the currently authenticated user
203
+ *
204
+ * @returns The currently authenticated user or null if not authenticated.
205
+ */
66
206
  user(): User | null;
207
+ /**
208
+ * Verify user credentials
209
+ *
210
+ * @param email The email address of the user.
211
+ * @param password The password of the user.
212
+ * @returns A boolean indicating whether the credentials are valid.
213
+ */
67
214
  verify(email: string, password: string): Promise<boolean>;
215
+ /**
216
+ * Attempt to authenticate a user with the given email and password.
217
+ *
218
+ * @param email
219
+ * @param password
220
+ * @returns
221
+ */
68
222
  attempt(email: string, password: string): Promise<User>;
223
+ /**
224
+ * Login a user and create a personal access token
225
+ *
226
+ * @param email
227
+ * @param password
228
+ * @returns
229
+ */
69
230
  login(email: string, password: string): Promise<PersonalAccessToken>;
231
+ /**
232
+ * Create a temporary token for a user with a specific purpose, such as
233
+ * two-factor authentication.
234
+ *
235
+ * @param user
236
+ * @param purpose
237
+ * @param expiresIn
238
+ * @returns
239
+ */
70
240
  createTemporaryToken(user: User, purpose: string, expiresIn?: string): Promise<string>;
241
+ /**
242
+ * Authorize a temporary token and return the associated user if the token is
243
+ * valid and matches the expected purpose.
244
+ *
245
+ * @param token
246
+ * @param purpose
247
+ * @returns
248
+ */
71
249
  authorizeTemporaryToken(token: string, purpose: string): Promise<User>;
250
+ /**
251
+ * Logout the currently authenticated user and delete all their personal access tokens
252
+ *
253
+ * @param token
254
+ * @returns
255
+ */
72
256
  logout(token?: string | PersonalAccessToken): Promise<void>;
257
+ /**
258
+ * Check if the user is authenticated
259
+ *
260
+ * @returns
261
+ */
73
262
  check(): Promise<boolean>;
263
+ /**
264
+ * Get the current session's personal access token
265
+ *
266
+ * @returns
267
+ */
74
268
  session(): Session;
269
+ /**
270
+ * Create a personal access token for a user
271
+ *
272
+ * @param user
273
+ * @returns
274
+ */
75
275
  create(user: User): Promise<PersonalAccessToken>;
276
+ /**
277
+ * Create or replace the personal access token for the same user and device
278
+ * while keeping a single active session record for that device.
279
+ *
280
+ * @param user The authenticated user.
281
+ * @param token The new bearer token to persist.
282
+ * @param deviceInfo The current request's device information.
283
+ */
76
284
  private upsertDeviceToken;
285
+ /**
286
+ * Authorize a token and return the associated user
287
+ *
288
+ * @param token
289
+ * @returns
290
+ */
77
291
  authorizeToken(token: string): Promise<User>;
292
+ /**
293
+ * Create a JWT token
294
+ *
295
+ * @param payload
296
+ * @returns
297
+ */
78
298
  private createJWT;
299
+ /**
300
+ * Verify a JWT token
301
+ *
302
+ * @param token
303
+ * @returns
304
+ */
79
305
  private verifyJWT;
80
306
  private getSecret;
307
+ /**
308
+ * Update the last used timestamp and device information of a personal
309
+ * access token to keep the session active and reflect the latest device details.
310
+ *
311
+ * @param pat The personal access token to update.
312
+ * @returns A promise that resolves when the update is complete.
313
+ */
81
314
  private touchSession;
82
315
  }
83
316
  //#endregion
84
317
  //#region src/utils.d.ts
318
+ /**
319
+ * Create a new instance of the Auth class with an optional secret for JWT
320
+ * signing and verification.
321
+ *
322
+ * @param secret — The secret key used for signing and verifying JWTs.
323
+ *
324
+ * @returns — A new instance of the Auth class.
325
+ */
85
326
  declare const auth: (secret?: string | undefined) => Auth;
86
327
  //#endregion
87
328
  //#region src/types/Session.d.ts
@@ -110,17 +351,86 @@ type DeviceAgentPayload = {
110
351
  //#region src/SessionDevice.d.ts
111
352
  declare class SessionDevice {
112
353
  private static readonly uniqueIdentityFields;
354
+ /**
355
+ * Extracts device information from the incoming request to build a SessionDeviceInfo object.
356
+ *
357
+ * @param req The incoming HTTP request object.
358
+ * @returns A SessionDeviceInfo object containing information about the client's device.
359
+ */
113
360
  static fromRequest(req?: Request): SessionDeviceInfo;
361
+ /**
362
+ * Generates a human-readable display name for the device based on available information.
363
+ *
364
+ * @param deviceInfo A record containing device information.
365
+ * @returns A string representing the display name of the device.
366
+ */
114
367
  static getDisplayName(deviceInfo?: Record<string, unknown> | null): string;
368
+ /**
369
+ * Builds a stable device key for matching previously issued sessions to the
370
+ * current request device.
371
+ *
372
+ * @param deviceInfo A record containing device information.
373
+ * @returns A normalized device key or null when there is not enough signal.
374
+ */
115
375
  static getUniqueKey(deviceInfo?: Record<string, unknown> | null): string | null;
376
+ /**
377
+ * Determines whether two device payloads represent the same device.
378
+ *
379
+ * @param left The first device payload.
380
+ * @param right The second device payload.
381
+ * @returns True when both payloads resolve to the same device key.
382
+ */
116
383
  static matches(left?: Record<string, unknown> | null, right?: Record<string, unknown> | null): boolean;
384
+ /**
385
+ * Safely reads the user agent string from the request headers.
386
+ *
387
+ * @param req
388
+ * @returns
389
+ */
117
390
  private static readUserAgent;
391
+ /**
392
+ * Safely reads a string value, ensuring it's a non-empty string or returns null.
393
+ *
394
+ * @param value
395
+ * @returns
396
+ */
118
397
  private static readString;
398
+ /**
399
+ * Reads a specific device-related header from the request
400
+ *
401
+ * @param req
402
+ * @param headerName
403
+ * @returns
404
+ */
119
405
  private static readDeviceAgent;
120
406
  private static normalizeDeviceType;
407
+ /**
408
+ * Detects the client's IP address from the request, considering common headers set by proxies.
409
+ *
410
+ * @param req
411
+ * @returns
412
+ */
121
413
  private static detectIpAddress;
414
+ /**
415
+ * Detects the browser from the user agent string.
416
+ *
417
+ * @param userAgent
418
+ * @returns
419
+ */
122
420
  private static detectBrowser;
421
+ /**
422
+ * Detects the operating system from the user agent string.
423
+ *
424
+ * @param userAgent
425
+ * @returns
426
+ */
123
427
  private static detectOs;
428
+ /**
429
+ * Detects the device type from the user agent string.
430
+ *
431
+ * @param userAgent
432
+ * @returns
433
+ */
124
434
  private static detectDeviceType;
125
435
  }
126
436
  //#endregion
@@ -151,28 +461,140 @@ declare class TwoFactor {
151
461
  private static upsert;
152
462
  static normalizeMethod(method?: string | null): TwoFactorMethod | null;
153
463
  static maskPhone(phone?: string | null): string | null;
464
+ /**
465
+ * Build the account label used inside the OTP URI.
466
+ *
467
+ * @param user
468
+ * @returns
469
+ */
154
470
  static getLabel(user: User): string;
471
+ /**
472
+ * Create the per-user TOTP instance for setup and verification.
473
+ *
474
+ * @param user
475
+ * @param secret
476
+ * @returns
477
+ */
155
478
  static getTotp(user: User, secret: string): _$otpauth.TOTP;
479
+ /**
480
+ * Generate a new shared secret for authenticator-based 2FA.
481
+ *
482
+ * @returns The generated secret in base32 format.
483
+ */
156
484
  static generateSecret(size?: number): string;
485
+ /**
486
+ * Build the setup payload returned to the client.
487
+ *
488
+ * @param user The user for whom the setup is being created.
489
+ * @param secret Optional existing secret to use for the setup.
490
+ * @returns An object containing the secret and the OTPAuth URL.
491
+ */
157
492
  static createSetup(user: User, secret?: string): TwoFactorSetup;
493
+ /**
494
+ * Verify a 6-digit authenticator code for a user.
495
+ *
496
+ * @param user The user for whom the code is being verified.
497
+ * @param secret The secret used to generate the code.
498
+ * @param code The 6-digit code to verify.
499
+ * @returns True if the code is valid, false otherwise.
500
+ */
158
501
  static verifyCode(user: User, secret: string, code: string): boolean;
159
502
  static getMethod(userId: User['id']): Promise<TwoFactorMethod | null>;
160
503
  static setMethod(userId: User['id'], method: TwoFactorMethod): Promise<void>;
504
+ /**
505
+ * Read the setup secret stored for a user.
506
+ *
507
+ * @param userId The ID of the user.
508
+ * @returns The stored secret, or null if not found.
509
+ */
161
510
  static getSecret(userId: User['id']): Promise<string | null>;
511
+ /**
512
+ * Store the setup secret for a user.
513
+ *
514
+ * @param userId The ID of the user.
515
+ * @param secret The secret to store.
516
+ */
162
517
  static setSecret(userId: User['id'], secret: string): Promise<void>;
163
518
  static clearSecret(userId: User['id']): Promise<void>;
519
+ /**
520
+ * Read the timestamp indicating whether 2FA is enabled.
521
+ *
522
+ * @param userId The ID of the user.
523
+ * @returns The timestamp when 2FA was enabled, or null if not enabled.
524
+ */
164
525
  static getEnabledAt(userId: User['id']): Promise<string | null>;
526
+ /**
527
+ * Persist the timestamp marking 2FA as enabled.
528
+ *
529
+ * @param userId The ID of the user.
530
+ * @param enabledAt The timestamp to store.
531
+ */
165
532
  static setEnabledAt(userId: User['id'], enabledAt?: string | Date): Promise<void>;
533
+ /**
534
+ * Remove all persisted 2FA state for a user.
535
+ *
536
+ * @param userId The ID of the user.
537
+ */
166
538
  static clear(userId: User['id']): Promise<void>;
539
+ /**
540
+ * Generate one-time recovery codes shown when 2FA is enabled.
541
+ *
542
+ * @returns An array of recovery codes.
543
+ */
167
544
  static generateBackupCodes(count?: number): string[];
545
+ /**
546
+ * Hash recovery codes before persisting them.
547
+ *
548
+ * @param codes An array of recovery codes to hash.
549
+ * @returns An array of hashed recovery codes.
550
+ */
168
551
  static hashBackupCodes(codes: string[]): Promise<string[]>;
552
+ /**
553
+ * Read stored recovery-code hashes for a user.
554
+ *
555
+ * @param userId The ID of the user.
556
+ * @returns An array of recovery-code hashes.
557
+ */
169
558
  static readRecoveryCodeHashes(userId: User['id']): Promise<string[]>;
559
+ /**
560
+ * Persist recovery-code hashes on the user's dedicated 2FA record.
561
+ *
562
+ * @param userId
563
+ * @param hashes
564
+ */
170
565
  static writeRecoveryCodeHashes(userId: User['id'], hashes: string[]): Promise<void>;
566
+ /**
567
+ * Consume a valid recovery code and invalidate it immediately.
568
+ *
569
+ * @param userId The ID of the user.
570
+ * @param recoveryCode The recovery code to consume.
571
+ * @returns True if the recovery code was valid and consumed, false otherwise.
572
+ */
171
573
  static consumeRecoveryCode(userId: User['id'], recoveryCode: string): Promise<boolean>;
574
+ /**
575
+ * Return the public 2FA status payload for a user.
576
+ *
577
+ * @param userId The ID of the user.
578
+ * @returns An object containing the 2FA status and recovery codes remaining.
579
+ */
172
580
  static readStatus(userId: User['id']): Promise<TwoFactorStatus>;
173
581
  static createSmsCode(): string;
582
+ /**
583
+ * Issue a new SMS code for the given user and send it via SMS for the specified purpose.
584
+ *
585
+ * @param user
586
+ * @param purpose
587
+ */
174
588
  static issueSmsCode(user: User, purpose: SmsCodePurpose): Promise<IssuedSmsCode>;
175
589
  static clearSmsCode(userId: User['id']): Promise<void>;
590
+ /**
591
+ * Verify a submitted SMS code for a user and purpose, consuming the code if valid.
592
+ *
593
+ * @param userId
594
+ * @param code
595
+ * @param purpose
596
+ * @returns
597
+ */
176
598
  static verifySmsCode(userId: User['id'], code: string, purpose: SmsCodePurpose): Promise<boolean>;
177
599
  }
178
600
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkstack/auth",
3
- "version": "0.12.6",
3
+ "version": "0.12.7",
4
4
  "type": "module",
5
5
  "description": "Authentication module for Arkstack, providing core authentication and identity features.",
6
6
  "homepage": "https://arkstack.toneflix.net/guide/auth",
@@ -38,12 +38,12 @@
38
38
  "jose": "^6.2.3",
39
39
  "otpauth": "^9.5.1",
40
40
  "ua-parser-js": "^2.0.9",
41
- "@arkstack/common": "^0.12.6",
42
- "@arkstack/http": "^0.12.6"
41
+ "@arkstack/http": "^0.12.7",
42
+ "@arkstack/common": "^0.12.7"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "@h3ravel/support": "^0.15.11",
46
- "@arkstack/database": "^0.12.6"
46
+ "@arkstack/database": "^0.12.7"
47
47
  },
48
48
  "scripts": {
49
49
  "build": "tsdown --config-loader unrun",