@ambushsoftworks/nestjs-auth-graphql 0.12.0 → 0.15.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 (62) hide show
  1. package/CHANGELOG.md +210 -0
  2. package/README.md +285 -1
  3. package/dist/auth.module.d.ts +9 -0
  4. package/dist/auth.module.d.ts.map +1 -1
  5. package/dist/auth.module.js +69 -4
  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/index.d.ts +3 -6
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +3 -6
  14. package/dist/index.js.map +1 -1
  15. package/dist/interfaces/biometric-repository.interface.d.ts +30 -17
  16. package/dist/interfaces/biometric-repository.interface.d.ts.map +1 -1
  17. package/dist/interfaces/biometric-verifier.interface.d.ts +10 -0
  18. package/dist/interfaces/biometric-verifier.interface.d.ts.map +1 -0
  19. package/dist/interfaces/{magic-link-repository.interface.js → biometric-verifier.interface.js} +1 -1
  20. package/dist/interfaces/biometric-verifier.interface.js.map +1 -0
  21. package/dist/services/biometric-auth.service.d.ts +51 -17
  22. package/dist/services/biometric-auth.service.d.ts.map +1 -1
  23. package/dist/services/biometric-auth.service.js +121 -67
  24. package/dist/services/biometric-auth.service.js.map +1 -1
  25. package/dist/services/biometric-challenge.service.d.ts +27 -0
  26. package/dist/services/biometric-challenge.service.d.ts.map +1 -0
  27. package/dist/services/biometric-challenge.service.js +116 -0
  28. package/dist/services/biometric-challenge.service.js.map +1 -0
  29. package/dist/services/biometric-verification.service.d.ts.map +1 -1
  30. package/dist/services/biometric-verification.service.js +4 -0
  31. package/dist/services/biometric-verification.service.js.map +1 -1
  32. package/dist/test-utils/mock-repositories.d.ts.map +1 -1
  33. package/dist/test-utils/mock-repositories.js +8 -7
  34. package/dist/test-utils/mock-repositories.js.map +1 -1
  35. package/dist/verifiers/es256-device-key.verifier.d.ts +14 -0
  36. package/dist/verifiers/es256-device-key.verifier.d.ts.map +1 -0
  37. package/dist/verifiers/es256-device-key.verifier.js +42 -0
  38. package/dist/verifiers/es256-device-key.verifier.js.map +1 -0
  39. package/package.json +8 -2
  40. package/dist/interfaces/magic-link-repository.interface.d.ts +0 -6
  41. package/dist/interfaces/magic-link-repository.interface.d.ts.map +0 -1
  42. package/dist/interfaces/magic-link-repository.interface.js.map +0 -1
  43. package/dist/interfaces/password-reset-strategy.interface.d.ts +0 -7
  44. package/dist/interfaces/password-reset-strategy.interface.d.ts.map +0 -1
  45. package/dist/interfaces/password-reset-strategy.interface.js +0 -3
  46. package/dist/interfaces/password-reset-strategy.interface.js.map +0 -1
  47. package/dist/repositories/noop-biometric.repository.d.ts +0 -26
  48. package/dist/repositories/noop-biometric.repository.d.ts.map +0 -1
  49. package/dist/repositories/noop-biometric.repository.js +0 -56
  50. package/dist/repositories/noop-biometric.repository.js.map +0 -1
  51. package/dist/repositories/noop-magic-link.repository.d.ts +0 -9
  52. package/dist/repositories/noop-magic-link.repository.d.ts.map +0 -1
  53. package/dist/repositories/noop-magic-link.repository.js +0 -37
  54. package/dist/repositories/noop-magic-link.repository.js.map +0 -1
  55. package/dist/strategies/magic-link.strategy.d.ts +0 -16
  56. package/dist/strategies/magic-link.strategy.d.ts.map +0 -1
  57. package/dist/strategies/magic-link.strategy.js +0 -80
  58. package/dist/strategies/magic-link.strategy.js.map +0 -1
  59. package/dist/strategies/verification-code.strategy.d.ts +0 -11
  60. package/dist/strategies/verification-code.strategy.d.ts.map +0 -1
  61. package/dist/strategies/verification-code.strategy.js +0 -44
  62. package/dist/strategies/verification-code.strategy.js.map +0 -1
@@ -11,102 +11,156 @@ var __metadata = (this && this.__metadata) || function (k, v) {
11
11
  var __param = (this && this.__param) || function (paramIndex, decorator) {
12
12
  return function (target, key) { decorator(target, key, paramIndex); }
13
13
  };
14
+ var BiometricAuthService_1;
14
15
  Object.defineProperty(exports, "__esModule", { value: true });
15
16
  exports.BiometricAuthService = void 0;
16
17
  const common_1 = require("@nestjs/common");
17
- const jwt_1 = require("@nestjs/jwt");
18
- const refresh_token_service_1 = require("./refresh-token.service");
18
+ const crypto_1 = require("crypto");
19
19
  const auth_logger_interface_1 = require("../interfaces/auth-logger.interface");
20
- let BiometricAuthService = class BiometricAuthService {
21
- constructor(userRepository, refreshTokenRepository, biometricRepository, securityLogger, jwtService, refreshTokenService) {
22
- this.userRepository = userRepository;
23
- this.refreshTokenRepository = refreshTokenRepository;
20
+ const constants_1 = require("../constants");
21
+ const biometric_challenge_service_1 = require("./biometric-challenge.service");
22
+ const auth_service_1 = require("./auth.service");
23
+ let BiometricAuthService = BiometricAuthService_1 = class BiometricAuthService {
24
+ constructor(biometricRepository, securityLogger, verifiers, challenges, authService, options) {
24
25
  this.biometricRepository = biometricRepository;
25
26
  this.securityLogger = securityLogger;
26
- this.jwtService = jwtService;
27
- this.refreshTokenService = refreshTokenService;
27
+ this.challenges = challenges;
28
+ this.authService = authService;
29
+ this.logger = new common_1.Logger(BiometricAuthService_1.name);
30
+ this.realmsEnabled = Boolean(options.realmExtractorInstance);
31
+ this.verifiersByAlgorithm = new Map(verifiers.map((v) => [v.algorithm, v]));
28
32
  }
29
- async enableBiometric(userId, deviceId, publicKey) {
30
- if (!deviceId || deviceId.trim().length === 0) {
31
- throw new common_1.BadRequestException('Device ID is required');
33
+ async enrolCredential(input) {
34
+ this.requireRealm(input.realm);
35
+ const algorithm = input.algorithm ?? this.defaultAlgorithm;
36
+ const verifier = this.verifiersByAlgorithm.get(algorithm);
37
+ if (!verifier) {
38
+ throw new common_1.UnauthorizedException(`No biometric verifier is configured for algorithm '${algorithm}'.`);
32
39
  }
33
- const user = await this.userRepository.findById(userId);
34
- if (!user) {
35
- throw new common_1.UnauthorizedException('User not found');
40
+ if (!(await verifier.validatePublicKey(input.publicKey))) {
41
+ throw new common_1.UnauthorizedException(`The public key is not a valid '${algorithm}' key.`);
36
42
  }
37
- await this.userRepository.enableBiometric(userId, deviceId, publicKey);
43
+ const record = {
44
+ credentialId: (0, crypto_1.randomUUID)(),
45
+ userId: input.userId,
46
+ publicKey: input.publicKey,
47
+ algorithm,
48
+ deviceName: input.deviceName,
49
+ ...(input.realm !== undefined ? { realm: input.realm } : {}),
50
+ createdAt: new Date(),
51
+ lastUsedAt: null,
52
+ isActive: true,
53
+ ...(input.metadata ? { metadata: input.metadata } : {}),
54
+ };
55
+ await this.biometricRepository.storeCredential(record);
38
56
  this.securityLogger.log(auth_logger_interface_1.SecurityEvent.BIOMETRIC_ENROLLED, {
39
- userId,
40
- deviceId,
57
+ userId: input.userId,
58
+ credentialId: record.credentialId,
59
+ algorithm,
41
60
  });
42
- return true;
61
+ return this.summarise(record);
43
62
  }
44
- async disableBiometric(userId) {
45
- const user = await this.userRepository.findById(userId);
46
- if (!user) {
47
- throw new common_1.UnauthorizedException('User not found');
48
- }
49
- await this.userRepository.disableBiometric(userId);
50
- this.securityLogger.log(auth_logger_interface_1.SecurityEvent.BIOMETRIC_DISABLED, {
51
- userId,
52
- });
53
- return true;
63
+ async requestChallenge(credentialId, opts = {}) {
64
+ return this.challenges.issueChallenge(credentialId, opts);
54
65
  }
55
- async authenticateWithBiometric(userId, deviceId) {
56
- if (!deviceId || deviceId.trim().length === 0) {
57
- throw new common_1.UnauthorizedException('Device ID is required');
66
+ async authenticateWithBiometric(input, opts = {}) {
67
+ this.requireRealm(opts.realm);
68
+ const fail = (reason, credentialId) => {
69
+ this.securityLogger.log(auth_logger_interface_1.SecurityEvent.BIOMETRIC_LOGIN_FAILURE, {
70
+ credentialId,
71
+ ipAddress: opts.ipAddress,
72
+ realm: opts.realm,
73
+ reason,
74
+ });
75
+ throw new common_1.UnauthorizedException('Biometric authentication failed');
76
+ };
77
+ const challenge = await this.challenges.consumeChallenge(input.challengeId);
78
+ if (!challenge) {
79
+ return fail('challenge_unavailable', input.credentialId);
80
+ }
81
+ if (challenge.credentialId !== input.credentialId) {
82
+ return fail('challenge_credential_mismatch', input.credentialId);
83
+ }
84
+ const credential = await this.biometricRepository.getCredential(input.credentialId);
85
+ if (!credential) {
86
+ return fail('credential_unknown', input.credentialId);
58
87
  }
59
- const user = await this.userRepository.findById(userId);
60
- if (!user) {
61
- throw new common_1.UnauthorizedException('Invalid biometric credentials');
88
+ if (!credential.isActive) {
89
+ return fail('credential_inactive', input.credentialId);
62
90
  }
63
- const credentials = await this.biometricRepository.listBiometricCredentials(userId);
64
- if (credentials.length === 0) {
65
- throw new common_1.UnauthorizedException('Biometric authentication not enabled');
91
+ if ((credential.realm ?? undefined) !== opts.realm) {
92
+ return fail('credential_realm_mismatch', input.credentialId);
66
93
  }
67
- const isValidDevice = credentials.some((cred) => cred.credentialId === deviceId);
68
- if (!isValidDevice) {
69
- throw new common_1.UnauthorizedException('Biometric authentication not enabled on this device');
94
+ const verifier = this.verifiersByAlgorithm.get(credential.algorithm);
95
+ if (!verifier) {
96
+ this.logger.error(`Credential ${input.credentialId} is enrolled under algorithm ` +
97
+ `'${credential.algorithm}', for which no verifier is configured. ` +
98
+ 'Add it to biometric.verifiers, or deactivate the credential.');
99
+ return fail('verifier_missing', input.credentialId);
70
100
  }
71
- const accessToken = this.jwtService.sign({
72
- userId: user.id,
73
- email: user.email,
101
+ const valid = await verifier.verify({
102
+ publicKey: credential.publicKey,
103
+ challenge: challenge.challenge,
104
+ signature: input.signature,
74
105
  });
75
- const { token: refreshToken, hash: refreshTokenHash } = this.refreshTokenService.generateToken();
76
- await this.refreshTokenRepository.create({
77
- userId: user.id,
78
- token: refreshToken,
79
- hashedToken: refreshTokenHash,
80
- expiresAt: this.refreshTokenService.getExpiryDate(),
106
+ if (!valid) {
107
+ return fail('signature_invalid', input.credentialId);
108
+ }
109
+ const session = await this.authService.issueAuthSession(credential.userId, opts.res, opts.realm);
110
+ void this.biometricRepository
111
+ .touchCredentialLastUsed(input.credentialId)
112
+ .catch((error) => {
113
+ this.logger.warn(`Recording last use of credential ${input.credentialId} failed: ${error instanceof Error ? error.message : String(error)}`);
81
114
  });
82
- await this.userRepository.updateLastBiometricLogin(userId);
83
115
  this.securityLogger.log(auth_logger_interface_1.SecurityEvent.BIOMETRIC_LOGIN_SUCCESS, {
116
+ userId: credential.userId,
117
+ credentialId: input.credentialId,
118
+ ipAddress: opts.ipAddress,
119
+ realm: opts.realm,
120
+ });
121
+ return session;
122
+ }
123
+ async listCredentials(userId, realm) {
124
+ const credentials = await this.biometricRepository.listCredentials(userId, realm);
125
+ return credentials.filter((c) => c.isActive).map((c) => this.summarise(c));
126
+ }
127
+ async removeCredential(userId, credentialId) {
128
+ const credential = await this.biometricRepository.getCredential(credentialId);
129
+ if (!credential || credential.userId !== userId) {
130
+ throw new common_1.UnauthorizedException('Biometric credential not found');
131
+ }
132
+ await this.biometricRepository.deactivateCredential(credentialId);
133
+ this.securityLogger.log(auth_logger_interface_1.SecurityEvent.BIOMETRIC_DEVICE_REMOVED, {
84
134
  userId,
135
+ credentialId,
85
136
  });
86
- return { accessToken, refreshToken };
87
137
  }
88
- async getBiometricStatus(userId) {
89
- const user = await this.userRepository.findById(userId);
90
- if (!user) {
91
- throw new common_1.UnauthorizedException('User not found');
138
+ requireRealm(realm) {
139
+ if (this.realmsEnabled && (realm === undefined || realm === null)) {
140
+ throw new common_1.BadRequestException('Realm required');
92
141
  }
93
- const credentials = await this.biometricRepository.listBiometricCredentials(userId);
94
- const enabled = credentials.length > 0;
95
- const deviceId = credentials.length > 0 ? credentials[0].credentialId : null;
142
+ }
143
+ get defaultAlgorithm() {
144
+ return this.verifiersByAlgorithm.keys().next().value;
145
+ }
146
+ summarise(record) {
96
147
  return {
97
- enabled,
98
- deviceId,
148
+ credentialId: record.credentialId,
149
+ deviceName: record.deviceName,
150
+ algorithm: record.algorithm,
151
+ createdAt: record.createdAt,
152
+ lastUsedAt: record.lastUsedAt,
99
153
  };
100
154
  }
101
155
  };
102
156
  exports.BiometricAuthService = BiometricAuthService;
103
- exports.BiometricAuthService = BiometricAuthService = __decorate([
157
+ exports.BiometricAuthService = BiometricAuthService = BiometricAuthService_1 = __decorate([
104
158
  (0, common_1.Injectable)(),
105
- __param(0, (0, common_1.Inject)('USER_REPOSITORY')),
106
- __param(1, (0, common_1.Inject)('REFRESH_TOKEN_REPOSITORY')),
107
- __param(2, (0, common_1.Inject)('BIOMETRIC_REPOSITORY')),
108
- __param(3, (0, common_1.Inject)('AUTH_LOGGER')),
109
- __metadata("design:paramtypes", [Object, Object, Object, Object, jwt_1.JwtService,
110
- refresh_token_service_1.RefreshTokenService])
159
+ __param(0, (0, common_1.Inject)(constants_1.BIOMETRIC_REPOSITORY)),
160
+ __param(1, (0, common_1.Inject)(constants_1.AUTH_LOGGER)),
161
+ __param(2, (0, common_1.Inject)(constants_1.BIOMETRIC_VERIFIERS)),
162
+ __param(5, (0, common_1.Inject)(constants_1.AUTH_MODULE_OPTIONS)),
163
+ __metadata("design:paramtypes", [Object, Object, Array, biometric_challenge_service_1.BiometricChallengeService,
164
+ auth_service_1.AuthService, Object])
111
165
  ], BiometricAuthService);
112
166
  //# sourceMappingURL=biometric-auth.service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"biometric-auth.service.js","sourceRoot":"","sources":["../../src/services/biometric-auth.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"biometric-auth.service.js","sourceRoot":"","sources":["../../src/services/biometric-auth.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { BiometricChallengeRecord, IBiometricChallengeStore } from '../interfaces/biometric-repository.interface';
2
+ import { IRateLimiter } from '../interfaces/rate-limiter.interface';
3
+ import { IAuthLogger } from '../interfaces/auth-logger.interface';
4
+ import type { AuthModuleOptions } from '../auth.module';
5
+ export declare class BiometricChallengeService {
6
+ private readonly store;
7
+ private readonly rateLimiter;
8
+ private readonly securityLogger;
9
+ private readonly options;
10
+ private lastSweepAt;
11
+ private readonly ipHashSalt;
12
+ constructor(store: IBiometricChallengeStore, rateLimiter: IRateLimiter, securityLogger: IAuthLogger, options: AuthModuleOptions);
13
+ private get expirySeconds();
14
+ private get rateLimit();
15
+ issueChallenge(credentialId: string, opts?: {
16
+ ipAddress?: string;
17
+ realm?: string;
18
+ }): Promise<{
19
+ challengeId: string;
20
+ challenge: string;
21
+ expiresAt: Date;
22
+ } | null>;
23
+ private withinLimit;
24
+ consumeChallenge(challengeId: string): Promise<BiometricChallengeRecord | null>;
25
+ private sweep;
26
+ }
27
+ //# sourceMappingURL=biometric-challenge.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"biometric-challenge.service.d.ts","sourceRoot":"","sources":["../../src/services/biometric-challenge.service.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAiB,MAAM,qCAAqC,CAAC;AAGjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAyBxD,qBACa,yBAAyB;IAgBlC,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,OAAO;IArB1B,OAAO,CAAC,WAAW,CAAK;IAWxB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAIjB,KAAK,EAAE,wBAAwB,EAE/B,WAAW,EAAE,YAAY,EAEzB,cAAc,EAAE,WAAW,EAE3B,OAAO,EAAE,iBAAiB;IAK7C,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,KAAK,SAAS,GAEpB;IAgCK,cAAc,CAClB,YAAY,EAAE,MAAM,EACpB,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAChD,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;YAoDhE,WAAW;IAsBnB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;YAqBvE,KAAK;CAkBpB"}
@@ -0,0 +1,116 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.BiometricChallengeService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const crypto_1 = require("crypto");
18
+ const auth_logger_interface_1 = require("../interfaces/auth-logger.interface");
19
+ const constants_1 = require("../constants");
20
+ const ip_hash_1 = require("../utils/ip-hash");
21
+ const CHALLENGE_BYTES = 32;
22
+ const DEFAULT_EXPIRY_SECONDS = 60;
23
+ const DEFAULT_RATE_LIMIT = { maxAttempts: 5, windowMs: 60_000 };
24
+ const SWEEP_THROTTLE_MS = 2 * 60_000;
25
+ let BiometricChallengeService = class BiometricChallengeService {
26
+ constructor(store, rateLimiter, securityLogger, options) {
27
+ this.store = store;
28
+ this.rateLimiter = rateLimiter;
29
+ this.securityLogger = securityLogger;
30
+ this.options = options;
31
+ this.lastSweepAt = 0;
32
+ this.ipHashSalt = process.env.AUTH_IP_HASH_SALT || this.options.jwtSecret || '';
33
+ }
34
+ get expirySeconds() {
35
+ return this.options.biometric?.challengeExpirySeconds ?? DEFAULT_EXPIRY_SECONDS;
36
+ }
37
+ get rateLimit() {
38
+ return this.options.biometric?.challengeRateLimit ?? DEFAULT_RATE_LIMIT;
39
+ }
40
+ async issueChallenge(credentialId, opts = {}) {
41
+ const { ipAddress, realm } = opts;
42
+ const { maxAttempts, windowMs } = this.rateLimit;
43
+ const scope = realm ? `${realm}:` : '';
44
+ const credentialKey = `auth:biometricChallenge:${scope}${credentialId}`;
45
+ if (!(await this.withinLimit(credentialKey, maxAttempts, windowMs))) {
46
+ this.securityLogger.log(auth_logger_interface_1.SecurityEvent.BIOMETRIC_LOGIN_FAILURE, {
47
+ credentialId,
48
+ realm,
49
+ reason: 'challenge_rate_limited',
50
+ });
51
+ return null;
52
+ }
53
+ if (ipAddress) {
54
+ const ipKey = `auth:biometricChallengeIp:${scope}${(0, ip_hash_1.hashIp)(ipAddress, this.ipHashSalt)}`;
55
+ if (!(await this.withinLimit(ipKey, maxAttempts * 10, windowMs))) {
56
+ this.securityLogger.log(auth_logger_interface_1.SecurityEvent.BIOMETRIC_LOGIN_FAILURE, {
57
+ ipAddress,
58
+ realm,
59
+ reason: 'challenge_ip_rate_limited',
60
+ });
61
+ return null;
62
+ }
63
+ }
64
+ const challenge = (0, crypto_1.randomBytes)(CHALLENGE_BYTES).toString('base64');
65
+ const expiresAt = new Date(Date.now() + this.expirySeconds * 1000);
66
+ const challengeId = await this.store.storeChallenge({
67
+ credentialId,
68
+ challenge,
69
+ expiresAt,
70
+ });
71
+ void this.sweep();
72
+ return { challengeId, challenge, expiresAt };
73
+ }
74
+ async withinLimit(key, limit, windowMs) {
75
+ const { allowed } = await this.rateLimiter.checkRateLimit(key, limit, windowMs);
76
+ if (!allowed) {
77
+ return false;
78
+ }
79
+ await this.rateLimiter.recordAttempt(key, windowMs);
80
+ return true;
81
+ }
82
+ async consumeChallenge(challengeId) {
83
+ const record = await this.store.consumeChallenge(challengeId);
84
+ if (!record) {
85
+ this.securityLogger.log(auth_logger_interface_1.SecurityEvent.BIOMETRIC_LOGIN_FAILURE, {
86
+ challengeId,
87
+ reason: 'challenge_unavailable',
88
+ });
89
+ return null;
90
+ }
91
+ return record;
92
+ }
93
+ async sweep() {
94
+ const now = Date.now();
95
+ if (now - this.lastSweepAt < SWEEP_THROTTLE_MS) {
96
+ return;
97
+ }
98
+ this.lastSweepAt = now;
99
+ try {
100
+ await this.store.deleteExpiredChallenges();
101
+ }
102
+ catch (error) {
103
+ this.securityLogger.warn(`Sweeping expired biometric challenges failed: ${error instanceof Error ? error.message : String(error)}. Challenges still expire — consumeChallenge re-checks it.`, 'BiometricChallengeService');
104
+ }
105
+ }
106
+ };
107
+ exports.BiometricChallengeService = BiometricChallengeService;
108
+ exports.BiometricChallengeService = BiometricChallengeService = __decorate([
109
+ (0, common_1.Injectable)(),
110
+ __param(0, (0, common_1.Inject)(constants_1.BIOMETRIC_REPOSITORY)),
111
+ __param(1, (0, common_1.Inject)(constants_1.RATE_LIMITER)),
112
+ __param(2, (0, common_1.Inject)(constants_1.AUTH_LOGGER)),
113
+ __param(3, (0, common_1.Inject)(constants_1.AUTH_MODULE_OPTIONS)),
114
+ __metadata("design:paramtypes", [Object, Object, Object, Object])
115
+ ], BiometricChallengeService);
116
+ //# sourceMappingURL=biometric-challenge.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"biometric-challenge.service.js","sourceRoot":"","sources":["../../src/services/biometric-challenge.service.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"biometric-verification.service.d.ts","sourceRoot":"","sources":["../../src/services/biometric-verification.service.ts"],"names":[],"mappings":"AA6BA,qBACa,4BAA4B;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiD;IACxE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAa;IAiB3C,eAAe,CACnB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;IA4Cb,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA2C/D,OAAO,CAAC,cAAc;IAkDtB,sBAAsB,IAAI,MAAM,EAAE;CAGnC"}
1
+ {"version":3,"file":"biometric-verification.service.d.ts","sourceRoot":"","sources":["../../src/services/biometric-verification.service.ts"],"names":[],"mappings":"AA6BA,qBACa,4BAA4B;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiD;IACxE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAa;IAiB3C,eAAe,CACnB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;IA4Cb,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA2C/D,OAAO,CAAC,cAAc;IA6DtB,sBAAsB,IAAI,MAAM,EAAE;CAGnC"}
@@ -61,6 +61,10 @@ let BiometricVerificationService = BiometricVerificationService_1 = class Biomet
61
61
  if (publicKey.asymmetricKeyType !== 'ec') {
62
62
  throw new Error(`Invalid key type: expected 'ec', got '${publicKey.asymmetricKeyType}'`);
63
63
  }
64
+ const namedCurve = publicKey.asymmetricKeyDetails?.namedCurve;
65
+ if (namedCurve !== 'prime256v1') {
66
+ throw new Error(`Invalid curve: expected 'prime256v1' (P-256), got '${namedCurve ?? 'unknown'}'`);
67
+ }
64
68
  return publicKey;
65
69
  }
66
70
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"biometric-verification.service.js","sourceRoot":"","sources":["../../src/services/biometric-verification.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"biometric-verification.service.js","sourceRoot":"","sources":["../../src/services/biometric-verification.service.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAyE;AACzE,mCAAkE;AA6B3D,IAAM,4BAA4B,oCAAlC,MAAM,4BAA4B;IAAlC;QACY,WAAM,GAAG,IAAI,eAAM,CAAC,8BAA4B,CAAC,IAAI,CAAC,CAAC;QACvD,wBAAmB,GAAG,CAAC,OAAO,CAAC,CAAC;IA4KnD,CAAC;IA3JC,KAAK,CAAC,eAAe,CACnB,YAAoB,EACpB,SAAiB,EACjB,SAAiB;QAEjB,IAAI,CAAC;YAEH,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;YAGpD,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACzD,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAGzD,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,QAAQ,CAAC,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;YAC/B,MAAM,CAAC,GAAG,EAAE,CAAC;YAGb,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;YAE1D,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,0CAA0C,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAC1E,CAAC;YAEF,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5E,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,gDAAgD,YAAY,EAAE,CAC/D,CAAC;YACF,MAAM,IAAI,4BAAmB,CAAC,6BAA6B,YAAY,EAAE,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IAeD,KAAK,CAAC,iBAAiB,CAAC,YAAoB;QAC1C,IAAI,CAAC;YAGH,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;YAWrD,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,gDAAgD,CACjD,CAAC;YAEF,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5E,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,8CAA8C,YAAY,EAAE,CAC7D,CAAC;YACF,MAAM,IAAI,4BAAmB,CAC3B,8BAA8B,YAAY,EAAE,CAC7C,CAAC;QACJ,CAAC;IACH,CAAC;IAcO,cAAc,CAAC,YAAoB;QACzC,IAAI,CAAC;YAEH,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAC/C,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACzE,CAAC;YAED,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC7C,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;YACvE,CAAC;YAGD,MAAM,SAAS,GAAG,IAAA,wBAAe,EAAC;gBAChC,GAAG,EAAE,YAAY;gBACjB,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,MAAM;aACb,CAAC,CAAC;YAGH,IAAI,SAAS,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;gBACzC,MAAM,IAAI,KAAK,CACb,yCAAyC,SAAS,CAAC,iBAAiB,GAAG,CACxE,CAAC;YACJ,CAAC;YAWD,MAAM,UAAU,GAAG,SAAS,CAAC,oBAAoB,EAAE,UAAU,CAAC;YAC9D,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;gBAChC,MAAM,IAAI,KAAK,CACb,sDAAsD,UAAU,IAAI,SAAS,GAAG,CACjF,CAAC;YACJ,CAAC;YAED,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,YAAY,EAAE,CAAC,CAAC;YACzE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAcD,sBAAsB;QACpB,OAAO,IAAI,CAAC,mBAAmB,CAAC;IAClC,CAAC;CACF,CAAA;AA9KY,oEAA4B;uCAA5B,4BAA4B;IADxC,IAAA,mBAAU,GAAE;GACA,4BAA4B,CA8KxC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mock-repositories.d.ts","sourceRoot":"","sources":["../../src/test-utils/mock-repositories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAM/I,wBAAgB,wBAAwB,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAwCvE;AAKD,wBAAgB,gCAAgC,IAAI,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAYvF;AAKD,wBAAgB,gCAAgC,IAAI,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAOvF;AAKD,wBAAgB,8BAA8B,IAAI,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,CASnF;AAKD,wBAAgB,6BAA6B,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAUjF"}
1
+ {"version":3,"file":"mock-repositories.d.ts","sourceRoot":"","sources":["../../src/test-utils/mock-repositories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAM/I,wBAAgB,wBAAwB,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAwCvE;AAKD,wBAAgB,gCAAgC,IAAI,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAYvF;AAKD,wBAAgB,gCAAgC,IAAI,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAOvF;AAKD,wBAAgB,8BAA8B,IAAI,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,CASnF;AAKD,wBAAgB,6BAA6B,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAWjF"}
@@ -78,13 +78,14 @@ function createMockBruteForceRepository() {
78
78
  }
79
79
  function createMockBiometricRepository() {
80
80
  return {
81
- storeBiometricCredential: jest.fn(),
82
- getBiometricCredential: jest.fn(),
83
- listBiometricCredentials: jest.fn(),
84
- removeBiometricCredential: jest.fn(),
85
- storeBiometricChallenge: jest.fn(),
86
- getBiometricChallenge: jest.fn(),
87
- markChallengeAsUsed: jest.fn(),
81
+ storeCredential: jest.fn(),
82
+ getCredential: jest.fn(),
83
+ listCredentials: jest.fn(),
84
+ deactivateCredential: jest.fn(),
85
+ touchCredentialLastUsed: jest.fn(),
86
+ storeChallenge: jest.fn(),
87
+ consumeChallenge: jest.fn(),
88
+ deleteExpiredChallenges: jest.fn(),
88
89
  };
89
90
  }
90
91
  //# sourceMappingURL=mock-repositories.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mock-repositories.js","sourceRoot":"","sources":["../../src/test-utils/mock-repositories.ts"],"names":[],"mappings":";;AAMA,4DAwCC;AAKD,4EAYC;AAKD,4EAOC;AAKD,wEASC;AAKD,sEAUC;AAlGD,SAAgB,wBAAwB;IACtC,OAAO;QACL,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;QACtB,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE;QACnB,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;QACzB,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC3B,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE;QACxB,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC5B,wBAAwB,EAAE,IAAI,CAAC,EAAE,EAAE;QACnC,qBAAqB,EAAE,IAAI,CAAC,EAAE,EAAE;QAChC,2BAA2B,EAAE,IAAI,CAAC,EAAE,EAAE;QACtC,6BAA6B,EAAE,IAAI,CAAC,EAAE,EAAE;QACxC,0BAA0B,EAAE,IAAI,CAAC,EAAE,EAAE;QACrC,sBAAsB,EAAE,IAAI,CAAC,EAAE,EAAE;QAEjC,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC9B,gCAAgC,EAAE,IAAI,CAAC,EAAE,EAAE;QAC3C,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC3B,kBAAkB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC7B,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC3B,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;QACjB,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;QACjB,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;QACtB,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;QACzB,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC5B,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC5B,4BAA4B,EAAE,IAAI,CAAC,EAAE,EAAE;QACvC,wBAAwB,EAAE,IAAI,CAAC,EAAE,EAAE;QACnC,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC5B,eAAe,EAAE,IAAI,CAAC,EAAE,EAAE;QAC1B,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC3B,wBAAwB,EAAE,IAAI,CAAC,EAAE,EAAE;QACnC,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC5B,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC9B,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC9B,qBAAqB,EAAE,IAAI,CAAC,EAAE,EAAE;QAChC,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC3B,kBAAkB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC7B,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;KACc,CAAC;AACpC,CAAC;AAKD,SAAgB,gCAAgC;IAC9C,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;QACjB,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC5B,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;QACvB,0BAA0B,EAAE,IAAI,CAAC,EAAE,EAAE;QACrC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;QACjB,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC9B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;QACzB,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC7C,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;KACS,CAAC;AAC5C,CAAC;AAKD,SAAgB,gCAAgC;IAC9C,OAAO;QACL,qBAAqB,EAAE,IAAI,CAAC,EAAE,EAAE;QAChC,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC9B,6BAA6B,EAAE,IAAI,CAAC,EAAE,EAAE;QACxC,qBAAqB,EAAE,IAAI,CAAC,EAAE,EAAE;KACO,CAAC;AAC5C,CAAC;AAKD,SAAgB,8BAA8B;IAC5C,OAAO;QACL,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC9B,qBAAqB,EAAE,IAAI,CAAC,EAAE,EAAE;QAChC,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;QACtB,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC3B,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC9B,eAAe,EAAE,IAAI,CAAC,EAAE,EAAE;KACW,CAAC;AAC1C,CAAC;AAKD,SAAgB,6BAA6B;IAC3C,OAAO;QACL,wBAAwB,EAAE,IAAI,CAAC,EAAE,EAAE;QACnC,sBAAsB,EAAE,IAAI,CAAC,EAAE,EAAE;QACjC,wBAAwB,EAAE,IAAI,CAAC,EAAE,EAAE;QACnC,yBAAyB,EAAE,IAAI,CAAC,EAAE,EAAE;QACpC,uBAAuB,EAAE,IAAI,CAAC,EAAE,EAAE;QAClC,qBAAqB,EAAE,IAAI,CAAC,EAAE,EAAE;QAChC,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;KACM,CAAC;AACzC,CAAC"}
1
+ {"version":3,"file":"mock-repositories.js","sourceRoot":"","sources":["../../src/test-utils/mock-repositories.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { IBiometricVerifier } from '../interfaces/biometric-verifier.interface';
2
+ import { BiometricVerificationService } from '../services/biometric-verification.service';
3
+ export declare class Es256DeviceKeyVerifier implements IBiometricVerifier {
4
+ private readonly verification;
5
+ readonly algorithm = "ES256";
6
+ constructor(verification?: BiometricVerificationService);
7
+ verify(input: {
8
+ publicKey: string;
9
+ challenge: string;
10
+ signature: string;
11
+ }): Promise<boolean>;
12
+ validatePublicKey(publicKey: string): Promise<boolean>;
13
+ }
14
+ //# sourceMappingURL=es256-device-key.verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"es256-device-key.verifier.d.ts","sourceRoot":"","sources":["../../src/verifiers/es256-device-key.verifier.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAChF,OAAO,EAAE,4BAA4B,EAAE,MAAM,4CAA4C,CAAC;AAwB1F,qBACa,sBAAuB,YAAW,kBAAkB;IAI7D,OAAO,CAAC,QAAQ,CAAC,YAAY;IAH/B,QAAQ,CAAC,SAAS,WAAW;gBAGV,YAAY,GAAE,4BAAiE;IAG5F,MAAM,CAAC,KAAK,EAAE;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBd,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAO7D"}
@@ -0,0 +1,42 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Es256DeviceKeyVerifier = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const biometric_verification_service_1 = require("../services/biometric-verification.service");
15
+ let Es256DeviceKeyVerifier = class Es256DeviceKeyVerifier {
16
+ constructor(verification = new biometric_verification_service_1.BiometricVerificationService()) {
17
+ this.verification = verification;
18
+ this.algorithm = 'ES256';
19
+ }
20
+ async verify(input) {
21
+ try {
22
+ return await this.verification.verifySignature(input.publicKey, input.challenge, input.signature);
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ async validatePublicKey(publicKey) {
29
+ try {
30
+ return await this.verification.validatePublicKey(publicKey);
31
+ }
32
+ catch {
33
+ return false;
34
+ }
35
+ }
36
+ };
37
+ exports.Es256DeviceKeyVerifier = Es256DeviceKeyVerifier;
38
+ exports.Es256DeviceKeyVerifier = Es256DeviceKeyVerifier = __decorate([
39
+ (0, common_1.Injectable)(),
40
+ __metadata("design:paramtypes", [biometric_verification_service_1.BiometricVerificationService])
41
+ ], Es256DeviceKeyVerifier);
42
+ //# sourceMappingURL=es256-device-key.verifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"es256-device-key.verifier.js","sourceRoot":"","sources":["../../src/verifiers/es256-device-key.verifier.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAE5C,+FAA0F;AAyBnF,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;IAGjC,YACmB,eAA6C,IAAI,6DAA4B,EAAE;QAA/E,iBAAY,GAAZ,YAAY,CAAmE;QAHzF,cAAS,GAAG,OAAO,CAAC;IAI1B,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,KAIZ;QACC,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,CAC5C,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,SAAS,CAChB,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YAMP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,SAAiB;QACvC,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAC9D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF,CAAA;AAnCY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,mBAAU,GAAE;qCAKsB,6DAA4B;GAJlD,sBAAsB,CAmClC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ambushsoftworks/nestjs-auth-graphql",
3
- "version": "0.12.0",
3
+ "version": "0.15.0",
4
4
  "description": "Production-grade authentication package for NestJS with GraphQL, supporting JWT, OAuth, email/SMS verification, and biometric auth",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -23,7 +23,9 @@
23
23
  "lint": "eslint \"{src,test}/**/*.ts\"",
24
24
  "format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"",
25
25
  "prepublishOnly": "npm run build",
26
- "lint:fix": "eslint \"{src,test}/**/*.ts\" --fix"
26
+ "lint:fix": "eslint \"{src,test}/**/*.ts\" --fix",
27
+ "release": "node scripts/release.js",
28
+ "release:verify": "node scripts/verify-release.js"
27
29
  },
28
30
  "keywords": [
29
31
  "nestjs",
@@ -46,6 +48,10 @@
46
48
  "type": "git",
47
49
  "url": "https://gitlab.com/ambushworks/nestjs-auth-graphql.git"
48
50
  },
51
+ "homepage": "https://gitlab.com/ambushworks/nestjs-auth-graphql#readme",
52
+ "bugs": {
53
+ "url": "https://gitlab.com/ambushworks/nestjs-auth-graphql/-/issues"
54
+ },
49
55
  "peerDependencies": {
50
56
  "@nestjs/common": "^10.0.0 || ^11.0.0",
51
57
  "@nestjs/core": "^10.0.0 || ^11.0.0",
@@ -1,6 +0,0 @@
1
- export interface IMagicLinkRepository {
2
- storeMagicLink(userId: string, tokenHash: string, expiresAt: Date): Promise<void>;
3
- validateMagicLink(userId: string, tokenHash: string): Promise<boolean>;
4
- deleteMagicLink(userId: string): Promise<void>;
5
- }
6
- //# sourceMappingURL=magic-link-repository.interface.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"magic-link-repository.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/magic-link-repository.interface.ts"],"names":[],"mappings":"AAoDA,MAAM,WAAW,oBAAoB;IAkBnC,cAAc,CACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,IAAI,GACd,OAAO,CAAC,IAAI,CAAC,CAAC;IAyBjB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAiBvE,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"magic-link-repository.interface.js","sourceRoot":"","sources":["../../src/interfaces/magic-link-repository.interface.ts"],"names":[],"mappings":""}
@@ -1,7 +0,0 @@
1
- export interface IPasswordResetStrategy {
2
- generateResetToken(userId: string): Promise<string>;
3
- validateResetToken(userId: string, token: string): Promise<boolean>;
4
- getExpiryDuration(): number;
5
- deleteResetToken(userId: string): Promise<void>;
6
- }
7
- //# sourceMappingURL=password-reset-strategy.interface.d.ts.map