@nauth-toolkit/core 0.1.0 → 0.1.5

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 (184) hide show
  1. package/LICENSE +90 -0
  2. package/README.md +9 -0
  3. package/package.json +8 -3
  4. package/jest.config.js +0 -15
  5. package/jest.setup.ts +0 -6
  6. package/src/adapters/database-columns.ts +0 -165
  7. package/src/adapters/express.adapter.ts +0 -385
  8. package/src/adapters/fastify.adapter.ts +0 -416
  9. package/src/adapters/index.ts +0 -16
  10. package/src/adapters/storage.factory.ts +0 -143
  11. package/src/bootstrap.ts +0 -374
  12. package/src/dto/auth-challenge.dto.ts +0 -231
  13. package/src/dto/auth-response.dto.ts +0 -253
  14. package/src/dto/challenge-response.dto.ts +0 -234
  15. package/src/dto/change-password-request.dto.ts +0 -50
  16. package/src/dto/change-password-response.dto.ts +0 -29
  17. package/src/dto/change-password.dto.ts +0 -57
  18. package/src/dto/error-response.dto.ts +0 -136
  19. package/src/dto/get-available-methods.dto.ts +0 -55
  20. package/src/dto/get-challenge-data-response.dto.ts +0 -28
  21. package/src/dto/get-challenge-data.dto.ts +0 -69
  22. package/src/dto/get-client-info.dto.ts +0 -104
  23. package/src/dto/get-device-token-response.dto.ts +0 -25
  24. package/src/dto/get-events-by-type.dto.ts +0 -76
  25. package/src/dto/get-ip-address-response.dto.ts +0 -24
  26. package/src/dto/get-mfa-status.dto.ts +0 -94
  27. package/src/dto/get-risk-assessment-history.dto.ts +0 -39
  28. package/src/dto/get-session-id-response.dto.ts +0 -25
  29. package/src/dto/get-setup-data-response.dto.ts +0 -31
  30. package/src/dto/get-setup-data.dto.ts +0 -75
  31. package/src/dto/get-suspicious-activity.dto.ts +0 -42
  32. package/src/dto/get-user-agent-response.dto.ts +0 -23
  33. package/src/dto/get-user-auth-history.dto.ts +0 -95
  34. package/src/dto/get-user-by-email.dto.ts +0 -61
  35. package/src/dto/get-user-by-id.dto.ts +0 -46
  36. package/src/dto/get-user-devices.dto.ts +0 -53
  37. package/src/dto/get-user-response.dto.ts +0 -17
  38. package/src/dto/has-provider.dto.ts +0 -56
  39. package/src/dto/index.ts +0 -57
  40. package/src/dto/is-trusted-device-response.dto.ts +0 -34
  41. package/src/dto/list-providers-response.dto.ts +0 -23
  42. package/src/dto/login.dto.ts +0 -95
  43. package/src/dto/logout-all-response.dto.ts +0 -24
  44. package/src/dto/logout-all.dto.ts +0 -65
  45. package/src/dto/logout-response.dto.ts +0 -25
  46. package/src/dto/logout.dto.ts +0 -64
  47. package/src/dto/refresh-token.dto.ts +0 -36
  48. package/src/dto/remove-devices.dto.ts +0 -85
  49. package/src/dto/resend-code-response.dto.ts +0 -32
  50. package/src/dto/resend-code.dto.ts +0 -51
  51. package/src/dto/reset-password.dto.ts +0 -115
  52. package/src/dto/respond-challenge.dto.ts +0 -272
  53. package/src/dto/set-mfa-exemption.dto.ts +0 -112
  54. package/src/dto/set-must-change-password-response.dto.ts +0 -27
  55. package/src/dto/set-must-change-password.dto.ts +0 -46
  56. package/src/dto/set-preferred-method.dto.ts +0 -80
  57. package/src/dto/setup-mfa.dto.ts +0 -98
  58. package/src/dto/signup.dto.ts +0 -174
  59. package/src/dto/social-auth.dto.ts +0 -422
  60. package/src/dto/trust-device-response.dto.ts +0 -30
  61. package/src/dto/trust-device.dto.ts +0 -9
  62. package/src/dto/update-user-attributes-request.dto.ts +0 -51
  63. package/src/dto/user-response.dto.ts +0 -138
  64. package/src/dto/user-update.dto.ts +0 -222
  65. package/src/dto/verify-email.dto.ts +0 -313
  66. package/src/dto/verify-mfa-code.dto.ts +0 -103
  67. package/src/dto/verify-phone-by-sub.dto.ts +0 -78
  68. package/src/dto/verify-phone.dto.ts +0 -245
  69. package/src/entities/auth-audit.entity.ts +0 -232
  70. package/src/entities/challenge-session.entity.ts +0 -116
  71. package/src/entities/index.ts +0 -29
  72. package/src/entities/login-attempt.entity.ts +0 -64
  73. package/src/entities/mfa-device.entity.ts +0 -151
  74. package/src/entities/rate-limit.entity.ts +0 -44
  75. package/src/entities/session.entity.ts +0 -180
  76. package/src/entities/social-account.entity.ts +0 -96
  77. package/src/entities/storage-lock.entity.ts +0 -39
  78. package/src/entities/trusted-device.entity.ts +0 -112
  79. package/src/entities/user.entity.ts +0 -243
  80. package/src/entities/verification-token.entity.ts +0 -141
  81. package/src/enums/auth-audit-event-type.enum.ts +0 -360
  82. package/src/enums/error-codes.enum.ts +0 -420
  83. package/src/enums/mfa-method.enum.ts +0 -97
  84. package/src/enums/risk-factor.enum.ts +0 -111
  85. package/src/exceptions/nauth.exception.ts +0 -231
  86. package/src/handlers/auth.handler.ts +0 -260
  87. package/src/handlers/client-info.handler.ts +0 -101
  88. package/src/handlers/csrf.handler.ts +0 -156
  89. package/src/handlers/token-delivery.handler.ts +0 -118
  90. package/src/index.ts +0 -118
  91. package/src/interfaces/client-info.interface.ts +0 -85
  92. package/src/interfaces/config.interface.ts +0 -2135
  93. package/src/interfaces/entities.interface.ts +0 -226
  94. package/src/interfaces/index.ts +0 -15
  95. package/src/interfaces/logger.interface.ts +0 -283
  96. package/src/interfaces/mfa-provider.interface.ts +0 -154
  97. package/src/interfaces/oauth.interface.ts +0 -148
  98. package/src/interfaces/provider.interface.ts +0 -47
  99. package/src/interfaces/social-auth-provider.interface.ts +0 -131
  100. package/src/interfaces/storage-adapter.interface.ts +0 -82
  101. package/src/interfaces/template.interface.ts +0 -510
  102. package/src/interfaces/token-verifier.interface.ts +0 -110
  103. package/src/internal.ts +0 -178
  104. package/src/platform/interfaces.ts +0 -299
  105. package/src/schemas/auth-config.schema.ts +0 -646
  106. package/src/services/adaptive-mfa-decision.service.spec.ts +0 -1058
  107. package/src/services/adaptive-mfa-decision.service.ts +0 -457
  108. package/src/services/auth-audit.service.spec.ts +0 -675
  109. package/src/services/auth-audit.service.ts +0 -558
  110. package/src/services/auth-challenge-helper.service.spec.ts +0 -3227
  111. package/src/services/auth-challenge-helper.service.ts +0 -825
  112. package/src/services/auth-flow-context-builder.service.ts +0 -520
  113. package/src/services/auth-flow-rules.ts +0 -202
  114. package/src/services/auth-flow-state-definitions.ts +0 -190
  115. package/src/services/auth-flow-state-machine.service.ts +0 -207
  116. package/src/services/auth-flow-state-machine.types.ts +0 -316
  117. package/src/services/auth.service.spec.ts +0 -4195
  118. package/src/services/auth.service.ts +0 -3727
  119. package/src/services/challenge.service.spec.ts +0 -1363
  120. package/src/services/challenge.service.ts +0 -696
  121. package/src/services/client-info.service.spec.ts +0 -572
  122. package/src/services/client-info.service.ts +0 -374
  123. package/src/services/csrf.service.ts +0 -54
  124. package/src/services/email-verification.service.spec.ts +0 -1229
  125. package/src/services/email-verification.service.ts +0 -578
  126. package/src/services/geo-location.service.spec.ts +0 -603
  127. package/src/services/geo-location.service.ts +0 -599
  128. package/src/services/index.ts +0 -13
  129. package/src/services/jwt.service.spec.ts +0 -882
  130. package/src/services/jwt.service.ts +0 -621
  131. package/src/services/mfa-base.service.spec.ts +0 -246
  132. package/src/services/mfa-base.service.ts +0 -611
  133. package/src/services/mfa.service.spec.ts +0 -693
  134. package/src/services/mfa.service.ts +0 -960
  135. package/src/services/password.service.spec.ts +0 -166
  136. package/src/services/password.service.ts +0 -309
  137. package/src/services/phone-verification.service.spec.ts +0 -1120
  138. package/src/services/phone-verification.service.ts +0 -751
  139. package/src/services/risk-detection.service.spec.ts +0 -1292
  140. package/src/services/risk-detection.service.ts +0 -1012
  141. package/src/services/risk-scoring.service.spec.ts +0 -204
  142. package/src/services/risk-scoring.service.ts +0 -131
  143. package/src/services/session.service.spec.ts +0 -1293
  144. package/src/services/session.service.ts +0 -803
  145. package/src/services/social-account.service.spec.ts +0 -725
  146. package/src/services/social-auth-base.service.spec.ts +0 -418
  147. package/src/services/social-auth-base.service.ts +0 -581
  148. package/src/services/social-auth.service.spec.ts +0 -238
  149. package/src/services/social-auth.service.ts +0 -436
  150. package/src/services/social-provider-registry.service.spec.ts +0 -238
  151. package/src/services/social-provider-registry.service.ts +0 -122
  152. package/src/services/trusted-device.service.spec.ts +0 -505
  153. package/src/services/trusted-device.service.ts +0 -339
  154. package/src/storage/account-lockout-storage.service.spec.ts +0 -310
  155. package/src/storage/account-lockout-storage.service.ts +0 -89
  156. package/src/storage/index.ts +0 -3
  157. package/src/storage/memory-storage.adapter.ts +0 -443
  158. package/src/storage/rate-limit-storage.service.spec.ts +0 -247
  159. package/src/storage/rate-limit-storage.service.ts +0 -38
  160. package/src/templates/html-template.engine.spec.ts +0 -161
  161. package/src/templates/html-template.engine.ts +0 -688
  162. package/src/templates/index.ts +0 -7
  163. package/src/utils/common-passwords.spec.ts +0 -230
  164. package/src/utils/common-passwords.ts +0 -170
  165. package/src/utils/context-storage.ts +0 -188
  166. package/src/utils/cookie-names.util.ts +0 -67
  167. package/src/utils/cookies.util.ts +0 -94
  168. package/src/utils/index.ts +0 -12
  169. package/src/utils/ip-extractor.spec.ts +0 -330
  170. package/src/utils/ip-extractor.ts +0 -220
  171. package/src/utils/nauth-logger.spec.ts +0 -388
  172. package/src/utils/nauth-logger.ts +0 -215
  173. package/src/utils/pii-redactor.spec.ts +0 -130
  174. package/src/utils/pii-redactor.ts +0 -288
  175. package/src/utils/setup/get-repositories.ts +0 -140
  176. package/src/utils/setup/init-services.ts +0 -422
  177. package/src/utils/setup/init-social.ts +0 -189
  178. package/src/utils/setup/init-storage.ts +0 -94
  179. package/src/utils/setup/register-mfa.ts +0 -165
  180. package/src/utils/setup/run-nauth-migrations.ts +0 -61
  181. package/src/utils/token-delivery-policy.ts +0 -38
  182. package/src/validators/template.validator.ts +0 -219
  183. package/tsconfig.json +0 -37
  184. package/tsconfig.lint.json +0 -6
package/src/bootstrap.ts DELETED
@@ -1,374 +0,0 @@
1
- /**
2
- * NAuth Bootstrap
3
- *
4
- * Entry point for initializing NAuth with platform adapters.
5
- *
6
- * **Usage:**
7
- * ```typescript
8
- * import { NAuth, ExpressAdapter } from '@nauth-toolkit/core';
9
- *
10
- * const nauth = await NAuth.create({
11
- * config: authConfig,
12
- * dataSource: dataSource,
13
- * adapter: new ExpressAdapter(),
14
- * });
15
- *
16
- * // Mount middleware
17
- * app.use(nauth.middleware.clientInfo);
18
- * app.use(nauth.middleware.csrf);
19
- * app.use(nauth.middleware.auth);
20
- * app.use(nauth.middleware.tokenDelivery);
21
- *
22
- * // Protected routes
23
- * app.get('/profile', nauth.helpers.requireAuth(), (req, res) => {
24
- * const user = nauth.helpers.getCurrentUser();
25
- * res.json({ user });
26
- * });
27
- * ```
28
- */
29
-
30
- import { DataSource } from 'typeorm';
31
- import { NAuthConfig } from './interfaces/config.interface';
32
- import { NAuthLogger } from './utils/nauth-logger';
33
- import { NAuthException } from './exceptions/nauth.exception';
34
- import { AuthErrorCode } from './enums/error-codes.enum';
35
- import { NAuthAdapter, NAuthRequest, NAuthResponse } from './platform/interfaces';
36
- import { ExpressAdapter } from './adapters/express.adapter';
37
- import { ContextStorage } from './utils/context-storage';
38
-
39
- // Handlers
40
- import { ClientInfoHandler } from './handlers/client-info.handler';
41
- import { AuthHandler } from './handlers/auth.handler';
42
- import { TokenDeliveryHandler } from './handlers/token-delivery.handler';
43
- import { CsrfHandler } from './handlers/csrf.handler';
44
- import { CsrfService } from './services/csrf.service';
45
-
46
- // Setup Helpers
47
- import { getRepositories } from './utils/setup/get-repositories';
48
- import { initStorage } from './utils/setup/init-storage';
49
- import { initServices, NAuthServices } from './utils/setup/init-services';
50
- import { registerMFAProviders } from './utils/setup/register-mfa';
51
- import { initSocialAuth, NAuthSocialProviders } from './utils/setup/init-social';
52
- import { runNAuthMigrationsOnStartup } from './utils/setup/run-nauth-migrations';
53
- import { AuthFlowContextBuilder, AuthFlowStateMachineService } from './internal';
54
- import { ClientInfo } from './interfaces/client-info.interface';
55
- import { IUser } from './interfaces/entities.interface';
56
-
57
- // ============================================================================
58
- // Types
59
- // ============================================================================
60
-
61
- /**
62
- * Options for NAuth initialization
63
- */
64
- export interface NAuthOptions {
65
- /** NAuth configuration */
66
- config: NAuthConfig;
67
-
68
- /** TypeORM DataSource */
69
- dataSource: DataSource;
70
-
71
- /**
72
- * Platform adapter (Express, Fastify, etc.)
73
- * @default ExpressAdapter
74
- */
75
- adapter?: NAuthAdapter;
76
- }
77
-
78
- /**
79
- * NAuth instance returned by NAuth.create()
80
- *
81
- * Contains services, middleware, and helpers for authentication.
82
- *
83
- * @typeParam TMiddleware - Type for middleware (framework-specific)
84
- * @typeParam THelper - Type for route helpers (framework-specific)
85
- */
86
- export interface NAuthInstance<TMiddleware = unknown, THelper = unknown>
87
- extends Omit<NAuthServices, 'challengeService' | 'authChallengeHelperService'>, NAuthSocialProviders {
88
- /** Framework-specific middleware/hooks */
89
- middleware: {
90
- /** Client info extraction (MUST BE FIRST) */
91
- clientInfo: TMiddleware;
92
- /** JWT authentication */
93
- auth: TMiddleware;
94
- /** CSRF protection */
95
- csrf: TMiddleware;
96
- /** Token delivery (response interceptor) */
97
- tokenDelivery: TMiddleware;
98
- };
99
-
100
- /** Route helpers */
101
- helpers: {
102
- /** Mark route as public (bypasses CSRF) */
103
- public: () => THelper;
104
- /** Require authentication (with optional CSRF bypass) */
105
- requireAuth: (options?: { csrf?: boolean }) => THelper;
106
- /** Optional authentication marker */
107
- optionalAuth: () => THelper;
108
- /** Override token delivery mode */
109
- tokenDelivery: (mode: 'json' | 'cookies') => THelper;
110
- /** Get current authenticated user */
111
- getCurrentUser: () => IUser | undefined;
112
- /** Get current session ID */
113
- getCurrentSession: () => string | number | undefined;
114
- /** Get client info */
115
- getClientInfo: () => ClientInfo | undefined;
116
- };
117
-
118
- /** The adapter being used */
119
- adapter: NAuthAdapter;
120
-
121
- /** Configuration */
122
- config: NAuthConfig;
123
-
124
- /** Logger instance */
125
- logger: NAuthLogger;
126
-
127
- /** CSRF service (if enabled) */
128
- csrfService?: CsrfService;
129
- }
130
-
131
- // ============================================================================
132
- // NAuth Bootstrap Class
133
- // ============================================================================
134
-
135
- /**
136
- * NAuth Bootstrap
137
- *
138
- * Main entry point for initializing NAuth.
139
- */
140
- export class NAuth {
141
- /**
142
- * Create NAuth instance
143
- *
144
- * @param options - Configuration options
145
- * @returns Initialized NAuth instance
146
- *
147
- * @example
148
- * ```typescript
149
- * const nauth = await NAuth.create({
150
- * config: authConfig,
151
- * dataSource: dataSource,
152
- * adapter: new ExpressAdapter(),
153
- * });
154
- * ```
155
- */
156
- static async create(options: NAuthOptions): Promise<NAuthInstance> {
157
- const { config, dataSource } = options;
158
- const adapter = options.adapter || new ExpressAdapter();
159
-
160
- const logger = new NAuthLogger(config.logger);
161
- logger.log(`Initializing NAuth with ${adapter.name}...`);
162
-
163
- // ========================================================================
164
- // 0. Run database migrations (adapter-owned, auto-run, no consumer burden)
165
- // ========================================================================
166
- await runNAuthMigrationsOnStartup(config, dataSource, logger);
167
-
168
- // ========================================================================
169
- // 1. Initialize Repositories & Storage
170
- // ========================================================================
171
- const repos = getRepositories(dataSource);
172
- const storage = await initStorage(config, repos.rateLimitRepository, repos.storageLockRepository, logger);
173
-
174
- // ========================================================================
175
- // 2. Initialize Services
176
- // ========================================================================
177
- const emailProvider = config.emailProvider;
178
- const smsProvider = config.smsProvider;
179
- const services: NAuthServices = initServices(config, repos, storage, logger, emailProvider, smsProvider);
180
-
181
- // ========================================================================
182
- // 3. Initialize Auth Flow State Machine
183
- // ========================================================================
184
- const contextBuilder = new AuthFlowContextBuilder(
185
- services.trustedDeviceService,
186
- services.adaptiveMFADecisionService,
187
- services.clientInfoService,
188
- logger,
189
- );
190
- const stateMachine = new AuthFlowStateMachineService(contextBuilder, logger);
191
-
192
- if (services.authChallengeHelperService) {
193
- (services.authChallengeHelperService as unknown as Record<string, unknown>).stateMachine = stateMachine;
194
- (services.authChallengeHelperService as unknown as Record<string, unknown>).contextBuilder = contextBuilder;
195
- } else {
196
- throw new NAuthException(AuthErrorCode.INTERNAL_ERROR, 'AuthChallengeHelperService not initialized.');
197
- }
198
-
199
- // ========================================================================
200
- // 4. Register MFA & Social Providers
201
- // ========================================================================
202
- const socialAuthStateStore = new Map<string, { timestamp: number; provider: string }>();
203
-
204
- if (config.mfa?.enabled && services.mfaService) {
205
- await registerMFAProviders(
206
- config,
207
- services.mfaService,
208
- repos.mfaDeviceRepository!,
209
- repos.userRepository,
210
- logger,
211
- services.passwordService,
212
- services.emailVerificationService,
213
- services.phoneVerificationService,
214
- services.challengeService,
215
- services.auditService,
216
- services.clientInfoService,
217
- );
218
- }
219
-
220
- const socialProviders: NAuthSocialProviders = await initSocialAuth(
221
- config,
222
- services.socialProviderRegistry,
223
- services.authService,
224
- services.socialAuthService,
225
- services.jwtService,
226
- services.sessionService,
227
- services.authChallengeHelperService,
228
- services.clientInfoService,
229
- logger,
230
- socialAuthStateStore,
231
- repos.userRepository,
232
- services.phoneVerificationService,
233
- services.auditService,
234
- services.trustedDeviceService,
235
- );
236
-
237
- // ========================================================================
238
- // 5. Create Handlers
239
- // ========================================================================
240
- const clientInfoHandler = new ClientInfoHandler(services.clientInfoService, services.geoLocationService, logger);
241
-
242
- const authHandler = new AuthHandler(
243
- services.jwtService,
244
- services.sessionService,
245
- repos.userRepository,
246
- config,
247
- logger,
248
- );
249
-
250
- const tokenDeliveryHandler = new TokenDeliveryHandler(config, logger);
251
-
252
- // CSRF service (only for cookies/hybrid delivery)
253
- const csrfService =
254
- config.tokenDelivery?.method === 'cookies' || config.tokenDelivery?.method === 'hybrid'
255
- ? new CsrfService(config)
256
- : undefined;
257
-
258
- const csrfHandler = csrfService ? new CsrfHandler(csrfService, config, logger) : null;
259
-
260
- // ========================================================================
261
- // 6. Register Middleware with Adapter
262
- // ========================================================================
263
- const middleware = {
264
- // ClientInfo MUST be first - initializes context
265
- clientInfo: adapter.registerMiddleware('clientInfo', clientInfoHandler.handle.bind(clientInfoHandler), {
266
- initializesContext: true,
267
- }),
268
-
269
- // Auth handler
270
- auth: adapter.registerMiddleware('auth', authHandler.handle.bind(authHandler)),
271
-
272
- // CSRF handler (no-op if disabled)
273
- csrf: csrfHandler
274
- ? adapter.registerMiddleware('csrf', csrfHandler.handle.bind(csrfHandler))
275
- : adapter.registerMiddleware('noop', async (_req: NAuthRequest, _res: NAuthResponse, next: () => void) => {
276
- await next();
277
- }),
278
-
279
- // Token delivery (response interceptor)
280
- tokenDelivery: adapter.registerResponseInterceptor(
281
- tokenDeliveryHandler.handleResponse.bind(tokenDeliveryHandler),
282
- ),
283
- };
284
-
285
- // ========================================================================
286
- // 7. Create Helpers
287
- // ========================================================================
288
- const helpers = {
289
- /**
290
- * Mark route as public - bypasses CSRF validation
291
- */
292
- public: () =>
293
- adapter.registerMiddleware('public', (req: NAuthRequest, _res: NAuthResponse, next: () => void) => {
294
- req.attributes.nauthPublic = true;
295
- return next();
296
- }),
297
-
298
- /**
299
- * Require authentication
300
- *
301
- * @param options.csrf - Set to false to bypass CSRF check (e.g., for logout)
302
- */
303
- requireAuth: (options?: { csrf?: boolean }) =>
304
- adapter.registerMiddleware('requireAuth', (req: NAuthRequest, res: NAuthResponse, next: () => void) => {
305
- // Enforce deferred CSRF check (unless disabled)
306
- if (options?.csrf !== false && req.attributes.nauthCsrfError) {
307
- throw req.attributes.nauthCsrfError;
308
- }
309
-
310
- // Enforce authentication
311
- if (!req.attributes.user) {
312
- res.status(401).json({
313
- statusCode: 401,
314
- error: 'Unauthorized',
315
- message: 'Authentication required',
316
- code: 'AUTH_REQUIRED',
317
- });
318
- return;
319
- }
320
-
321
- return next();
322
- }),
323
-
324
- /**
325
- * Optional authentication marker
326
- *
327
- * Auth middleware already does optional auth by default.
328
- * This helper is a semantic marker for documentation purposes.
329
- */
330
- optionalAuth: () =>
331
- adapter.registerMiddleware('optionalAuth', (_req: NAuthRequest, _res: NAuthResponse, next: () => void) => {
332
- return next();
333
- }),
334
-
335
- /**
336
- * Override token delivery mode for this route
337
- */
338
- tokenDelivery: (mode: 'json' | 'cookies') =>
339
- adapter.registerMiddleware(
340
- 'tokenDeliveryConfig',
341
- (req: NAuthRequest, _res: NAuthResponse, next: () => void) => {
342
- req.attributes.nauthTokenDelivery = mode;
343
- return next();
344
- },
345
- ),
346
-
347
- // Context helpers (read from ContextStorage)
348
- getCurrentUser: () => ContextStorage.get<IUser>('CURRENT_USER'),
349
- getCurrentSession: () => ContextStorage.get<string | number>('CURRENT_SESSION'),
350
- getClientInfo: () => ContextStorage.get<ClientInfo>('CLIENT_INFO'),
351
- };
352
-
353
- // ========================================================================
354
- // 8. Build and Return Instance
355
- // ========================================================================
356
-
357
- // Exclude internal services from public API
358
- const { challengeService, authChallengeHelperService, ...publicServices } = services;
359
-
360
- logger.log(`NAuth initialized successfully with ${adapter.name}`);
361
-
362
- return {
363
- ...publicServices,
364
- ...socialProviders,
365
- middleware,
366
- helpers,
367
- adapter,
368
- config,
369
- logger,
370
- socialAuthService: services.socialAuthService,
371
- csrfService,
372
- };
373
- }
374
- }
@@ -1,231 +0,0 @@
1
- import { IsEnum, IsUUID, IsObject } from 'class-validator';
2
- import { Transform } from 'class-transformer';
3
-
4
- /**
5
- * Authentication Challenge Types
6
- *
7
- * Represents different challenges that must be completed before
8
- * a user can gain full access to the system. This is similar to
9
- * AWS Cognito's challenge system.
10
- *
11
- * @example
12
- * ```typescript
13
- * // After login, check for challenges
14
- * const result = await authService.login(credentials);
15
- * if (result.challengeName) {
16
- * // User must complete challenge before accessing system
17
- * console.log('Challenge required:', result.challengeName);
18
- * }
19
- * ```
20
- */
21
- export enum AuthChallenge {
22
- /**
23
- * Email verification required
24
- * User must verify their email address before proceeding
25
- */
26
- VERIFY_EMAIL = 'VERIFY_EMAIL',
27
-
28
- /**
29
- * Phone verification required
30
- * User must verify their phone number before proceeding
31
- */
32
- VERIFY_PHONE = 'VERIFY_PHONE',
33
-
34
- /**
35
- * Multi-factor authentication required
36
- * User must complete MFA verification (TOTP, SMS, etc.)
37
- * This challenge is used when user already has MFA enabled and needs to verify
38
- */
39
- MFA_REQUIRED = 'MFA_REQUIRED',
40
-
41
- /**
42
- * MFA setup required
43
- * User must set up multi-factor authentication before being allowed to login.
44
- * This occurs when enforcement is 'REQUIRED' and grace period has expired or is disabled.
45
- */
46
- MFA_SETUP_REQUIRED = 'MFA_SETUP_REQUIRED',
47
-
48
- /**
49
- * Password change required
50
- * User must change their password before proceeding
51
- * (e.g., admin-forced password reset, expired password)
52
- */
53
- FORCE_CHANGE_PASSWORD = 'FORCE_CHANGE_PASSWORD',
54
- }
55
-
56
- /**
57
- * Challenge Response DTO
58
- *
59
- * Used when a user's authentication is incomplete due to pending challenges.
60
- * Contains minimal information about the user and what challenges they must complete.
61
- *
62
- * Note: This is primarily a response DTO, but validation is included for completeness.
63
- *
64
- * @example
65
- * ```typescript
66
- * // Login response with challenge
67
- * {
68
- * challengeName: 'VERIFY_EMAIL',
69
- * session: 'a21b654c-2746-4168-acee-c175083a65cd',
70
- * challengeParameters: {
71
- * email: 'user@example.com',
72
- * codeDeliveryDestination: 'u***@example.com'
73
- * },
74
- * userSub: 'a21b654c-2746-4168-acee-c175083a65cd'
75
- * }
76
- * ```
77
- */
78
- export class AuthChallengeResponseDTO {
79
- /**
80
- * The challenge that must be completed
81
- *
82
- * Validation:
83
- * - Must be a valid AuthChallenge enum value
84
- */
85
- @IsEnum(AuthChallenge, {
86
- message: 'Challenge name must be a valid AuthChallenge enum value',
87
- })
88
- challengeName!: AuthChallenge;
89
-
90
- /**
91
- * Temporary session identifier for challenge completion (UUID v4)
92
- * This is NOT a full JWT token - only used for challenge verification
93
- *
94
- * Validation:
95
- * - Must be a valid UUID v4 format
96
- * - Generated using randomUUID() in challenge service
97
- *
98
- * @example "a21b654c-2746-4168-acee-c175083a65cd"
99
- */
100
- @IsUUID('4', { message: 'Session token must be a valid UUID v4 format' })
101
- @Transform(({ value }) => {
102
- if (typeof value === 'string') {
103
- return value.trim().toLowerCase();
104
- }
105
- return value;
106
- })
107
- session!: string;
108
-
109
- /**
110
- * Challenge-specific parameters
111
- * Contains information needed to complete the challenge
112
- *
113
- * Validation:
114
- * - Must be an object
115
- *
116
- * @example
117
- * ```typescript
118
- * // For VERIFY_EMAIL
119
- * {
120
- * email: 'user@example.com',
121
- * codeDeliveryDestination: 'u***@example.com'
122
- * }
123
- *
124
- * // For VERIFY_PHONE
125
- * {
126
- * phone: '+1234567890',
127
- * codeDeliveryDestination: '***-***-7890'
128
- * }
129
- * ```
130
- */
131
- @IsObject({ message: 'Challenge parameters must be an object' })
132
- challengeParameters!: Record<string, unknown>;
133
-
134
- /**
135
- * User's unique identifier (UUID v4)
136
- * Provided so the client knows which user is completing challenges
137
- *
138
- * Validation:
139
- * - Must be a valid UUID v4 format
140
- * - Matches DB constraint: char(36) or uuid
141
- *
142
- * @example "a21b654c-2746-4168-acee-c175083a65cd"
143
- */
144
- @IsUUID('4', { message: 'User sub must be a valid UUID v4 format' })
145
- @Transform(({ value }) => {
146
- if (typeof value === 'string') {
147
- return value.trim().toLowerCase();
148
- }
149
- return value;
150
- })
151
- userSub!: string;
152
- }
153
-
154
- /**
155
- * Challenge Completion Request DTO
156
- *
157
- * Used to submit a response to an authentication challenge.
158
- *
159
- * Note: This is a legacy DTO. The codebase now uses RespondChallengeDTO for the unified API.
160
- * This DTO is kept for backwards compatibility.
161
- *
162
- * Security:
163
- * - Session token validated as UUID v4 format
164
- * - Challenge name validated against enum
165
- * - Challenge responses validated as object
166
- *
167
- * @example
168
- * ```typescript
169
- * // Verify email challenge
170
- * const request: ChallengeResponseRequestDTO = {
171
- * session: 'a21b654c-2746-4168-acee-c175083a65cd',
172
- * challengeName: 'VERIFY_EMAIL',
173
- * challengeResponses: {
174
- * code: '123456'
175
- * }
176
- * };
177
- * ```
178
- */
179
- export class ChallengeResponseRequestDTO {
180
- /**
181
- * Temporary session from initial auth response (UUID v4)
182
- *
183
- * Validation:
184
- * - Must be a valid UUID v4 format
185
- * - Generated using randomUUID() in challenge service
186
- *
187
- * Sanitization:
188
- * - Trimmed
189
- * - Lowercased for consistency
190
- *
191
- * @example "a21b654c-2746-4168-acee-c175083a65cd"
192
- */
193
- @IsUUID('4', { message: 'Session token must be a valid UUID v4 format' })
194
- @Transform(({ value }) => {
195
- if (typeof value === 'string') {
196
- return value.trim().toLowerCase();
197
- }
198
- return value;
199
- })
200
- session!: string;
201
-
202
- /**
203
- * The challenge being responded to
204
- *
205
- * Validation:
206
- * - Must be a valid AuthChallenge enum value
207
- */
208
- @IsEnum(AuthChallenge, {
209
- message: 'Challenge name must be a valid AuthChallenge enum value',
210
- })
211
- challengeName!: AuthChallenge;
212
-
213
- /**
214
- * Challenge-specific responses
215
- *
216
- * Validation:
217
- * - Must be an object
218
- * - Structure validated in service layer based on challenge type
219
- *
220
- * @example
221
- * ```typescript
222
- * // For VERIFY_EMAIL or VERIFY_PHONE
223
- * { code: '123456' }
224
- *
225
- * // For FORCE_CHANGE_PASSWORD
226
- * { newPassword: 'NewSecure123!' }
227
- * ```
228
- */
229
- @IsObject({ message: 'Challenge responses must be an object' })
230
- challengeResponses!: Record<string, unknown>;
231
- }