@ambushsoftworks/nestjs-auth-graphql 0.7.2 → 0.9.0-rc.1
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.
- package/README.md +270 -9
- package/dist/auth.module.d.ts +7 -0
- package/dist/auth.module.d.ts.map +1 -1
- package/dist/auth.module.js +53 -0
- package/dist/auth.module.js.map +1 -1
- package/dist/exceptions/invalid-auth-config.exception.d.ts +4 -0
- package/dist/exceptions/invalid-auth-config.exception.d.ts.map +1 -0
- package/dist/exceptions/invalid-auth-config.exception.js +12 -0
- package/dist/exceptions/invalid-auth-config.exception.js.map +1 -0
- package/dist/guards/tenant.guard.d.ts.map +1 -1
- package/dist/guards/tenant.guard.js +9 -1
- package/dist/guards/tenant.guard.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/auth-lifecycle-hooks.interface.d.ts +1 -0
- package/dist/interfaces/auth-lifecycle-hooks.interface.d.ts.map +1 -1
- package/dist/interfaces/auth-logger.interface.d.ts +2 -0
- package/dist/interfaces/auth-logger.interface.d.ts.map +1 -1
- package/dist/interfaces/auth-logger.interface.js +2 -0
- package/dist/interfaces/auth-logger.interface.js.map +1 -1
- package/dist/interfaces/brute-force-repository.interface.d.ts +1 -0
- package/dist/interfaces/brute-force-repository.interface.d.ts.map +1 -1
- package/dist/interfaces/email-service.interface.d.ts +2 -6
- package/dist/interfaces/email-service.interface.d.ts.map +1 -1
- package/dist/interfaces/email-template-renderer.interface.d.ts +2 -6
- package/dist/interfaces/email-template-renderer.interface.d.ts.map +1 -1
- package/dist/interfaces/realm-extractor.interface.d.ts +1 -1
- package/dist/interfaces/realm-extractor.interface.d.ts.map +1 -1
- package/dist/interfaces/tenant-extractor.interface.d.ts +1 -1
- package/dist/interfaces/tenant-extractor.interface.d.ts.map +1 -1
- package/dist/middleware/realm.middleware.d.ts +2 -1
- package/dist/middleware/realm.middleware.d.ts.map +1 -1
- package/dist/middleware/realm.middleware.js +15 -5
- package/dist/middleware/realm.middleware.js.map +1 -1
- package/dist/repositories/noop-brute-force.repository.d.ts +1 -0
- package/dist/repositories/noop-brute-force.repository.d.ts.map +1 -1
- package/dist/repositories/noop-brute-force.repository.js +4 -0
- package/dist/repositories/noop-brute-force.repository.js.map +1 -1
- package/dist/resolvers/base-auth.resolver.d.ts +1 -0
- package/dist/resolvers/base-auth.resolver.d.ts.map +1 -1
- package/dist/resolvers/base-auth.resolver.js +12 -2
- package/dist/resolvers/base-auth.resolver.js.map +1 -1
- package/dist/services/auth.service.d.ts +9 -0
- package/dist/services/auth.service.d.ts.map +1 -1
- package/dist/services/auth.service.js +34 -11
- package/dist/services/auth.service.js.map +1 -1
- package/dist/services/brute-force-protection.service.d.ts +12 -3
- package/dist/services/brute-force-protection.service.d.ts.map +1 -1
- package/dist/services/brute-force-protection.service.js +70 -6
- package/dist/services/brute-force-protection.service.js.map +1 -1
- package/dist/services/configurable-email.service.d.ts +3 -7
- package/dist/services/configurable-email.service.d.ts.map +1 -1
- package/dist/services/configurable-email.service.js +16 -60
- package/dist/services/configurable-email.service.js.map +1 -1
- package/dist/services/default-email-template-renderer.d.ts +4 -7
- package/dist/services/default-email-template-renderer.d.ts.map +1 -1
- package/dist/services/default-email-template-renderer.js +40 -55
- package/dist/services/default-email-template-renderer.js.map +1 -1
- package/dist/services/noop-email-sender.d.ts +2 -0
- package/dist/services/noop-email-sender.d.ts.map +1 -1
- package/dist/services/noop-email-sender.js +28 -0
- package/dist/services/noop-email-sender.js.map +1 -1
- package/dist/services/noop-email.service.d.ts +2 -6
- package/dist/services/noop-email.service.d.ts.map +1 -1
- package/dist/services/noop-email.service.js +9 -17
- package/dist/services/noop-email.service.js.map +1 -1
- package/dist/services/sendgrid-email.service.d.ts +0 -13
- package/dist/services/sendgrid-email.service.d.ts.map +1 -1
- package/dist/services/sendgrid-email.service.js +4 -528
- package/dist/services/sendgrid-email.service.js.map +1 -1
- package/dist/services/verification.service.d.ts +15 -0
- package/dist/services/verification.service.d.ts.map +1 -1
- package/dist/services/verification.service.js +70 -3
- package/dist/services/verification.service.js.map +1 -1
- package/dist/test-utils/index.d.ts +1 -1
- package/dist/test-utils/index.d.ts.map +1 -1
- package/dist/test-utils/index.js +2 -1
- package/dist/test-utils/index.js.map +1 -1
- package/dist/test-utils/mock-repositories.d.ts.map +1 -1
- package/dist/test-utils/mock-repositories.js +1 -0
- package/dist/test-utils/mock-repositories.js.map +1 -1
- package/dist/test-utils/mock-services.d.ts +2 -0
- package/dist/test-utils/mock-services.d.ts.map +1 -1
- package/dist/test-utils/mock-services.js +10 -4
- package/dist/test-utils/mock-services.js.map +1 -1
- package/dist/utils/ip-hash.d.ts +2 -0
- package/dist/utils/ip-hash.d.ts.map +1 -0
- package/dist/utils/ip-hash.js +11 -0
- package/dist/utils/ip-hash.js.map +1 -0
- package/examples/full-resolver-template.ts +311 -0
- package/package.json +2 -1
|
@@ -68,10 +68,7 @@ let EmailService = EmailService_1 = class EmailService {
|
|
|
68
68
|
try {
|
|
69
69
|
const msg = {
|
|
70
70
|
to: email,
|
|
71
|
-
from: {
|
|
72
|
-
email: this.fromEmail,
|
|
73
|
-
name: this.fromName,
|
|
74
|
-
},
|
|
71
|
+
from: { email: this.fromEmail, name: this.fromName },
|
|
75
72
|
subject: 'Verify your LiftIQ account',
|
|
76
73
|
text: this.renderVerificationTextTemplate(code, expiresInMinutes),
|
|
77
74
|
html: this.renderVerificationHtmlTemplate(code, expiresInMinutes),
|
|
@@ -88,10 +85,7 @@ let EmailService = EmailService_1 = class EmailService {
|
|
|
88
85
|
try {
|
|
89
86
|
const msg = {
|
|
90
87
|
to: email,
|
|
91
|
-
from: {
|
|
92
|
-
email: this.fromEmail,
|
|
93
|
-
name: this.fromName,
|
|
94
|
-
},
|
|
88
|
+
from: { email: this.fromEmail, name: this.fromName },
|
|
95
89
|
subject: 'Reset Your Password',
|
|
96
90
|
text: this.renderPasswordResetTextTemplate(code),
|
|
97
91
|
html: this.renderPasswordResetHtmlTemplate(code),
|
|
@@ -104,94 +98,12 @@ let EmailService = EmailService_1 = class EmailService {
|
|
|
104
98
|
throw new Error('Failed to send password reset email');
|
|
105
99
|
}
|
|
106
100
|
}
|
|
107
|
-
async sendAccountLockedEmail(email, lockDurationMinutes) {
|
|
108
|
-
try {
|
|
109
|
-
const msg = {
|
|
110
|
-
to: email,
|
|
111
|
-
from: {
|
|
112
|
-
email: this.fromEmail,
|
|
113
|
-
name: this.fromName,
|
|
114
|
-
},
|
|
115
|
-
subject: 'Your LiftIQ account has been temporarily locked',
|
|
116
|
-
text: this.renderAccountLockedTextTemplate(lockDurationMinutes),
|
|
117
|
-
html: this.renderAccountLockedHtmlTemplate(lockDurationMinutes),
|
|
118
|
-
};
|
|
119
|
-
await sgMail.send(msg);
|
|
120
|
-
this.logger.log(`Account locked email sent to ${email}`);
|
|
121
|
-
}
|
|
122
|
-
catch (error) {
|
|
123
|
-
this.logger.error(`Failed to send account locked email to ${email}`, error);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
async sendWelcomeEmail(email, name) {
|
|
127
|
-
try {
|
|
128
|
-
const msg = {
|
|
129
|
-
to: email,
|
|
130
|
-
from: {
|
|
131
|
-
email: this.fromEmail,
|
|
132
|
-
name: this.fromName,
|
|
133
|
-
},
|
|
134
|
-
subject: 'Welcome to LiftIQ!',
|
|
135
|
-
text: this.renderWelcomeTextTemplate(name),
|
|
136
|
-
html: this.renderWelcomeHtmlTemplate(name),
|
|
137
|
-
};
|
|
138
|
-
await sgMail.send(msg);
|
|
139
|
-
this.logger.log(`Welcome email sent to ${email}`);
|
|
140
|
-
}
|
|
141
|
-
catch (error) {
|
|
142
|
-
this.logger.error(`Failed to send welcome email to ${email}`, error);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
async sendAccountLinkedEmail(email, provider, linkedAt) {
|
|
146
|
-
try {
|
|
147
|
-
const subject = `${this.capitalize(provider)} Account Linked`;
|
|
148
|
-
const msg = {
|
|
149
|
-
to: email,
|
|
150
|
-
from: {
|
|
151
|
-
email: this.fromEmail,
|
|
152
|
-
name: this.fromName,
|
|
153
|
-
},
|
|
154
|
-
subject,
|
|
155
|
-
text: this.renderAccountLinkedTextTemplate(provider, linkedAt),
|
|
156
|
-
html: this.renderAccountLinkedHtmlTemplate(provider, linkedAt),
|
|
157
|
-
};
|
|
158
|
-
await sgMail.send(msg);
|
|
159
|
-
this.logger.log(`Account linked email sent to ${email} (provider: ${provider})`);
|
|
160
|
-
}
|
|
161
|
-
catch (error) {
|
|
162
|
-
this.logger.error(`Failed to send account linked email to ${email}`, error);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
async sendAccountUnlinkedEmail(email, provider, unlinkedAt) {
|
|
166
|
-
try {
|
|
167
|
-
const subject = `${this.capitalize(provider)} Account Unlinked`;
|
|
168
|
-
const msg = {
|
|
169
|
-
to: email,
|
|
170
|
-
from: {
|
|
171
|
-
email: this.fromEmail,
|
|
172
|
-
name: this.fromName,
|
|
173
|
-
},
|
|
174
|
-
subject,
|
|
175
|
-
text: this.renderAccountUnlinkedTextTemplate(provider, unlinkedAt),
|
|
176
|
-
html: this.renderAccountUnlinkedHtmlTemplate(provider, unlinkedAt),
|
|
177
|
-
};
|
|
178
|
-
await sgMail.send(msg);
|
|
179
|
-
this.logger.log(`Account unlinked email sent to ${email} (provider: ${provider})`);
|
|
180
|
-
}
|
|
181
|
-
catch (error) {
|
|
182
|
-
this.logger.error(`Failed to send account unlinked email to ${email}`, error);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
101
|
async sendPasswordChangedEmail(email, changedAt, ipAddress) {
|
|
186
102
|
try {
|
|
187
|
-
const subject = 'Password Changed';
|
|
188
103
|
const msg = {
|
|
189
104
|
to: email,
|
|
190
|
-
from: {
|
|
191
|
-
|
|
192
|
-
name: this.fromName,
|
|
193
|
-
},
|
|
194
|
-
subject,
|
|
105
|
+
from: { email: this.fromEmail, name: this.fromName },
|
|
106
|
+
subject: 'Password Changed',
|
|
195
107
|
text: this.renderPasswordChangedTextTemplate(changedAt, ipAddress),
|
|
196
108
|
html: this.renderPasswordChangedHtmlTemplate(changedAt, ipAddress),
|
|
197
109
|
};
|
|
@@ -386,371 +298,6 @@ let EmailService = EmailService_1 = class EmailService {
|
|
|
386
298
|
</body>
|
|
387
299
|
</html>
|
|
388
300
|
`;
|
|
389
|
-
}
|
|
390
|
-
renderAccountLockedHtmlTemplate(lockDurationMinutes) {
|
|
391
|
-
return `
|
|
392
|
-
<!DOCTYPE html>
|
|
393
|
-
<html lang="en">
|
|
394
|
-
<head>
|
|
395
|
-
<meta charset="UTF-8">
|
|
396
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
397
|
-
<title>Account Temporarily Locked</title>
|
|
398
|
-
<style>
|
|
399
|
-
body {
|
|
400
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
401
|
-
line-height: 1.6;
|
|
402
|
-
color: #333;
|
|
403
|
-
margin: 0;
|
|
404
|
-
padding: 0;
|
|
405
|
-
background-color: #f5f5f5;
|
|
406
|
-
}
|
|
407
|
-
.container {
|
|
408
|
-
max-width: 600px;
|
|
409
|
-
margin: 0 auto;
|
|
410
|
-
padding: 40px 20px;
|
|
411
|
-
background-color: #ffffff;
|
|
412
|
-
}
|
|
413
|
-
.header {
|
|
414
|
-
text-align: center;
|
|
415
|
-
margin-bottom: 40px;
|
|
416
|
-
}
|
|
417
|
-
.logo {
|
|
418
|
-
font-size: 32px;
|
|
419
|
-
font-weight: bold;
|
|
420
|
-
color: #64b5f6;
|
|
421
|
-
letter-spacing: -0.5px;
|
|
422
|
-
}
|
|
423
|
-
.footer {
|
|
424
|
-
text-align: center;
|
|
425
|
-
color: #666;
|
|
426
|
-
font-size: 14px;
|
|
427
|
-
margin-top: 40px;
|
|
428
|
-
padding-top: 20px;
|
|
429
|
-
border-top: 1px solid #e0e0e0;
|
|
430
|
-
}
|
|
431
|
-
h1 {
|
|
432
|
-
color: #333;
|
|
433
|
-
font-size: 24px;
|
|
434
|
-
margin-bottom: 20px;
|
|
435
|
-
}
|
|
436
|
-
p {
|
|
437
|
-
color: #666;
|
|
438
|
-
font-size: 16px;
|
|
439
|
-
margin: 15px 0;
|
|
440
|
-
}
|
|
441
|
-
.warning {
|
|
442
|
-
background-color: #fff3cd;
|
|
443
|
-
border: 1px solid #ffc107;
|
|
444
|
-
border-radius: 8px;
|
|
445
|
-
padding: 15px;
|
|
446
|
-
margin: 20px 0;
|
|
447
|
-
}
|
|
448
|
-
.warning strong {
|
|
449
|
-
color: #333;
|
|
450
|
-
}
|
|
451
|
-
</style>
|
|
452
|
-
</head>
|
|
453
|
-
<body>
|
|
454
|
-
<div class="container">
|
|
455
|
-
<div class="header">
|
|
456
|
-
<div class="logo">LiftIQ</div>
|
|
457
|
-
</div>
|
|
458
|
-
|
|
459
|
-
<h1>Account Temporarily Locked</h1>
|
|
460
|
-
<p>Your account has been temporarily locked due to multiple failed login attempts.</p>
|
|
461
|
-
|
|
462
|
-
<div class="warning">
|
|
463
|
-
<p><strong>Lock duration:</strong> ${lockDurationMinutes} minutes</p>
|
|
464
|
-
</div>
|
|
465
|
-
|
|
466
|
-
<p>This is a security measure to protect your account. You can try logging in again after the lock period expires.</p>
|
|
467
|
-
|
|
468
|
-
<p>If you didn't attempt to log in, please contact support immediately as this may indicate unauthorized access attempts.</p>
|
|
469
|
-
|
|
470
|
-
<div class="footer">
|
|
471
|
-
<p>© ${new Date().getFullYear()} LiftIQ. All rights reserved.</p>
|
|
472
|
-
</div>
|
|
473
|
-
</div>
|
|
474
|
-
</body>
|
|
475
|
-
</html>
|
|
476
|
-
`;
|
|
477
|
-
}
|
|
478
|
-
renderWelcomeHtmlTemplate(name) {
|
|
479
|
-
const greeting = name ? `Hi ${name}` : 'Welcome';
|
|
480
|
-
return `
|
|
481
|
-
<!DOCTYPE html>
|
|
482
|
-
<html lang="en">
|
|
483
|
-
<head>
|
|
484
|
-
<meta charset="UTF-8">
|
|
485
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
486
|
-
<title>Welcome to LiftIQ</title>
|
|
487
|
-
<style>
|
|
488
|
-
body {
|
|
489
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
490
|
-
line-height: 1.6;
|
|
491
|
-
color: #333;
|
|
492
|
-
margin: 0;
|
|
493
|
-
padding: 0;
|
|
494
|
-
background-color: #f5f5f5;
|
|
495
|
-
}
|
|
496
|
-
.container {
|
|
497
|
-
max-width: 600px;
|
|
498
|
-
margin: 0 auto;
|
|
499
|
-
padding: 40px 20px;
|
|
500
|
-
background-color: #ffffff;
|
|
501
|
-
}
|
|
502
|
-
.header {
|
|
503
|
-
text-align: center;
|
|
504
|
-
margin-bottom: 40px;
|
|
505
|
-
}
|
|
506
|
-
.logo {
|
|
507
|
-
font-size: 32px;
|
|
508
|
-
font-weight: bold;
|
|
509
|
-
color: #64b5f6;
|
|
510
|
-
letter-spacing: -0.5px;
|
|
511
|
-
}
|
|
512
|
-
.footer {
|
|
513
|
-
text-align: center;
|
|
514
|
-
color: #666;
|
|
515
|
-
font-size: 14px;
|
|
516
|
-
margin-top: 40px;
|
|
517
|
-
padding-top: 20px;
|
|
518
|
-
border-top: 1px solid #e0e0e0;
|
|
519
|
-
}
|
|
520
|
-
h1 {
|
|
521
|
-
color: #333;
|
|
522
|
-
font-size: 24px;
|
|
523
|
-
margin-bottom: 20px;
|
|
524
|
-
}
|
|
525
|
-
p {
|
|
526
|
-
color: #666;
|
|
527
|
-
font-size: 16px;
|
|
528
|
-
margin: 15px 0;
|
|
529
|
-
}
|
|
530
|
-
ul {
|
|
531
|
-
color: #666;
|
|
532
|
-
font-size: 16px;
|
|
533
|
-
padding-left: 20px;
|
|
534
|
-
}
|
|
535
|
-
li {
|
|
536
|
-
margin: 10px 0;
|
|
537
|
-
}
|
|
538
|
-
</style>
|
|
539
|
-
</head>
|
|
540
|
-
<body>
|
|
541
|
-
<div class="container">
|
|
542
|
-
<div class="header">
|
|
543
|
-
<div class="logo">LiftIQ</div>
|
|
544
|
-
</div>
|
|
545
|
-
|
|
546
|
-
<h1>${greeting}!</h1>
|
|
547
|
-
<p>Thank you for joining LiftIQ. We're excited to help you track your fitness journey.</p>
|
|
548
|
-
|
|
549
|
-
<p>Here's what you can do next:</p>
|
|
550
|
-
<ul>
|
|
551
|
-
<li>Select your available equipment</li>
|
|
552
|
-
<li>Choose your favorite muscle groups</li>
|
|
553
|
-
<li>Start your first workout</li>
|
|
554
|
-
</ul>
|
|
555
|
-
|
|
556
|
-
<p>We're here to support you every step of the way.</p>
|
|
557
|
-
|
|
558
|
-
<div class="footer">
|
|
559
|
-
<p>© ${new Date().getFullYear()} LiftIQ. All rights reserved.</p>
|
|
560
|
-
</div>
|
|
561
|
-
</div>
|
|
562
|
-
</body>
|
|
563
|
-
</html>
|
|
564
|
-
`;
|
|
565
|
-
}
|
|
566
|
-
renderAccountLinkedHtmlTemplate(provider, linkedAt) {
|
|
567
|
-
return `
|
|
568
|
-
<!DOCTYPE html>
|
|
569
|
-
<html lang="en">
|
|
570
|
-
<head>
|
|
571
|
-
<meta charset="UTF-8">
|
|
572
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
573
|
-
<title>Account Linked Successfully</title>
|
|
574
|
-
<style>
|
|
575
|
-
body {
|
|
576
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
577
|
-
line-height: 1.6;
|
|
578
|
-
color: #333;
|
|
579
|
-
margin: 0;
|
|
580
|
-
padding: 0;
|
|
581
|
-
background-color: #f5f5f5;
|
|
582
|
-
}
|
|
583
|
-
.container {
|
|
584
|
-
max-width: 600px;
|
|
585
|
-
margin: 0 auto;
|
|
586
|
-
padding: 40px 20px;
|
|
587
|
-
background-color: #ffffff;
|
|
588
|
-
}
|
|
589
|
-
.header {
|
|
590
|
-
text-align: center;
|
|
591
|
-
margin-bottom: 40px;
|
|
592
|
-
}
|
|
593
|
-
.logo {
|
|
594
|
-
font-size: 32px;
|
|
595
|
-
font-weight: bold;
|
|
596
|
-
color: #64b5f6;
|
|
597
|
-
letter-spacing: -0.5px;
|
|
598
|
-
}
|
|
599
|
-
.footer {
|
|
600
|
-
text-align: center;
|
|
601
|
-
color: #666;
|
|
602
|
-
font-size: 14px;
|
|
603
|
-
margin-top: 40px;
|
|
604
|
-
padding-top: 20px;
|
|
605
|
-
border-top: 1px solid #e0e0e0;
|
|
606
|
-
}
|
|
607
|
-
h1 {
|
|
608
|
-
color: #4F46E5;
|
|
609
|
-
font-size: 24px;
|
|
610
|
-
margin-bottom: 20px;
|
|
611
|
-
}
|
|
612
|
-
p {
|
|
613
|
-
color: #666;
|
|
614
|
-
font-size: 16px;
|
|
615
|
-
margin: 15px 0;
|
|
616
|
-
}
|
|
617
|
-
.security-tip {
|
|
618
|
-
background: #F3F4F6;
|
|
619
|
-
padding: 16px;
|
|
620
|
-
border-radius: 8px;
|
|
621
|
-
margin: 24px 0;
|
|
622
|
-
}
|
|
623
|
-
.security-tip p {
|
|
624
|
-
margin: 0;
|
|
625
|
-
font-size: 14px;
|
|
626
|
-
color: #6B7280;
|
|
627
|
-
}
|
|
628
|
-
@media only screen and (max-width: 600px) {
|
|
629
|
-
.container {
|
|
630
|
-
padding: 20px 15px;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
</style>
|
|
634
|
-
</head>
|
|
635
|
-
<body>
|
|
636
|
-
<div class="container">
|
|
637
|
-
<div class="header">
|
|
638
|
-
<div class="logo">LiftIQ</div>
|
|
639
|
-
</div>
|
|
640
|
-
|
|
641
|
-
<h1>Account Linked Successfully</h1>
|
|
642
|
-
<p>Hi there,</p>
|
|
643
|
-
<p>Your <strong>${this.capitalize(provider)}</strong> account was successfully linked to your LiftIQ account on <strong>${this.formatDate(linkedAt)}</strong>.</p>
|
|
644
|
-
<p>You can now sign in with ${this.capitalize(provider)} for a faster, more convenient experience.</p>
|
|
645
|
-
|
|
646
|
-
<div class="security-tip">
|
|
647
|
-
<p><strong>Security Tip:</strong> If you didn't link this account, please secure your LiftIQ account immediately and contact support.</p>
|
|
648
|
-
</div>
|
|
649
|
-
|
|
650
|
-
<p>Best,<br>The LiftIQ Team</p>
|
|
651
|
-
|
|
652
|
-
<div class="footer">
|
|
653
|
-
<p>© ${new Date().getFullYear()} LiftIQ. All rights reserved.</p>
|
|
654
|
-
</div>
|
|
655
|
-
</div>
|
|
656
|
-
</body>
|
|
657
|
-
</html>
|
|
658
|
-
`;
|
|
659
|
-
}
|
|
660
|
-
renderAccountUnlinkedHtmlTemplate(provider, unlinkedAt) {
|
|
661
|
-
return `
|
|
662
|
-
<!DOCTYPE html>
|
|
663
|
-
<html lang="en">
|
|
664
|
-
<head>
|
|
665
|
-
<meta charset="UTF-8">
|
|
666
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
667
|
-
<title>Account Unlinked</title>
|
|
668
|
-
<style>
|
|
669
|
-
body {
|
|
670
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
671
|
-
line-height: 1.6;
|
|
672
|
-
color: #333;
|
|
673
|
-
margin: 0;
|
|
674
|
-
padding: 0;
|
|
675
|
-
background-color: #f5f5f5;
|
|
676
|
-
}
|
|
677
|
-
.container {
|
|
678
|
-
max-width: 600px;
|
|
679
|
-
margin: 0 auto;
|
|
680
|
-
padding: 40px 20px;
|
|
681
|
-
background-color: #ffffff;
|
|
682
|
-
}
|
|
683
|
-
.header {
|
|
684
|
-
text-align: center;
|
|
685
|
-
margin-bottom: 40px;
|
|
686
|
-
}
|
|
687
|
-
.logo {
|
|
688
|
-
font-size: 32px;
|
|
689
|
-
font-weight: bold;
|
|
690
|
-
color: #64b5f6;
|
|
691
|
-
letter-spacing: -0.5px;
|
|
692
|
-
}
|
|
693
|
-
.footer {
|
|
694
|
-
text-align: center;
|
|
695
|
-
color: #666;
|
|
696
|
-
font-size: 14px;
|
|
697
|
-
margin-top: 40px;
|
|
698
|
-
padding-top: 20px;
|
|
699
|
-
border-top: 1px solid #e0e0e0;
|
|
700
|
-
}
|
|
701
|
-
h1 {
|
|
702
|
-
color: #DC2626;
|
|
703
|
-
font-size: 24px;
|
|
704
|
-
margin-bottom: 20px;
|
|
705
|
-
}
|
|
706
|
-
p {
|
|
707
|
-
color: #666;
|
|
708
|
-
font-size: 16px;
|
|
709
|
-
margin: 15px 0;
|
|
710
|
-
}
|
|
711
|
-
.security-alert {
|
|
712
|
-
background: #FEF2F2;
|
|
713
|
-
padding: 16px;
|
|
714
|
-
border-radius: 8px;
|
|
715
|
-
margin: 24px 0;
|
|
716
|
-
border-left: 4px solid #DC2626;
|
|
717
|
-
}
|
|
718
|
-
.security-alert p {
|
|
719
|
-
margin: 0;
|
|
720
|
-
font-size: 14px;
|
|
721
|
-
color: #991B1B;
|
|
722
|
-
}
|
|
723
|
-
@media only screen and (max-width: 600px) {
|
|
724
|
-
.container {
|
|
725
|
-
padding: 20px 15px;
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
</style>
|
|
729
|
-
</head>
|
|
730
|
-
<body>
|
|
731
|
-
<div class="container">
|
|
732
|
-
<div class="header">
|
|
733
|
-
<div class="logo">LiftIQ</div>
|
|
734
|
-
</div>
|
|
735
|
-
|
|
736
|
-
<h1>Account Unlinked</h1>
|
|
737
|
-
<p>Hi there,</p>
|
|
738
|
-
<p>Your <strong>${this.capitalize(provider)}</strong> account was unlinked from your LiftIQ account on <strong>${this.formatDate(unlinkedAt)}</strong>.</p>
|
|
739
|
-
<p>You will no longer be able to sign in with ${this.capitalize(provider)}. Please use your email and password to log in.</p>
|
|
740
|
-
|
|
741
|
-
<div class="security-alert">
|
|
742
|
-
<p><strong>Security Alert:</strong> If you didn't unlink this account, your LiftIQ account may have been compromised. Please change your password immediately.</p>
|
|
743
|
-
</div>
|
|
744
|
-
|
|
745
|
-
<p>Best,<br>The LiftIQ Team</p>
|
|
746
|
-
|
|
747
|
-
<div class="footer">
|
|
748
|
-
<p>© ${new Date().getFullYear()} LiftIQ. All rights reserved.</p>
|
|
749
|
-
</div>
|
|
750
|
-
</div>
|
|
751
|
-
</body>
|
|
752
|
-
</html>
|
|
753
|
-
`;
|
|
754
301
|
}
|
|
755
302
|
renderPasswordChangedHtmlTemplate(changedAt, ipAddress) {
|
|
756
303
|
return `
|
|
@@ -887,74 +434,6 @@ Your password will not be changed.
|
|
|
887
434
|
This email was sent by LiftIQ Authentication Service
|
|
888
435
|
© ${new Date().getFullYear()} LiftIQ. All rights reserved.
|
|
889
436
|
`.trim();
|
|
890
|
-
}
|
|
891
|
-
renderAccountLockedTextTemplate(lockDurationMinutes) {
|
|
892
|
-
return `
|
|
893
|
-
LiftIQ - Account Temporarily Locked
|
|
894
|
-
|
|
895
|
-
Your account has been temporarily locked due to multiple failed login attempts.
|
|
896
|
-
|
|
897
|
-
Lock duration: ${lockDurationMinutes} minutes
|
|
898
|
-
|
|
899
|
-
This is a security measure to protect your account. You can try logging in again after the lock period expires.
|
|
900
|
-
|
|
901
|
-
If you didn't attempt to log in, please contact support immediately.
|
|
902
|
-
|
|
903
|
-
© ${new Date().getFullYear()} LiftIQ. All rights reserved.
|
|
904
|
-
`.trim();
|
|
905
|
-
}
|
|
906
|
-
renderWelcomeTextTemplate(name) {
|
|
907
|
-
const greeting = name ? `Hi ${name}` : 'Welcome';
|
|
908
|
-
return `
|
|
909
|
-
LiftIQ - ${greeting}!
|
|
910
|
-
|
|
911
|
-
Thank you for joining LiftIQ. We're excited to help you track your fitness journey.
|
|
912
|
-
|
|
913
|
-
Here's what you can do next:
|
|
914
|
-
- Select your available equipment
|
|
915
|
-
- Choose your favorite muscle groups
|
|
916
|
-
- Start your first workout
|
|
917
|
-
|
|
918
|
-
We're here to support you every step of the way.
|
|
919
|
-
|
|
920
|
-
© ${new Date().getFullYear()} LiftIQ. All rights reserved.
|
|
921
|
-
`.trim();
|
|
922
|
-
}
|
|
923
|
-
renderAccountLinkedTextTemplate(provider, linkedAt) {
|
|
924
|
-
return `
|
|
925
|
-
LiftIQ - Account Linked Successfully
|
|
926
|
-
|
|
927
|
-
Hi there,
|
|
928
|
-
|
|
929
|
-
Your ${this.capitalize(provider)} account was successfully linked to your LiftIQ account on ${this.formatDate(linkedAt)}.
|
|
930
|
-
|
|
931
|
-
You can now sign in with ${this.capitalize(provider)} for a faster, more convenient experience.
|
|
932
|
-
|
|
933
|
-
Security Tip: If you didn't link this account, please secure your LiftIQ account immediately and contact support.
|
|
934
|
-
|
|
935
|
-
Best,
|
|
936
|
-
The LiftIQ Team
|
|
937
|
-
|
|
938
|
-
© ${new Date().getFullYear()} LiftIQ. All rights reserved.
|
|
939
|
-
`.trim();
|
|
940
|
-
}
|
|
941
|
-
renderAccountUnlinkedTextTemplate(provider, unlinkedAt) {
|
|
942
|
-
return `
|
|
943
|
-
LiftIQ - Account Unlinked
|
|
944
|
-
|
|
945
|
-
Hi there,
|
|
946
|
-
|
|
947
|
-
Your ${this.capitalize(provider)} account was unlinked from your LiftIQ account on ${this.formatDate(unlinkedAt)}.
|
|
948
|
-
|
|
949
|
-
You will no longer be able to sign in with ${this.capitalize(provider)}. Please use your email and password to log in.
|
|
950
|
-
|
|
951
|
-
Security Alert: If you didn't unlink this account, your LiftIQ account may have been compromised. Please change your password immediately.
|
|
952
|
-
|
|
953
|
-
Best,
|
|
954
|
-
The LiftIQ Team
|
|
955
|
-
|
|
956
|
-
© ${new Date().getFullYear()} LiftIQ. All rights reserved.
|
|
957
|
-
`.trim();
|
|
958
437
|
}
|
|
959
438
|
renderPasswordChangedTextTemplate(changedAt, ipAddress) {
|
|
960
439
|
return `
|
|
@@ -974,9 +453,6 @@ The LiftIQ Team
|
|
|
974
453
|
© ${new Date().getFullYear()} LiftIQ. All rights reserved.
|
|
975
454
|
`.trim();
|
|
976
455
|
}
|
|
977
|
-
capitalize(str) {
|
|
978
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
979
|
-
}
|
|
980
456
|
formatDate(date) {
|
|
981
457
|
return date.toLocaleString('en-US', {
|
|
982
458
|
dateStyle: 'long',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sendgrid-email.service.js","sourceRoot":"","sources":["../../src/services/sendgrid-email.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA4D;AAC5D,uDAAyC;AAEzC,4CAAmD;AAmB5C,IAAM,YAAY,oBAAlB,MAAM,YAAY;IAKvB,YAAyC,OAAkC;QAA1B,YAAO,GAAP,OAAO,CAAmB;QAJ1D,WAAM,GAAG,IAAI,eAAM,CAAC,cAAY,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"sendgrid-email.service.js","sourceRoot":"","sources":["../../src/services/sendgrid-email.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,12 @@ import { IAuthLogger } from '../interfaces/auth-logger.interface';
|
|
|
3
3
|
import { IVerificationRepository } from '../interfaces/verification-repository.interface';
|
|
4
4
|
import { IUserRepository } from '../interfaces/user-repository.interface';
|
|
5
5
|
import { IAuthUser } from '../interfaces/auth-user.interface';
|
|
6
|
+
export interface IssuedVerificationCredential {
|
|
7
|
+
credential: string;
|
|
8
|
+
url?: string;
|
|
9
|
+
expiresInMinutes: number;
|
|
10
|
+
mode: 'code' | 'token';
|
|
11
|
+
}
|
|
6
12
|
export declare class VerificationService {
|
|
7
13
|
private options;
|
|
8
14
|
private readonly userRepository;
|
|
@@ -11,6 +17,8 @@ export declare class VerificationService {
|
|
|
11
17
|
private readonly codeLength;
|
|
12
18
|
private readonly expiryMinutes;
|
|
13
19
|
private readonly maxAttempts;
|
|
20
|
+
private warnedLegacyBaseUrl;
|
|
21
|
+
private warnedPlaceholderBaseUrl;
|
|
14
22
|
constructor(options: AuthModuleOptions, userRepository: IUserRepository<IAuthUser>, verificationRepository: IVerificationRepository, securityLogger: IAuthLogger);
|
|
15
23
|
generateCode(identifier: string, type: 'email' | 'sms' | 'password-reset', realm?: string): Promise<string>;
|
|
16
24
|
validateCode(identifier: string, type: 'email' | 'sms' | 'password-reset', code: string, realm?: string): Promise<boolean>;
|
|
@@ -29,9 +37,16 @@ export declare class VerificationService {
|
|
|
29
37
|
attempts: number;
|
|
30
38
|
} | null>;
|
|
31
39
|
get verificationMode(): 'code' | 'token';
|
|
40
|
+
get codeExpiresInMinutes(): number;
|
|
41
|
+
get tokenExpiresInMinutes(): number;
|
|
42
|
+
get credentialExpiresInMinutes(): number;
|
|
43
|
+
issueCredential(identifier: string, type: 'email' | 'password-reset', realm?: string): Promise<IssuedVerificationCredential>;
|
|
44
|
+
verifyCredential(identifier: string, type: 'email' | 'password-reset', submitted: string, realm?: string): Promise<boolean>;
|
|
32
45
|
generateToken(identifier: string, type: 'email' | 'password-reset', realm?: string): Promise<string>;
|
|
33
46
|
verifyToken(identifier: string, type: 'email' | 'password-reset', token: string, realm?: string): Promise<boolean>;
|
|
34
47
|
buildVerificationUrl(token: string, type: 'email' | 'password-reset', email: string): string;
|
|
48
|
+
private verificationPath;
|
|
49
|
+
private buildPageUrl;
|
|
35
50
|
private hashToken;
|
|
36
51
|
private resolveUser;
|
|
37
52
|
private mapToRepositoryType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification.service.d.ts","sourceRoot":"","sources":["../../src/services/verification.service.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAiB,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,iDAAiD,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"verification.service.d.ts","sourceRoot":"","sources":["../../src/services/verification.service.ts"],"names":[],"mappings":"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"}
|