@ambushsoftworks/nestjs-auth-graphql 0.17.1 → 0.18.0

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 (68) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +173 -0
  3. package/dist/auth.module.d.ts +10 -0
  4. package/dist/auth.module.d.ts.map +1 -1
  5. package/dist/auth.module.js +41 -3
  6. package/dist/auth.module.js.map +1 -1
  7. package/dist/constants.d.ts +1 -0
  8. package/dist/constants.d.ts.map +1 -1
  9. package/dist/constants.js +2 -1
  10. package/dist/constants.js.map +1 -1
  11. package/dist/exceptions/email-challenge.exceptions.d.ts +8 -0
  12. package/dist/exceptions/email-challenge.exceptions.d.ts.map +1 -0
  13. package/dist/exceptions/email-challenge.exceptions.js +21 -0
  14. package/dist/exceptions/email-challenge.exceptions.js.map +1 -0
  15. package/dist/index.d.ts +4 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +4 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/interfaces/auth-logger.interface.d.ts +5 -1
  20. package/dist/interfaces/auth-logger.interface.d.ts.map +1 -1
  21. package/dist/interfaces/auth-logger.interface.js +4 -0
  22. package/dist/interfaces/auth-logger.interface.js.map +1 -1
  23. package/dist/interfaces/email-challenge-repository.interface.d.ts +22 -0
  24. package/dist/interfaces/email-challenge-repository.interface.d.ts.map +1 -0
  25. package/dist/interfaces/email-challenge-repository.interface.js +3 -0
  26. package/dist/interfaces/email-challenge-repository.interface.js.map +1 -0
  27. package/dist/interfaces/email-service.interface.d.ts +5 -0
  28. package/dist/interfaces/email-service.interface.d.ts.map +1 -1
  29. package/dist/interfaces/email-template-renderer.interface.d.ts +7 -0
  30. package/dist/interfaces/email-template-renderer.interface.d.ts.map +1 -1
  31. package/dist/interfaces/index.d.ts +1 -0
  32. package/dist/interfaces/index.d.ts.map +1 -1
  33. package/dist/interfaces/index.js +1 -0
  34. package/dist/interfaces/index.js.map +1 -1
  35. package/dist/repositories/in-memory-email-challenge.repository.d.ts +14 -0
  36. package/dist/repositories/in-memory-email-challenge.repository.d.ts.map +1 -0
  37. package/dist/repositories/in-memory-email-challenge.repository.js +55 -0
  38. package/dist/repositories/in-memory-email-challenge.repository.js.map +1 -0
  39. package/dist/services/configurable-email.service.d.ts +2 -1
  40. package/dist/services/configurable-email.service.d.ts.map +1 -1
  41. package/dist/services/configurable-email.service.js +24 -0
  42. package/dist/services/configurable-email.service.js.map +1 -1
  43. package/dist/services/default-email-template-renderer.d.ts +7 -0
  44. package/dist/services/default-email-template-renderer.d.ts.map +1 -1
  45. package/dist/services/default-email-template-renderer.js +31 -0
  46. package/dist/services/default-email-template-renderer.js.map +1 -1
  47. package/dist/services/email-challenge.service.d.ts +74 -0
  48. package/dist/services/email-challenge.service.d.ts.map +1 -0
  49. package/dist/services/email-challenge.service.js +306 -0
  50. package/dist/services/email-challenge.service.js.map +1 -0
  51. package/dist/services/passkey.service.d.ts.map +1 -1
  52. package/dist/services/passkey.service.js +8 -20
  53. package/dist/services/passkey.service.js.map +1 -1
  54. package/dist/testing/email-challenge-repository.contract.d.ts +15 -0
  55. package/dist/testing/email-challenge-repository.contract.d.ts.map +1 -0
  56. package/dist/testing/email-challenge-repository.contract.js +287 -0
  57. package/dist/testing/email-challenge-repository.contract.js.map +1 -0
  58. package/dist/testing/index.d.ts +1 -0
  59. package/dist/testing/index.d.ts.map +1 -1
  60. package/dist/testing/index.js +4 -1
  61. package/dist/testing/index.js.map +1 -1
  62. package/dist/utils/rate-limit-helpers.d.ts +4 -0
  63. package/dist/utils/rate-limit-helpers.d.ts.map +1 -0
  64. package/dist/utils/rate-limit-helpers.js +20 -0
  65. package/dist/utils/rate-limit-helpers.js.map +1 -0
  66. package/examples/email-challenge/prisma-email-challenge.repository.ts +85 -0
  67. package/examples/email-challenge/schema.prisma +24 -0
  68. package/package.json +1 -1
@@ -0,0 +1,74 @@
1
+ import type { AuthModuleOptions } from '../auth.module';
2
+ import { IAuthLogger } from '../interfaces/auth-logger.interface';
3
+ import { IEmailChallengeRepository } from '../interfaces/email-challenge-repository.interface';
4
+ import { IEmailService } from '../interfaces/email-service.interface';
5
+ import { IRateLimiter } from '../interfaces/rate-limiter.interface';
6
+ export declare const DEFAULT_EMAIL_CHALLENGE_ISSUE_LIMITS: {
7
+ readonly cooldownSeconds: 60;
8
+ readonly perHour: 5;
9
+ readonly perIpPerHour: 30;
10
+ };
11
+ export type EmailChallengeFailureReason = 'WRONG' | 'EXPIRED' | 'LOCKED';
12
+ export type EmailChallengeResult = {
13
+ ok: true;
14
+ email: string;
15
+ purpose: string;
16
+ } | {
17
+ ok: false;
18
+ reason: EmailChallengeFailureReason;
19
+ };
20
+ export interface IssuedEmailChallenge {
21
+ challengeId: string;
22
+ expiresAt: Date;
23
+ expiresInMinutes: number;
24
+ }
25
+ interface CallOptions {
26
+ realm?: string | null;
27
+ ipAddress?: string;
28
+ }
29
+ export declare class EmailChallengeService {
30
+ private readonly repository;
31
+ private readonly options;
32
+ private readonly securityLogger;
33
+ private readonly rateLimiter;
34
+ private readonly emailService;
35
+ private readonly logger;
36
+ private readonly key;
37
+ private readonly realmsEnabled;
38
+ private readonly ipHashSalt;
39
+ private lastSweepAt;
40
+ private warnedMissingIp;
41
+ constructor(repository: IEmailChallengeRepository | null, options: AuthModuleOptions, securityLogger: IAuthLogger, rateLimiter: IRateLimiter, emailService?: IEmailService | null);
42
+ get available(): boolean;
43
+ issue(input: {
44
+ email: string;
45
+ purpose: string;
46
+ emailData?: Record<string, unknown>;
47
+ }, opts?: CallOptions & {
48
+ ttlMinutes?: number;
49
+ }): Promise<IssuedEmailChallenge>;
50
+ verify(input: {
51
+ challengeId: string;
52
+ code: string;
53
+ email: string;
54
+ purpose: string;
55
+ }, opts?: CallOptions): Promise<EmailChallengeResult>;
56
+ revoke(input: {
57
+ purpose: string;
58
+ email?: string;
59
+ }, opts?: CallOptions): Promise<number>;
60
+ private requireRepository;
61
+ private requireIssuing;
62
+ private realmOf;
63
+ private mac;
64
+ private hashEmail;
65
+ private hashPurpose;
66
+ private hashCode;
67
+ private issueLimits;
68
+ private assertWithinLimits;
69
+ private record;
70
+ private cancelUnsent;
71
+ private sweep;
72
+ }
73
+ export {};
74
+ //# sourceMappingURL=email-challenge.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-challenge.service.d.ts","sourceRoot":"","sources":["../../src/services/email-challenge.service.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAiB,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAEL,yBAAyB,EAC1B,MAAM,oDAAoD,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAsBpE,eAAO,MAAM,oCAAoC;;;;CAIvC,CAAC;AAWX,MAAM,MAAM,2BAA2B,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAC5B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,2BAA2B,CAAA;CAAE,CAAC;AAEvD,MAAM,WAAW,oBAAoB;IAEnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,WAAW;IAEnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAmCD,qBACa,qBAAqB;IAU9B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAE3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAjB/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,eAAe,CAAS;gBAIb,UAAU,EAAE,yBAAyB,GAAG,IAAI,EAE5C,OAAO,EAAE,iBAAiB,EAE1B,cAAc,EAAE,WAAW,EAE3B,WAAW,EAAE,YAAY,EAEzB,YAAY,GAAE,aAAa,GAAG,IAAW;IAqB5D,IAAI,SAAS,IAAI,OAAO,CAEvB;IAqBK,KAAK,CACT,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,EAC9E,IAAI,GAAE,WAAW,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO,GAC/C,OAAO,CAAC,oBAAoB,CAAC;IA+E1B,MAAM,CACV,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAC5E,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,oBAAoB,CAAC;IAqE1B,MAAM,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;IAcjG,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,OAAO;IAaf,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,WAAW;YAsCL,kBAAkB;YAYlB,MAAM;YAON,YAAY;YAaZ,KAAK;CAgBpB"}
@@ -0,0 +1,306 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var EmailChallengeService_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.EmailChallengeService = exports.DEFAULT_EMAIL_CHALLENGE_ISSUE_LIMITS = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const crypto_1 = require("crypto");
19
+ const constants_1 = require("../constants");
20
+ const auth_logger_interface_1 = require("../interfaces/auth-logger.interface");
21
+ const email_challenge_exceptions_1 = require("../exceptions/email-challenge.exceptions");
22
+ const step_up_exceptions_1 = require("../exceptions/step-up.exceptions");
23
+ const ip_hash_1 = require("../utils/ip-hash");
24
+ const rate_limit_helpers_1 = require("../utils/rate-limit-helpers");
25
+ const CODE_ATTEMPTS = 3;
26
+ const DEFAULT_TTL_MINUTES = 15;
27
+ const MAX_TTL_MINUTES = 60;
28
+ const MAX_PURPOSE_LENGTH = 200;
29
+ const MAX_CHALLENGE_ID_LENGTH = 128;
30
+ const CHALLENGE_ID_BYTES = 32;
31
+ const HOUR_MS = 3_600_000;
32
+ const SWEEP_THROTTLE_MS = 2 * 60_000;
33
+ const HKDF_INFO = 'nestjs-auth-graphql email-challenge/v1';
34
+ exports.DEFAULT_EMAIL_CHALLENGE_ISSUE_LIMITS = {
35
+ cooldownSeconds: 60,
36
+ perHour: 5,
37
+ perIpPerHour: 30,
38
+ };
39
+ let EmailChallengeService = EmailChallengeService_1 = class EmailChallengeService {
40
+ constructor(repository, options, securityLogger, rateLimiter, emailService = null) {
41
+ this.repository = repository;
42
+ this.options = options;
43
+ this.securityLogger = securityLogger;
44
+ this.rateLimiter = rateLimiter;
45
+ this.emailService = emailService;
46
+ this.logger = new common_1.Logger(EmailChallengeService_1.name);
47
+ this.lastSweepAt = 0;
48
+ this.warnedMissingIp = false;
49
+ this.key = Buffer.from((0, crypto_1.hkdfSync)('sha256', options.verificationCodeSecret || options.jwtSecret, Buffer.alloc(0), HKDF_INFO, 32));
50
+ this.realmsEnabled = Boolean(options.realmExtractorInstance);
51
+ this.ipHashSalt = process.env.AUTH_IP_HASH_SALT || options.jwtSecret || '';
52
+ }
53
+ get available() {
54
+ return this.repository !== null && typeof this.emailService?.sendEmailChallengeCode === 'function';
55
+ }
56
+ async issue(input, opts = {}) {
57
+ const { repository, send } = this.requireIssuing();
58
+ const realm = this.realmOf(opts);
59
+ const email = (0, rate_limit_helpers_1.normaliseEmail)(input.email);
60
+ const purpose = requirePurpose(input.purpose);
61
+ const emailData = requireEmailData(input.emailData);
62
+ const ttlMinutes = requireTtl(opts.ttlMinutes ?? this.options.emailChallenge?.ttlMinutes);
63
+ const emailHash = this.hashEmail(email, realm);
64
+ const purposeHash = this.hashPurpose(purpose, realm);
65
+ const { cooldown, hourly, perIp } = this.issueLimits(emailHash, purposeHash, realm, opts.ipAddress);
66
+ await this.assertWithinLimits([cooldown, hourly, perIp]);
67
+ await this.record([cooldown, perIp]);
68
+ const id = (0, crypto_1.randomBytes)(CHALLENGE_ID_BYTES).toString('base64url');
69
+ const code = String((0, crypto_1.randomInt)(0, 1_000_000)).padStart(6, '0');
70
+ const now = Date.now();
71
+ const expiresAt = new Date(now + ttlMinutes * 60_000);
72
+ await repository.invalidateChallenges({ purposeHash, emailHash });
73
+ await repository.createChallenge({
74
+ id,
75
+ emailHash,
76
+ purposeHash,
77
+ codeHash: this.hashCode(id, code),
78
+ attempts: 0,
79
+ consumedAt: null,
80
+ expiresAt,
81
+ createdAt: new Date(now),
82
+ });
83
+ try {
84
+ await send(email, code, ttlMinutes, {
85
+ purpose,
86
+ ...(emailData !== undefined ? { data: emailData } : {}),
87
+ });
88
+ }
89
+ catch (error) {
90
+ await this.cancelUnsent(repository, id);
91
+ this.securityLogger.error('Email challenge code could not be sent', error instanceof Error ? error.stack : String(error), 'EmailChallengeService');
92
+ throw new email_challenge_exceptions_1.EmailChallengeSendFailedException();
93
+ }
94
+ await this.record([hourly]);
95
+ this.securityLogger.log(auth_logger_interface_1.SecurityEvent.EMAIL_CHALLENGE_ISSUED, {
96
+ email,
97
+ purpose,
98
+ realm,
99
+ ipAddress: opts.ipAddress,
100
+ challenge: challengeRef(id),
101
+ expiresAt,
102
+ });
103
+ void this.sweep(repository);
104
+ return { challengeId: id, expiresAt, expiresInMinutes: ttlMinutes };
105
+ }
106
+ async verify(input, opts = {}) {
107
+ const repository = this.requireRepository();
108
+ const realm = this.realmOf(opts);
109
+ const email = (0, rate_limit_helpers_1.normaliseEmail)(input.email);
110
+ const purpose = requirePurpose(input.purpose);
111
+ const id = input.challengeId;
112
+ const refuse = (reason, cause) => {
113
+ this.securityLogger.log(reason === 'LOCKED' ? auth_logger_interface_1.SecurityEvent.EMAIL_CHALLENGE_LOCKED : auth_logger_interface_1.SecurityEvent.EMAIL_CHALLENGE_FAILED, {
114
+ email,
115
+ purpose,
116
+ realm,
117
+ ipAddress: opts.ipAddress,
118
+ ...(typeof id === 'string' ? { challenge: challengeRef(id) } : {}),
119
+ reason: cause,
120
+ });
121
+ return { ok: false, reason };
122
+ };
123
+ if (typeof id !== 'string' || id === '' || id.length > MAX_CHALLENGE_ID_LENGTH) {
124
+ return refuse('EXPIRED', 'challenge_malformed');
125
+ }
126
+ const challenge = await repository.findChallenge(id);
127
+ if (!challenge)
128
+ return refuse('EXPIRED', 'challenge_unknown');
129
+ if (!sameHash(challenge.emailHash, this.hashEmail(email, realm))) {
130
+ return refuse('EXPIRED', 'email_mismatch');
131
+ }
132
+ if (!sameHash(challenge.purposeHash, this.hashPurpose(purpose, realm))) {
133
+ return refuse('EXPIRED', 'purpose_mismatch');
134
+ }
135
+ if (challenge.expiresAt.getTime() <= Date.now())
136
+ return refuse('EXPIRED', 'challenge_expired');
137
+ if (!(await repository.registerAttempt(id, CODE_ATTEMPTS))) {
138
+ const latest = await repository.findChallenge(id);
139
+ return latest && latest.consumedAt === null
140
+ ? refuse('LOCKED', 'attempts_exhausted')
141
+ : refuse('EXPIRED', 'challenge_consumed');
142
+ }
143
+ if (typeof input.code !== 'string' || !sameHash(challenge.codeHash, this.hashCode(id, input.code))) {
144
+ return refuse('WRONG', 'code_wrong');
145
+ }
146
+ if (!(await repository.consumeChallenge(id)))
147
+ return refuse('EXPIRED', 'challenge_consumed');
148
+ this.securityLogger.log(auth_logger_interface_1.SecurityEvent.EMAIL_CHALLENGE_VERIFIED, {
149
+ email,
150
+ purpose,
151
+ realm,
152
+ ipAddress: opts.ipAddress,
153
+ challenge: challengeRef(id),
154
+ });
155
+ return { ok: true, email, purpose };
156
+ }
157
+ async revoke(input, opts = {}) {
158
+ const repository = this.requireRepository();
159
+ const realm = this.realmOf(opts);
160
+ const purpose = requirePurpose(input.purpose);
161
+ return repository.invalidateChallenges({
162
+ purposeHash: this.hashPurpose(purpose, realm),
163
+ ...(input.email !== undefined ? { emailHash: this.hashEmail((0, rate_limit_helpers_1.normaliseEmail)(input.email), realm) } : {}),
164
+ });
165
+ }
166
+ requireRepository() {
167
+ if (!this.repository)
168
+ throw new email_challenge_exceptions_1.EmailChallengeUnavailableException();
169
+ return this.repository;
170
+ }
171
+ requireIssuing() {
172
+ const service = this.emailService;
173
+ const send = service?.sendEmailChallengeCode;
174
+ if (!this.repository || !service || typeof send !== 'function') {
175
+ throw new email_challenge_exceptions_1.EmailChallengeUnavailableException();
176
+ }
177
+ return { repository: this.repository, send: send.bind(service) };
178
+ }
179
+ realmOf(opts) {
180
+ const realm = opts.realm ?? undefined;
181
+ if (this.realmsEnabled && realm === undefined) {
182
+ throw new common_1.BadRequestException('Realm required');
183
+ }
184
+ return realm;
185
+ }
186
+ mac(...parts) {
187
+ return (0, crypto_1.createHmac)('sha256', this.key).update(JSON.stringify(parts)).digest('hex');
188
+ }
189
+ hashEmail(email, realm) {
190
+ return this.mac('email', realm ?? null, email);
191
+ }
192
+ hashPurpose(purpose, realm) {
193
+ return this.mac('purpose', realm ?? null, purpose);
194
+ }
195
+ hashCode(challengeId, code) {
196
+ return this.mac('code', challengeId, code);
197
+ }
198
+ issueLimits(emailHash, purposeHash, realm, ipAddress) {
199
+ const configured = this.options.emailChallenge?.issueLimits;
200
+ const cooldownSeconds = configured?.cooldownSeconds ?? exports.DEFAULT_EMAIL_CHALLENGE_ISSUE_LIMITS.cooldownSeconds;
201
+ const perHour = configured?.perHour ?? exports.DEFAULT_EMAIL_CHALLENGE_ISSUE_LIMITS.perHour;
202
+ const perIpPerHour = configured?.perIpPerHour ?? exports.DEFAULT_EMAIL_CHALLENGE_ISSUE_LIMITS.perIpPerHour;
203
+ const subject = `${emailHash.slice(0, 32)}:${purposeHash.slice(0, 32)}`;
204
+ if (perIpPerHour > 0 && !ipAddress && !this.warnedMissingIp) {
205
+ this.warnedMissingIp = true;
206
+ this.logger.warn('EmailChallengeService.issue was called without opts.ipAddress, so the per-IP limit on ' +
207
+ 'sending codes is not applied. Pass the client IP.');
208
+ }
209
+ return {
210
+ ...(cooldownSeconds > 0
211
+ ? { cooldown: { key: `auth:emailChallenge:cooldown:${subject}`, max: 1, windowMs: cooldownSeconds * 1000 } }
212
+ : {}),
213
+ hourly: { key: `auth:emailChallenge:hour:${subject}`, max: perHour, windowMs: HOUR_MS },
214
+ ...(perIpPerHour > 0 && ipAddress
215
+ ? {
216
+ perIp: {
217
+ key: `auth:emailChallenge:ip:${(0, rate_limit_helpers_1.realmKeyPrefix)(realm)}${(0, ip_hash_1.hashIp)(ipAddress, this.ipHashSalt)}`,
218
+ max: perIpPerHour,
219
+ windowMs: HOUR_MS,
220
+ },
221
+ }
222
+ : {}),
223
+ };
224
+ }
225
+ async assertWithinLimits(limits) {
226
+ let retryAfter = 0;
227
+ for (const limit of limits) {
228
+ if (!limit)
229
+ continue;
230
+ const { allowed, resetAt } = await this.rateLimiter.checkRateLimit(limit.key, limit.max, limit.windowMs);
231
+ if (!allowed)
232
+ retryAfter = Math.max(retryAfter, (0, rate_limit_helpers_1.retryAfterSeconds)(resetAt));
233
+ }
234
+ if (retryAfter > 0) {
235
+ throw new step_up_exceptions_1.AuthRateLimitException('Too many code requests. Please try again later.', retryAfter);
236
+ }
237
+ }
238
+ async record(limits) {
239
+ for (const limit of limits) {
240
+ if (limit)
241
+ await this.rateLimiter.recordAttempt(limit.key, limit.windowMs);
242
+ }
243
+ }
244
+ async cancelUnsent(repository, id) {
245
+ try {
246
+ await repository.consumeChallenge(id);
247
+ }
248
+ catch (error) {
249
+ this.securityLogger.error('Email challenge could not be cancelled after its email failed to send; it expires on its own', error instanceof Error ? error.stack : String(error), 'EmailChallengeService');
250
+ }
251
+ }
252
+ async sweep(repository) {
253
+ const now = Date.now();
254
+ if (now - this.lastSweepAt < SWEEP_THROTTLE_MS) {
255
+ return;
256
+ }
257
+ this.lastSweepAt = now;
258
+ try {
259
+ await repository.deleteExpiredChallenges();
260
+ }
261
+ catch (error) {
262
+ this.logger.warn(`Sweeping expired email challenges failed: ${error instanceof Error ? error.message : String(error)}. Challenges still expire: verify checks expiry.`);
263
+ }
264
+ }
265
+ };
266
+ exports.EmailChallengeService = EmailChallengeService;
267
+ exports.EmailChallengeService = EmailChallengeService = EmailChallengeService_1 = __decorate([
268
+ (0, common_1.Injectable)(),
269
+ __param(0, (0, common_1.Inject)(constants_1.EMAIL_CHALLENGE_REPOSITORY)),
270
+ __param(1, (0, common_1.Inject)(constants_1.AUTH_MODULE_OPTIONS)),
271
+ __param(2, (0, common_1.Inject)(constants_1.AUTH_LOGGER)),
272
+ __param(3, (0, common_1.Inject)(constants_1.RATE_LIMITER)),
273
+ __param(4, (0, common_1.Inject)(constants_1.EMAIL_SERVICE)),
274
+ __metadata("design:paramtypes", [Object, Object, Object, Object, Object])
275
+ ], EmailChallengeService);
276
+ function challengeRef(id) {
277
+ return (0, crypto_1.createHash)('sha256').update(id).digest('hex').slice(0, 16);
278
+ }
279
+ function sameHash(a, b) {
280
+ const left = Buffer.from(String(a), 'utf8');
281
+ const right = Buffer.from(b, 'utf8');
282
+ return left.length === right.length && (0, crypto_1.timingSafeEqual)(left, right);
283
+ }
284
+ function requirePurpose(purpose) {
285
+ if (typeof purpose !== 'string' || purpose.length === 0 || purpose.length > MAX_PURPOSE_LENGTH) {
286
+ throw new common_1.BadRequestException(`An email challenge needs a purpose: a non-empty string of at most ${MAX_PURPOSE_LENGTH} characters`);
287
+ }
288
+ return purpose;
289
+ }
290
+ function requireTtl(ttlMinutes) {
291
+ if (ttlMinutes === undefined)
292
+ return DEFAULT_TTL_MINUTES;
293
+ if (typeof ttlMinutes !== 'number' || !Number.isInteger(ttlMinutes) || ttlMinutes < 1 || ttlMinutes > MAX_TTL_MINUTES) {
294
+ throw new common_1.BadRequestException(`ttlMinutes must be an integer from 1 to ${MAX_TTL_MINUTES}`);
295
+ }
296
+ return ttlMinutes;
297
+ }
298
+ function requireEmailData(data) {
299
+ if (data === undefined)
300
+ return undefined;
301
+ if (typeof data !== 'object' || data === null || Array.isArray(data)) {
302
+ throw new common_1.BadRequestException('emailData must be an object');
303
+ }
304
+ return data;
305
+ }
306
+ //# sourceMappingURL=email-challenge.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-challenge.service.js","sourceRoot":"","sources":["../../src/services/email-challenge.service.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"passkey.service.d.ts","sourceRoot":"","sources":["../../src/services/passkey.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"passkey.service.d.ts","sourceRoot":"","sources":["../../src/services/passkey.service.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,7 @@ const webauthn_adapter_1 = require("../passkey/webauthn-adapter");
24
24
  const passkey_exceptions_1 = require("../exceptions/passkey.exceptions");
25
25
  const step_up_exceptions_1 = require("../exceptions/step-up.exceptions");
26
26
  const ip_hash_1 = require("../utils/ip-hash");
27
+ const rate_limit_helpers_1 = require("../utils/rate-limit-helpers");
27
28
  const provider_helpers_1 = require("../utils/provider-helpers");
28
29
  const passkey_rp_1 = require("../utils/passkey-rp");
29
30
  const auth_service_1 = require("./auth.service");
@@ -67,7 +68,7 @@ let PasskeyService = PasskeyService_1 = class PasskeyService {
67
68
  throw new step_up_exceptions_1.StepUpRequiredException();
68
69
  }
69
70
  const user = await this.authService.requireActiveUser(userId);
70
- await this.enforceRateLimit(`auth:passkeyReg:${scope(opts.realm)}${userId}`);
71
+ await this.enforceRateLimit(`auth:passkeyReg:${(0, rate_limit_helpers_1.realmKeyPrefix)(opts.realm)}${userId}`);
71
72
  const rp = this.relyingParty(opts.realm);
72
73
  const existing = await repository.listCredentials(userId, opts.realm);
73
74
  const userHandle = existing[0]?.userHandle ?? Buffer.from((0, crypto_1.randomBytes)(USER_HANDLE_BYTES)).toString('base64url');
@@ -174,7 +175,7 @@ let PasskeyService = PasskeyService_1 = class PasskeyService {
174
175
  const { webauthn } = this.require();
175
176
  this.requireRealm(opts.realm);
176
177
  if (opts.ipAddress) {
177
- await this.enforceRateLimit(`auth:passkeyAuth:${scope(opts.realm)}${(0, ip_hash_1.hashIp)(opts.ipAddress, this.ipHashSalt)}`);
178
+ await this.enforceRateLimit(`auth:passkeyAuth:${(0, rate_limit_helpers_1.realmKeyPrefix)(opts.realm)}${(0, ip_hash_1.hashIp)(opts.ipAddress, this.ipHashSalt)}`);
178
179
  }
179
180
  else if (!this.warnedMissingIp) {
180
181
  this.warnedMissingIp = true;
@@ -239,7 +240,7 @@ let PasskeyService = PasskeyService_1 = class PasskeyService {
239
240
  if (active.length === 0) {
240
241
  throw new step_up_exceptions_1.StepUpUnavailableException('passkey');
241
242
  }
242
- await this.enforceRateLimit(`auth:passkeyStepUp:${scope(opts.realm)}${userId}`);
243
+ await this.enforceRateLimit(`auth:passkeyStepUp:${(0, rate_limit_helpers_1.realmKeyPrefix)(opts.realm)}${userId}`);
243
244
  const timeoutSeconds = this.authenticationTimeoutSeconds;
244
245
  const options = await webauthn.authenticationOptions({
245
246
  rp: this.relyingParty(opts.realm),
@@ -289,8 +290,8 @@ let PasskeyService = PasskeyService_1 = class PasskeyService {
289
290
  async startSignup(input, opts = {}) {
290
291
  const { users, tokens, email: mailer } = this.requireSignup();
291
292
  this.requireRealm(opts.realm);
292
- const email = normaliseEmail(input.email);
293
- const where = scope(opts.realm);
293
+ const email = (0, rate_limit_helpers_1.normaliseEmail)(input.email);
294
+ const where = (0, rate_limit_helpers_1.realmKeyPrefix)(opts.realm);
294
295
  if (opts.ipAddress) {
295
296
  await this.enforceLimit(`auth:passkeySignupIp:${where}${(0, ip_hash_1.hashIp)(opts.ipAddress, this.ipHashSalt)}`, 5, 3_600_000);
296
297
  }
@@ -514,7 +515,7 @@ let PasskeyService = PasskeyService_1 = class PasskeyService {
514
515
  async enforceLimit(key, maxAttempts, windowMs) {
515
516
  const { allowed, resetAt } = await this.rateLimiter.checkRateLimit(key, maxAttempts, windowMs);
516
517
  if (!allowed) {
517
- throw new step_up_exceptions_1.AuthRateLimitException('Too many sign-up requests. Please try again later.', retryAfterSeconds(resetAt));
518
+ throw new step_up_exceptions_1.AuthRateLimitException('Too many sign-up requests. Please try again later.', (0, rate_limit_helpers_1.retryAfterSeconds)(resetAt));
518
519
  }
519
520
  await this.rateLimiter.recordAttempt(key, windowMs);
520
521
  }
@@ -654,7 +655,7 @@ let PasskeyService = PasskeyService_1 = class PasskeyService {
654
655
  const { maxAttempts, windowMs } = this.options.passkey?.rateLimit ?? DEFAULT_RATE_LIMIT;
655
656
  const { allowed, resetAt } = await this.rateLimiter.checkRateLimit(key, maxAttempts, windowMs);
656
657
  if (!allowed) {
657
- throw new step_up_exceptions_1.AuthRateLimitException('Too many passkey requests. Please try again later.', retryAfterSeconds(resetAt));
658
+ throw new step_up_exceptions_1.AuthRateLimitException('Too many passkey requests. Please try again later.', (0, rate_limit_helpers_1.retryAfterSeconds)(resetAt));
658
659
  }
659
660
  await this.rateLimiter.recordAttempt(key, windowMs);
660
661
  }
@@ -736,22 +737,9 @@ exports.PasskeyService = PasskeyService = PasskeyService_1 = __decorate([
736
737
  __metadata("design:paramtypes", [Object, Object, Object, Object, Object, Object, auth_service_1.AuthService,
737
738
  step_up_token_service_1.StepUpTokenService, Object, Object, passkey_signup_token_service_1.PasskeySignupTokenService])
738
739
  ], PasskeyService);
739
- function retryAfterSeconds(resetAt) {
740
- return Math.max(1, Math.ceil((resetAt.getTime() - Date.now()) / 1000));
741
- }
742
- function scope(realm) {
743
- return realm ? `${realm}:` : '';
744
- }
745
740
  function freshBytes(length) {
746
741
  return new Uint8Array((0, crypto_1.randomBytes)(length));
747
742
  }
748
- function normaliseEmail(email) {
749
- const normalised = typeof email === 'string' ? email.trim().toLowerCase() : '';
750
- if (!/^[^\s@]+@[^\s@]+$/.test(normalised)) {
751
- throw new common_1.BadRequestException('A valid email address is required');
752
- }
753
- return normalised;
754
- }
755
743
  function signupBinding(pending) {
756
744
  return `signup:${pending.id}`;
757
745
  }