@nauth-toolkit/core 0.1.0 → 0.1.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.
Files changed (184) hide show
  1. package/LICENSE +90 -0
  2. package/README.md +30 -0
  3. package/package.json +7 -2
  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
@@ -1,385 +0,0 @@
1
- /**
2
- * Express Framework Adapter
3
- *
4
- * Adapts NAuth to work with Express.js (4.x and 5.x compatible).
5
- *
6
- * **Context Management:**
7
- * - First middleware (clientInfo) initializes AsyncLocalStorage context
8
- * - Context automatically propagates through Express middleware chain
9
- * - Route handlers have automatic context access (no wrapper needed)
10
- *
11
- * **Express 5.x Compatibility:**
12
- * - Uses req.hostname instead of deprecated req.host
13
- * - Handles async middleware errors automatically
14
- * - Compatible with new path matching behavior
15
- */
16
-
17
- import {
18
- NAuthAdapter,
19
- NAuthRequest,
20
- NAuthResponse,
21
- NAuthCookieOptions,
22
- NAuthRequestAttributes,
23
- NAuthMiddlewareHandler,
24
- NAuthResponseInterceptorHandler,
25
- NAuthRouteHandler,
26
- MiddlewareOptions,
27
- } from '../platform/interfaces';
28
- import { ContextStorage } from '../utils/context-storage';
29
-
30
- // ============================================================================
31
- // Express Adapter
32
- // ============================================================================
33
-
34
- /**
35
- * Express Adapter Implementation
36
- *
37
- * Provides NAuth integration for Express.js applications.
38
- */
39
- export class ExpressAdapter implements NAuthAdapter {
40
- public readonly name = 'ExpressAdapter';
41
-
42
- /**
43
- * Register a middleware handler
44
- *
45
- * Wraps the generic NAuth handler into Express middleware format.
46
- * Handles context initialization for the first middleware.
47
- */
48
- public registerMiddleware(
49
- name: string,
50
- handler: NAuthMiddlewareHandler,
51
- options?: MiddlewareOptions,
52
- ): ExpressMiddleware {
53
- const initializesContext = options?.initializesContext || name === 'clientInfo';
54
-
55
- return async (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction): Promise<void> => {
56
- // Ensure we have attribute storage
57
- if (!req._nauthAttributes) {
58
- req._nauthAttributes = {};
59
- }
60
-
61
- const nauthReq = new ExpressRequestWrapper(req);
62
- const nauthRes = new ExpressResponseWrapper(res);
63
-
64
- try {
65
- if (initializesContext) {
66
- // First middleware - initialize context
67
- await ContextStorage.run(async () => {
68
- await this.executeHandler(handler, nauthReq, nauthRes, next);
69
- });
70
- } else {
71
- // Subsequent middleware - context should exist from first middleware
72
- await this.executeHandler(handler, nauthReq, nauthRes, next);
73
- }
74
- } catch (error) {
75
- next(error);
76
- }
77
- };
78
- }
79
-
80
- /**
81
- * Execute handler with proper async flow control
82
- */
83
- private async executeHandler(
84
- handler: NAuthMiddlewareHandler,
85
- req: NAuthRequest,
86
- res: NAuthResponse,
87
- next: ExpressNextFunction,
88
- ): Promise<void> {
89
- let nextCalled = false;
90
- const nextError: unknown = undefined;
91
-
92
- const wrappedNext = (): void => {
93
- nextCalled = true;
94
- };
95
-
96
- await handler(req, res, wrappedNext);
97
-
98
- // Only call Express next if handler called next and no response sent
99
- if (nextCalled && !res.isSent()) {
100
- next(nextError);
101
- }
102
- }
103
-
104
- /**
105
- * Register a response interceptor
106
- *
107
- * Uses res.json monkey-patching to intercept JSON responses.
108
- * This is the standard pattern for Express response interception.
109
- */
110
- public registerResponseInterceptor(handler: NAuthResponseInterceptorHandler): ExpressMiddleware {
111
- return (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction): void => {
112
- // Ensure we have attribute storage
113
- if (!req._nauthAttributes) {
114
- req._nauthAttributes = {};
115
- }
116
-
117
- const originalJson = res.json.bind(res);
118
-
119
- // Monkey-patch res.json
120
- res.json = function (body: unknown): ExpressResponse {
121
- const nauthReq = new ExpressRequestWrapper(req);
122
- const nauthRes = new ExpressResponseWrapper(res);
123
-
124
- // Execute interceptor synchronously wrapped in promise handling
125
- Promise.resolve(handler(nauthReq, nauthRes, body))
126
- .then((modifiedBody) => {
127
- // Restore original json to prevent recursion
128
- res.json = originalJson;
129
- return originalJson(modifiedBody);
130
- })
131
- .catch((error) => {
132
- // On error, send original body (error handled gracefully)
133
- res.json = originalJson;
134
- return originalJson(body);
135
- });
136
-
137
- // Return res for chaining (Express 5 style)
138
- return res;
139
- };
140
-
141
- next();
142
- };
143
- }
144
-
145
- /**
146
- * Wrap a route handler
147
- *
148
- * For Express, this provides:
149
- * - NAuthRequest/NAuthResponse wrappers
150
- * - Automatic error handling
151
- * - Context is automatically available (no restoration needed)
152
- */
153
- public wrapRouteHandler<T>(handler: NAuthRouteHandler<T>): ExpressMiddleware {
154
- return async (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction): Promise<void> => {
155
- // Ensure we have attribute storage
156
- if (!req._nauthAttributes) {
157
- req._nauthAttributes = {};
158
- }
159
-
160
- const nauthReq = new ExpressRequestWrapper(req);
161
- const nauthRes = new ExpressResponseWrapper(res);
162
-
163
- try {
164
- const result = await handler(nauthReq, nauthRes);
165
-
166
- // If handler returned a value and response not sent, send it as JSON
167
- if (result !== undefined && !res.headersSent) {
168
- res.json(result);
169
- }
170
- } catch (error) {
171
- next(error);
172
- }
173
- };
174
- }
175
- }
176
-
177
- // ============================================================================
178
- // Express Request Wrapper
179
- // ============================================================================
180
-
181
- /**
182
- * Wraps Express request into NAuthRequest interface
183
- */
184
- class ExpressRequestWrapper implements NAuthRequest {
185
- constructor(private readonly req: ExpressRequest) {}
186
-
187
- get raw(): unknown {
188
- return this.req;
189
- }
190
-
191
- get method(): string {
192
- return this.req.method.toUpperCase();
193
- }
194
-
195
- get path(): string {
196
- // Express provides path without query string
197
- return this.req.path || this.req.url.split('?')[0];
198
- }
199
-
200
- get url(): string {
201
- return this.req.originalUrl || this.req.url;
202
- }
203
-
204
- get body(): Record<string, unknown> {
205
- return (this.req.body as Record<string, unknown>) || {};
206
- }
207
-
208
- get query(): Record<string, unknown> {
209
- return (this.req.query as Record<string, unknown>) || {};
210
- }
211
-
212
- get params(): Record<string, string> {
213
- return (this.req.params as Record<string, string>) || {};
214
- }
215
-
216
- get headers(): Record<string, string | string[] | undefined> {
217
- return this.req.headers as Record<string, string | string[] | undefined>;
218
- }
219
-
220
- get cookies(): Record<string, string | undefined> {
221
- // Express with cookie-parser middleware
222
- return (this.req.cookies as Record<string, string | undefined>) || {};
223
- }
224
-
225
- get ip(): string {
226
- // Express 4.x and 5.x compatible
227
- // Trust proxy must be configured for X-Forwarded-For
228
- return this.req.ip || this.req.socket?.remoteAddress || '0.0.0.0';
229
- }
230
-
231
- get attributes(): NAuthRequestAttributes {
232
- // Return isolated storage, not raw request
233
- return this.req._nauthAttributes || {};
234
- }
235
-
236
- public getHeader(name: string): string | undefined {
237
- // Express provides req.get() for case-insensitive header lookup
238
- const val = this.req.get ? this.req.get(name) : this.req.headers[name.toLowerCase()];
239
- if (Array.isArray(val)) return val[0];
240
- return val;
241
- }
242
- }
243
-
244
- // ============================================================================
245
- // Express Response Wrapper
246
- // ============================================================================
247
-
248
- /**
249
- * Wraps Express response into NAuthResponse interface
250
- */
251
- class ExpressResponseWrapper implements NAuthResponse {
252
- constructor(private readonly res: ExpressResponse) {}
253
-
254
- get raw(): unknown {
255
- return this.res;
256
- }
257
-
258
- public status(code: number): this {
259
- this.res.status(code);
260
- return this;
261
- }
262
-
263
- public header(name: string, value: string | string[]): this {
264
- this.res.setHeader(name, value);
265
- return this;
266
- }
267
-
268
- public setCookie(name: string, value: string, options?: NAuthCookieOptions): this {
269
- // Express provides res.cookie()
270
- if (typeof this.res.cookie === 'function') {
271
- this.res.cookie(name, value, this.convertCookieOptions(options));
272
- }
273
- return this;
274
- }
275
-
276
- public clearCookie(name: string, options?: NAuthCookieOptions): this {
277
- if (typeof this.res.clearCookie === 'function') {
278
- this.res.clearCookie(name, this.convertCookieOptions(options));
279
- }
280
- return this;
281
- }
282
-
283
- public send(body: unknown): void {
284
- this.res.send(body);
285
- }
286
-
287
- public json(body: unknown): void {
288
- this.res.json(body);
289
- }
290
-
291
- public redirect(url: string, status?: number): void {
292
- if (status) {
293
- this.res.redirect(status, url);
294
- } else {
295
- this.res.redirect(url);
296
- }
297
- }
298
-
299
- public isSent(): boolean {
300
- return this.res.headersSent;
301
- }
302
-
303
- /**
304
- * Convert NAuth cookie options to Express cookie options
305
- */
306
- private convertCookieOptions(options?: NAuthCookieOptions): Record<string, unknown> {
307
- if (!options) return {};
308
-
309
- return {
310
- httpOnly: options.httpOnly,
311
- secure: options.secure,
312
- sameSite: options.sameSite,
313
- domain: options.domain,
314
- path: options.path,
315
- maxAge: options.maxAge,
316
- expires: options.expires,
317
- };
318
- }
319
- }
320
-
321
- // ============================================================================
322
- // Express Type Definitions (minimal, for internal use)
323
- // ============================================================================
324
-
325
- /**
326
- * Express Request type (minimal interface for our needs)
327
- * Compatible with Express 4.x and 5.x
328
- */
329
- interface ExpressRequest {
330
- method: string;
331
- path: string;
332
- url: string;
333
- originalUrl: string;
334
- body: unknown;
335
- query: unknown;
336
- params: unknown;
337
- headers: Record<string, string | string[] | undefined>;
338
- cookies?: Record<string, string>;
339
- ip: string;
340
- socket?: { remoteAddress?: string };
341
- get?(name: string): string | undefined;
342
-
343
- /** NAuth attribute storage - isolated from raw request */
344
- _nauthAttributes?: NAuthRequestAttributes;
345
- }
346
-
347
- /**
348
- * Express Response type (minimal interface for our needs)
349
- * Compatible with Express 4.x and 5.x
350
- */
351
- interface ExpressResponse {
352
- status(code: number): this;
353
- setHeader(name: string, value: string | string[]): void;
354
- cookie(name: string, value: string, options?: Record<string, unknown>): void;
355
- clearCookie(name: string, options?: Record<string, unknown>): void;
356
- send(body: unknown): void;
357
- json(body: unknown): this;
358
- redirect(status: number, url: string): void;
359
- redirect(url: string): void;
360
- headersSent: boolean;
361
- }
362
-
363
- /**
364
- * Express NextFunction type
365
- */
366
- type ExpressNextFunction = (err?: unknown) => void;
367
-
368
- /**
369
- * Express middleware signature
370
- */
371
- type ExpressMiddleware = (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void | Promise<void>;
372
-
373
- // ============================================================================
374
- // Type Exports for Consumer Applications
375
- // ============================================================================
376
-
377
- /**
378
- * Express middleware type for use with app.use()
379
- *
380
- * Consumer apps should cast nauth.middleware.* to this type:
381
- * ```typescript
382
- * app.use(nauth.middleware.clientInfo as ExpressMiddlewareType);
383
- * ```
384
- */
385
- export type ExpressMiddlewareType = (req: unknown, res: unknown, next: (err?: unknown) => void) => void | Promise<void>;