@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
@@ -1,688 +0,0 @@
1
- import { TemplateEngine, TemplateType, TemplateVariables, EmailTemplate } from '../interfaces/template.interface';
2
- import { NAuthException } from '../exceptions/nauth.exception';
3
- import { AuthErrorCode } from '../enums/error-codes.enum';
4
-
5
- /**
6
- * HTML Template Engine
7
- *
8
- * Simple yet powerful template engine for email templates using HTML with placeholder tokens.
9
- * Supports {{variable}} syntax for variable injection.
10
- *
11
- * Features:
12
- * - Simple {{variable}} placeholder syntax
13
- * - Built-in default templates for all email types
14
- * - Custom template registration
15
- * - Automatic HTML entity escaping for security
16
- * - Plain text generation from HTML
17
- *
18
- * @example
19
- * ```typescript
20
- * const engine = new HtmlTemplateEngine();
21
- * const result = await engine.render(
22
- * TemplateType.VERIFICATION,
23
- * { userName: 'John', code: '123456', expiryMinutes: 60 }
24
- * );
25
- * ```
26
- */
27
- export class HtmlTemplateEngine implements TemplateEngine {
28
- /**
29
- * Storage for registered templates
30
- * Maps template type to template definition
31
- */
32
- private templates: Map<string, EmailTemplate> = new Map();
33
-
34
- /**
35
- * Constructor
36
- * Initializes the engine with default templates
37
- */
38
- constructor() {
39
- this.registerDefaultTemplates();
40
- }
41
-
42
- /**
43
- * Render a template with variables
44
- *
45
- * Replaces all {{variable}} placeholders with actual values.
46
- * Variables are HTML-escaped for security.
47
- * Handles firstName/username fallback for greetings.
48
- *
49
- * @param type - Template type to render
50
- * @param variables - Variables to inject
51
- * @returns Rendered email template
52
- * @throws {Error} If template type not found
53
- */
54
- async render(type: TemplateType | string, variables: TemplateVariables): Promise<EmailTemplate> {
55
- const template = this.templates.get(type);
56
-
57
- if (!template) {
58
- throw new NAuthException(
59
- AuthErrorCode.INTERNAL_ERROR,
60
- `Template "${type}" not found. Available templates: ${Array.from(this.templates.keys()).join(', ')}`,
61
- );
62
- }
63
-
64
- // Merge with default variables and add greeting name
65
- const allVariables: TemplateVariables = {
66
- currentYear: new Date().getFullYear(),
67
- ...variables,
68
- greetingName: this.getGreetingName(variables),
69
- };
70
-
71
- // Render subject and HTML
72
- const subject = this.replaceVariables(template.subject, allVariables);
73
- const html = this.replaceVariables(template.html, allVariables);
74
-
75
- // Generate plain text if not provided
76
- const text = template.text ? this.replaceVariablesForText(template.text, allVariables) : this.htmlToText(html);
77
-
78
- return { subject, html, text };
79
- }
80
-
81
- /**
82
- * Register a custom template
83
- *
84
- * @param type - Template type identifier
85
- * @param template - Template definition
86
- */
87
- registerTemplate(type: TemplateType | string, template: EmailTemplate): void {
88
- this.templates.set(type, template);
89
- }
90
-
91
- /**
92
- * Get all available template types
93
- *
94
- * @returns Array of template type identifiers
95
- */
96
- getAvailableTemplates(): string[] {
97
- return Array.from(this.templates.keys());
98
- }
99
-
100
- /**
101
- * Check if a template exists
102
- *
103
- * @param type - Template type to check
104
- * @returns True if template is registered
105
- */
106
- hasTemplate(type: TemplateType | string): boolean {
107
- return this.templates.has(type);
108
- }
109
-
110
- /**
111
- * Replace {{variable}} placeholders with values
112
- *
113
- * Escapes HTML entities in variables for security.
114
- * Handles missing variables gracefully (replaces with empty string).
115
- * Supports firstName/username fallback logic and simple conditionals.
116
- *
117
- * @param template - Template string with {{placeholders}}
118
- * @param variables - Variables to inject
119
- * @returns Template with variables replaced
120
- * @private
121
- */
122
- private replaceVariables(template: string, variables: TemplateVariables): string {
123
- let result = template;
124
-
125
- // Handle simple conditionals like {{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}
126
- result = result.replace(
127
- /\{\{#if (\w+)\}\}(.*?)\{\{else\}\}(.*?)\{\{\/if\}\}/g,
128
- (_match, key, ifContent, elseContent) => {
129
- const value = variables[key];
130
- if (value && value !== '') {
131
- return ifContent;
132
- } else {
133
- return elseContent;
134
- }
135
- },
136
- );
137
-
138
- // Replace regular variables
139
- result = result.replace(/\{\{(\w+)\}\}/g, (_match, key) => {
140
- const value = variables[key];
141
-
142
- // Return empty string if variable is undefined
143
- if (value === undefined || value === null) {
144
- return '';
145
- }
146
-
147
- // Convert to string and escape HTML entities
148
- return this.escapeHtml(String(value));
149
- });
150
-
151
- return result;
152
- }
153
-
154
- /**
155
- * Replace {{variable}} placeholders with values for text content
156
- *
157
- * Similar to replaceVariables but doesn't escape HTML entities for plain text.
158
- *
159
- * @param template - Template string with {{placeholders}}
160
- * @param variables - Variables to inject
161
- * @returns Template with variables replaced
162
- * @private
163
- */
164
- private replaceVariablesForText(template: string, variables: TemplateVariables): string {
165
- let result = template;
166
-
167
- // Handle simple conditionals like {{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}
168
- result = result.replace(
169
- /\{\{#if (\w+)\}\}(.*?)\{\{else\}\}(.*?)\{\{\/if\}\}/g,
170
- (_match, key, ifContent, elseContent) => {
171
- const value = variables[key];
172
- if (value && value !== '') {
173
- return ifContent;
174
- } else {
175
- return elseContent;
176
- }
177
- },
178
- );
179
-
180
- // Replace regular variables without HTML escaping
181
- result = result.replace(/\{\{(\w+)\}\}/g, (_match, key) => {
182
- const value = variables[key];
183
-
184
- // Return empty string if variable is undefined
185
- if (value === undefined || value === null) {
186
- return '';
187
- }
188
-
189
- // Convert to string without escaping HTML entities for text
190
- return String(value);
191
- });
192
-
193
- return result;
194
- }
195
-
196
- /**
197
- * Get greeting name with firstName/username fallback logic
198
- *
199
- * @param variables - Template variables
200
- * @returns Greeting name or empty string
201
- * @private
202
- */
203
- private getGreetingName(variables: TemplateVariables): string {
204
- if (variables.firstName) {
205
- return variables.firstName;
206
- }
207
- if (variables.userName) {
208
- return variables.userName;
209
- }
210
- return '';
211
- }
212
-
213
- /**
214
- * Escape HTML entities to prevent XSS
215
- *
216
- * @param text - Text to escape
217
- * @returns HTML-safe text
218
- * @private
219
- */
220
- private escapeHtml(text: string): string {
221
- const map: Record<string, string> = {
222
- '&': '&amp;',
223
- '<': '&lt;',
224
- '>': '&gt;',
225
- '"': '&quot;',
226
- "'": '&#039;',
227
- };
228
-
229
- return text.replace(/[&<>"']/g, (char) => map[char] || char);
230
- }
231
-
232
- /**
233
- * Convert HTML to plain text
234
- *
235
- * Simple conversion: strips HTML tags and decodes entities.
236
- *
237
- * @param html - HTML content
238
- * @returns Plain text
239
- * @private
240
- */
241
- private htmlToText(html: string): string {
242
- // Strip HTML tags
243
- let text = html.replace(/<[^>]*>/g, '');
244
-
245
- // Decode common HTML entities
246
- text = text.replace(/&nbsp;/g, ' ');
247
- text = text.replace(/&lt;/g, '<');
248
- text = text.replace(/&gt;/g, '>');
249
- text = text.replace(/&quot;/g, '"');
250
- text = text.replace(/&#039;/g, "'");
251
- text = text.replace(/&amp;/g, '&');
252
-
253
- // Normalize whitespace
254
- text = text.replace(/\s+/g, ' ').trim();
255
-
256
- return text;
257
- }
258
-
259
- /**
260
- * Register default templates for all email types
261
- *
262
- * These templates can be overridden using registerTemplate().
263
- * @private
264
- */
265
- private registerDefaultTemplates(): void {
266
- // ============================================================================
267
- // Email Verification Template
268
- // ============================================================================
269
- this.registerTemplate(TemplateType.VERIFICATION, {
270
- subject: 'Email Verification - {{appName}}',
271
- html: `
272
- <!DOCTYPE html>
273
- <html>
274
- <head>
275
- <meta charset="UTF-8">
276
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
277
- <title>Email Verification</title>
278
- <style>
279
- body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; }
280
- .container { max-width: 600px; margin: 0 auto; }
281
- h1 { font-size: 24px; margin: 0 0 20px 0; }
282
- p { margin: 0 0 15px 0; }
283
- .code { font-size: 24px; font-weight: bold; letter-spacing: 3px; margin: 20px 0; }
284
- </style>
285
- </head>
286
- <body>
287
- <div class="container">
288
- <h1>Email Verification</h1>
289
- <p>{{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}</p>
290
- <p>Thank you for signing up! Please verify your email address to activate your account.</p>
291
-
292
- <p>Your Verification Code:</p>
293
- <div class="code">{{code}}</div>
294
-
295
- <p>Or click the link below to verify:</p>
296
- <p><a href="{{link}}">Verify Email Address</a></p>
297
-
298
- <p>This code expires in {{expiryMinutes}} minutes.</p>
299
- <p>If you didn't request this verification, please ignore this email.</p>
300
- </div>
301
- </body>
302
- </html>
303
- `,
304
- text: `
305
- Email Verification
306
-
307
- {{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}
308
-
309
- Thank you for signing up! Please verify your email address to activate your account.
310
-
311
- Your Verification Code: {{code}}
312
-
313
- Or use this link: {{link}}
314
-
315
- This code expires in {{expiryMinutes}} minutes.
316
-
317
- If you didn't request this verification, please ignore this email.
318
- `,
319
- });
320
-
321
- // ============================================================================
322
- // Password Reset Template
323
- // ============================================================================
324
- this.registerTemplate(TemplateType.PASSWORD_RESET, {
325
- subject: 'Password Reset - {{appName}}',
326
- html: `
327
- <!DOCTYPE html>
328
- <html>
329
- <head>
330
- <meta charset="UTF-8">
331
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
332
- <title>Password Reset</title>
333
- <style>
334
- body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; }
335
- .container { max-width: 600px; margin: 0 auto; }
336
- h1 { font-size: 24px; margin: 0 0 20px 0; }
337
- p { margin: 0 0 15px 0; }
338
- </style>
339
- </head>
340
- <body>
341
- <div class="container">
342
- <h1>Password Reset</h1>
343
- <p>{{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}</p>
344
- <p>We received a request to reset your password. Click the link below to create a new password:</p>
345
-
346
- <p><a href="{{link}}">Reset Your Password</a></p>
347
-
348
- <p>This link expires in {{expiryMinutes}} minutes.</p>
349
- <p>If you didn't request a password reset, your account is secure and you can ignore this email.</p>
350
-
351
- <p>If the link doesn't work, copy and paste this URL into your browser:</p>
352
- <p>{{link}}</p>
353
- </div>
354
- </body>
355
- </html>
356
- `,
357
- text: `
358
- Password Reset
359
-
360
- {{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}
361
-
362
- We received a request to reset your password. Use the link below to create a new password:
363
-
364
- {{link}}
365
-
366
- This link expires in {{expiryMinutes}} minutes.
367
-
368
- If you didn't request a password reset, your account is secure and you can ignore this email.
369
- `,
370
- });
371
-
372
- // ============================================================================
373
- // Welcome Email Template
374
- // ============================================================================
375
- this.registerTemplate(TemplateType.WELCOME, {
376
- subject: 'Welcome to {{appName}}!',
377
- html: `
378
- <!DOCTYPE html>
379
- <html>
380
- <head>
381
- <meta charset="UTF-8">
382
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
383
- <title>Welcome</title>
384
- <style>
385
- body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; }
386
- .container { max-width: 600px; margin: 0 auto; }
387
- h1 { font-size: 24px; margin: 0 0 20px 0; }
388
- p { margin: 0 0 15px 0; }
389
- </style>
390
- </head>
391
- <body>
392
- <div class="container">
393
- <h1>Welcome</h1>
394
- <p>{{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}</p>
395
- <p>We're excited to have you with us! Your account has been successfully created and you're ready to get started.</p>
396
-
397
- <p><a href="{{dashboardUrl}}">Get Started</a></p>
398
-
399
- <p>If you have any questions or need assistance, feel free to reach out to our support team at {{supportEmail}}.</p>
400
-
401
- <p>Happy exploring!</p>
402
- </div>
403
- </body>
404
- </html>
405
- `,
406
- text: `
407
- Welcome to {{appName}}!
408
-
409
- {{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}
410
-
411
- We're excited to have you with us! Your account has been successfully created and you're ready to get started.
412
-
413
- Visit: {{dashboardUrl}}
414
-
415
- If you have any questions or need assistance, reach out to our support team at {{supportEmail}}.
416
-
417
- Happy exploring!
418
- `,
419
- });
420
-
421
- // ============================================================================
422
- // Account Lockout Template
423
- // ============================================================================
424
- this.registerTemplate(TemplateType.ACCOUNT_LOCKOUT, {
425
- subject: 'Account Locked - {{appName}}',
426
- html: `
427
- <!DOCTYPE html>
428
- <html>
429
- <head>
430
- <meta charset="UTF-8">
431
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
432
- <title>Account Lockout</title>
433
- <style>
434
- body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; }
435
- .container { max-width: 600px; margin: 0 auto; }
436
- h1 { font-size: 24px; margin: 0 0 20px 0; }
437
- p { margin: 0 0 15px 0; }
438
- ul { margin: 0 0 15px 0; }
439
- </style>
440
- </head>
441
- <body>
442
- <div class="container">
443
- <h1>Account Locked</h1>
444
- <p>{{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}</p>
445
- <p>Your account has been temporarily locked for security reasons.</p>
446
-
447
- <p><strong>Reason:</strong> {{reason}}</p>
448
- <p><strong>Duration:</strong> Your account will be automatically unlocked in {{durationMinutes}} minutes.</p>
449
-
450
- <p><strong>What happened?</strong></p>
451
- <p>We detected multiple failed login attempts or suspicious activity on your account. As a security measure, we've temporarily locked your account to protect it.</p>
452
-
453
- <p><strong>What should I do?</strong></p>
454
- <ul>
455
- <li>Wait {{durationMinutes}} minutes for automatic unlock</li>
456
- <li>If this was you, try logging in again after the lockout period</li>
457
- <li>If this wasn't you, please contact support immediately at {{supportEmail}}</li>
458
- <li>Consider changing your password after unlock</li>
459
- </ul>
460
- </div>
461
- </body>
462
- </html>
463
- `,
464
- text: `
465
- Account Locked
466
-
467
- {{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}
468
-
469
- Your account has been temporarily locked for security reasons.
470
-
471
- Reason: {{reason}}
472
- Duration: Your account will be automatically unlocked in {{durationMinutes}} minutes.
473
-
474
- What happened?
475
- We detected multiple failed login attempts or suspicious activity on your account.
476
-
477
- What should I do?
478
- - Wait {{durationMinutes}} minutes for automatic unlock
479
- - If this was you, try logging in again after the lockout period
480
- - If this wasn't you, contact support at {{supportEmail}}
481
- - Consider changing your password after unlock
482
- `,
483
- });
484
-
485
- // ============================================================================
486
- // New Device Login Template
487
- // ============================================================================
488
- this.registerTemplate(TemplateType.NEW_DEVICE, {
489
- subject: 'New Device Login - {{appName}}',
490
- html: `
491
- <!DOCTYPE html>
492
- <html>
493
- <head>
494
- <meta charset="UTF-8">
495
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
496
- <title>New Device Login</title>
497
- <style>
498
- body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; }
499
- .container { max-width: 600px; margin: 0 auto; }
500
- h1 { font-size: 24px; margin: 0 0 20px 0; }
501
- p { margin: 0 0 15px 0; }
502
- ul { margin: 0 0 15px 0; }
503
- </style>
504
- </head>
505
- <body>
506
- <div class="container">
507
- <h1>New Device Login</h1>
508
- <p>{{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}</p>
509
- <p>We detected a login to your account from a new device.</p>
510
-
511
- <p><strong>Device:</strong> {{deviceName}}</p>
512
- <p><strong>Type:</strong> {{deviceType}}</p>
513
- <p><strong>IP Address:</strong> {{ipAddress}}</p>
514
- <p><strong>Location:</strong> {{location}}</p>
515
- <p><strong>Time:</strong> {{timestamp}}</p>
516
-
517
- <p><strong>Was this you?</strong></p>
518
- <p>If you recognize this login, no action is needed. Your account is secure.</p>
519
-
520
- <p><strong>Not you?</strong></p>
521
- <p>If you don't recognize this activity, please secure your account immediately:</p>
522
- <ul>
523
- <li>Change your password</li>
524
- <li>Review your recent account activity</li>
525
- <li>Contact support at {{supportEmail}}</li>
526
- </ul>
527
- </div>
528
- </body>
529
- </html>
530
- `,
531
- text: `
532
- New Device Login
533
-
534
- {{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}
535
-
536
- We detected a login to your account from a new device.
537
-
538
- Device: {{deviceName}}
539
- Type: {{deviceType}}
540
- IP Address: {{ipAddress}}
541
- Location: {{location}}
542
- Time: {{timestamp}}
543
-
544
- Was this you?
545
- If you recognize this login, no action is needed.
546
-
547
- Not you?
548
- If you don't recognize this activity, secure your account immediately:
549
- - Change your password
550
- - Review your recent account activity
551
- - Contact support at {{supportEmail}}
552
- `,
553
- });
554
- // Password Changed Template
555
- // ============================================================================
556
- this.registerTemplate(TemplateType.PASSWORD_CHANGED, {
557
- subject: 'Password Changed - {{appName}}',
558
- html: `
559
- <!DOCTYPE html>
560
- <html>
561
- <head>
562
- <meta charset="UTF-8">
563
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
564
- <title>Password Changed</title>
565
- <style>
566
- body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; }
567
- .container { max-width: 600px; margin: 0 auto; }
568
- h1 { font-size: 24px; margin: 0 0 20px 0; }
569
- p { margin: 0 0 15px 0; }
570
- </style>
571
- </head>
572
- <body>
573
- <div class="container">
574
- <h1>Password Changed</h1>
575
- <p>{{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}</p>
576
- <p>Your password has been successfully changed.</p>
577
-
578
- <p>If you made this change, no further action is required.</p>
579
-
580
- <p>If you didn't make this change, please contact support immediately at {{supportEmail}}.</p>
581
- </div>
582
- </body>
583
- </html>
584
- `,
585
- text: `
586
- Password Changed
587
-
588
- {{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}
589
-
590
- Your password has been successfully changed.
591
-
592
- If you made this change, no further action is required.
593
-
594
- If you didn't make this change, please contact support immediately at {{supportEmail}}.
595
- `,
596
- });
597
-
598
- // ============================================================================
599
- // Email Changed Template
600
- // ============================================================================
601
- this.registerTemplate(TemplateType.EMAIL_CHANGED, {
602
- subject: 'Email Address Changed - {{appName}}',
603
- html: `
604
- <!DOCTYPE html>
605
- <html>
606
- <head>
607
- <meta charset="UTF-8">
608
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
609
- <title>Email Changed</title>
610
- <style>
611
- body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; }
612
- .container { max-width: 600px; margin: 0 auto; }
613
- h1 { font-size: 24px; margin: 0 0 20px 0; }
614
- p { margin: 0 0 15px 0; }
615
- </style>
616
- </head>
617
- <body>
618
- <div class="container">
619
- <h1>Email Address Changed</h1>
620
- <p>{{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}</p>
621
- <p>Your email address has been successfully changed to {{userEmail}}.</p>
622
-
623
- <p>If you made this change, no further action is required.</p>
624
-
625
- <p>If you didn't make this change, please contact support immediately at {{supportEmail}}.</p>
626
- </div>
627
- </body>
628
- </html>
629
- `,
630
- text: `
631
- Email Address Changed
632
-
633
- {{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}
634
-
635
- Your email address has been successfully changed to {{userEmail}}.
636
-
637
- If you made this change, no further action is required.
638
-
639
- If you didn't make this change, please contact support immediately at {{supportEmail}}.
640
- `,
641
- });
642
-
643
- // ============================================================================
644
- // MFA Enabled Template
645
- // ============================================================================
646
- this.registerTemplate(TemplateType.MFA_ENABLED, {
647
- subject: 'Two-Factor Authentication Enabled - {{appName}}',
648
- html: `
649
- <!DOCTYPE html>
650
- <html>
651
- <head>
652
- <meta charset="UTF-8">
653
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
654
- <title>MFA Enabled</title>
655
- <style>
656
- body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; }
657
- .container { max-width: 600px; margin: 0 auto; }
658
- h1 { font-size: 24px; margin: 0 0 20px 0; }
659
- p { margin: 0 0 15px 0; }
660
- </style>
661
- </head>
662
- <body>
663
- <div class="container">
664
- <h1>Two-Factor Authentication Enabled</h1>
665
- <p>{{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}</p>
666
- <p>Two-factor authentication has been successfully enabled for your account.</p>
667
-
668
- <p>Your account is now more secure. You'll need to provide both your password and a verification code when logging in.</p>
669
-
670
- <p>If you didn't enable this feature, please contact support immediately at {{supportEmail}}.</p>
671
- </div>
672
- </body>
673
- </html>
674
- `,
675
- text: `
676
- Two-Factor Authentication Enabled
677
-
678
- {{#if greetingName}}Hi {{greetingName}},{{else}}Hi,{{/if}}
679
-
680
- Two-factor authentication has been successfully enabled for your account.
681
-
682
- Your account is now more secure. You'll need to provide both your password and a verification code when logging in.
683
-
684
- If you didn't enable this feature, please contact support immediately at {{supportEmail}}.
685
- `,
686
- });
687
- }
688
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * Email Template System Exports
3
- *
4
- * Provides template engines and utilities for email notifications.
5
- */
6
-
7
- export * from './html-template.engine';