@ambushsoftworks/nestjs-auth-graphql 0.15.1 → 0.16.0-rc.2

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 (113) hide show
  1. package/CHANGELOG.md +160 -0
  2. package/README.md +385 -3
  3. package/dist/auth.module.d.ts +21 -0
  4. package/dist/auth.module.d.ts.map +1 -1
  5. package/dist/auth.module.js +104 -0
  6. package/dist/auth.module.js.map +1 -1
  7. package/dist/constants.d.ts +2 -0
  8. package/dist/constants.d.ts.map +1 -1
  9. package/dist/constants.js +3 -1
  10. package/dist/constants.js.map +1 -1
  11. package/dist/dto/passkey.dto.d.ts +43 -0
  12. package/dist/dto/passkey.dto.d.ts.map +1 -0
  13. package/dist/dto/passkey.dto.js +5 -0
  14. package/dist/dto/passkey.dto.js.map +1 -0
  15. package/dist/enums/verification-type.enum.d.ts +3 -2
  16. package/dist/enums/verification-type.enum.d.ts.map +1 -1
  17. package/dist/enums/verification-type.enum.js +1 -0
  18. package/dist/enums/verification-type.enum.js.map +1 -1
  19. package/dist/exceptions/passkey.exceptions.d.ts +11 -0
  20. package/dist/exceptions/passkey.exceptions.d.ts.map +1 -0
  21. package/dist/exceptions/passkey.exceptions.js +29 -0
  22. package/dist/exceptions/passkey.exceptions.js.map +1 -0
  23. package/dist/exceptions/step-up.exceptions.d.ts +14 -0
  24. package/dist/exceptions/step-up.exceptions.d.ts.map +1 -0
  25. package/dist/exceptions/step-up.exceptions.js +41 -0
  26. package/dist/exceptions/step-up.exceptions.js.map +1 -0
  27. package/dist/index.d.ts +10 -0
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +9 -0
  30. package/dist/index.js.map +1 -1
  31. package/dist/interfaces/auth-lifecycle-hooks.interface.d.ts +2 -0
  32. package/dist/interfaces/auth-lifecycle-hooks.interface.d.ts.map +1 -1
  33. package/dist/interfaces/auth-logger.interface.d.ts +10 -1
  34. package/dist/interfaces/auth-logger.interface.d.ts.map +1 -1
  35. package/dist/interfaces/auth-logger.interface.js +9 -0
  36. package/dist/interfaces/auth-logger.interface.js.map +1 -1
  37. package/dist/interfaces/biometric-verifier.interface.d.ts.map +1 -1
  38. package/dist/interfaces/email-service.interface.d.ts +3 -0
  39. package/dist/interfaces/email-service.interface.d.ts.map +1 -1
  40. package/dist/interfaces/email-template-renderer.interface.d.ts +15 -0
  41. package/dist/interfaces/email-template-renderer.interface.d.ts.map +1 -1
  42. package/dist/interfaces/index.d.ts +1 -0
  43. package/dist/interfaces/index.d.ts.map +1 -1
  44. package/dist/interfaces/index.js +1 -0
  45. package/dist/interfaces/index.js.map +1 -1
  46. package/dist/interfaces/passkey-repository.interface.d.ts +48 -0
  47. package/dist/interfaces/passkey-repository.interface.d.ts.map +1 -0
  48. package/dist/interfaces/passkey-repository.interface.js +13 -0
  49. package/dist/interfaces/passkey-repository.interface.js.map +1 -0
  50. package/dist/passkey/passkey-json.types.d.ts +44 -0
  51. package/dist/passkey/passkey-json.types.d.ts.map +1 -0
  52. package/dist/passkey/passkey-json.types.js +3 -0
  53. package/dist/passkey/passkey-json.types.js.map +1 -0
  54. package/dist/passkey/webauthn-adapter.d.ts +104 -0
  55. package/dist/passkey/webauthn-adapter.d.ts.map +1 -0
  56. package/dist/passkey/webauthn-adapter.js +207 -0
  57. package/dist/passkey/webauthn-adapter.js.map +1 -0
  58. package/dist/repositories/in-memory-passkey.repository.d.ts +21 -0
  59. package/dist/repositories/in-memory-passkey.repository.d.ts.map +1 -0
  60. package/dist/repositories/in-memory-passkey.repository.js +72 -0
  61. package/dist/repositories/in-memory-passkey.repository.js.map +1 -0
  62. package/dist/resolvers/base-auth.resolver.d.ts +20 -0
  63. package/dist/resolvers/base-auth.resolver.d.ts.map +1 -1
  64. package/dist/resolvers/base-auth.resolver.js +104 -0
  65. package/dist/resolvers/base-auth.resolver.js.map +1 -1
  66. package/dist/services/auth.service.d.ts +5 -0
  67. package/dist/services/auth.service.d.ts.map +1 -1
  68. package/dist/services/auth.service.js +24 -0
  69. package/dist/services/auth.service.js.map +1 -1
  70. package/dist/services/biometric-challenge.service.d.ts.map +1 -1
  71. package/dist/services/biometric-challenge.service.js.map +1 -1
  72. package/dist/services/configurable-email.service.d.ts +3 -0
  73. package/dist/services/configurable-email.service.d.ts.map +1 -1
  74. package/dist/services/configurable-email.service.js +54 -0
  75. package/dist/services/configurable-email.service.js.map +1 -1
  76. package/dist/services/default-email-template-renderer.d.ts +16 -0
  77. package/dist/services/default-email-template-renderer.d.ts.map +1 -1
  78. package/dist/services/default-email-template-renderer.js +84 -0
  79. package/dist/services/default-email-template-renderer.js.map +1 -1
  80. package/dist/services/passkey.service.d.ts +104 -0
  81. package/dist/services/passkey.service.d.ts.map +1 -0
  82. package/dist/services/passkey.service.js +519 -0
  83. package/dist/services/passkey.service.js.map +1 -0
  84. package/dist/services/step-up-token.service.d.ts +15 -0
  85. package/dist/services/step-up-token.service.d.ts.map +1 -0
  86. package/dist/services/step-up-token.service.js +71 -0
  87. package/dist/services/step-up-token.service.js.map +1 -0
  88. package/dist/services/step-up.service.d.ts +50 -0
  89. package/dist/services/step-up.service.d.ts.map +1 -0
  90. package/dist/services/step-up.service.js +142 -0
  91. package/dist/services/step-up.service.js.map +1 -0
  92. package/dist/services/verification.service.d.ts +2 -2
  93. package/dist/services/verification.service.d.ts.map +1 -1
  94. package/dist/services/verification.service.js +5 -4
  95. package/dist/services/verification.service.js.map +1 -1
  96. package/dist/test-utils/software-authenticator.d.ts +37 -0
  97. package/dist/test-utils/software-authenticator.d.ts.map +1 -0
  98. package/dist/test-utils/software-authenticator.js +212 -0
  99. package/dist/test-utils/software-authenticator.js.map +1 -0
  100. package/dist/testing/index.d.ts +3 -0
  101. package/dist/testing/index.d.ts.map +1 -0
  102. package/dist/testing/index.js +9 -0
  103. package/dist/testing/index.js.map +1 -0
  104. package/dist/testing/passkey-repository.contract.d.ts +8 -0
  105. package/dist/testing/passkey-repository.contract.d.ts.map +1 -0
  106. package/dist/testing/passkey-repository.contract.js +248 -0
  107. package/dist/testing/passkey-repository.contract.js.map +1 -0
  108. package/dist/utils/passkey-rp.d.ts +13 -0
  109. package/dist/utils/passkey-rp.d.ts.map +1 -0
  110. package/dist/utils/passkey-rp.js +89 -0
  111. package/dist/utils/passkey-rp.js.map +1 -0
  112. package/package.json +7 -1
  113. package/testing/package.json +5 -0
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SoftwareAuthenticator = exports.PasskeyRepositoryContractError = exports.assertPasskeyRepositoryContract = void 0;
4
+ var passkey_repository_contract_1 = require("./passkey-repository.contract");
5
+ Object.defineProperty(exports, "assertPasskeyRepositoryContract", { enumerable: true, get: function () { return passkey_repository_contract_1.assertPasskeyRepositoryContract; } });
6
+ Object.defineProperty(exports, "PasskeyRepositoryContractError", { enumerable: true, get: function () { return passkey_repository_contract_1.PasskeyRepositoryContractError; } });
7
+ var software_authenticator_1 = require("../test-utils/software-authenticator");
8
+ Object.defineProperty(exports, "SoftwareAuthenticator", { enumerable: true, get: function () { return software_authenticator_1.SoftwareAuthenticator; } });
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":";;;AAMA,6EAGuC;AAFrC,8IAAA,+BAA+B,OAAA;AAC/B,6IAAA,8BAA8B,OAAA;AAEhC,+EAK8C;AAJ5C,+HAAA,qBAAqB,OAAA"}
@@ -0,0 +1,8 @@
1
+ import { IPasskeyRepository } from '../interfaces/passkey-repository.interface';
2
+ export declare class PasskeyRepositoryContractError extends Error {
3
+ constructor(check: string, detail: string);
4
+ }
5
+ type Factory = () => IPasskeyRepository | Promise<IPasskeyRepository>;
6
+ export declare function assertPasskeyRepositoryContract(factory: Factory): Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=passkey-repository.contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkey-repository.contract.d.ts","sourceRoot":"","sources":["../../src/testing/passkey-repository.contract.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAGnB,MAAM,4CAA4C,CAAC;AAGpD,qBAAa,8BAA+B,SAAQ,KAAK;gBAC3C,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAI1C;AAED,KAAK,OAAO,GAAG,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAuCtE,wBAAsB,+BAA+B,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAarF"}
@@ -0,0 +1,248 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PasskeyRepositoryContractError = void 0;
4
+ exports.assertPasskeyRepositoryContract = assertPasskeyRepositoryContract;
5
+ const crypto_1 = require("crypto");
6
+ const passkey_repository_interface_1 = require("../interfaces/passkey-repository.interface");
7
+ class PasskeyRepositoryContractError extends Error {
8
+ constructor(check, detail) {
9
+ super(`IPasskeyRepository contract — ${check}: ${detail}`);
10
+ this.name = 'PasskeyRepositoryContractError';
11
+ }
12
+ }
13
+ exports.PasskeyRepositoryContractError = PasskeyRepositoryContractError;
14
+ const CONCURRENCY = 8;
15
+ const MAX_COUNTER = 2 ** 32 - 1;
16
+ async function assertPasskeyRepositoryContract(factory) {
17
+ for (const [name, check] of CHECKS) {
18
+ const repository = await factory();
19
+ try {
20
+ await check(repository);
21
+ }
22
+ catch (error) {
23
+ if (error instanceof PasskeyRepositoryContractError)
24
+ throw error;
25
+ throw new PasskeyRepositoryContractError(name, `threw ${error instanceof Error ? `${error.name}: ${error.message}` : String(error)}`);
26
+ }
27
+ }
28
+ }
29
+ function fail(check, detail) {
30
+ throw new PasskeyRepositoryContractError(check, detail);
31
+ }
32
+ function credential(overrides = {}) {
33
+ return {
34
+ credentialId: `contract-${(0, crypto_1.randomUUID)()}`,
35
+ userId: `contract-user-${(0, crypto_1.randomUUID)()}`,
36
+ realm: 'contract-realm',
37
+ publicKey: 'pQECAyYgASFYIA',
38
+ counter: 0,
39
+ userHandle: `handle-${(0, crypto_1.randomUUID)()}`,
40
+ transports: ['internal', 'hybrid'],
41
+ deviceType: 'multiDevice',
42
+ backedUp: true,
43
+ aaguid: '00000000-0000-0000-0000-000000000000',
44
+ name: 'Contract passkey',
45
+ createdAt: new Date(Math.floor(Date.now() / 1000) * 1000),
46
+ lastUsedAt: null,
47
+ isActive: true,
48
+ ...overrides,
49
+ };
50
+ }
51
+ const sameTime = (a, b) => a === b || (a instanceof Date && b instanceof Date && Math.abs(a.getTime() - b.getTime()) < 1000);
52
+ const CHECKS = [
53
+ [
54
+ 'challenges round-trip every field',
55
+ async (repo) => {
56
+ const check = 'challenges round-trip every field';
57
+ const input = {
58
+ challenge: `challenge-${(0, crypto_1.randomUUID)()}`,
59
+ purpose: 'registration',
60
+ userId: `user-${(0, crypto_1.randomUUID)()}`,
61
+ realm: 'contract-realm',
62
+ userHandle: `handle-${(0, crypto_1.randomUUID)()}`,
63
+ expiresAt: new Date(Date.now() + 60_000),
64
+ };
65
+ const id = await repo.storeChallenge(input);
66
+ if (typeof id !== 'string' || id === '')
67
+ fail(check, `storeChallenge returned ${JSON.stringify(id)}`);
68
+ const got = await repo.consumeChallenge(id);
69
+ if (!got)
70
+ fail(check, 'consumeChallenge returned null for a fresh challenge');
71
+ for (const key of ['challenge', 'purpose', 'userId', 'realm', 'userHandle']) {
72
+ if (got[key] !== input[key]) {
73
+ fail(check, `${key} came back as ${JSON.stringify(got[key])}, stored ${JSON.stringify(input[key])}`);
74
+ }
75
+ }
76
+ if (got.challengeId !== id)
77
+ fail(check, `challengeId came back as ${JSON.stringify(got.challengeId)}`);
78
+ if (!sameTime(got.expiresAt, input.expiresAt))
79
+ fail(check, 'expiresAt changed');
80
+ },
81
+ ],
82
+ [
83
+ 'a challenge is claimed exactly once, under concurrency',
84
+ async (repo) => {
85
+ const check = 'a challenge is claimed exactly once, under concurrency';
86
+ const id = await repo.storeChallenge({
87
+ challenge: 'c',
88
+ purpose: 'authentication',
89
+ expiresAt: new Date(Date.now() + 60_000),
90
+ });
91
+ const claims = await Promise.all(Array.from({ length: CONCURRENCY }, () => repo.consumeChallenge(id)));
92
+ const won = claims.filter(Boolean).length;
93
+ if (won !== 1) {
94
+ fail(check, `${won} of ${CONCURRENCY} concurrent consumeChallenge calls succeeded. It must be one ` +
95
+ 'conditional update (UPDATE … WHERE used = false, then check the row count), not a read then a write.');
96
+ }
97
+ if (await repo.consumeChallenge(id))
98
+ fail(check, 'a consumed challenge was returned again');
99
+ },
100
+ ],
101
+ [
102
+ 'expired and unknown challenges answer null',
103
+ async (repo) => {
104
+ const check = 'expired and unknown challenges answer null';
105
+ const id = await repo.storeChallenge({
106
+ challenge: 'c',
107
+ purpose: 'authentication',
108
+ expiresAt: new Date(Date.now() - 1_000),
109
+ });
110
+ if (await repo.consumeChallenge(id)) {
111
+ fail(check, 'an expired challenge was returned; check expiresAt in the claim, do not rely on a TTL');
112
+ }
113
+ if (await repo.consumeChallenge((0, crypto_1.randomUUID)()))
114
+ fail(check, 'an unknown challenge id returned a record');
115
+ },
116
+ ],
117
+ [
118
+ 'credentials round-trip every field, counter up to 2^32-1',
119
+ async (repo) => {
120
+ const check = 'credentials round-trip every field';
121
+ const record = credential({ counter: MAX_COUNTER, metadata: { device: 'contract' } });
122
+ await repo.createCredential(record);
123
+ const got = await repo.getCredential(record.credentialId);
124
+ if (!got)
125
+ fail(check, 'getCredential returned null for a credential just created');
126
+ for (const key of [
127
+ 'credentialId', 'userId', 'realm', 'publicKey', 'counter', 'userHandle',
128
+ 'deviceType', 'backedUp', 'aaguid', 'name', 'isActive',
129
+ ]) {
130
+ if (got[key] !== record[key]) {
131
+ fail(check, `${key} came back as ${JSON.stringify(got[key])}, stored ${JSON.stringify(record[key])}` +
132
+ (key === 'counter' ? ' (a uint32: store it in a bigint column)' : ''));
133
+ }
134
+ }
135
+ if (JSON.stringify(got.transports) !== JSON.stringify(record.transports)) {
136
+ fail(check, `transports came back as ${JSON.stringify(got.transports)}`);
137
+ }
138
+ if (!sameTime(got.createdAt, record.createdAt))
139
+ fail(check, 'createdAt changed');
140
+ if (got.lastUsedAt !== null)
141
+ fail(check, `lastUsedAt came back as ${String(got.lastUsedAt)}, stored null`);
142
+ },
143
+ ],
144
+ [
145
+ 'a duplicate credential id throws PasskeyCredentialExistsError and leaves the original',
146
+ async (repo) => {
147
+ const check = 'a duplicate credential id is refused';
148
+ const original = credential();
149
+ await repo.createCredential(original);
150
+ try {
151
+ await repo.createCredential(credential({ credentialId: original.credentialId }));
152
+ }
153
+ catch (error) {
154
+ if (!(error instanceof passkey_repository_interface_1.PasskeyCredentialExistsError)) {
155
+ fail(check, `threw ${error instanceof Error ? error.name : String(error)}; map your unique-constraint ` +
156
+ 'violation (Prisma P2002) to PasskeyCredentialExistsError');
157
+ }
158
+ const kept = await repo.getCredential(original.credentialId);
159
+ if (kept?.userId !== original.userId)
160
+ fail(check, "the original credential's owner changed");
161
+ return;
162
+ }
163
+ fail(check, 'a second credential with the same id, for another user, was accepted');
164
+ },
165
+ ],
166
+ [
167
+ 'deactivated credentials are still returned',
168
+ async (repo) => {
169
+ const check = 'deactivated credentials are still returned';
170
+ const record = credential();
171
+ await repo.createCredential(record);
172
+ await repo.deactivateCredential(record.credentialId);
173
+ const got = await repo.getCredential(record.credentialId);
174
+ if (!got)
175
+ fail(check, 'getCredential hid a deactivated credential; the package decides, not the store');
176
+ if (got.isActive !== false)
177
+ fail(check, 'deactivateCredential did not set isActive to false');
178
+ const listed = await repo.listCredentials(record.userId, record.realm);
179
+ if (!listed.some((c) => c.credentialId === record.credentialId)) {
180
+ fail(check, 'listCredentials hid a deactivated credential');
181
+ }
182
+ },
183
+ ],
184
+ [
185
+ 'listing is by user, narrowed by realm',
186
+ async (repo) => {
187
+ const check = 'listing is by user, narrowed by realm';
188
+ const userId = `contract-user-${(0, crypto_1.randomUUID)()}`;
189
+ const mine = credential({ userId, realm: 'realm-a' });
190
+ const otherRealm = credential({ userId, realm: 'realm-b' });
191
+ const otherUser = credential({ realm: 'realm-a' });
192
+ for (const c of [mine, otherRealm, otherUser])
193
+ await repo.createCredential(c);
194
+ const inRealm = (await repo.listCredentials(userId, 'realm-a')).map((c) => c.credentialId);
195
+ if (inRealm.length !== 1 || inRealm[0] !== mine.credentialId) {
196
+ fail(check, `listCredentials(user, 'realm-a') returned ${JSON.stringify(inRealm)}`);
197
+ }
198
+ const all = (await repo.listCredentials(userId)).map((c) => c.credentialId).sort();
199
+ const expected = [mine.credentialId, otherRealm.credentialId].sort();
200
+ if (JSON.stringify(all) !== JSON.stringify(expected)) {
201
+ fail(check, `listCredentials(user) returned ${JSON.stringify(all)}`);
202
+ }
203
+ },
204
+ ],
205
+ [
206
+ 'updateCounter is a compare-and-set, under concurrency',
207
+ async (repo) => {
208
+ const check = 'updateCounter is a compare-and-set';
209
+ const record = credential({ counter: 3 });
210
+ await repo.createCredential(record);
211
+ const update = (expectedCounter, newCounter) => repo.updateCounter({
212
+ credentialId: record.credentialId,
213
+ expectedCounter,
214
+ newCounter,
215
+ backedUp: false,
216
+ lastUsedAt: new Date(),
217
+ });
218
+ if (await update(2, 9))
219
+ fail(check, 'applied with a stale expectedCounter');
220
+ const results = await Promise.all(Array.from({ length: CONCURRENCY }, (_, i) => update(3, 4 + i)));
221
+ const applied = results.filter(Boolean).length;
222
+ if (applied !== 1) {
223
+ fail(check, `${applied} of ${CONCURRENCY} concurrent updates from the same counter applied. It must be one ` +
224
+ 'conditional update (UPDATE … WHERE counter = expected), not a read then a write.');
225
+ }
226
+ const got = await repo.getCredential(record.credentialId);
227
+ if (!got || got.counter < 4)
228
+ fail(check, `the counter is ${String(got?.counter)} after an applied update`);
229
+ if (got.backedUp !== false)
230
+ fail(check, 'backedUp was not written');
231
+ if (!(got.lastUsedAt instanceof Date))
232
+ fail(check, 'lastUsedAt was not written');
233
+ },
234
+ ],
235
+ [
236
+ 'renameCredential changes the name',
237
+ async (repo) => {
238
+ const record = credential();
239
+ await repo.createCredential(record);
240
+ await repo.renameCredential(record.credentialId, 'Renamed');
241
+ const got = await repo.getCredential(record.credentialId);
242
+ if (got?.name !== 'Renamed') {
243
+ fail('renameCredential changes the name', `name is ${JSON.stringify(got?.name)}`);
244
+ }
245
+ },
246
+ ],
247
+ ];
248
+ //# sourceMappingURL=passkey-repository.contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkey-repository.contract.js","sourceRoot":"","sources":["../../src/testing/passkey-repository.contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface PasskeyRelyingPartyConfig {
2
+ id: string | ((realm?: string) => string);
3
+ name: string | ((realm?: string) => string);
4
+ origins: string[] | ((realm?: string) => string[]);
5
+ }
6
+ export interface ResolvedRelyingPartyValues {
7
+ id: string;
8
+ name: string;
9
+ origins: string[];
10
+ }
11
+ export declare function resolveRelyingParty(config: PasskeyRelyingPartyConfig, realm?: string): ResolvedRelyingPartyValues;
12
+ export declare function assertUsableRelyingParty(rp: ResolvedRelyingPartyValues, realm?: string): void;
13
+ //# sourceMappingURL=passkey-rp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkey-rp.d.ts","sourceRoot":"","sources":["../../src/utils/passkey-rp.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,yBAAyB;IAExC,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAE1C,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAM5C,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAcD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,yBAAyB,EACjC,KAAK,CAAC,EAAE,MAAM,GACb,0BAA0B,CAQ5B;AAWD,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,0BAA0B,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CA+B7F"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveRelyingParty = resolveRelyingParty;
4
+ exports.assertUsableRelyingParty = assertUsableRelyingParty;
5
+ const net_1 = require("net");
6
+ const invalid_auth_config_exception_1 = require("../exceptions/invalid-auth-config.exception");
7
+ const ANDROID_ORIGIN = /^android:apk-key-hash:[A-Za-z0-9_-]{43}$/;
8
+ const LOOPBACK_HOSTS = new Set(['localhost', '127.0.0.1', '[::1]']);
9
+ function resolveRelyingParty(config, realm) {
10
+ const resolved = {
11
+ id: call(config.id, realm, 'passkey.rp.id'),
12
+ name: call(config.name, realm, 'passkey.rp.name'),
13
+ origins: call(config.origins, realm, 'passkey.rp.origins'),
14
+ };
15
+ assertUsableRelyingParty(resolved, realm);
16
+ return resolved;
17
+ }
18
+ function assertUsableRelyingParty(rp, realm) {
19
+ const where = realm === undefined ? '' : ` for realm "${realm}"`;
20
+ const id = rp.id;
21
+ if (typeof id !== 'string' || id === '' || id !== id.toLowerCase() || !/^[a-z0-9.-]+$/.test(id)) {
22
+ throw new invalid_auth_config_exception_1.InvalidAuthConfigException(`[AuthModule] passkey.rp.id${where} must be a lowercase domain such as 'example.com', ` +
23
+ `with no scheme, port or path; received ${JSON.stringify(id)}.`);
24
+ }
25
+ if ((0, net_1.isIP)(id) !== 0) {
26
+ throw new invalid_auth_config_exception_1.InvalidAuthConfigException(`[AuthModule] passkey.rp.id${where} must be a domain, not an IP address; received "${id}". ` +
27
+ "WebAuthn does not allow IP addresses. Use 'localhost' for local development.");
28
+ }
29
+ if (typeof rp.name !== 'string' || rp.name.trim() === '') {
30
+ throw new invalid_auth_config_exception_1.InvalidAuthConfigException(`[AuthModule] passkey.rp.name${where} must be a non-empty string, e.g. your product name.`);
31
+ }
32
+ if (!Array.isArray(rp.origins) || rp.origins.length === 0) {
33
+ throw new invalid_auth_config_exception_1.InvalidAuthConfigException(`[AuthModule] passkey.rp.origins${where} must list at least one origin, e.g. ` +
34
+ `['https://app.${id}'].`);
35
+ }
36
+ for (const origin of rp.origins) {
37
+ assertUsableOrigin(origin, id, where);
38
+ }
39
+ }
40
+ function assertUsableOrigin(origin, rpId, where) {
41
+ if (typeof origin !== 'string') {
42
+ throw new invalid_auth_config_exception_1.InvalidAuthConfigException(`[AuthModule] passkey.rp.origins${where} must contain strings; received ${JSON.stringify(origin)}.`);
43
+ }
44
+ if (origin.startsWith('android:')) {
45
+ if (!ANDROID_ORIGIN.test(origin)) {
46
+ throw new invalid_auth_config_exception_1.InvalidAuthConfigException(`[AuthModule] passkey.rp.origins${where} has a malformed Android origin "${origin}". ` +
47
+ "It must be 'android:apk-key-hash:' followed by the base64url (no padding) SHA-256 of " +
48
+ 'the app signing certificate: 43 characters. A colon-separated hex fingerprint, as ' +
49
+ 'keytool prints it, must be converted first.');
50
+ }
51
+ return;
52
+ }
53
+ let parsed;
54
+ try {
55
+ parsed = new URL(origin);
56
+ }
57
+ catch {
58
+ throw new invalid_auth_config_exception_1.InvalidAuthConfigException(`[AuthModule] passkey.rp.origins${where} has "${origin}", which is not an origin. ` +
59
+ "Use the scheme and host only, e.g. 'https://app.example.com'.");
60
+ }
61
+ if (parsed.origin !== origin) {
62
+ throw new invalid_auth_config_exception_1.InvalidAuthConfigException(`[AuthModule] passkey.rp.origins${where} has "${origin}", which is not exactly an origin ` +
63
+ `(did you mean "${parsed.origin}"?). Browsers send scheme, host and port only, with no ` +
64
+ 'path and no trailing slash, and the comparison is exact.');
65
+ }
66
+ const loopback = LOOPBACK_HOSTS.has(parsed.hostname);
67
+ if (parsed.protocol !== 'https:' && !(parsed.protocol === 'http:' && loopback)) {
68
+ throw new invalid_auth_config_exception_1.InvalidAuthConfigException(`[AuthModule] passkey.rp.origins${where} has "${origin}". WebAuthn requires https, except ` +
69
+ 'on localhost.');
70
+ }
71
+ const host = parsed.hostname;
72
+ if (host !== rpId && !host.endsWith(`.${rpId}`)) {
73
+ throw new invalid_auth_config_exception_1.InvalidAuthConfigException(`[AuthModule] passkey.rp.origins${where} has "${origin}", whose host is neither ` +
74
+ `passkey.rp.id ("${rpId}") nor a subdomain of it. Browsers refuse such a ceremony ` +
75
+ 'before it reaches the server.');
76
+ }
77
+ }
78
+ function call(value, realm, setting) {
79
+ if (typeof value !== 'function') {
80
+ return value;
81
+ }
82
+ try {
83
+ return value(realm);
84
+ }
85
+ catch (error) {
86
+ throw new invalid_auth_config_exception_1.InvalidAuthConfigException(`[AuthModule] ${setting} is a resolver that threw for realm ${JSON.stringify(realm)}: ${error instanceof Error ? error.message : String(error)}`);
87
+ }
88
+ }
89
+ //# sourceMappingURL=passkey-rp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkey-rp.js","sourceRoot":"","sources":["../../src/utils/passkey-rp.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@ambushsoftworks/nestjs-auth-graphql",
3
- "version": "0.15.1",
3
+ "version": "0.16.0-rc.2",
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",
7
7
  "files": [
8
8
  "dist",
9
+ "testing",
9
10
  "examples",
10
11
  "CHANGELOG.md",
11
12
  "README.md",
@@ -59,6 +60,7 @@
59
60
  "@nestjs/jwt": "^10.0.0 || ^11.0.0",
60
61
  "@nestjs/passport": "^10.0.0 || ^11.0.0",
61
62
  "@nestjs/throttler": "^6.0.0",
63
+ "@simplewebauthn/server": "^14.0.0",
62
64
  "graphql": "^16.0.0",
63
65
  "passport": "^0.7.0",
64
66
  "passport-jwt": "^4.0.0",
@@ -67,6 +69,9 @@
67
69
  "rxjs": "^7.0.0"
68
70
  },
69
71
  "peerDependenciesMeta": {
72
+ "@simplewebauthn/server": {
73
+ "optional": true
74
+ },
70
75
  "resend": {
71
76
  "optional": true
72
77
  }
@@ -90,6 +95,7 @@
90
95
  "@nestjs/platform-express": "^10.4.22",
91
96
  "@nestjs/testing": "^10.3.1",
92
97
  "@nestjs/throttler": "^6.4.0",
98
+ "@simplewebauthn/server": "^14.0.3",
93
99
  "@types/bcrypt": "^6.0.0",
94
100
  "@types/jest": "^29.5.11",
95
101
  "@types/node": "^20.11.5",
@@ -0,0 +1,5 @@
1
+ {
2
+ "//": "Resolves @ambushsoftworks/nestjs-auth-graphql/testing without an `exports` map, which would break existing deep imports into dist/.",
3
+ "main": "../dist/testing/index.js",
4
+ "types": "../dist/testing/index.d.ts"
5
+ }