@eaccess/auth 0.1.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.
@@ -0,0 +1,930 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ import { Pool } from 'pg';
3
+
4
+ interface OAuthProviderConfig {
5
+ clientId: string;
6
+ clientSecret: string;
7
+ redirectUri: string;
8
+ }
9
+ interface GitHubProviderConfig extends OAuthProviderConfig {
10
+ }
11
+ interface GoogleProviderConfig extends OAuthProviderConfig {
12
+ }
13
+ interface AzureProviderConfig extends OAuthProviderConfig {
14
+ tenantId: string;
15
+ }
16
+ interface AuthConfig {
17
+ db: Pool;
18
+ createUser?: (userData: OAuthUserData) => string | number | Promise<string | number>;
19
+ tablePrefix?: string;
20
+ minPasswordLength?: number;
21
+ maxPasswordLength?: number;
22
+ rememberDuration?: string;
23
+ rememberCookieName?: string;
24
+ resyncInterval?: string;
25
+ activityLog?: {
26
+ enabled?: boolean;
27
+ maxEntries?: number;
28
+ actions?: AuthActivityActionType[];
29
+ };
30
+ providers?: {
31
+ github?: GitHubProviderConfig;
32
+ google?: GoogleProviderConfig;
33
+ azure?: AzureProviderConfig;
34
+ };
35
+ twoFactor?: {
36
+ enabled?: boolean;
37
+ requireForOAuth?: boolean;
38
+ issuer?: string;
39
+ codeLength?: number;
40
+ tokenExpiry?: string;
41
+ totpWindow?: number;
42
+ backupCodesCount?: number;
43
+ };
44
+ }
45
+ interface AuthAccount {
46
+ id: number;
47
+ user_id: string;
48
+ email: string;
49
+ password: string | null;
50
+ verified: boolean;
51
+ status: number;
52
+ rolemask: number;
53
+ last_login: Date | null;
54
+ force_logout: number;
55
+ resettable: boolean;
56
+ registered: Date;
57
+ }
58
+ interface AuthProvider {
59
+ id: number;
60
+ account_id: number;
61
+ provider: string;
62
+ provider_id: string;
63
+ provider_email: string | null;
64
+ provider_username: string | null;
65
+ provider_name: string | null;
66
+ provider_avatar: string | null;
67
+ created_at: Date;
68
+ updated_at: Date;
69
+ }
70
+ interface OAuthUserData {
71
+ id: string;
72
+ email: string;
73
+ username?: string;
74
+ name?: string;
75
+ avatar?: string;
76
+ }
77
+ interface OAuthProvider {
78
+ getAuthUrl(state?: string, scopes?: string[]): string;
79
+ handleCallback(req: Request): Promise<void>;
80
+ getUserData(req: Request): Promise<OAuthUserData>;
81
+ }
82
+ interface AuthConfirmation {
83
+ id: number;
84
+ account_id: number;
85
+ token: string;
86
+ email: string;
87
+ expires: Date;
88
+ }
89
+ interface AuthRemember {
90
+ id: number;
91
+ account_id: number;
92
+ token: string;
93
+ expires: Date;
94
+ }
95
+ interface AuthReset {
96
+ id: number;
97
+ account_id: number;
98
+ token: string;
99
+ expires: Date;
100
+ }
101
+ interface AuthActivity {
102
+ id: number;
103
+ account_id: number | null;
104
+ action: string;
105
+ ip_address: string | null;
106
+ user_agent: string | null;
107
+ browser: string | null;
108
+ os: string | null;
109
+ device: string | null;
110
+ success: boolean;
111
+ metadata: Record<string, any> | null;
112
+ created_at: Date;
113
+ }
114
+ interface AuthSession {
115
+ loggedIn: boolean;
116
+ accountId: number;
117
+ userId: string;
118
+ email: string;
119
+ status: number;
120
+ rolemask: number;
121
+ remembered: boolean;
122
+ lastResync: Date;
123
+ lastRememberCheck: Date;
124
+ forceLogout: number;
125
+ verified: boolean;
126
+ shouldForceLogout?: boolean;
127
+ awaitingTwoFactor?: {
128
+ accountId: number;
129
+ expiresAt: Date;
130
+ remember: boolean;
131
+ availableMechanisms: TwoFactorMechanism[];
132
+ attemptedMechanisms: TwoFactorMechanism[];
133
+ originalEmail: string;
134
+ selectors?: {
135
+ email?: string;
136
+ sms?: string;
137
+ };
138
+ };
139
+ }
140
+ declare enum TwoFactorMechanism {
141
+ TOTP = 1,
142
+ EMAIL = 2,
143
+ SMS = 3
144
+ }
145
+ interface TwoFactorMethod {
146
+ id: number;
147
+ account_id: number;
148
+ mechanism: TwoFactorMechanism;
149
+ secret: string | null;
150
+ backup_codes: string[] | null;
151
+ verified: boolean;
152
+ created_at: Date;
153
+ last_used_at: Date | null;
154
+ }
155
+ interface TwoFactorToken {
156
+ id: number;
157
+ account_id: number;
158
+ mechanism: TwoFactorMechanism;
159
+ selector: string;
160
+ token_hash: string;
161
+ expires_at: Date;
162
+ created_at: Date;
163
+ }
164
+ interface TwoFactorSetupResult {
165
+ secret: string;
166
+ qrCode: string;
167
+ backupCodes?: string[];
168
+ }
169
+ interface TwoFactorChallenge {
170
+ totp?: boolean;
171
+ email?: {
172
+ otpValue: string;
173
+ maskedContact: string;
174
+ };
175
+ sms?: {
176
+ otpValue: string;
177
+ maskedContact: string;
178
+ };
179
+ selectors?: {
180
+ email?: string;
181
+ sms?: string;
182
+ };
183
+ }
184
+ declare const AuthStatus: {
185
+ readonly Normal: 0;
186
+ readonly Archived: 1;
187
+ readonly Banned: 2;
188
+ readonly Locked: 3;
189
+ readonly PendingReview: 4;
190
+ readonly Suspended: 5;
191
+ };
192
+ declare const AuthRole: {
193
+ readonly Admin: 1;
194
+ readonly Author: 2;
195
+ readonly Collaborator: 4;
196
+ readonly Consultant: 8;
197
+ readonly Consumer: 16;
198
+ readonly Contributor: 32;
199
+ readonly Coordinator: 64;
200
+ readonly Creator: 128;
201
+ readonly Developer: 256;
202
+ readonly Director: 512;
203
+ readonly Editor: 1024;
204
+ readonly Employee: 2048;
205
+ readonly Maintainer: 4096;
206
+ readonly Manager: 8192;
207
+ readonly Moderator: 16384;
208
+ readonly Publisher: 32768;
209
+ readonly Reviewer: 65536;
210
+ readonly Subscriber: 131072;
211
+ readonly SuperAdmin: 262144;
212
+ readonly SuperEditor: 524288;
213
+ readonly SuperModerator: 1048576;
214
+ readonly Translator: 2097152;
215
+ };
216
+ declare const AuthActivityAction: {
217
+ readonly Login: "login";
218
+ readonly Logout: "logout";
219
+ readonly FailedLogin: "failed_login";
220
+ readonly Register: "register";
221
+ readonly EmailConfirmed: "email_confirmed";
222
+ readonly PasswordResetRequested: "password_reset_requested";
223
+ readonly PasswordResetCompleted: "password_reset_completed";
224
+ readonly PasswordChanged: "password_changed";
225
+ readonly EmailChanged: "email_changed";
226
+ readonly RoleChanged: "role_changed";
227
+ readonly StatusChanged: "status_changed";
228
+ readonly ForceLogout: "force_logout";
229
+ readonly OAuthConnected: "oauth_connected";
230
+ readonly RememberTokenCreated: "remember_token_created";
231
+ readonly TwoFactorSetup: "two_factor_setup";
232
+ readonly TwoFactorVerified: "two_factor_verified";
233
+ readonly TwoFactorFailed: "two_factor_failed";
234
+ readonly TwoFactorDisabled: "two_factor_disabled";
235
+ readonly BackupCodeUsed: "backup_code_used";
236
+ };
237
+ type AuthActivityActionType = (typeof AuthActivityAction)[keyof typeof AuthActivityAction];
238
+ type TokenCallback = (token: string) => void;
239
+ declare module "express-session" {
240
+ interface SessionData {
241
+ auth?: AuthSession;
242
+ }
243
+ }
244
+ declare global {
245
+ namespace Express {
246
+ interface Request {
247
+ auth: AuthManager$1;
248
+ authAdmin: AuthAdminManager;
249
+ }
250
+ }
251
+ }
252
+ interface AuthManager$1 {
253
+ isLoggedIn(): boolean;
254
+ login(email: string, password: string, remember?: boolean): Promise<void>;
255
+ completeTwoFactorLogin(): Promise<void>;
256
+ logout(): Promise<void>;
257
+ register(email: string, password: string, userId?: string | number, callback?: TokenCallback): Promise<AuthAccount>;
258
+ getId(): number | null;
259
+ getEmail(): string | null;
260
+ getStatus(): number | null;
261
+ getVerified(): boolean | null;
262
+ getRoleNames(rolemask?: number): string[];
263
+ getStatusName(): string | null;
264
+ hasRole(role: number): Promise<boolean>;
265
+ isAdmin(): Promise<boolean>;
266
+ isRemembered(): boolean;
267
+ changeEmail(newEmail: string, callback: TokenCallback): Promise<void>;
268
+ confirmEmail(token: string): Promise<string>;
269
+ confirmEmailAndLogin(token: string, remember?: boolean): Promise<void>;
270
+ resetPassword(email: string, expiresAfter?: string | number | null, maxOpenRequests?: number | null, callback?: TokenCallback): Promise<void>;
271
+ confirmResetPassword(token: string, password: string, logout?: boolean): Promise<void>;
272
+ verifyPassword(password: string): Promise<boolean>;
273
+ logoutEverywhere(): Promise<void>;
274
+ logoutEverywhereElse(): Promise<void>;
275
+ providers: {
276
+ github?: OAuthProvider;
277
+ google?: OAuthProvider;
278
+ azure?: OAuthProvider;
279
+ };
280
+ twoFactor: TwoFactorManager$1;
281
+ }
282
+ interface TwoFactorManager$1 {
283
+ isEnabled(): Promise<boolean>;
284
+ totpEnabled(): Promise<boolean>;
285
+ emailEnabled(): Promise<boolean>;
286
+ smsEnabled(): Promise<boolean>;
287
+ getEnabledMethods(): Promise<TwoFactorMechanism[]>;
288
+ setup: {
289
+ /**
290
+ * Setup TOTP authentication using an authenticator app.
291
+ * Generates a secret, QR code for easy setup, and optionally backup codes.
292
+ *
293
+ * @param requireVerification - If true, method is created in unverified state and requires calling complete.totp() with a valid code. If false (default), method is immediately enabled and backup codes are generated.
294
+ * @returns Promise resolving to setup result containing secret (for manual entry), QR code URL (for scanning), and backup codes (if verification not required)
295
+ * @throws {UserNotLoggedInError} User is not logged in
296
+ * @throws {TwoFactorAlreadyEnabledError} TOTP is already enabled for this user
297
+ */
298
+ totp(requireVerification?: boolean): Promise<TwoFactorSetupResult>;
299
+ /**
300
+ * Setup email-based two-factor authentication.
301
+ * Uses the user's account email or a specified email address for OTP delivery.
302
+ *
303
+ * @param email - Email address to use for 2FA. If not provided, uses the current user's account email
304
+ * @param requireVerification - If true, method is created in unverified state and requires calling complete.email() with a valid code. If false (default), method is immediately enabled
305
+ * @throws {UserNotLoggedInError} User is not logged in
306
+ * @throws {TwoFactorAlreadyEnabledError} Email 2FA is already enabled for this user
307
+ */
308
+ email(email?: string, requireVerification?: boolean): Promise<void>;
309
+ /**
310
+ * Setup SMS-based two-factor authentication.
311
+ * Uses the provided phone number for OTP delivery via SMS.
312
+ *
313
+ * @param phone - Phone number to use for SMS OTP delivery (should include country code, e.g., "+1234567890")
314
+ * @param requireVerification - If true (default), method is created in unverified state and requires calling complete.sms() with a valid code. If false, method is immediately enabled
315
+ * @throws {UserNotLoggedInError} User is not logged in
316
+ * @throws {TwoFactorAlreadyEnabledError} SMS 2FA is already enabled for this user
317
+ */
318
+ sms(phone: string, requireVerification?: boolean): Promise<void>;
319
+ };
320
+ complete: {
321
+ /**
322
+ * Complete TOTP setup by verifying a code from the user's authenticator app.
323
+ * This is only required if setup.totp() was called with requireVerification: true.
324
+ * Upon successful verification, the method is enabled and backup codes are generated.
325
+ *
326
+ * @param code - The 6-digit TOTP code from the user's authenticator app
327
+ * @returns Promise resolving to an array of backup codes that should be securely stored by the user
328
+ * @throws {UserNotLoggedInError} User is not logged in
329
+ * @throws {TwoFactorNotSetupError} TOTP method was not previously set up or doesn't exist
330
+ * @throws {TwoFactorAlreadyEnabledError} TOTP method is already verified/enabled
331
+ * @throws {InvalidTwoFactorCodeError} The provided TOTP code is invalid or expired
332
+ */
333
+ totp(code: string): Promise<string[]>;
334
+ /**
335
+ * Complete email 2FA setup by verifying an OTP code sent to the user's email.
336
+ * This is only required if setup.email() was called with requireVerification: true.
337
+ * Upon successful verification, the email 2FA method is enabled.
338
+ *
339
+ * @param code - The OTP code that was sent to the user's email address
340
+ * @throws {UserNotLoggedInError} User is not logged in
341
+ * @throws {TwoFactorNotSetupError} Email 2FA method was not previously set up or doesn't exist
342
+ * @throws {TwoFactorAlreadyEnabledError} Email 2FA method is already verified/enabled
343
+ * @throws {InvalidTwoFactorCodeError} The provided email OTP code is invalid or expired
344
+ */
345
+ email(code: string): Promise<void>;
346
+ /**
347
+ * Complete SMS 2FA setup by verifying an OTP code sent to the user's phone.
348
+ * This is only required if setup.sms() was called with requireVerification: true.
349
+ * Upon successful verification, the SMS 2FA method is enabled.
350
+ *
351
+ * @param code - The OTP code that was sent to the user's phone number via SMS
352
+ * @throws {UserNotLoggedInError} User is not logged in
353
+ * @throws {TwoFactorNotSetupError} SMS 2FA method was not previously set up or doesn't exist
354
+ * @throws {TwoFactorAlreadyEnabledError} SMS 2FA method is already verified/enabled
355
+ * @throws {InvalidTwoFactorCodeError} The provided SMS OTP code is invalid or expired
356
+ */
357
+ sms(code: string): Promise<void>;
358
+ };
359
+ verify: {
360
+ /**
361
+ * Verifies a TOTP code during the login flow when two-factor authentication is required.
362
+ * This is used after a login attempt triggers a SecondFactorRequiredError and the user
363
+ * provides a code from their authenticator app. After successful verification, call
364
+ * completeTwoFactorLogin() to finish the login process.
365
+ *
366
+ * @param code - The 6-digit TOTP code from the user's authenticator app
367
+ * @throws {UserNotLoggedInError} No active two-factor authentication session
368
+ * @throws {TwoFactorNotSetupError} TOTP method is not enabled for this user
369
+ * @throws {InvalidTwoFactorCodeError} The provided TOTP code is invalid or expired
370
+ */
371
+ totp(code: string): Promise<void>;
372
+ /**
373
+ * Verifies an email OTP code during the login flow when two-factor authentication is required.
374
+ * This is used after a login attempt triggers a SecondFactorRequiredError and the user
375
+ * provides the OTP code that was sent to their email. After successful verification, call
376
+ * completeTwoFactorLogin() to finish the login process.
377
+ *
378
+ * @param code - The OTP code that was sent to the user's email address
379
+ * @throws {UserNotLoggedInError} No active two-factor authentication session
380
+ * @throws {TwoFactorNotSetupError} Email 2FA method is not enabled for this user
381
+ * @throws {InvalidTwoFactorCodeError} The provided email OTP code is invalid or expired
382
+ */
383
+ email(code: string): Promise<void>;
384
+ /**
385
+ * Verifies an SMS OTP code during the login flow when two-factor authentication is required.
386
+ * This is used after a login attempt triggers a SecondFactorRequiredError and the user
387
+ * provides the OTP code that was sent to their phone. After successful verification, call
388
+ * completeTwoFactorLogin() to finish the login process.
389
+ *
390
+ * @param code - The OTP code that was sent to the user's phone number via SMS
391
+ * @throws {UserNotLoggedInError} No active two-factor authentication session
392
+ * @throws {TwoFactorNotSetupError} SMS 2FA method is not enabled for this user
393
+ * @throws {InvalidTwoFactorCodeError} The provided SMS OTP code is invalid or expired
394
+ */
395
+ sms(code: string): Promise<void>;
396
+ /**
397
+ * Verifies a TOTP backup code during the login flow when two-factor authentication is required.
398
+ * Backup codes are generated when TOTP is first set up and can be used as an alternative to
399
+ * the authenticator app. Each backup code can only be used once and is automatically removed
400
+ * after successful verification. After successful verification, call completeTwoFactorLogin()
401
+ * to finish the login process.
402
+ *
403
+ * @param code - A backup code that was generated during TOTP setup (8-character alphanumeric)
404
+ * @throws {UserNotLoggedInError} No active two-factor authentication session
405
+ * @throws {TwoFactorNotSetupError} TOTP method is not enabled for this user or no backup codes exist
406
+ * @throws {InvalidBackupCodeError} The provided backup code is invalid, expired, or already used
407
+ */
408
+ backupCode(code: string): Promise<void>;
409
+ /**
410
+ * Smart OTP verification that works with both email and SMS codes during the login flow.
411
+ * This method automatically determines whether the provided code is an email or SMS OTP
412
+ * by trying to verify it against all available OTP methods. Use this when you want to
413
+ * provide a single input field for users who may have multiple OTP methods enabled.
414
+ * After successful verification, call completeTwoFactorLogin() to finish the login process.
415
+ *
416
+ * @param code - Either an email or SMS OTP code
417
+ * @throws {UserNotLoggedInError} No active two-factor authentication session
418
+ * @throws {TwoFactorNotSetupError} No email or SMS 2FA methods are enabled for this user
419
+ * @throws {InvalidTwoFactorCodeError} The provided code doesn't match any available OTP methods or is expired
420
+ */
421
+ otp(code: string): Promise<void>;
422
+ };
423
+ /**
424
+ * Disable a TwoFactorMechanism for the session user.
425
+ * @param mechanism - The TwoFactorMechanism to disable for the session user
426
+ * @throws {UserNotLoggedInError} User is not logged in
427
+ * @throws {TwoFactorNotSetupError} The specified method is not enabled for this user
428
+ */
429
+ disable(mechanism: TwoFactorMechanism): Promise<void>;
430
+ /**
431
+ * Generates and stores new TOTP backup codes for the session user, invalidating the old ones in the process.
432
+ * @returns Promise resolving to an array of new backup codes that should be securely stored by the user
433
+ * @throws {UserNotLoggedInError} User is not logged in
434
+ * @throws {TwoFactorNotSetupError} TOTP method is not enabled for this user
435
+ */
436
+ generateNewBackupCodes(): Promise<string[]>;
437
+ /**
438
+ * Returns either the email or mobile number for the session user depending on the provided TwoFactorMechanism.
439
+ * @param mechanism - The TwoFactorMechanism for which to return the contact information
440
+ * @returns Promise resolving to the contact information (email or phone number) or null if not found
441
+ * @throws {UserNotLoggedInError} User is not logged in (returns null instead of throwing in implementation)
442
+ */
443
+ getContact(mechanism: TwoFactorMechanism.EMAIL | TwoFactorMechanism.SMS): Promise<string | null>;
444
+ }
445
+ interface AuthAdminManager {
446
+ createUser(credentials: {
447
+ email: string;
448
+ password: string;
449
+ }, userId?: string | number, callback?: TokenCallback): Promise<AuthAccount>;
450
+ loginAsUserBy(identifier: {
451
+ accountId?: number;
452
+ email?: string;
453
+ userId?: string;
454
+ }): Promise<void>;
455
+ deleteUserBy(identifier: {
456
+ accountId?: number;
457
+ email?: string;
458
+ userId?: string;
459
+ }): Promise<void>;
460
+ addRoleForUserBy(identifier: {
461
+ accountId?: number;
462
+ email?: string;
463
+ userId?: string;
464
+ }, role: number): Promise<void>;
465
+ removeRoleForUserBy(identifier: {
466
+ accountId?: number;
467
+ email?: string;
468
+ userId?: string;
469
+ }, role: number): Promise<void>;
470
+ hasRoleForUserBy(identifier: {
471
+ accountId?: number;
472
+ email?: string;
473
+ userId?: string;
474
+ }, role: number): Promise<boolean>;
475
+ changePasswordForUserBy(identifier: {
476
+ accountId?: number;
477
+ email?: string;
478
+ userId?: string;
479
+ }, password: string): Promise<void>;
480
+ setStatusForUserBy(identifier: {
481
+ accountId?: number;
482
+ email?: string;
483
+ userId?: string;
484
+ }, status: number): Promise<void>;
485
+ initiatePasswordResetForUserBy(identifier: {
486
+ accountId?: number;
487
+ email?: string;
488
+ userId?: string;
489
+ }, expiresAfter?: string | number | null, callback?: TokenCallback): Promise<void>;
490
+ forceLogoutForUserBy(identifier: {
491
+ accountId?: number;
492
+ email?: string;
493
+ userId?: string;
494
+ }): Promise<void>;
495
+ }
496
+
497
+ declare function createAuthMiddleware(config: AuthConfig): (req: Request, res: Response, next: NextFunction) => Promise<void>;
498
+
499
+ declare function createAuthTables(config: AuthConfig): Promise<void>;
500
+ declare function dropAuthTables(config: AuthConfig): Promise<void>;
501
+ declare function cleanupExpiredTokens(config: AuthConfig): Promise<void>;
502
+ declare function getAuthTableStats(config: AuthConfig): Promise<{
503
+ accounts: number;
504
+ providers: number;
505
+ confirmations: number;
506
+ remembers: number;
507
+ resets: number;
508
+ twoFactorMethods: number;
509
+ twoFactorTokens: number;
510
+ expiredConfirmations: number;
511
+ expiredRemembers: number;
512
+ expiredResets: number;
513
+ expiredTwoFactorTokens: number;
514
+ }>;
515
+
516
+ declare class AuthError extends Error {
517
+ constructor(message: string);
518
+ }
519
+ declare class ConfirmationExpiredError extends AuthError {
520
+ constructor();
521
+ }
522
+ declare class ConfirmationNotFoundError extends AuthError {
523
+ constructor();
524
+ }
525
+ declare class EmailNotVerifiedError extends AuthError {
526
+ constructor();
527
+ }
528
+ declare class EmailTakenError extends AuthError {
529
+ constructor();
530
+ }
531
+ declare class InvalidEmailError extends AuthError {
532
+ constructor();
533
+ }
534
+ declare class InvalidPasswordError extends AuthError {
535
+ constructor();
536
+ }
537
+ declare class InvalidTokenError extends AuthError {
538
+ constructor();
539
+ }
540
+ declare class ResetDisabledError extends AuthError {
541
+ constructor();
542
+ }
543
+ declare class ResetExpiredError extends AuthError {
544
+ constructor();
545
+ }
546
+ declare class ResetNotFoundError extends AuthError {
547
+ constructor();
548
+ }
549
+ declare class TooManyResetsError extends AuthError {
550
+ constructor();
551
+ }
552
+ declare class UserInactiveError extends AuthError {
553
+ constructor();
554
+ }
555
+ declare class UserNotFoundError extends AuthError {
556
+ constructor();
557
+ }
558
+ declare class UserNotLoggedInError extends AuthError {
559
+ constructor();
560
+ }
561
+ declare class SecondFactorRequiredError extends AuthError {
562
+ availableMethods: {
563
+ totp?: boolean;
564
+ email?: {
565
+ otpValue: string;
566
+ maskedContact: string;
567
+ };
568
+ sms?: {
569
+ otpValue: string;
570
+ maskedContact: string;
571
+ };
572
+ };
573
+ constructor(availableMethods: SecondFactorRequiredError["availableMethods"]);
574
+ }
575
+ declare class InvalidTwoFactorCodeError extends AuthError {
576
+ constructor();
577
+ }
578
+ declare class TwoFactorExpiredError extends AuthError {
579
+ constructor();
580
+ }
581
+ declare class TwoFactorNotSetupError extends AuthError {
582
+ constructor();
583
+ }
584
+ declare class TwoFactorAlreadyEnabledError extends AuthError {
585
+ constructor();
586
+ }
587
+ declare class InvalidBackupCodeError extends AuthError {
588
+ constructor();
589
+ }
590
+ declare class TwoFactorSetupIncompleteError extends AuthError {
591
+ constructor();
592
+ }
593
+
594
+ declare const isValidEmail: (email: string) => boolean;
595
+ declare const validateEmail: (email: string) => void;
596
+
597
+ declare class ActivityLogger {
598
+ private config;
599
+ private enabled;
600
+ private maxEntries;
601
+ private allowedActions;
602
+ private tablePrefix;
603
+ constructor(config: AuthConfig);
604
+ private get activityTable();
605
+ private parseUserAgent;
606
+ private parseUserAgentSimple;
607
+ private getIpAddress;
608
+ logActivity(accountId: number | null, action: AuthActivityActionType, req: Request, success?: boolean, metadata?: Record<string, any>): Promise<void>;
609
+ cleanup(): Promise<void>;
610
+ getRecentActivity(limit?: number, accountId?: number): Promise<AuthActivity[]>;
611
+ getActivityStats(): Promise<{
612
+ totalEntries: number;
613
+ uniqueUsers: number;
614
+ recentLogins: number;
615
+ failedAttempts: number;
616
+ }>;
617
+ }
618
+
619
+ declare class TwoFactorManager implements TwoFactorManager$1 {
620
+ private req;
621
+ private res;
622
+ private config;
623
+ private queries;
624
+ private activityLogger;
625
+ private totpProvider;
626
+ private otpProvider;
627
+ constructor(req: Request, res: Response, config: AuthConfig);
628
+ private getAccountId;
629
+ private getEmail;
630
+ isEnabled(): Promise<boolean>;
631
+ totpEnabled(): Promise<boolean>;
632
+ emailEnabled(): Promise<boolean>;
633
+ smsEnabled(): Promise<boolean>;
634
+ getEnabledMethods(): Promise<TwoFactorMechanism[]>;
635
+ setup: {
636
+ totp: (requireVerification?: boolean) => Promise<TwoFactorSetupResult>;
637
+ email: (email?: string, requireVerification?: boolean) => Promise<void>;
638
+ sms: (phone: string, requireVerification?: boolean) => Promise<void>;
639
+ };
640
+ complete: {
641
+ totp: (code: string) => Promise<string[]>;
642
+ email: (code: string) => Promise<void>;
643
+ sms: (code: string) => Promise<void>;
644
+ };
645
+ private completeOtpSetup;
646
+ verify: {
647
+ totp: (code: string) => Promise<void>;
648
+ email: (code: string) => Promise<void>;
649
+ sms: (code: string) => Promise<void>;
650
+ backupCode: (code: string) => Promise<void>;
651
+ otp: (code: string) => Promise<void>;
652
+ };
653
+ private verifyOtp;
654
+ disable(mechanism: TwoFactorMechanism): Promise<void>;
655
+ generateNewBackupCodes(): Promise<string[]>;
656
+ getContact(mechanism: TwoFactorMechanism.EMAIL | TwoFactorMechanism.SMS): Promise<string | null>;
657
+ createChallenge(accountId: number): Promise<TwoFactorChallenge>;
658
+ }
659
+
660
+ declare class TotpProvider {
661
+ private config;
662
+ constructor(config: AuthConfig);
663
+ generateSecret(): string;
664
+ generateQRCode(email: string, secret: string): string;
665
+ verify(secret: string, code: string): boolean;
666
+ generateBackupCodes(count?: number): string[];
667
+ hashBackupCodes(codes: string[]): string[];
668
+ verifyBackupCode(hashedCodes: string[], inputCode: string): {
669
+ isValid: boolean;
670
+ index: number;
671
+ };
672
+ maskEmail(email: string): string;
673
+ }
674
+
675
+ declare class OtpProvider {
676
+ private config;
677
+ private queries;
678
+ constructor(config: AuthConfig);
679
+ generateOTP(): string;
680
+ generateSelector(): string;
681
+ createAndStoreOTP(accountId: number, mechanism: TwoFactorMechanism.EMAIL | TwoFactorMechanism.SMS): Promise<{
682
+ otp: string;
683
+ selector: string;
684
+ }>;
685
+ verifyOTP(selector: string, inputCode: string): Promise<{
686
+ isValid: boolean;
687
+ token?: TwoFactorToken;
688
+ }>;
689
+ maskPhone(phone: string): string;
690
+ maskEmail(email: string): string;
691
+ }
692
+
693
+ declare class AuthManager implements AuthManager$1 {
694
+ private req;
695
+ private res;
696
+ private config;
697
+ private queries;
698
+ private activityLogger;
699
+ providers: {
700
+ github?: OAuthProvider;
701
+ google?: OAuthProvider;
702
+ azure?: OAuthProvider;
703
+ };
704
+ twoFactor: TwoFactorManager;
705
+ constructor(req: Request, res: Response, config: AuthConfig);
706
+ private initializeProviders;
707
+ private generateAutoUserId;
708
+ private shouldRequire2FA;
709
+ private validatePassword;
710
+ private getRoleMap;
711
+ private getStatusMap;
712
+ private getAuthAccount;
713
+ private setRememberCookie;
714
+ private getRememberToken;
715
+ private regenerateSession;
716
+ resyncSession(force?: boolean): Promise<void>;
717
+ processRememberDirective(): Promise<void>;
718
+ private onLoginSuccessful;
719
+ private createRememberDirective;
720
+ /**
721
+ * Check if the current user is logged in.
722
+ * @returns true if user has an active authenticated session
723
+ */
724
+ isLoggedIn(): boolean;
725
+ /**
726
+ * Authenticate user with email and password.
727
+ * Creates a new session and optionally sets a remember token for persistent login.
728
+ *
729
+ * @param email - User's email address
730
+ * @param password - Plain text password
731
+ * @param remember - If true, sets a persistent cookie for auto-login on future visits
732
+ * @throws {UserNotFoundError} Account with this email doesn't exist
733
+ * @throws {InvalidPasswordError} Password is incorrect
734
+ * @throws {EmailNotVerifiedError} Account exists but email is not verified
735
+ * @throws {UserInactiveError} Account is banned, locked, or otherwise inactive
736
+ */
737
+ login(email: string, password: string, remember?: boolean): Promise<void>;
738
+ /**
739
+ * Complete two-factor authentication and log in the user.
740
+ * This should be called after receiving a SecondFactorRequiredError.
741
+ */
742
+ completeTwoFactorLogin(): Promise<void>;
743
+ /**
744
+ * Log out the current user.
745
+ * Clears the session and removes any remember tokens.
746
+ */
747
+ logout(): Promise<void>;
748
+ /**
749
+ * Register a new account.
750
+ *
751
+ * @param email - Email address for the new account
752
+ * @param password - Plain text password (will be hashed)
753
+ * @param userId - Optional user ID to link this auth account to. If not provided, a UUID will be generated automatically.
754
+ * @param callback - If provided, account is created unverified and callback receives confirmation token. Create a URL like /confirm/{token} and call confirmEmail() in that handler. If omitted, account is immediately verified.
755
+ * @returns The created account record
756
+ * @throws {EmailTakenError} Email is already registered
757
+ * @throws {InvalidPasswordError} Password doesn't meet length requirements
758
+ */
759
+ register(email: string, password: string, userId?: string | number, callback?: TokenCallback): Promise<AuthAccount>;
760
+ private createConfirmationToken;
761
+ /**
762
+ * Get the current user's account ID.
763
+ * @returns Account ID if logged in, null otherwise
764
+ */
765
+ getId(): number | null;
766
+ /**
767
+ * Get the current user's email address.
768
+ * @returns Email if logged in, null otherwise
769
+ */
770
+ getEmail(): string | null;
771
+ /**
772
+ * Get the current user's account status.
773
+ * @returns Status number (0=Normal, 1=Archived, 2=Banned, etc.) if logged in, null otherwise
774
+ */
775
+ getStatus(): number | null;
776
+ /**
777
+ * Check if the current user's email is verified.
778
+ * @returns true if verified, false if unverified, null if not logged in
779
+ */
780
+ getVerified(): boolean | null;
781
+ /**
782
+ * Get human-readable role names for the current user or a specific rolemask.
783
+ * @param rolemask - Optional specific rolemask to check. If omitted, uses current user's roles
784
+ * @returns Array of role names (e.g., ['Admin', 'Editor'])
785
+ */
786
+ getRoleNames(rolemask?: number): string[];
787
+ /**
788
+ * Get human-readable status name for the current user.
789
+ * @returns Status name (e.g., 'Normal', 'Banned', 'Locked') if logged in, null otherwise
790
+ */
791
+ getStatusName(): string | null;
792
+ /**
793
+ * Check if the current user has a specific role.
794
+ * @param role - Role bitmask to check (e.g., AuthRole.Admin)
795
+ * @returns true if user has the role, false otherwise
796
+ */
797
+ hasRole(role: number): Promise<boolean>;
798
+ /**
799
+ * Check if the current user has admin privileges.
800
+ * @returns true if user has Admin role, false otherwise
801
+ */
802
+ isAdmin(): Promise<boolean>;
803
+ /**
804
+ * Check if the current user was automatically logged in via remember token.
805
+ * @returns true if auto-logged in from persistent cookie, false if manual login or not logged in
806
+ */
807
+ isRemembered(): boolean;
808
+ /**
809
+ * Request an email change for the current user.
810
+ * Sends a confirmation token to verify the new email before changing it.
811
+ *
812
+ * @param newEmail - New email address
813
+ * @param callback - Called with confirmation token. Create a URL like /confirm/{token} and call confirmEmail() in that handler
814
+ * @throws {UserNotLoggedInError} User is not logged in
815
+ * @throws {EmailTakenError} New email is already registered
816
+ * @throws {UserNotFoundError} Current user account not found
817
+ * @throws {EmailNotVerifiedError} Current account's email is not verified
818
+ */
819
+ changeEmail(newEmail: string, callback: TokenCallback): Promise<void>;
820
+ /**
821
+ * Confirm an email address using a token from registration or email change.
822
+ * Updates the account to verified status and changes email if this was from changeEmail.
823
+ *
824
+ * @param token - Confirmation token from registration or email change
825
+ * @returns The confirmed email address
826
+ * @throws {ConfirmationNotFoundError} Token is invalid or doesn't exist
827
+ * @throws {ConfirmationExpiredError} Token has expired
828
+ * @throws {InvalidTokenError} Token format is invalid
829
+ */
830
+ confirmEmail(token: string): Promise<string>;
831
+ /**
832
+ * Confirm email and automatically log in the user.
833
+ * Useful for "click to verify and login" flows.
834
+ *
835
+ * @param token - Confirmation token from registration
836
+ * @param remember - Whether to set persistent login cookie
837
+ * @throws {ConfirmationNotFoundError} Token is invalid or doesn't exist
838
+ * @throws {ConfirmationExpiredError} Token has expired
839
+ * @throws {InvalidTokenError} Token format is invalid
840
+ * @throws {UserNotFoundError} Associated account no longer exists
841
+ */
842
+ confirmEmailAndLogin(token: string, remember?: boolean): Promise<void>;
843
+ /**
844
+ * Initiate a password reset for a user.
845
+ * Creates a reset token and calls the callback to send reset email.
846
+ *
847
+ * @param email - Email address of account to reset
848
+ * @param expiresAfter - Token expiration (default: 6h). Accepts ms format like '1h', '30m'
849
+ * @param maxOpenRequests - Maximum concurrent reset tokens (default: 2)
850
+ * @param callback - Called with reset token. Create a URL like /reset/{token} and call confirmResetPassword() in that handler
851
+ * @throws {EmailNotVerifiedError} Account doesn't exist or email not verified
852
+ * @throws {ResetDisabledError} Account has password reset disabled
853
+ * @throws {TooManyResetsError} Too many active reset requests
854
+ */
855
+ resetPassword(email: string, expiresAfter?: string | number | null, maxOpenRequests?: number | null, callback?: TokenCallback): Promise<void>;
856
+ /**
857
+ * Complete a password reset using a reset token.
858
+ * Changes the password and optionally logs out all sessions.
859
+ *
860
+ * @param token - Reset token from resetPassword callback
861
+ * @param password - New password (will be hashed)
862
+ * @param logout - Whether to force logout all sessions (default: true)
863
+ * @throws {ResetNotFoundError} Token is invalid or doesn't exist
864
+ * @throws {ResetExpiredError} Token has expired
865
+ * @throws {UserNotFoundError} Associated account no longer exists
866
+ * @throws {ResetDisabledError} Account has password reset disabled
867
+ * @throws {InvalidPasswordError} New password doesn't meet requirements
868
+ * @throws {InvalidTokenError} Token format is invalid
869
+ */
870
+ confirmResetPassword(token: string, password: string, logout?: boolean): Promise<void>;
871
+ /**
872
+ * Verify if a password matches the current user's password.
873
+ * Useful for "confirm current password" flows before sensitive operations.
874
+ *
875
+ * @param password - Password to verify
876
+ * @returns true if password matches, false otherwise
877
+ * @throws {UserNotLoggedInError} User is not logged in
878
+ * @throws {UserNotFoundError} Current user account not found
879
+ */
880
+ verifyPassword(password: string): Promise<boolean>;
881
+ private forceLogoutForAccountById;
882
+ /**
883
+ * Force logout all OTHER sessions while keeping current session active.
884
+ * Useful for "logout other devices" functionality.
885
+ */
886
+ logoutEverywhereElse(): Promise<void>;
887
+ /**
888
+ * Force logout ALL sessions including the current one.
889
+ * Logs out everywhere else, then logs out current session.
890
+ */
891
+ logoutEverywhere(): Promise<void>;
892
+ }
893
+
894
+ declare abstract class BaseOAuthProvider implements OAuthProvider {
895
+ protected config: OAuthProviderConfig;
896
+ protected authConfig: AuthConfig;
897
+ protected authManager: AuthManager;
898
+ constructor(config: OAuthProviderConfig, authConfig: AuthConfig, authManager: AuthManager);
899
+ abstract getAuthUrl(state?: string, scopes?: string[]): string;
900
+ abstract getUserData(req: Request): Promise<OAuthUserData>;
901
+ handleCallback(req: Request): Promise<void>;
902
+ protected processOAuthLogin(userData: OAuthUserData, req: Request): Promise<void>;
903
+ protected abstract getProviderName(): string;
904
+ protected exchangeCodeForToken(code: string, tokenUrl: string): Promise<string>;
905
+ protected fetchUserFromAPI(accessToken: string, apiUrl: string): Promise<any>;
906
+ }
907
+
908
+ declare class GitHubProvider extends BaseOAuthProvider {
909
+ constructor(config: GitHubProviderConfig, authConfig: AuthConfig, authManager: AuthManager);
910
+ getAuthUrl(state?: string, scopes?: string[]): string;
911
+ getUserData(req: Request): Promise<OAuthUserData>;
912
+ protected getProviderName(): string;
913
+ }
914
+
915
+ declare class GoogleProvider extends BaseOAuthProvider {
916
+ constructor(config: GoogleProviderConfig, authConfig: AuthConfig, authManager: AuthManager);
917
+ getAuthUrl(state?: string, scopes?: string[]): string;
918
+ getUserData(req: Request): Promise<OAuthUserData>;
919
+ protected getProviderName(): string;
920
+ }
921
+
922
+ declare class AzureProvider extends BaseOAuthProvider {
923
+ constructor(config: AzureProviderConfig, authConfig: AuthConfig, authManager: AuthManager);
924
+ getAuthUrl(state?: string, scopes?: string[]): string;
925
+ getUserData(req: Request): Promise<OAuthUserData>;
926
+ protected getProviderName(): string;
927
+ protected exchangeCodeForToken(code: string, tokenUrl: string): Promise<string>;
928
+ }
929
+
930
+ export { ActivityLogger, type AuthAccount, type AuthActivity, AuthActivityAction, type AuthActivityActionType, type AuthAdminManager, type AuthConfig, type AuthConfirmation, AuthError, type AuthManager$1 as AuthManager, type AuthProvider, type AuthRemember, type AuthReset, AuthRole, type AuthSession, AuthStatus, AzureProvider, type AzureProviderConfig, BaseOAuthProvider, ConfirmationExpiredError, ConfirmationNotFoundError, EmailNotVerifiedError, EmailTakenError, GitHubProvider, type GitHubProviderConfig, GoogleProvider, type GoogleProviderConfig, InvalidBackupCodeError, InvalidEmailError, InvalidPasswordError, InvalidTokenError, InvalidTwoFactorCodeError, type OAuthProvider, type OAuthProviderConfig, type OAuthUserData, OtpProvider, ResetDisabledError, ResetExpiredError, ResetNotFoundError, SecondFactorRequiredError, type TokenCallback, TooManyResetsError, TotpProvider, TwoFactorAlreadyEnabledError, type TwoFactorChallenge, TwoFactorExpiredError, TwoFactorManager, TwoFactorMechanism, type TwoFactorMethod, TwoFactorNotSetupError, TwoFactorSetupIncompleteError, type TwoFactorSetupResult, type TwoFactorToken, UserInactiveError, UserNotFoundError, UserNotLoggedInError, cleanupExpiredTokens, createAuthMiddleware, createAuthTables, dropAuthTables, getAuthTableStats, isValidEmail, validateEmail };