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