@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,165 +0,0 @@
1
- /**
2
- * MFA Provider Registration
3
- *
4
- * Dynamically loads and registers MFA providers with the MFAService.
5
- */
6
-
7
- import { Repository } from 'typeorm';
8
- // Public API imports
9
- import {
10
- NAuthConfig,
11
- NAuthLogger,
12
- MFAService,
13
- BaseMFADevice,
14
- BaseUser,
15
- PhoneVerificationService,
16
- EmailVerificationService,
17
- AuthAuditService,
18
- ClientInfoService,
19
- IMFAProviderService,
20
- } from '../../index';
21
- // Internal API imports (for framework adapter use only)
22
- import { PasswordService, ChallengeService } from '../../internal';
23
-
24
- /**
25
- * Register MFA providers with the MFA service
26
- *
27
- * Dynamically imports MFA provider packages based on configuration.
28
- * Each provider is initialized with required services and registered.
29
- *
30
- * @param config - NAuth configuration
31
- * @param mfaService - MFA management service
32
- * @param mfaDeviceRepository - MFA device repository
33
- * @param userRepository - User repository
34
- * @param logger - Logger instance
35
- * @param passwordService - Password service (required by base provider)
36
- * @param phoneVerificationService - Phone verification service (optional, for SMS MFA)
37
- * @param challengeService - Challenge service (optional)
38
- * @param auditService - Audit service (optional)
39
- * @param clientInfoService - Client info service (optional)
40
- */
41
- export async function registerMFAProviders(
42
- config: NAuthConfig,
43
- mfaService: MFAService,
44
- mfaDeviceRepository: Repository<BaseMFADevice>,
45
- userRepository: Repository<BaseUser>,
46
- logger: NAuthLogger,
47
- passwordService: PasswordService,
48
- emailVerificationService: EmailVerificationService,
49
- phoneVerificationService?: PhoneVerificationService,
50
- challengeService?: ChallengeService,
51
- auditService?: AuthAuditService,
52
- clientInfoService?: ClientInfoService,
53
- ): Promise<void> {
54
- if (!config.mfa?.enabled) {
55
- return;
56
- }
57
-
58
- // ============================================================================
59
- // TOTP MFA Provider
60
- // ============================================================================
61
- try {
62
- // @ts-ignore - Optional peer dependency, may not be installed
63
- const { TOTPMFAProviderService, TOTPService } = await import('@nauth-toolkit/mfa-totp');
64
-
65
- const totpService = new TOTPService(config, logger);
66
-
67
- const totpProvider = new TOTPMFAProviderService(
68
- mfaDeviceRepository,
69
- userRepository,
70
- config,
71
- logger,
72
- passwordService,
73
- totpService,
74
- challengeService,
75
- auditService,
76
- clientInfoService,
77
- );
78
-
79
- mfaService.registerProvider(totpProvider as unknown as IMFAProviderService);
80
- logger?.debug?.('TOTP MFA provider registered');
81
- } catch (error) {
82
- logger?.warn?.('TOTP MFA package not found. Install @nauth-toolkit/mfa-totp to enable TOTP MFA.');
83
- }
84
-
85
- // ============================================================================
86
- // SMS MFA Provider
87
- // ============================================================================
88
- if (phoneVerificationService) {
89
- try {
90
- // @ts-ignore - Optional peer dependency, may not be installed
91
- const { SMSMFAProviderService } = await import('@nauth-toolkit/mfa-sms');
92
-
93
- const smsProvider = new SMSMFAProviderService(
94
- mfaDeviceRepository,
95
- userRepository,
96
- config,
97
- logger,
98
- passwordService,
99
- phoneVerificationService,
100
- challengeService,
101
- auditService,
102
- clientInfoService,
103
- );
104
-
105
- mfaService.registerProvider(smsProvider as unknown as IMFAProviderService);
106
- logger?.debug?.('SMS MFA provider registered');
107
- } catch (error) {
108
- logger?.warn?.('SMS MFA package not found. Install @nauth-toolkit/mfa-sms to enable SMS MFA.');
109
- }
110
- } else {
111
- logger?.debug?.('Phone verification service not configured. Skipping SMS MFA registration.');
112
- }
113
-
114
- // ============================================================================
115
- // Email MFA Provider
116
- // ============================================================================
117
- try {
118
- // @ts-ignore - Optional peer dependency, may not be installed
119
- const { EmailMFAProviderService } = await import('@nauth-toolkit/mfa-email');
120
-
121
- const emailProvider = new EmailMFAProviderService(
122
- mfaDeviceRepository,
123
- userRepository,
124
- config,
125
- logger,
126
- passwordService,
127
- emailVerificationService,
128
- challengeService,
129
- auditService,
130
- clientInfoService,
131
- );
132
-
133
- mfaService.registerProvider(emailProvider as unknown as IMFAProviderService);
134
- logger?.debug?.('Email MFA provider registered');
135
- } catch (error) {
136
- logger?.warn?.('Email MFA package not found. Install @nauth-toolkit/mfa-email to enable Email MFA.');
137
- }
138
-
139
- // ============================================================================
140
- // Passkey MFA Provider
141
- // ============================================================================
142
- try {
143
- // @ts-ignore - Optional peer dependency, may not be installed
144
- const { PasskeyMFAProviderService, PasskeyService } = await import('@nauth-toolkit/mfa-passkey');
145
-
146
- const passkeyService = new PasskeyService(config, logger);
147
-
148
- const passkeyProvider = new PasskeyMFAProviderService(
149
- mfaDeviceRepository,
150
- userRepository,
151
- config,
152
- logger,
153
- passwordService,
154
- passkeyService,
155
- challengeService,
156
- auditService,
157
- clientInfoService,
158
- );
159
-
160
- mfaService.registerProvider(passkeyProvider as unknown as IMFAProviderService);
161
- logger?.debug?.('Passkey MFA provider registered');
162
- } catch (error) {
163
- logger?.warn?.('Passkey MFA package not found. Install @nauth-toolkit/mfa-passkey to enable Passkey MFA.');
164
- }
165
- }
@@ -1,61 +0,0 @@
1
- import type { DataSource } from 'typeorm';
2
- import type { NAuthConfig } from '../../interfaces/config.interface';
3
- import type { NAuthLogger } from '../nauth-logger';
4
-
5
- type SupportedTypeOrmDbType = 'postgres' | 'mysql' | 'mariadb';
6
-
7
- function getDbType(dataSource: DataSource): SupportedTypeOrmDbType | null {
8
- const type = (dataSource.options as { type?: unknown } | undefined)?.type;
9
- if (type === 'postgres' || type === 'mysql' || type === 'mariadb') return type;
10
- return null;
11
- }
12
-
13
- type MigrationRunnerModule = {
14
- runNAuthMigrations?: (dataSource: DataSource, logger: NAuthLogger, config: NAuthConfig) => Promise<void>;
15
- };
16
-
17
- /**
18
- * Runs nauth-toolkit migrations automatically on startup (zero consumer burden).
19
- *
20
- * @remarks
21
- * This dynamically loads the database-specific adapter package and asks it to run its
22
- * own adapter-owned migrations into the provided `DataSource`.
23
- */
24
- export async function runNAuthMigrationsOnStartup(
25
- config: NAuthConfig,
26
- dataSource: DataSource,
27
- logger: NAuthLogger,
28
- ): Promise<void> {
29
- if (!dataSource.isInitialized) {
30
- logger.warn('[nauth-toolkit] DataSource not initialized; skipping migrations');
31
- return;
32
- }
33
-
34
- const dbType = getDbType(dataSource);
35
- if (!dbType) {
36
- logger.debug(
37
- `[nauth-toolkit] Skipping migrations: unsupported TypeORM DataSource type: ${String(
38
- (dataSource.options as { type?: unknown } | undefined)?.type,
39
- )}`,
40
- );
41
- return;
42
- }
43
-
44
- const adapterPackageName =
45
- dbType === 'postgres' ? '@nauth-toolkit/database-typeorm-postgres' : '@nauth-toolkit/database-typeorm-mysql';
46
-
47
- let imported: MigrationRunnerModule;
48
- try {
49
- // NOTE: use a variable import (not a string literal) to avoid hard dependency from core -> adapter packages
50
- imported = (await import(adapterPackageName)) as unknown as MigrationRunnerModule;
51
- } catch (err) {
52
- const message = err instanceof Error ? err.message : String(err);
53
- throw new Error(`[nauth-toolkit] Failed to load migration adapter ${adapterPackageName}: ${message}`);
54
- }
55
-
56
- if (typeof imported.runNAuthMigrations !== 'function') {
57
- throw new Error(`[nauth-toolkit] Migration adapter ${adapterPackageName} does not export runNAuthMigrations()`);
58
- }
59
-
60
- await imported.runNAuthMigrations(dataSource, logger, config);
61
- }
@@ -1,38 +0,0 @@
1
- /**
2
- * Token Delivery Policy Resolution
3
- *
4
- * Framework-agnostic utility to determine per-request token delivery:
5
- * - 'cookies' for web browser origins
6
- * - 'json' for native/mobile or non-web clients
7
- *
8
- * Uses only generic request shape (headers.origin) to avoid express/fastify types.
9
- */
10
-
11
- export interface HybridPolicy {
12
- /** Allowed web SPA origins (cookies) */
13
- webOrigins?: string[];
14
- /** Allowed native or non-web origins (json tokens) */
15
- nativeOrigins?: string[];
16
- }
17
-
18
- /**
19
- * Resolve effective delivery for a request in hybrid mode.
20
- *
21
- * Safe default: return 'cookies' when origin is unknown or not matched.
22
- * This avoids leaking tokens to browsers by default.
23
- */
24
- export function resolveDeliveryForRequest(req: unknown, policy?: HybridPolicy): 'cookies' | 'json' {
25
- const r = req as { headers?: Record<string, unknown> } | undefined;
26
- const origin = (r?.headers?.origin as string) || '';
27
-
28
- // Prefer explicit origin classification
29
- if (policy?.nativeOrigins && policy.nativeOrigins.includes(origin)) {
30
- return 'json';
31
- }
32
- if (policy?.webOrigins && policy.webOrigins.includes(origin)) {
33
- return 'cookies';
34
- }
35
-
36
- // Default safe posture: treat as web (cookies only)
37
- return 'cookies';
38
- }
@@ -1,219 +0,0 @@
1
- /**
2
- * Template Validation Utility
3
- *
4
- * Validates custom templates to ensure they include all required parameters.
5
- * Provides clear error messages for missing parameters.
6
- */
7
-
8
- import { TemplateType, CustomTemplateDefinition } from '../interfaces/template.interface';
9
- import { NAuthException } from '../exceptions/nauth.exception';
10
- import { AuthErrorCode } from '../enums/error-codes.enum';
11
-
12
- /**
13
- * Required parameters for each template type
14
- *
15
- * Maps template types to their required Handlebars variables.
16
- */
17
- export const TEMPLATE_REQUIRED_PARAMS: Record<TemplateType, string[]> = {
18
- [TemplateType.VERIFICATION]: ['code', 'link', 'expiryMinutes'],
19
- [TemplateType.PASSWORD_RESET]: ['link', 'expiryMinutes'],
20
- [TemplateType.WELCOME]: [],
21
- [TemplateType.ACCOUNT_LOCKOUT]: ['reason', 'durationMinutes'],
22
- [TemplateType.NEW_DEVICE]: ['deviceName', 'timestamp'],
23
- [TemplateType.PASSWORD_CHANGED]: [],
24
- [TemplateType.EMAIL_CHANGED]: ['userEmail'],
25
- [TemplateType.MFA_ENABLED]: [],
26
- };
27
-
28
- /**
29
- * Optional parameters available to all templates
30
- *
31
- * These can be used but are not required.
32
- * Injected by the template engine at runtime if available.
33
- */
34
- export const TEMPLATE_OPTIONAL_PARAMS = [
35
- // User information
36
- 'firstName',
37
- 'lastName',
38
- 'userName',
39
- 'userEmail',
40
- 'greetingName',
41
-
42
- // Global branding
43
- 'appName',
44
- 'companyName',
45
- 'companyAddress',
46
- 'brandColor',
47
- 'logoUrl',
48
- 'dashboardUrl',
49
- 'supportEmail',
50
-
51
- // Social media
52
- 'facebookUrl',
53
- 'twitterUrl',
54
- 'linkedinUrl',
55
-
56
- // Timestamps
57
- 'currentYear',
58
-
59
- // Security alerts (device-specific)
60
- 'deviceType',
61
- 'ipAddress',
62
- 'location',
63
- ];
64
-
65
- /**
66
- * Validate template content for required parameters
67
- *
68
- * Scans template HTML/text for required Handlebars variables.
69
- * Throws error if any required parameters are missing.
70
- *
71
- * @param templateType - Type of template being validated
72
- * @param templateContent - HTML or text content to validate
73
- * @throws {NAuthException} If required parameters are missing
74
- *
75
- * @example
76
- * ```typescript
77
- * validateTemplateParams(
78
- * TemplateType.VERIFICATION,
79
- * '<html>{{code}} {{link}} {{expiryMinutes}}</html>'
80
- * ); // OK
81
- *
82
- * validateTemplateParams(
83
- * TemplateType.VERIFICATION,
84
- * '<html>{{code}}</html>'
85
- * ); // Throws: Missing required parameters: link, expiryMinutes
86
- * ```
87
- */
88
- export function validateTemplateParams(templateType: TemplateType | string, templateContent: string): void {
89
- // Get required params for this template type
90
- const requiredParams = TEMPLATE_REQUIRED_PARAMS[templateType as TemplateType] || [];
91
-
92
- if (requiredParams.length === 0) {
93
- // No validation needed for templates with no required params
94
- return;
95
- }
96
-
97
- // Extract all Handlebars variables from template
98
- // Matches: {{variable}}, {{#if variable}}, {{#each variable}}, etc.
99
- const variablePattern = /\{\{[#/]?(\w+)(?:\s|}})/g;
100
- const foundVariables = new Set<string>();
101
-
102
- let match;
103
- while ((match = variablePattern.exec(templateContent)) !== null) {
104
- foundVariables.add(match[1]);
105
- }
106
-
107
- // Check for missing required parameters
108
- const missingParams = requiredParams.filter((param) => !foundVariables.has(param));
109
-
110
- if (missingParams.length > 0) {
111
- throw new NAuthException(
112
- AuthErrorCode.INTERNAL_ERROR,
113
- `Invalid template configuration for "${templateType}": ` +
114
- `Missing required parameters: ${missingParams.join(', ')}. ` +
115
- `Template must include: ${requiredParams.map((p) => `{{${p}}}`).join(', ')}`,
116
- );
117
- }
118
- }
119
-
120
- /**
121
- * Validate custom template definition
122
- *
123
- * Ensures template definition is valid:
124
- * - Has either htmlPath OR html content
125
- * - Contains all required parameters for template type
126
- *
127
- * @param templateType - Type of template being validated
128
- * @param definition - Template definition to validate
129
- * @param templateContent - Already loaded template content (if available)
130
- * @throws {NAuthException} If template definition is invalid
131
- *
132
- * @example
133
- * ```typescript
134
- * validateCustomTemplate(TemplateType.VERIFICATION, {
135
- * htmlPath: './verification.html.hbs'
136
- * });
137
- * ```
138
- */
139
- export function validateCustomTemplate(
140
- templateType: TemplateType | string,
141
- definition: CustomTemplateDefinition,
142
- templateContent?: string,
143
- ): void {
144
- // Validate that either htmlPath or html is provided
145
- if (!definition.htmlPath && !definition.html) {
146
- throw new NAuthException(
147
- AuthErrorCode.INTERNAL_ERROR,
148
- `Invalid template configuration for "${templateType}": ` + `Must provide either "htmlPath" or "html" content.`,
149
- );
150
- }
151
-
152
- // Validate that both htmlPath and html are not provided
153
- if (definition.htmlPath && definition.html) {
154
- throw new NAuthException(
155
- AuthErrorCode.INTERNAL_ERROR,
156
- `Invalid template configuration for "${templateType}": ` +
157
- `Cannot provide both "htmlPath" and "html". Use one or the other.`,
158
- );
159
- }
160
-
161
- // Validate that both textPath and text are not provided
162
- if (definition.textPath && definition.text) {
163
- throw new NAuthException(
164
- AuthErrorCode.INTERNAL_ERROR,
165
- `Invalid template configuration for "${templateType}": ` +
166
- `Cannot provide both "textPath" and "text". Use one or the other.`,
167
- );
168
- }
169
-
170
- // If template content is provided, validate parameters
171
- if (templateContent) {
172
- validateTemplateParams(templateType, templateContent);
173
- }
174
- }
175
-
176
- /**
177
- * Get help text for template parameters
178
- *
179
- * Returns human-readable list of required and optional parameters
180
- * for a specific template type.
181
- *
182
- * @param templateType - Template type
183
- * @returns Help text with parameter information
184
- *
185
- * @example
186
- * ```typescript
187
- * console.log(getTemplateParamsHelp(TemplateType.VERIFICATION));
188
- * // Output:
189
- * // Required parameters:
190
- * // - {{code}}: Verification code
191
- * // - {{link}}: Verification link
192
- * // - {{expiryMinutes}}: Code expiry time
193
- * // Optional parameters:
194
- * // - {{firstName}}, {{lastName}}, {{userName}}, {{appName}}, etc.
195
- * ```
196
- */
197
- export function getTemplateParamsHelp(templateType: TemplateType): string {
198
- const required = TEMPLATE_REQUIRED_PARAMS[templateType];
199
-
200
- let help = `Template: ${templateType}\n\n`;
201
-
202
- if (required.length > 0) {
203
- help += `Required parameters (must be in template):\n`;
204
- required.forEach((param) => {
205
- help += ` - {{${param}}}\n`;
206
- });
207
- } else {
208
- help += `No required parameters.\n`;
209
- }
210
-
211
- help += `\nOptional parameters (available at runtime):\n`;
212
- help += ` - User: {{firstName}}, {{lastName}}, {{userName}}, {{greetingName}}\n`;
213
- help += ` - Branding: {{appName}}, {{companyName}}, {{brandColor}}, {{logoUrl}}\n`;
214
- help += ` - Support: {{supportEmail}}, {{dashboardUrl}}\n`;
215
- help += ` - Social: {{facebookUrl}}, {{twitterUrl}}, {{linkedinUrl}}\n`;
216
- help += ` - Other: {{currentYear}}\n`;
217
-
218
- return help;
219
- }
package/tsconfig.json DELETED
@@ -1,37 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "composite": true,
4
- "target": "ES2022",
5
- "module": "commonjs",
6
- "lib": ["ES2022"],
7
- "declaration": true,
8
- "declarationMap": true,
9
- "sourceMap": true,
10
- "outDir": "./dist",
11
- "rootDir": "./src",
12
- "removeComments": true,
13
- "strict": true,
14
- "noImplicitAny": true,
15
- "strictNullChecks": true,
16
- "strictFunctionTypes": true,
17
- "strictBindCallApply": true,
18
- "strictPropertyInitialization": true,
19
- "noImplicitThis": true,
20
- "alwaysStrict": true,
21
- "noUnusedLocals": false,
22
- "noUnusedParameters": false,
23
- "noImplicitReturns": true,
24
- "noFallthroughCasesInSwitch": true,
25
- "esModuleInterop": true,
26
- "skipLibCheck": true,
27
- "forceConsistentCasingInFileNames": true,
28
- "resolveJsonModule": true,
29
- "experimentalDecorators": true,
30
- "emitDecoratorMetadata": true,
31
- "moduleResolution": "node",
32
- "allowSyntheticDefaultImports": true
33
- },
34
- "include": ["src/**/*"],
35
- "exclude": ["node_modules", "dist", "**/*.spec.ts", "../social/**/*", "*.tsbuildinfo"]
36
- }
37
-
@@ -1,6 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "include": ["src/**/*"],
4
- "exclude": ["node_modules", "dist"]
5
- }
6
-