@bitgo-beta/passkey-crypto 0.0.1-beta.8 → 0.0.1-beta.80

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 (59) hide show
  1. package/dist/src/attachPasskeyToWallet.d.ts +11 -0
  2. package/dist/src/attachPasskeyToWallet.d.ts.map +1 -0
  3. package/dist/src/attachPasskeyToWallet.js +63 -0
  4. package/dist/src/base64url.d.ts +16 -0
  5. package/dist/src/base64url.d.ts.map +1 -0
  6. package/dist/src/base64url.js +27 -0
  7. package/dist/src/deriveEnterpriseSalt.d.ts +7 -1
  8. package/dist/src/deriveEnterpriseSalt.d.ts.map +1 -1
  9. package/dist/src/deriveEnterpriseSalt.js +12 -42
  10. package/dist/src/derivePasskeyPrfKey.d.ts +15 -0
  11. package/dist/src/derivePasskeyPrfKey.d.ts.map +1 -0
  12. package/dist/src/derivePasskeyPrfKey.js +68 -0
  13. package/dist/src/index.d.ts +5 -0
  14. package/dist/src/index.d.ts.map +1 -1
  15. package/dist/src/index.js +12 -2
  16. package/dist/src/prfHelpers.d.ts.map +1 -1
  17. package/dist/src/prfHelpers.js +19 -4
  18. package/dist/src/registerPasskey.d.ts +10 -0
  19. package/dist/src/registerPasskey.d.ts.map +1 -0
  20. package/dist/src/registerPasskey.js +93 -0
  21. package/dist/src/removePasskeyFromAccount.d.ts +11 -0
  22. package/dist/src/removePasskeyFromAccount.d.ts.map +1 -0
  23. package/dist/src/removePasskeyFromAccount.js +15 -0
  24. package/dist/src/removePasskeyFromWallet.d.ts +10 -0
  25. package/dist/src/removePasskeyFromWallet.d.ts.map +1 -0
  26. package/dist/src/removePasskeyFromWallet.js +22 -0
  27. package/dist/test/integration/helpers/fixtures.d.ts +12 -0
  28. package/dist/test/integration/helpers/fixtures.d.ts.map +1 -0
  29. package/dist/test/integration/helpers/fixtures.js +15 -0
  30. package/dist/test/integration/helpers/mockBitGo.d.ts +27 -0
  31. package/dist/test/integration/helpers/mockBitGo.d.ts.map +1 -0
  32. package/dist/test/integration/helpers/mockBitGo.js +148 -0
  33. package/dist/test/integration/helpers/mockProvider.d.ts +5 -0
  34. package/dist/test/integration/helpers/mockProvider.d.ts.map +1 -0
  35. package/dist/test/integration/helpers/mockProvider.js +37 -0
  36. package/dist/test/integration/passkeyLifecycle.test.d.ts +2 -0
  37. package/dist/test/integration/passkeyLifecycle.test.d.ts.map +1 -0
  38. package/dist/test/integration/passkeyLifecycle.test.js +153 -0
  39. package/dist/test/unit/attachPasskeyToWallet.test.d.ts +2 -0
  40. package/dist/test/unit/attachPasskeyToWallet.test.d.ts.map +1 -0
  41. package/dist/test/unit/attachPasskeyToWallet.test.js +222 -0
  42. package/dist/test/unit/base64url.test.d.ts +2 -0
  43. package/dist/test/unit/base64url.test.d.ts.map +1 -0
  44. package/dist/test/unit/base64url.test.js +75 -0
  45. package/dist/test/unit/deriveEnterpriseSalt.test.js +8 -4
  46. package/dist/test/unit/derivePasskeyPrfKey.test.d.ts +2 -0
  47. package/dist/test/unit/derivePasskeyPrfKey.test.d.ts.map +1 -0
  48. package/dist/test/unit/derivePasskeyPrfKey.test.js +152 -0
  49. package/dist/test/unit/registerPasskey.test.d.ts +2 -0
  50. package/dist/test/unit/registerPasskey.test.d.ts.map +1 -0
  51. package/dist/test/unit/registerPasskey.test.js +155 -0
  52. package/dist/test/unit/removePasskeyFromAccount.test.d.ts +2 -0
  53. package/dist/test/unit/removePasskeyFromAccount.test.d.ts.map +1 -0
  54. package/dist/test/unit/removePasskeyFromAccount.test.js +88 -0
  55. package/dist/test/unit/removePasskeyFromWallet.test.d.ts +2 -0
  56. package/dist/test/unit/removePasskeyFromWallet.test.d.ts.map +1 -0
  57. package/dist/test/unit/removePasskeyFromWallet.test.js +170 -0
  58. package/dist/tsconfig.tsbuildinfo +1 -1
  59. package/package.json +7 -5
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const assert = __importStar(require("assert"));
37
+ const sinon = __importStar(require("sinon"));
38
+ const attachPasskeyToWallet_1 = require("../../src/attachPasskeyToWallet");
39
+ const derivePassword_1 = require("../../src/derivePassword");
40
+ describe('attachPasskeyToWallet', function () {
41
+ const coin = 'tbtc';
42
+ const walletId = 'wallet-abc123';
43
+ const keychainId = 'key-user-id';
44
+ const enterpriseId = 'enterprise-xyz';
45
+ const encryptedPrv = 'encrypted-prv-string';
46
+ const decryptedPrv = 'xprv-decrypted';
47
+ const existingPassphrase = 'correct-passphrase';
48
+ const reEncryptedPrv = 're-encrypted-prv';
49
+ const prfResultBuffer = new Uint8Array([0x1e, 0x5c, 0xb4, 0x78]).buffer;
50
+ const device = {
51
+ id: 'mongo-object-id-123',
52
+ credentialId: 'cred-id-456',
53
+ prfSalt: 'ZqJ64M2dL65zn2-Jxd58SMN2ILc9QjbCFxUTGHd_LC8',
54
+ isPasskey: true,
55
+ };
56
+ const mockAuthResult = {
57
+ prfResult: prfResultBuffer,
58
+ credentialId: 'cred-id-456',
59
+ otpCode: '123456',
60
+ };
61
+ const updatedKeychain = {
62
+ id: keychainId,
63
+ pub: 'xpub-123',
64
+ type: 'independent',
65
+ encryptedPrv,
66
+ };
67
+ let mockWallet;
68
+ let mockWallets;
69
+ let mockBaseCoin;
70
+ let mockBitGo;
71
+ let mockProvider;
72
+ beforeEach(function () {
73
+ mockWallet = {
74
+ type: sinon.stub().returns('hot'),
75
+ toJSON: sinon.stub().returns({ enterprise: enterpriseId }),
76
+ getEncryptedUserKeychain: sinon.stub().resolves({ id: keychainId, encryptedPrv }),
77
+ };
78
+ mockWallets = {
79
+ get: sinon.stub().resolves(mockWallet),
80
+ };
81
+ mockBaseCoin = {
82
+ wallets: sinon.stub().returns(mockWallets),
83
+ };
84
+ mockBitGo = {
85
+ url: sinon
86
+ .stub()
87
+ .callsFake((path, version) => `/api/v${version ?? 1}${path}`),
88
+ coin: sinon.stub().returns(mockBaseCoin),
89
+ put: sinon.stub(),
90
+ decryptAsync: sinon.stub(),
91
+ encryptAsync: sinon.stub(),
92
+ };
93
+ mockProvider = {
94
+ create: sinon.stub(),
95
+ get: sinon.stub(),
96
+ };
97
+ mockBitGo.decryptAsync.resolves(decryptedPrv);
98
+ mockBitGo.encryptAsync.resolves(reEncryptedPrv);
99
+ const putSendStub = sinon.stub().returns({ result: sinon.stub().resolves(updatedKeychain) });
100
+ mockBitGo.put.returns({ send: putSendStub });
101
+ mockProvider.get.resolves(mockAuthResult);
102
+ });
103
+ afterEach(function () {
104
+ sinon.restore();
105
+ });
106
+ async function callAttach(overrides) {
107
+ return (0, attachPasskeyToWallet_1.attachPasskeyToWallet)({
108
+ bitgo: mockBitGo,
109
+ coin,
110
+ walletId,
111
+ device,
112
+ existingPassphrase,
113
+ provider: mockProvider,
114
+ ...overrides,
115
+ });
116
+ }
117
+ it('should attach a passkey and return the updated keychain', async function () {
118
+ const result = await callAttach();
119
+ sinon.assert.calledWith(mockBitGo.coin, coin);
120
+ sinon.assert.calledWith(mockWallets.get, { id: walletId });
121
+ sinon.assert.calledOnce(mockWallet.type);
122
+ sinon.assert.calledOnce(mockWallet.getEncryptedUserKeychain);
123
+ sinon.assert.calledOnce(mockBitGo.decryptAsync);
124
+ sinon.assert.calledWithExactly(mockBitGo.decryptAsync, { password: existingPassphrase, input: encryptedPrv });
125
+ // provider.get called with evalByCredential keyed on device.credentialId
126
+ sinon.assert.calledOnce(mockProvider.get);
127
+ const getArgs = mockProvider.get.firstCall.args[0];
128
+ assert.ok(getArgs.evalByCredential);
129
+ assert.strictEqual(typeof getArgs.evalByCredential[device.credentialId], 'string');
130
+ // allowCredentials must be populated with the credential ID as an ArrayBuffer
131
+ assert.ok(Array.isArray(getArgs.publicKey.allowCredentials));
132
+ assert.strictEqual(getArgs.publicKey.allowCredentials.length, 1);
133
+ assert.strictEqual(getArgs.publicKey.allowCredentials[0].type, 'public-key');
134
+ assert.ok(getArgs.publicKey.allowCredentials[0].id instanceof ArrayBuffer);
135
+ // PUT called with correct shape
136
+ sinon.assert.calledOnce(mockBitGo.put);
137
+ sinon.assert.calledWith(mockBitGo.put, `/api/v2/${coin}/key/${keychainId}`);
138
+ const sendStub = mockBitGo.put.firstCall.returnValue.send;
139
+ sinon.assert.calledOnce(sendStub);
140
+ const putBody = sendStub.firstCall.args[0];
141
+ assert.ok(putBody.webauthnInfo);
142
+ assert.strictEqual(putBody.webauthnInfo.otpDeviceId, device.id);
143
+ // prfSalt must be base64url (URL-safe, no padding) as required by server validation
144
+ assert.match(putBody.webauthnInfo.prfSalt, /^[A-Za-z0-9\-_]+$/);
145
+ assert.strictEqual(typeof putBody.webauthnInfo.encryptedPrv, 'string');
146
+ // encryptAsync must be called with encryptionVersion 2
147
+ sinon.assert.calledOnce(mockBitGo.encryptAsync);
148
+ sinon.assert.calledWithMatch(mockBitGo.encryptAsync, { encryptionVersion: 2 });
149
+ assert.strictEqual(result.id, keychainId);
150
+ });
151
+ it('should re-encrypt the private key as a v2 Argon2id envelope', async function () {
152
+ const expectedPrfPassword = (0, derivePassword_1.derivePassword)(prfResultBuffer);
153
+ await callAttach();
154
+ // The PRF-derived password and the decrypted xprv must be passed to encryptAsync
155
+ sinon.assert.calledWithMatch(mockBitGo.encryptAsync, {
156
+ password: expectedPrfPassword,
157
+ input: decryptedPrv,
158
+ encryptionVersion: 2,
159
+ });
160
+ // The v2 blob returned by encryptAsync is what gets stored on the server
161
+ const putBody = mockBitGo.put.firstCall.returnValue.send.firstCall.args[0];
162
+ assert.strictEqual(putBody.webauthnInfo.encryptedPrv, reEncryptedPrv);
163
+ });
164
+ it('should decode credentialId containing base64url-specific characters (- and _)', async function () {
165
+ const deviceWithUrlChars = {
166
+ ...device,
167
+ credentialId: 'abc-def_ghi+jkl',
168
+ };
169
+ const result = await callAttach({ device: deviceWithUrlChars });
170
+ assert.ok(result);
171
+ const getArgs = mockProvider.get.firstCall.args[0];
172
+ assert.ok(getArgs.publicKey.allowCredentials[0].id instanceof ArrayBuffer);
173
+ });
174
+ it('should throw if device.prfSalt is undefined', async function () {
175
+ const deviceNoPrf = { ...device, prfSalt: undefined };
176
+ await assert.rejects(() => callAttach({ device: deviceNoPrf }), (err) => {
177
+ assert.strictEqual(err.message, 'PRF extension not supported by this device. Please use a different passkey.');
178
+ return true;
179
+ });
180
+ sinon.assert.notCalled(mockBitGo.coin);
181
+ sinon.assert.notCalled(mockBitGo.put);
182
+ });
183
+ it('should throw if wallet is not a hot wallet', async function () {
184
+ mockWallet.type.returns('cold');
185
+ await assert.rejects(() => callAttach(), (err) => {
186
+ assert.ok(err.message.includes('not a hot wallet'));
187
+ return true;
188
+ });
189
+ sinon.assert.notCalled(mockBitGo.put);
190
+ });
191
+ it('should throw if wallet has no enterprise', async function () {
192
+ mockWallet.toJSON.returns({ enterprise: undefined });
193
+ await assert.rejects(() => callAttach(), (err) => {
194
+ assert.ok(err.message.includes('has no enterprise'));
195
+ return true;
196
+ });
197
+ });
198
+ it('should throw if PRF assertion returns no result', async function () {
199
+ mockProvider.get.resolves({ ...mockAuthResult, prfResult: undefined });
200
+ await assert.rejects(() => callAttach(), (err) => {
201
+ assert.ok(err.message.includes('PRF assertion did not return a result'));
202
+ return true;
203
+ });
204
+ sinon.assert.notCalled(mockBitGo.put);
205
+ });
206
+ it('should propagate decrypt errors', async function () {
207
+ mockBitGo.decryptAsync.rejects(new Error('decryption failed'));
208
+ await assert.rejects(() => callAttach(), (err) => {
209
+ assert.ok(err.message.includes('decryption failed'));
210
+ return true;
211
+ });
212
+ sinon.assert.notCalled(mockBitGo.put);
213
+ });
214
+ it('should use device.credentialId as the key in evalByCredential', async function () {
215
+ await callAttach();
216
+ const getArgs = mockProvider.get.firstCall.args[0];
217
+ const evalKeys = Object.keys(getArgs.evalByCredential);
218
+ assert.strictEqual(evalKeys.length, 1);
219
+ assert.strictEqual(evalKeys[0], device.credentialId);
220
+ });
221
+ });
222
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0YWNoUGFzc2tleVRvV2FsbGV0LnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvYXR0YWNoUGFzc2tleVRvV2FsbGV0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQ0FBaUM7QUFDakMsNkNBQStCO0FBQy9CLDJFQUF3RTtBQUN4RSw2REFBMEQ7QUFHMUQsUUFBUSxDQUFDLHVCQUF1QixFQUFFO0lBQ2hDLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQztJQUNwQixNQUFNLFFBQVEsR0FBRyxlQUFlLENBQUM7SUFDakMsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDO0lBQ2pDLE1BQU0sWUFBWSxHQUFHLGdCQUFnQixDQUFDO0lBQ3RDLE1BQU0sWUFBWSxHQUFHLHNCQUFzQixDQUFDO0lBQzVDLE1BQU0sWUFBWSxHQUFHLGdCQUFnQixDQUFDO0lBQ3RDLE1BQU0sa0JBQWtCLEdBQUcsb0JBQW9CLENBQUM7SUFDaEQsTUFBTSxjQUFjLEdBQUcsa0JBQWtCLENBQUM7SUFFMUMsTUFBTSxlQUFlLEdBQUcsSUFBSSxVQUFVLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUV4RSxNQUFNLE1BQU0sR0FBc0I7UUFDaEMsRUFBRSxFQUFFLHFCQUFxQjtRQUN6QixZQUFZLEVBQUUsYUFBYTtRQUMzQixPQUFPLEVBQUUsNkNBQTZDO1FBQ3RELFNBQVMsRUFBRSxJQUFJO0tBQ2hCLENBQUM7SUFFRixNQUFNLGNBQWMsR0FBc0I7UUFDeEMsU0FBUyxFQUFFLGVBQWU7UUFDMUIsWUFBWSxFQUFFLGFBQWE7UUFDM0IsT0FBTyxFQUFFLFFBQVE7S0FDbEIsQ0FBQztJQUVGLE1BQU0sZUFBZSxHQUFHO1FBQ3RCLEVBQUUsRUFBRSxVQUFVO1FBQ2QsR0FBRyxFQUFF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TUFBTSxDQUFDLE9BQU8sQ0FDbEIsR0FBRyxFQUFFLENBQUMsVUFBVSxFQUFFLEVBQ2xCLENBQUMsR0FBVSxFQUFFLEVBQUU7WUFDYixNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztZQUNyRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUMsQ0FDRixDQUFDO1FBRUYsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3hDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLCtEQUErRCxFQUFFLEtBQUs7UUFDdkUsTUFBTSxVQUFVLEVBQUUsQ0FBQztRQUVuQixNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkQsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUN2RCxNQUFNLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDdkMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3ZELENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCB7IGF0dGFjaFBhc3NrZXlUb1dhbGxldCB9IGZyb20gJy4uLy4uL3NyYy9hdHRhY2hQYXNza2V5VG9XYWxsZXQnO1xuaW1wb3J0IHsgZGVyaXZlUGFzc3dvcmQgfSBmcm9tICcuLi8uLi9zcmMvZGVyaXZlUGFzc3dvcmQnO1xuaW1wb3J0IHsgV2ViQXV0aG5PdHBEZXZpY2UsIFBhc3NrZXlBdXRoUmVzdWx0LCBXZWJBdXRoblByb3ZpZGVyIH0gZnJvbSAnLi4vLi4vc3JjL3dlYkF1dGhuVHlwZXMnO1xuXG5kZXNjcmliZSgnYXR0YWNoUGFzc2tleVRvV2FsbGV0JywgZnVuY3Rpb24gKCkge1xuICBjb25zdCBjb2luID0gJ3RidGMnO1xuICBjb25zdCB3YWxsZXRJZCA9ICd3YWxsZXQtYWJjMTIzJztcbiAgY29uc3Qga2V5Y2hhaW5JZCA9ICdrZXktdXNlci1pZCc7XG4gIGNvbnN0IGVudGVycHJpc2VJZCA9ICdlbnRlcnByaXNlLXh5eic7XG4gIGNvbnN0IGVuY3J5cHRlZFBydiA9ICdlbmNyeXB0ZWQtcHJ2LXN0cmluZyc7XG4gIGNvbnN0IGRlY3J5cHRlZFBydiA9ICd4cHJ2LWRlY3J5cHRlZCc7XG4gIGNvbnN0IGV4aXN0aW5nUGFzc3BocmFzZSA9ICdjb3JyZWN0LXBhc3NwaHJhc2UnO1xuICBjb25zdCByZUVuY3J5cHRlZFBydiA9ICdyZS1lbmNyeXB0ZWQtcHJ2JztcblxuICBjb25zdCBwcmZSZXN1bHRCdWZmZXIgPSBuZXcgVWludDhBcnJheShbMHgxZSwgMHg1YywgMHhiNCwgMHg3OF0pLmJ1ZmZlcjtcblxuICBjb25zdCBkZXZpY2U6IFdlYkF1dGhuT3RwRGV2aWNlID0ge1xuICAgIGlkOiAnbW9uZ28tb2JqZWN0LWlkLTEyMycsXG4gICAgY3JlZGVudGlhbElkOiAnY3JlZC1pZC00NTYnLFxuICAgIHByZlNhbHQ6ICdacUo2NE0yZEw2NXpuMi1KeGQ1OFNNTjJJTGM5UWpiQ0Z4VVRHSGRfTEM4JyxcbiAgICBpc1Bhc3NrZXk6IHRydWUsXG4gIH07XG5cbiAgY29uc3QgbW9ja0F1dGhSZXN1bHQ6IFBhc3NrZXlBdXRoUmVzdWx0ID0ge1xuICAgIHByZlJlc3VsdDogcHJmUmVzdWx0QnVmZmVyLFxuICAgIGNyZWRlbnRpYWxJZDogJ2NyZWQtaWQtNDU2JyxcbiAgICBvdHBDb2RlOiAnMTIzNDU2JyxcbiAgfTtcblxuICBjb25zdCB1cGRhdGVkS2V5Y2hhaW4gPSB7XG4gICAgaWQ6IGtleWNoYWluSWQsXG4gICAgcHViOiAneHB1Yi0xMjMnLFxuICAgIHR5cGU6ICdpbmRlcGVuZGVudCcgYXMgY29uc3QsXG4gICAgZW5jcnlwdGVkUHJ2LFxuICB9O1xuXG4gIGxldCBtb2NrV2FsbGV0OiB7XG4gICAgdHlwZTogc2lub24uU2lub25TdHViO1xuICAgIHRvSlNPTjogc2lub24uU2lub25TdHViO1xuICAgIGdldEVuY3J5cHRlZFVzZXJLZXljaGFpbjogc2lub24uU2lub25TdHViO1xuICB9O1xuXG4gIGxldCBtb2NrV2FsbGV0czoge1xuICAgIGdldDogc2lub24uU2lub25TdHViO1xuICB9O1xuXG4gIGxldCBtb2NrQmFzZUNvaW46IHtcbiAgICB3YWxsZXRzOiBzaW5vbi5TaW5vblN0dWI7XG4gIH07XG5cbiAgbGV0IG1vY2tCaXRHbzoge1xuICAgIHVybDogc2lub24uU2lub25TdHViO1xuICAgIGNvaW46IHNpbm9uLlNpbm9uU3R1YjtcbiAgICBwdXQ6IHNpbm9uLlNpbm9uU3R1YjtcbiAgICBkZWNyeXB0QXN5bmM6IHNpbm9uLlNpbm9uU3R1YjtcbiAgICBlbmNyeXB0QXN5bmM6IHNpbm9uLlNpbm9uU3R1YjtcbiAgfTtcblxuICBsZXQgbW9ja1Byb3ZpZGVyOiB7XG4gICAgY3JlYXRlOiBzaW5vbi5TaW5vblN0dWI7XG4gICAgZ2V0OiBzaW5vbi5TaW5vblN0dWI7XG4gIH07XG5cbiAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgbW9ja1dhbGxldCA9IHtcbiAgICAgIHR5cGU6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdob3QnKSxcbiAgICAgIHRvSlNPTjogc2lub24uc3R1YigpLnJldHVybnMoeyBlbnRlcnByaXNlOiBlbnRlcnByaXNlSWQgfSksXG4gICAgICBnZXRFbmNyeXB0ZWRVc2VyS2V5Y2hhaW46IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7IGlkOiBrZXljaGFpbklkLCBlbmNyeXB0ZWRQcnYgfSksXG4gICAgfTtcblxuICAgIG1vY2tXYWxsZXRzID0ge1xuICAgICAgZ2V0OiBzaW5vbi5zdHViKCkucmVzb2x2ZXMobW9ja1dhbGxldCksXG4gICAgfTtcblxuICAgIG1vY2tCYXNlQ29pbiA9IHtcbiAgICAgIHdhbGxldHM6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKG1vY2tXYWxsZXRzKSxcbiAgICB9O1xuXG4gICAgbW9ja0JpdEdvID0ge1xuICAgICAgdXJsOiBzaW5vblxuICAgICAgICAuc3R1YjxbcGF0aDogc3RyaW5nLCB2ZXJzaW9uPzogbnVtYmVyXSwgc3RyaW5nPigpXG4gICAgICAgIC5jYWxsc0Zha2UoKHBhdGgsIHZlcnNpb24pID0+IGAvYXBpL3Yke3ZlcnNpb24gPz8gMX0ke3BhdGh9YCksXG4gICAgICBjb2luOiBzaW5vbi5zdHViKCkucmV0dXJucyhtb2NrQmFzZUNvaW4pLFxuICAgICAgcHV0OiBzaW5vbi5zdHViKCksXG4gICAgICBkZWNyeXB0QXN5bmM6IHNpbm9uLnN0dWIoKSxcbiAgICAgIGVuY3J5cHRBc3luYzogc2lub24uc3R1YigpLFxuICAgIH07XG5cbiAgICBtb2NrUHJvdmlkZXIgPSB7XG4gICAgICBjcmVhdGU6IHNpbm9uLnN0dWIoKSxcbiAgICAgIGdldDogc2lub24uc3R1YigpLFxuICAgIH07XG5cbiAgICBtb2NrQml0R28uZGVjcnlwdEFzeW5jLnJlc29sdmVzKGRlY3J5cHRlZFBydik7XG4gICAgbW9ja0JpdEdvLmVuY3J5cHRBc3luYy5yZXNvbHZlcyhyZUVuY3J5cHRlZFBydik7XG5cbiAgICBjb25zdCBwdXRTZW5kU3R1YiA9IHNpbm9uLnN0dWIoKS5yZXR1cm5zKHsgcmVzdWx0OiBzaW5vbi5zdHViKCkucmVzb2x2ZXModXBkYXRlZEtleWNoYWluKSB9KTtcbiAgICBtb2NrQml0R28ucHV0LnJldHVybnMoeyBzZW5kOiBwdXRTZW5kU3R1YiB9KTtcblxuICAgIG1vY2tQcm92aWRlci5nZXQucmVzb2x2ZXMobW9ja0F1dGhSZXN1bHQpO1xuICB9KTtcblxuICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgYXN5bmMgZnVuY3Rpb24gY2FsbEF0dGFjaChvdmVycmlkZXM/OiBQYXJ0aWFsPFBhcmFtZXRlcnM8dHlwZW9mIGF0dGFjaFBhc3NrZXlUb1dhbGxldD5bMF0+KSB7XG4gICAgcmV0dXJuIGF0dGFjaFBhc3NrZXlUb1dhbGxldCh7XG4gICAgICBiaXRnbzogbW9ja0JpdEdvIGFzIHVua25vd24gYXMgUGFyYW1ldGVyczx0eXBlb2YgYXR0YWNoUGFzc2tleVRvV2FsbGV0PlswXVsnYml0Z28nXSxcbiAgICAgIGNvaW4sXG4gICAgICB3YWxsZXRJZCxcbiAgICAgIGRldmljZSxcbiAgICAgIGV4aXN0aW5nUGFzc3BocmFzZSxcbiAgICAgIHByb3ZpZGVyOiBtb2NrUHJvdmlkZXIgYXMgdW5rbm93biBhcyBXZWJBdXRoblByb3ZpZGVyLFxuICAgICAgLi4ub3ZlcnJpZGVzLFxuICAgIH0pO1xuICB9XG5cbiAgaXQoJ3Nob3VsZCBhdHRhY2ggYSBwYXNza2V5IGFuZCByZXR1cm4gdGhlIHVwZGF0ZWQga2V5Y2hhaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY2FsbEF0dGFjaCgpO1xuXG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGgobW9ja0JpdEdvLmNvaW4sIGNvaW4pO1xuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRXaXRoKG1vY2tXYWxsZXRzLmdldCwgeyBpZDogd2FsbGV0SWQgfSk7XG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2UobW9ja1dhbGxldC50eXBlKTtcbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShtb2NrV2FsbGV0LmdldEVuY3J5cHRlZFVzZXJLZXljaGFpbik7XG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2UobW9ja0JpdEdvLmRlY3J5cHRBc3luYyk7XG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGhFeGFjdGx5KG1vY2tCaXRHby5kZWNyeXB0QXN5bmMsIHsgcGFzc3dvcmQ6IGV4aXN0aW5nUGFzc3BocmFzZSwgaW5wdXQ6IGVuY3J5cHRlZFBydiB9KTtcblxuICAgIC8vIHByb3ZpZGVyLmdldCBjYWxsZWQgd2l0aCBldmFsQnlDcmVkZW50aWFsIGtleWVkIG9uIGRldmljZS5jcmVkZW50aWFsSWRcbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShtb2NrUHJvdmlkZXIuZ2V0KTtcbiAgICBjb25zdCBnZXRBcmdzID0gbW9ja1Byb3ZpZGVyLmdldC5maXJzdENhbGwuYXJnc1swXTtcbiAgICBhc3NlcnQub2soZ2V0QXJncy5ldmFsQnlDcmVkZW50aWFsKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHlwZW9mIGdldEFyZ3MuZXZhbEJ5Q3JlZGVudGlhbFtkZXZpY2UuY3JlZGVudGlhbElkXSwgJ3N0cmluZycpO1xuXG4gICAgLy8gYWxsb3dDcmVkZW50aWFscyBtdXN0IGJlIHBvcHVsYXRlZCB3aXRoIHRoZSBjcmVkZW50aWFsIElEIGFzIGFuIEFycmF5QnVmZmVyXG4gICAgYXNzZXJ0Lm9rKEFycmF5LmlzQXJyYXkoZ2V0QXJncy5wdWJsaWNLZXkuYWxsb3dDcmVkZW50aWFscykpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChnZXRBcmdzLnB1YmxpY0tleS5hbGxvd0NyZWRlbnRpYWxzLmxlbmd0aCwgMSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGdldEFyZ3MucHVibGljS2V5LmFsbG93Q3JlZGVudGlhbHNbMF0udHlwZSwgJ3B1YmxpYy1rZXknKTtcbiAgICBhc3NlcnQub2soZ2V0QXJncy5wdWJsaWNLZXkuYWxsb3dDcmVkZW50aWFsc1swXS5pZCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKTtcblxuICAgIC8vIFBVVCBjYWxsZWQgd2l0aCBjb3JyZWN0IHNoYXBlXG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2UobW9ja0JpdEdvLnB1dCk7XG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGgobW9ja0JpdEdvLnB1dCwgYC9hcGkvdjIvJHtjb2lufS9rZXkvJHtrZXljaGFpbklkfWApO1xuICAgIGNvbnN0IHNlbmRTdHViID0gbW9ja0JpdEdvLnB1dC5maXJzdENhbGwucmV0dXJuVmFsdWUuc2VuZDtcbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShzZW5kU3R1Yik7XG4gICAgY29uc3QgcHV0Qm9keSA9IHNlbmRTdHViLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgIGFzc2VydC5vayhwdXRCb2R5LndlYmF1dGhuSW5mbyk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHB1dEJvZHkud2ViYXV0aG5JbmZvLm90cERldmljZUlkLCBkZXZpY2UuaWQpO1xuICAgIC8vIHByZlNhbHQgbXVzdCBiZSBiYXNlNjR1cmwgKFVSTC1zYWZlLCBubyBwYWRkaW5nKSBhcyByZXF1aXJlZCBieSBzZXJ2ZXIgdmFsaWRhdGlvblxuICAgIGFzc2VydC5tYXRjaChwdXRCb2R5LndlYmF1dGhuSW5mby5wcmZTYWx0LCAvXltBLVphLXowLTlcXC1fXSskLyk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR5cGVvZiBwdXRCb2R5LndlYmF1dGhuSW5mby5lbmNyeXB0ZWRQcnYsICdzdHJpbmcnKTtcblxuICAgIC8vIGVuY3J5cHRBc3luYyBtdXN0IGJlIGNhbGxlZCB3aXRoIGVuY3J5cHRpb25WZXJzaW9uIDJcbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShtb2NrQml0R28uZW5jcnlwdEFzeW5jKTtcbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkV2l0aE1hdGNoKG1vY2tCaXRHby5lbmNyeXB0QXN5bmMsIHsgZW5jcnlwdGlvblZlcnNpb246IDIgfSk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LmlkLCBrZXljaGFpbklkKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZS1lbmNyeXB0IHRoZSBwcml2YXRlIGtleSBhcyBhIHYyIEFyZ29uMmlkIGVudmVsb3BlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGV4cGVjdGVkUHJmUGFzc3dvcmQgPSBkZXJpdmVQYXNzd29yZChwcmZSZXN1bHRCdWZmZXIpO1xuXG4gICAgYXdhaXQgY2FsbEF0dGFjaCgpO1xuXG4gICAgLy8gVGhlIFBSRi1kZXJpdmVkIHBhc3N3b3JkIGFuZCB0aGUgZGVjcnlwdGVkIHhwcnYgbXVzdCBiZSBwYXNzZWQgdG8gZW5jcnlwdEFzeW5jXG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGhNYXRjaChtb2NrQml0R28uZW5jcnlwdEFzeW5jLCB7XG4gICAgICBwYXNzd29yZDogZXhwZWN0ZWRQcmZQYXNzd29yZCxcbiAgICAgIGlucHV0OiBkZWNyeXB0ZWRQcnYsXG4gICAgICBlbmNyeXB0aW9uVmVyc2lvbjogMixcbiAgICB9KTtcblxuICAgIC8vIFRoZSB2MiBibG9iIHJldHVybmVkIGJ5IGVuY3J5cHRBc3luYyBpcyB3aGF0IGdldHMgc3RvcmVkIG9uIHRoZSBzZXJ2ZXJcbiAgICBjb25zdCBwdXRCb2R5ID0gbW9ja0JpdEdvLnB1dC5maXJzdENhbGwucmV0dXJuVmFsdWUuc2VuZC5maXJzdENhbGwuYXJnc1swXTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHV0Qm9keS53ZWJhdXRobkluZm8uZW5jcnlwdGVkUHJ2LCByZUVuY3J5cHRlZFBydik7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgZGVjb2RlIGNyZWRlbnRpYWxJZCBjb250YWluaW5nIGJhc2U2NHVybC1zcGVjaWZpYyBjaGFyYWN0ZXJzICgtIGFuZCBfKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBkZXZpY2VXaXRoVXJsQ2hhcnM6IFdlYkF1dGhuT3RwRGV2aWNlID0ge1xuICAgICAgLi4uZGV2aWNlLFxuICAgICAgY3JlZGVudGlhbElkOiAnYWJjLWRlZl9naGkramtsJyxcbiAgICB9O1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY2FsbEF0dGFjaCh7IGRldmljZTogZGV2aWNlV2l0aFVybENoYXJzIH0pO1xuICAgIGFzc2VydC5vayhyZXN1bHQpO1xuXG4gICAgY29uc3QgZ2V0QXJncyA9IG1vY2tQcm92aWRlci5nZXQuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgYXNzZXJ0Lm9rKGdldEFyZ3MucHVibGljS2V5LmFsbG93Q3JlZGVudGlhbHNbMF0uaWQgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcik7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdGhyb3cgaWYgZGV2aWNlLnByZlNhbHQgaXMgdW5kZWZpbmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGRldmljZU5vUHJmOiBXZWJBdXRobk90cERldmljZSA9IHsgLi4uZGV2aWNlLCBwcmZTYWx0OiB1bmRlZmluZWQgfTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT4gY2FsbEF0dGFjaCh7IGRldmljZTogZGV2aWNlTm9QcmYgfSksXG4gICAgICAoZXJyOiBFcnJvcikgPT4ge1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXJyLm1lc3NhZ2UsICdQUkYgZXh0ZW5zaW9uIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBkZXZpY2UuIFBsZWFzZSB1c2UgYSBkaWZmZXJlbnQgcGFzc2tleS4nKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgKTtcblxuICAgIHNpbm9uLmFzc2VydC5ub3RDYWxsZWQobW9ja0JpdEdvLmNvaW4pO1xuICAgIHNpbm9uLmFzc2VydC5ub3RDYWxsZWQobW9ja0JpdEdvLnB1dCk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdGhyb3cgaWYgd2FsbGV0IGlzIG5vdCBhIGhvdCB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgbW9ja1dhbGxldC50eXBlLnJldHVybnMoJ2NvbGQnKTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT4gY2FsbEF0dGFjaCgpLFxuICAgICAgKGVycjogRXJyb3IpID0+IHtcbiAgICAgICAgYXNzZXJ0Lm9rKGVyci5tZXNzYWdlLmluY2x1ZGVzKCdub3QgYSBob3Qgd2FsbGV0JykpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgc2lub24uYXNzZXJ0Lm5vdENhbGxlZChtb2NrQml0R28ucHV0KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyBpZiB3YWxsZXQgaGFzIG5vIGVudGVycHJpc2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgbW9ja1dhbGxldC50b0pTT04ucmV0dXJucyh7IGVudGVycHJpc2U6IHVuZGVmaW5lZCB9KTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT4gY2FsbEF0dGFjaCgpLFxuICAgICAgKGVycjogRXJyb3IpID0+IHtcbiAgICAgICAgYXNzZXJ0Lm9rKGVyci5tZXNzYWdlLmluY2x1ZGVzKCdoYXMgbm8gZW50ZXJwcmlzZScpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBQUkYgYXNzZXJ0aW9uIHJldHVybnMgbm8gcmVzdWx0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIG1vY2tQcm92aWRlci5nZXQucmVzb2x2ZXMoeyAuLi5tb2NrQXV0aFJlc3VsdCwgcHJmUmVzdWx0OiB1bmRlZmluZWQgfSk7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+IGNhbGxBdHRhY2goKSxcbiAgICAgIChlcnI6IEVycm9yKSA9PiB7XG4gICAgICAgIGFzc2VydC5vayhlcnIubWVzc2FnZS5pbmNsdWRlcygnUFJGIGFzc2VydGlvbiBkaWQgbm90IHJldHVybiBhIHJlc3VsdCcpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgKTtcblxuICAgIHNpbm9uLmFzc2VydC5ub3RDYWxsZWQobW9ja0JpdEdvLnB1dCk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcHJvcGFnYXRlIGRlY3J5cHQgZXJyb3JzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIG1vY2tCaXRHby5kZWNyeXB0QXN5bmMucmVqZWN0cyhuZXcgRXJyb3IoJ2RlY3J5cHRpb24gZmFpbGVkJykpO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PiBjYWxsQXR0YWNoKCksXG4gICAgICAoZXJyOiBFcnJvcikgPT4ge1xuICAgICAgICBhc3NlcnQub2soZXJyLm1lc3NhZ2UuaW5jbHVkZXMoJ2RlY3J5cHRpb24gZmFpbGVkJykpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgc2lub24uYXNzZXJ0Lm5vdENhbGxlZChtb2NrQml0R28ucHV0KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB1c2UgZGV2aWNlLmNyZWRlbnRpYWxJZCBhcyB0aGUga2V5IGluIGV2YWxCeUNyZWRlbnRpYWwnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgYXdhaXQgY2FsbEF0dGFjaCgpO1xuXG4gICAgY29uc3QgZ2V0QXJncyA9IG1vY2tQcm92aWRlci5nZXQuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgY29uc3QgZXZhbEtleXMgPSBPYmplY3Qua2V5cyhnZXRBcmdzLmV2YWxCeUNyZWRlbnRpYWwpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChldmFsS2V5cy5sZW5ndGgsIDEpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChldmFsS2V5c1swXSwgZGV2aWNlLmNyZWRlbnRpYWxJZCk7XG4gIH0pO1xufSk7XG4iXX0=
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=base64url.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base64url.test.d.ts","sourceRoot":"","sources":["../../../test/unit/base64url.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const assert = __importStar(require("assert"));
37
+ const base64url_1 = require("../../src/base64url");
38
+ describe('base64url helpers', function () {
39
+ describe('toBase64Url', function () {
40
+ it('replaces +, / and strips padding', function () {
41
+ assert.strictEqual((0, base64url_1.toBase64Url)('a+b/c=='), 'a-b_c');
42
+ });
43
+ it('is a no-op on already-base64url input', function () {
44
+ assert.strictEqual((0, base64url_1.toBase64Url)('a-b_c'), 'a-b_c');
45
+ });
46
+ it('handles empty string', function () {
47
+ assert.strictEqual((0, base64url_1.toBase64Url)(''), '');
48
+ });
49
+ });
50
+ describe('bufferToBase64Url', function () {
51
+ it('encodes a Buffer to unpadded base64url', function () {
52
+ // bytes that produce + and / in standard base64
53
+ const buf = Buffer.from([0xfb, 0xff, 0xbf]);
54
+ assert.strictEqual(buf.toString('base64'), '+/+/');
55
+ assert.strictEqual((0, base64url_1.bufferToBase64Url)(buf), '-_-_');
56
+ });
57
+ it('encodes an ArrayBuffer to unpadded base64url', function () {
58
+ const ab = new Uint8Array([0xff, 0xfe, 0xfd]).buffer;
59
+ assert.strictEqual((0, base64url_1.bufferToBase64Url)(ab), '__79');
60
+ });
61
+ });
62
+ describe('base64UrlToBuffer', function () {
63
+ it('round-trips through bufferToBase64Url', function () {
64
+ const original = Buffer.from([0x00, 0xff, 0x10, 0x20, 0xab, 0xcd]);
65
+ const encoded = (0, base64url_1.bufferToBase64Url)(original);
66
+ const decoded = (0, base64url_1.base64UrlToBuffer)(encoded);
67
+ assert.deepStrictEqual(decoded, original);
68
+ });
69
+ it('decodes base64url with - and _ chars', function () {
70
+ const decoded = (0, base64url_1.base64UrlToBuffer)('-_-_');
71
+ assert.deepStrictEqual(decoded, Buffer.from([0xfb, 0xff, 0xbf]));
72
+ });
73
+ });
74
+ });
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZTY0dXJsLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvYmFzZTY0dXJsLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQ0FBaUM7QUFDakMsbURBQXdGO0FBRXhGLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRTtJQUM1QixRQUFRLENBQUMsYUFBYSxFQUFFO1FBQ3RCLEVBQUUsQ0FBQyxrQ0FBa0MsRUFBRTtZQUNyQyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUEsdUJBQVcsRUFBQyxTQUFTLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN0RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRTtZQUMxQyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUEsdUJBQVcsRUFBQyxPQUFPLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNwRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzQkFBc0IsRUFBRTtZQUN6QixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUEsdUJBQVcsRUFBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUMxQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLG1CQUFtQixFQUFFO1FBQzVCLEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRTtZQUMzQyxnREFBZ0Q7WUFDaEQsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUM1QyxNQUFNLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDbkQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFBLDZCQUFpQixFQUFDLEdBQUcsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3JELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lBQ2pELE1BQU0sRUFBRSxHQUFHLElBQUksVUFBVSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztZQUNyRCxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUEsNkJBQWlCLEVBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDcEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxtQkFBbUIsRUFBRTtRQUM1QixFQUFFLENBQUMsdUNBQXVDLEVBQUU7WUFDMUMsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNuRSxNQUFNLE9BQU8sR0FBRyxJQUFBLDZCQUFpQixFQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzVDLE1BQU0sT0FBTyxHQUFHLElBQUEsNkJBQWlCLEVBQUMsT0FBTyxDQUFDLENBQUM7WUFDM0MsTUFBTSxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsc0NBQXNDLEVBQUU7WUFDekMsTUFBTSxPQUFPLEdBQUcsSUFBQSw2QkFBaUIsRUFBQyxNQUFNLENBQUMsQ0FBQztZQUMxQyxNQUFNLENBQUMsZUFBZSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgeyBiYXNlNjRVcmxUb0J1ZmZlciwgYnVmZmVyVG9CYXNlNjRVcmwsIHRvQmFzZTY0VXJsIH0gZnJvbSAnLi4vLi4vc3JjL2Jhc2U2NHVybCc7XG5cbmRlc2NyaWJlKCdiYXNlNjR1cmwgaGVscGVycycsIGZ1bmN0aW9uICgpIHtcbiAgZGVzY3JpYmUoJ3RvQmFzZTY0VXJsJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdyZXBsYWNlcyArLCAvIGFuZCBzdHJpcHMgcGFkZGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0b0Jhc2U2NFVybCgnYStiL2M9PScpLCAnYS1iX2MnKTtcbiAgICB9KTtcblxuICAgIGl0KCdpcyBhIG5vLW9wIG9uIGFscmVhZHktYmFzZTY0dXJsIGlucHV0JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRvQmFzZTY0VXJsKCdhLWJfYycpLCAnYS1iX2MnKTtcbiAgICB9KTtcblxuICAgIGl0KCdoYW5kbGVzIGVtcHR5IHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0b0Jhc2U2NFVybCgnJyksICcnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2J1ZmZlclRvQmFzZTY0VXJsJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdlbmNvZGVzIGEgQnVmZmVyIHRvIHVucGFkZGVkIGJhc2U2NHVybCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGJ5dGVzIHRoYXQgcHJvZHVjZSArIGFuZCAvIGluIHN0YW5kYXJkIGJhc2U2NFxuICAgICAgY29uc3QgYnVmID0gQnVmZmVyLmZyb20oWzB4ZmIsIDB4ZmYsIDB4YmZdKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChidWYudG9TdHJpbmcoJ2Jhc2U2NCcpLCAnKy8rLycpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJ1ZmZlclRvQmFzZTY0VXJsKGJ1ZiksICctXy1fJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnZW5jb2RlcyBhbiBBcnJheUJ1ZmZlciB0byB1bnBhZGRlZCBiYXNlNjR1cmwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhYiA9IG5ldyBVaW50OEFycmF5KFsweGZmLCAweGZlLCAweGZkXSkuYnVmZmVyO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJ1ZmZlclRvQmFzZTY0VXJsKGFiKSwgJ19fNzknKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2Jhc2U2NFVybFRvQnVmZmVyJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdyb3VuZC10cmlwcyB0aHJvdWdoIGJ1ZmZlclRvQmFzZTY0VXJsJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgb3JpZ2luYWwgPSBCdWZmZXIuZnJvbShbMHgwMCwgMHhmZiwgMHgxMCwgMHgyMCwgMHhhYiwgMHhjZF0pO1xuICAgICAgY29uc3QgZW5jb2RlZCA9IGJ1ZmZlclRvQmFzZTY0VXJsKG9yaWdpbmFsKTtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSBiYXNlNjRVcmxUb0J1ZmZlcihlbmNvZGVkKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoZGVjb2RlZCwgb3JpZ2luYWwpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2RlY29kZXMgYmFzZTY0dXJsIHdpdGggLSBhbmQgXyBjaGFycycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSBiYXNlNjRVcmxUb0J1ZmZlcignLV8tXycpO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChkZWNvZGVkLCBCdWZmZXIuZnJvbShbMHhmYiwgMHhmZiwgMHhiZl0pKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
@@ -39,7 +39,10 @@ const src_1 = require("../../src");
39
39
  const REAL_FIXTURE = {
40
40
  basePrfSalt: 'ZqJ64M2dL65zn2-Jxd58SMN2ILc9QjbCFxUTGHd_LC8',
41
41
  enterpriseId: '69c2aea1a3d7bc07f7f775c0ca86b0ec',
42
- expectedDerivedSalt: 'oiasOqzkuyuEz/8043+3IXYghSu3LV4N/a1MLIRzmU8=',
42
+ // base64url encoding of the HMAC-SHA256(baseSalt_decoded, enterpriseId) digest.
43
+ // Same encoding the server stores and the WebAuthn PRF extension consumes — keeping
44
+ // one encoding everywhere avoids the hex/base64url mismatch that broke browser PRF.
45
+ expectedDerivedSalt: 'oiasOqzkuyuEz_8043-3IXYghSu3LV4N_a1MLIRzmU8',
43
46
  };
44
47
  describe('deriveEnterpriseSalt', function () {
45
48
  it('produces the correct derived salt for real fixture values', function () {
@@ -63,11 +66,12 @@ describe('deriveEnterpriseSalt', function () {
63
66
  const saltB = (0, src_1.deriveEnterpriseSalt)('deadbeefcafebabe0102030405060708', REAL_FIXTURE.enterpriseId);
64
67
  assert.notStrictEqual(saltA, saltB);
65
68
  });
66
- it('returns a non-empty base64 string', function () {
69
+ it('returns a non-empty unpadded base64url string', function () {
67
70
  const result = (0, src_1.deriveEnterpriseSalt)(REAL_FIXTURE.basePrfSalt, REAL_FIXTURE.enterpriseId);
68
71
  assert.strictEqual(typeof result, 'string');
69
72
  assert.ok(result.length > 0);
70
- assert.match(result, /^[A-Za-z0-9+/]+=*$/);
73
+ // Base64url alphabet, no padding. SHA-256 = 32 bytes → 43 base64url chars.
74
+ assert.match(result, /^[A-Za-z0-9_-]{43}$/);
71
75
  });
72
76
  });
73
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVyaXZlRW50ZXJwcmlzZVNhbHQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvdW5pdC9kZXJpdmVFbnRlcnByaXNlU2FsdC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsK0NBQWlDO0FBQ2pDLG1DQUFpRDtBQUVqRCwrRUFBK0U7QUFDL0UsTUFBTSxZQUFZLEdBQUc7SUFDbkIsV0FBVyxFQUFFLDZDQUE2QztJQUMxRCxZQUFZLEVBQUUsa0NBQWtDO0lBQ2hELG1CQUFtQixFQUFFLDhDQUE4QztDQUNwRSxDQUFDO0FBRUYsUUFBUSxDQUFDLHNCQUFzQixFQUFFO0lBQy9CLEVBQUUsQ0FBQywyREFBMkQsRUFBRTtRQUM5RCwrRUFBK0U7UUFDL0UsbUVBQW1FO1FBQ25FLE1BQU0sQ0FBQyxXQUFXLENBQ2hCLElBQUEsMEJBQW9CLEVBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUMsWUFBWSxDQUFDLEVBQ3pFLFlBQVksQ0FBQyxtQkFBbUIsQ0FDakMsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDZEQUE2RCxFQUFFO1FBQ2hFLE1BQU0sS0FBSyxHQUFHLElBQUEsMEJBQW9CLEVBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDeEYsTUFBTSxNQUFNLEdBQUcsSUFBQSwwQkFBb0IsRUFBQyxZQUFZLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN6RixNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pCLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3BDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDRFQUE0RSxFQUFFO1FBQy9FLE1BQU0sS0FBSyxHQUFHLElBQUEsMEJBQW9CLEVBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDeEYsTUFBTSxLQUFLLEdBQUcsSUFBQSwwQkFBb0IsRUFBQyxZQUFZLENBQUMsV0FBVyxFQUFFLHlCQUF5QixDQUFDLENBQUM7UUFDeEYsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDdEMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNEVBQTRFLEVBQUU7UUFDL0UsTUFBTSxLQUFLLEdBQUcsSUFBQSwwQkFBb0IsRUFBQyxZQUFZLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN4RixNQUFNLEtBQUssR0FBRyxJQUFBLDBCQUFvQixFQUFDLGtDQUFrQyxFQUFFLFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNsRyxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxtQ0FBbUMsRUFBRTtRQUN0QyxNQUFNLE1BQU0sR0FBRyxJQUFBLDBCQUFvQixFQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3pGLE1BQU0sQ0FBQyxXQUFXLENBQUMsT0FBTyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDNUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzdCLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDN0MsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgZGVyaXZlRW50ZXJwcmlzZVNhbHQgfSBmcm9tICcuLi8uLi9zcmMnO1xuXG4vLyBSZWFsIGZpeHR1cmUgdmFsdWVzIGNhcHR1cmVkIGZyb20gYSBsaXZlIGVudmlyb25tZW50IChEQiArIGJyb3dzZXIgZGV2dG9vbHMpXG5jb25zdCBSRUFMX0ZJWFRVUkUgPSB7XG4gIGJhc2VQcmZTYWx0OiAnWnFKNjRNMmRMNjV6bjItSnhkNThTTU4ySUxjOVFqYkNGeFVUR0hkX0xDOCcsXG4gIGVudGVycHJpc2VJZDogJzY5YzJhZWExYTNkN2JjMDdmN2Y3NzVjMGNhODZiMGVjJyxcbiAgZXhwZWN0ZWREZXJpdmVkU2FsdDogJ29pYXNPcXprdXl1RXovODA0MyszSVhZZ2hTdTNMVjROL2ExTUxJUnptVTg9Jyxcbn07XG5cbmRlc2NyaWJlKCdkZXJpdmVFbnRlcnByaXNlU2FsdCcsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ3Byb2R1Y2VzIHRoZSBjb3JyZWN0IGRlcml2ZWQgc2FsdCBmb3IgcmVhbCBmaXh0dXJlIHZhbHVlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBWZXJpZmllcyBTREsgb3V0cHV0IG1hdGNoZXMgd2hhdCB0aGUgcmV0YWlsIFVJIHByb2R1Y2VzIGZvciB0aGUgc2FtZSBpbnB1dHMsXG4gICAgLy8gZW5zdXJpbmcgY2xpZW50cyBjYW4gbW92ZSBiZXR3ZWVuIFNESyBhbmQgcmV0YWlsIGFwcCBzZWFtbGVzc2x5LlxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgIGRlcml2ZUVudGVycHJpc2VTYWx0KFJFQUxfRklYVFVSRS5iYXNlUHJmU2FsdCwgUkVBTF9GSVhUVVJFLmVudGVycHJpc2VJZCksXG4gICAgICBSRUFMX0ZJWFRVUkUuZXhwZWN0ZWREZXJpdmVkU2FsdFxuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdpcyBkZXRlcm1pbmlzdGljIOKAlCBzYW1lIGlucHV0cyBhbHdheXMgcHJvZHVjZSB0aGUgc2FtZSBzYWx0JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGZpcnN0ID0gZGVyaXZlRW50ZXJwcmlzZVNhbHQoUkVBTF9GSVhUVVJFLmJhc2VQcmZTYWx0LCBSRUFMX0ZJWFRVUkUuZW50ZXJwcmlzZUlkKTtcbiAgICBjb25zdCBzZWNvbmQgPSBkZXJpdmVFbnRlcnByaXNlU2FsdChSRUFMX0ZJWFRVUkUuYmFzZVByZlNhbHQsIFJFQUxfRklYVFVSRS5lbnRlcnByaXNlSWQpO1xuICAgIGFzc2VydC5vayhmaXJzdCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGZpcnN0LCBzZWNvbmQpO1xuICB9KTtcblxuICBpdCgncHJvZHVjZXMgZGlmZmVyZW50IHNhbHRzIGZvciBkaWZmZXJlbnQgZW50ZXJwcmlzZUlkcyB3aXRoIHRoZSBzYW1lIHByZlNhbHQnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2FsdEEgPSBkZXJpdmVFbnRlcnByaXNlU2FsdChSRUFMX0ZJWFRVUkUuYmFzZVByZlNhbHQsIFJFQUxfRklYVFVSRS5lbnRlcnByaXNlSWQpO1xuICAgIGNvbnN0IHNhbHRCID0gZGVyaXZlRW50ZXJwcmlzZVNhbHQoUkVBTF9GSVhUVVJFLmJhc2VQcmZTYWx0LCAnZGlmZmVyZW50LWVudGVycHJpc2UtaWQnKTtcbiAgICBhc3NlcnQubm90U3RyaWN0RXF1YWwoc2FsdEEsIHNhbHRCKTtcbiAgfSk7XG5cbiAgaXQoJ3Byb2R1Y2VzIGRpZmZlcmVudCBzYWx0cyBmb3IgZGlmZmVyZW50IHByZlNhbHRzIHdpdGggdGhlIHNhbWUgZW50ZXJwcmlzZUlkJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNhbHRBID0gZGVyaXZlRW50ZXJwcmlzZVNhbHQoUkVBTF9GSVhUVVJFLmJhc2VQcmZTYWx0LCBSRUFMX0ZJWFRVUkUuZW50ZXJwcmlzZUlkKTtcbiAgICBjb25zdCBzYWx0QiA9IGRlcml2ZUVudGVycHJpc2VTYWx0KCdkZWFkYmVlZmNhZmViYWJlMDEwMjAzMDQwNTA2MDcwOCcsIFJFQUxfRklYVFVSRS5lbnRlcnByaXNlSWQpO1xuICAgIGFzc2VydC5ub3RTdHJpY3RFcXVhbChzYWx0QSwgc2FsdEIpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyBhIG5vbi1lbXB0eSBiYXNlNjQgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGRlcml2ZUVudGVycHJpc2VTYWx0KFJFQUxfRklYVFVSRS5iYXNlUHJmU2FsdCwgUkVBTF9GSVhUVVJFLmVudGVycHJpc2VJZCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR5cGVvZiByZXN1bHQsICdzdHJpbmcnKTtcbiAgICBhc3NlcnQub2socmVzdWx0Lmxlbmd0aCA+IDApO1xuICAgIGFzc2VydC5tYXRjaChyZXN1bHQsIC9eW0EtWmEtejAtOSsvXSs9KiQvKTtcbiAgfSk7XG59KTtcbiJdfQ==
77
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVyaXZlRW50ZXJwcmlzZVNhbHQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvdW5pdC9kZXJpdmVFbnRlcnByaXNlU2FsdC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsK0NBQWlDO0FBQ2pDLG1DQUFpRDtBQUVqRCwrRUFBK0U7QUFDL0UsTUFBTSxZQUFZLEdBQUc7SUFDbkIsV0FBVyxFQUFFLDZDQUE2QztJQUMxRCxZQUFZLEVBQUUsa0NBQWtDO0lBQ2hELGdGQUFnRjtJQUNoRixvRkFBb0Y7SUFDcEYsb0ZBQW9GO0lBQ3BGLG1CQUFtQixFQUFFLDZDQUE2QztDQUNuRSxDQUFDO0FBRUYsUUFBUSxDQUFDLHNCQUFzQixFQUFFO0lBQy9CLEVBQUUsQ0FBQywyREFBMkQsRUFBRTtRQUM5RCwrRUFBK0U7UUFDL0UsbUVBQW1FO1FBQ25FLE1BQU0sQ0FBQyxXQUFXLENBQ2hCLElBQUEsMEJBQW9CLEVBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUMsWUFBWSxDQUFDLEVBQ3pFLFlBQVksQ0FBQyxtQkFBbUIsQ0FDakMsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDZEQUE2RCxFQUFFO1FBQ2hFLE1BQU0sS0FBSyxHQUFHLElBQUEsMEJBQW9CLEVBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDeEYsTUFBTSxNQUFNLEdBQUcsSUFBQSwwQkFBb0IsRUFBQyxZQUFZLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN6RixNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pCLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3BDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDRFQUE0RSxFQUFFO1FBQy9FLE1BQU0sS0FBSyxHQUFHLElBQUEsMEJBQW9CLEVBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDeEYsTUFBTSxLQUFLLEdBQUcsSUFBQSwwQkFBb0IsRUFBQyxZQUFZLENBQUMsV0FBVyxFQUFFLHlCQUF5QixDQUFDLENBQUM7UUFDeEYsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDdEMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNEVBQTRFLEVBQUU7UUFDL0UsTUFBTSxLQUFLLEdBQUcsSUFBQSwwQkFBb0IsRUFBQyxZQUFZLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN4RixNQUFNLEtBQUssR0FBRyxJQUFBLDBCQUFvQixFQUFDLGtDQUFrQyxFQUFFLFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNsRyxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywrQ0FBK0MsRUFBRTtRQUNsRCxNQUFNLE1BQU0sR0FBRyxJQUFBLDBCQUFvQixFQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3pGLE1BQU0sQ0FBQyxXQUFXLENBQUMsT0FBTyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDNUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzdCLDJFQUEyRTtRQUMzRSxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO0lBQzlDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IGRlcml2ZUVudGVycHJpc2VTYWx0IH0gZnJvbSAnLi4vLi4vc3JjJztcblxuLy8gUmVhbCBmaXh0dXJlIHZhbHVlcyBjYXB0dXJlZCBmcm9tIGEgbGl2ZSBlbnZpcm9ubWVudCAoREIgKyBicm93c2VyIGRldnRvb2xzKVxuY29uc3QgUkVBTF9GSVhUVVJFID0ge1xuICBiYXNlUHJmU2FsdDogJ1pxSjY0TTJkTDY1em4yLUp4ZDU4U01OMklMYzlRamJDRnhVVEdIZF9MQzgnLFxuICBlbnRlcnByaXNlSWQ6ICc2OWMyYWVhMWEzZDdiYzA3ZjdmNzc1YzBjYTg2YjBlYycsXG4gIC8vIGJhc2U2NHVybCBlbmNvZGluZyBvZiB0aGUgSE1BQy1TSEEyNTYoYmFzZVNhbHRfZGVjb2RlZCwgZW50ZXJwcmlzZUlkKSBkaWdlc3QuXG4gIC8vIFNhbWUgZW5jb2RpbmcgdGhlIHNlcnZlciBzdG9yZXMgYW5kIHRoZSBXZWJBdXRobiBQUkYgZXh0ZW5zaW9uIGNvbnN1bWVzIOKAlCBrZWVwaW5nXG4gIC8vIG9uZSBlbmNvZGluZyBldmVyeXdoZXJlIGF2b2lkcyB0aGUgaGV4L2Jhc2U2NHVybCBtaXNtYXRjaCB0aGF0IGJyb2tlIGJyb3dzZXIgUFJGLlxuICBleHBlY3RlZERlcml2ZWRTYWx0OiAnb2lhc09xemt1eXVFel84MDQzLTNJWFlnaFN1M0xWNE5fYTFNTElSem1VOCcsXG59O1xuXG5kZXNjcmliZSgnZGVyaXZlRW50ZXJwcmlzZVNhbHQnLCBmdW5jdGlvbiAoKSB7XG4gIGl0KCdwcm9kdWNlcyB0aGUgY29ycmVjdCBkZXJpdmVkIHNhbHQgZm9yIHJlYWwgZml4dHVyZSB2YWx1ZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgLy8gVmVyaWZpZXMgU0RLIG91dHB1dCBtYXRjaGVzIHdoYXQgdGhlIHJldGFpbCBVSSBwcm9kdWNlcyBmb3IgdGhlIHNhbWUgaW5wdXRzLFxuICAgIC8vIGVuc3VyaW5nIGNsaWVudHMgY2FuIG1vdmUgYmV0d2VlbiBTREsgYW5kIHJldGFpbCBhcHAgc2VhbWxlc3NseS5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICBkZXJpdmVFbnRlcnByaXNlU2FsdChSRUFMX0ZJWFRVUkUuYmFzZVByZlNhbHQsIFJFQUxfRklYVFVSRS5lbnRlcnByaXNlSWQpLFxuICAgICAgUkVBTF9GSVhUVVJFLmV4cGVjdGVkRGVyaXZlZFNhbHRcbiAgICApO1xuICB9KTtcblxuICBpdCgnaXMgZGV0ZXJtaW5pc3RpYyDigJQgc2FtZSBpbnB1dHMgYWx3YXlzIHByb2R1Y2UgdGhlIHNhbWUgc2FsdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBmaXJzdCA9IGRlcml2ZUVudGVycHJpc2VTYWx0KFJFQUxfRklYVFVSRS5iYXNlUHJmU2FsdCwgUkVBTF9GSVhUVVJFLmVudGVycHJpc2VJZCk7XG4gICAgY29uc3Qgc2Vjb25kID0gZGVyaXZlRW50ZXJwcmlzZVNhbHQoUkVBTF9GSVhUVVJFLmJhc2VQcmZTYWx0LCBSRUFMX0ZJWFRVUkUuZW50ZXJwcmlzZUlkKTtcbiAgICBhc3NlcnQub2soZmlyc3QpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChmaXJzdCwgc2Vjb25kKTtcbiAgfSk7XG5cbiAgaXQoJ3Byb2R1Y2VzIGRpZmZlcmVudCBzYWx0cyBmb3IgZGlmZmVyZW50IGVudGVycHJpc2VJZHMgd2l0aCB0aGUgc2FtZSBwcmZTYWx0JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNhbHRBID0gZGVyaXZlRW50ZXJwcmlzZVNhbHQoUkVBTF9GSVhUVVJFLmJhc2VQcmZTYWx0LCBSRUFMX0ZJWFRVUkUuZW50ZXJwcmlzZUlkKTtcbiAgICBjb25zdCBzYWx0QiA9IGRlcml2ZUVudGVycHJpc2VTYWx0KFJFQUxfRklYVFVSRS5iYXNlUHJmU2FsdCwgJ2RpZmZlcmVudC1lbnRlcnByaXNlLWlkJyk7XG4gICAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKHNhbHRBLCBzYWx0Qik7XG4gIH0pO1xuXG4gIGl0KCdwcm9kdWNlcyBkaWZmZXJlbnQgc2FsdHMgZm9yIGRpZmZlcmVudCBwcmZTYWx0cyB3aXRoIHRoZSBzYW1lIGVudGVycHJpc2VJZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBzYWx0QSA9IGRlcml2ZUVudGVycHJpc2VTYWx0KFJFQUxfRklYVFVSRS5iYXNlUHJmU2FsdCwgUkVBTF9GSVhUVVJFLmVudGVycHJpc2VJZCk7XG4gICAgY29uc3Qgc2FsdEIgPSBkZXJpdmVFbnRlcnByaXNlU2FsdCgnZGVhZGJlZWZjYWZlYmFiZTAxMDIwMzA0MDUwNjA3MDgnLCBSRUFMX0ZJWFRVUkUuZW50ZXJwcmlzZUlkKTtcbiAgICBhc3NlcnQubm90U3RyaWN0RXF1YWwoc2FsdEEsIHNhbHRCKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgYSBub24tZW1wdHkgdW5wYWRkZWQgYmFzZTY0dXJsIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCByZXN1bHQgPSBkZXJpdmVFbnRlcnByaXNlU2FsdChSRUFMX0ZJWFRVUkUuYmFzZVByZlNhbHQsIFJFQUxfRklYVFVSRS5lbnRlcnByaXNlSWQpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgcmVzdWx0LCAnc3RyaW5nJyk7XG4gICAgYXNzZXJ0Lm9rKHJlc3VsdC5sZW5ndGggPiAwKTtcbiAgICAvLyBCYXNlNjR1cmwgYWxwaGFiZXQsIG5vIHBhZGRpbmcuIFNIQS0yNTYgPSAzMiBieXRlcyDihpIgNDMgYmFzZTY0dXJsIGNoYXJzLlxuICAgIGFzc2VydC5tYXRjaChyZXN1bHQsIC9eW0EtWmEtejAtOV8tXXs0M30kLyk7XG4gIH0pO1xufSk7XG4iXX0=
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=derivePasskeyPrfKey.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derivePasskeyPrfKey.test.d.ts","sourceRoot":"","sources":["../../../test/unit/derivePasskeyPrfKey.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const assert = __importStar(require("assert"));
37
+ const sinon = __importStar(require("sinon"));
38
+ const derivePasskeyPrfKey_1 = require("../../src/derivePasskeyPrfKey");
39
+ describe('derivePasskeyPrfKey', function () {
40
+ const mockDevices = [
41
+ {
42
+ otpDeviceId: 'device-1',
43
+ authenticatorInfo: { credID: 'cred-aaa', fmt: 'none', publicKey: 'pk-1' },
44
+ prfSalt: 'salt-aaa',
45
+ encryptedPrv: 'enc-prv-1',
46
+ },
47
+ {
48
+ otpDeviceId: 'device-2',
49
+ authenticatorInfo: { credID: 'cred-bbb', fmt: 'none', publicKey: 'pk-2' },
50
+ prfSalt: 'salt-bbb',
51
+ encryptedPrv: 'enc-prv-2',
52
+ },
53
+ ];
54
+ function makeWallet(devices) {
55
+ return {
56
+ getEncryptedUserKeychain: sinon.stub().resolves({
57
+ id: 'keychain-id',
58
+ pub: 'xpub123',
59
+ encryptedPrv: 'encrypted-prv',
60
+ type: 'independent',
61
+ webauthnDevices: devices,
62
+ }),
63
+ };
64
+ }
65
+ function makeBitGo(challenge = 'dGVzdC1jaGFsbGVuZ2U=') {
66
+ return {
67
+ url: sinon.stub().callsFake((path) => `https://app.bitgo.com/api/v2${path}`),
68
+ get: sinon.stub().returns({
69
+ result: sinon.stub().resolves({ challenge }),
70
+ }),
71
+ };
72
+ }
73
+ afterEach(function () {
74
+ sinon.restore();
75
+ });
76
+ it('should return a hex string on happy path', async function () {
77
+ const prfResult = new Uint8Array([0xde, 0xad, 0xbe, 0xef]).buffer;
78
+ const mockProvider = {
79
+ create: sinon.stub(),
80
+ get: sinon.stub().resolves({
81
+ prfResult,
82
+ credentialId: 'cred-aaa',
83
+ otpCode: 'otp-123',
84
+ }),
85
+ };
86
+ const wallet = makeWallet(mockDevices);
87
+ const mockBitGo = makeBitGo();
88
+ const result = await (0, derivePasskeyPrfKey_1.derivePasskeyPrfKey)({
89
+ bitgo: mockBitGo,
90
+ wallet: wallet,
91
+ provider: mockProvider,
92
+ });
93
+ // derivePassword converts ArrayBuffer to hex
94
+ assert.strictEqual(result, 'deadbeef');
95
+ assert.ok(mockProvider.get.calledOnce);
96
+ // Verify evalByCredential was passed
97
+ const getCallArgs = mockProvider.get.firstCall.args[0];
98
+ assert.strictEqual(getCallArgs.evalByCredential['cred-aaa'], 'salt-aaa');
99
+ assert.strictEqual(getCallArgs.evalByCredential['cred-bbb'], 'salt-bbb');
100
+ // Verify bitgo was used to fetch the assertion challenge
101
+ assert.ok(mockBitGo.get.calledOnce);
102
+ assert.ok(mockBitGo.url.calledWith('/user/otp/webauthn/auth', 2));
103
+ });
104
+ it("should throw 'No passkey devices available' when no devices", async function () {
105
+ const wallet = makeWallet(undefined);
106
+ const mockProvider = { create: sinon.stub(), get: sinon.stub() };
107
+ await assert.rejects(() => (0, derivePasskeyPrfKey_1.derivePasskeyPrfKey)({ bitgo: makeBitGo(), wallet: wallet, provider: mockProvider }), (err) => {
108
+ assert.strictEqual(err.message, 'No passkey devices available');
109
+ return true;
110
+ });
111
+ });
112
+ it("should throw 'No passkey devices available' when devices array is empty", async function () {
113
+ const wallet = makeWallet([]);
114
+ const mockProvider = { create: sinon.stub(), get: sinon.stub() };
115
+ await assert.rejects(() => (0, derivePasskeyPrfKey_1.derivePasskeyPrfKey)({ bitgo: makeBitGo(), wallet: wallet, provider: mockProvider }), (err) => {
116
+ assert.strictEqual(err.message, 'No passkey devices available');
117
+ return true;
118
+ });
119
+ });
120
+ it("should throw 'No passkey devices available with a valid PRF salt' when no device has prfSalt", async function () {
121
+ const devicesWithoutSalt = [
122
+ {
123
+ otpDeviceId: 'device-1',
124
+ authenticatorInfo: { credID: 'cred-aaa', fmt: 'none', publicKey: 'pk-1' },
125
+ prfSalt: '', // empty — buildEvalByCredential skips falsy prfSalt
126
+ encryptedPrv: 'enc-prv-1',
127
+ },
128
+ ];
129
+ const wallet = makeWallet(devicesWithoutSalt);
130
+ const mockProvider = { create: sinon.stub(), get: sinon.stub() };
131
+ await assert.rejects(() => (0, derivePasskeyPrfKey_1.derivePasskeyPrfKey)({ bitgo: makeBitGo(), wallet: wallet, provider: mockProvider }), (err) => {
132
+ assert.strictEqual(err.message, 'No passkey devices available with a valid PRF salt');
133
+ return true;
134
+ });
135
+ });
136
+ it("should throw 'Could not identify which passkey device was used' when credentialId not found", async function () {
137
+ const mockProvider = {
138
+ create: sinon.stub(),
139
+ get: sinon.stub().resolves({
140
+ prfResult: new ArrayBuffer(32),
141
+ credentialId: 'unknown-cred-id',
142
+ otpCode: 'otp-123',
143
+ }),
144
+ };
145
+ const wallet = makeWallet(mockDevices);
146
+ await assert.rejects(() => (0, derivePasskeyPrfKey_1.derivePasskeyPrfKey)({ bitgo: makeBitGo(), wallet: wallet, provider: mockProvider }), (err) => {
147
+ assert.strictEqual(err.message, 'Could not identify which passkey device was used');
148
+ return true;
149
+ });
150
+ });
151
+ });
152
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVyaXZlUGFzc2tleVByZktleS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2Rlcml2ZVBhc3NrZXlQcmZLZXkudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtDQUFpQztBQUNqQyw2Q0FBK0I7QUFDL0IsdUVBQW9FO0FBRXBFLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRTtJQUM5QixNQUFNLFdBQVcsR0FBRztRQUNsQjtZQUNFLFdBQVcsRUFBRSxVQUFVO1lBQ3ZCLGlCQUFpQixFQUFFLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsTUFBZSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUU7WUFDbEYsT0FBTyxFQUFFLFVBQVU7WUFDbkIsWUFBWSxFQUFFLFdBQVc7U0FDMUI7UUFDRDtZQUNFLFdBQVcsRUFBRSxVQUFVO1lBQ3ZCLGlCQUFpQixFQUFFLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsTUFBZSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUU7WUFDbEYsT0FBTyxFQUFFLFVBQVU7WUFDbkIsWUFBWSxFQUFFLFdBQVc7U0FDMUI7S0FDRixDQUFDO0lBRUYsU0FBUyxVQUFVLENBQUMsT0FBdUM7UUFDekQsT0FBTztZQUNMLHdCQUF3QixFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBQzlDLEVBQUUsRUFBRSxhQUFhO2dCQUNqQixHQUFHLEVBQUUsU0FBUztnQkFDZCxZQUFZLEVBQUUsZUFBZTtnQkFDN0IsSUFBSSxFQUFFLGFBQWE7Z0JBQ25CLGVBQWUsRUFBRSxPQUFPO2FBQ3pCLENBQUM7U0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVELFNBQVMsU0FBUyxDQUFDLFNBQVMsR0FBRyxzQkFBc0I7UUFDbkQsT0FBTztZQUNMLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBWSxFQUFFLEVBQUUsQ0FBQywrQkFBK0IsSUFBSSxFQUFFLENBQUM7WUFDcEYsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxPQUFPLENBQUM7Z0JBQ3hCLE1BQU0sRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUM7YUFDN0MsQ0FBQztTQUNILENBQUM7SUFDSixDQUFDO0lBRUQsU0FBUyxDQUFDO1FBQ1IsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2xCLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDBDQUEwQyxFQUFFLEtBQUs7UUFDbEQsTUFBTSxTQUFTLEdBQUcsSUFBSSxVQUFVLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUVsRSxNQUFNLFlBQVksR0FBRztZQUNuQixNQUFNLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRTtZQUNwQixHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFDekIsU0FBUztnQkFDVCxZQUFZLEVBQUUsVUFBVTtnQkFDeEIsT0FBTyxFQUFFLFNBQVM7YUFDbkIsQ0FBQztTQUNILENBQUM7UUFFRixNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDdkMsTUFBTSxTQUFTLEdBQUcsU0FBUyxFQUFFLENBQUM7UUFFOUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFBLHlDQUFtQixFQUFDO1lBQ3ZDLEtBQUssRUFBRSxTQUFnQjtZQUN2QixNQUFNLEVBQUUsTUFBYTtZQUNyQixRQUFRLEVBQUUsWUFBWTtTQUN2QixDQUFDLENBQUM7UUFFSCw2Q0FBNkM7UUFDN0MsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDdkMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3ZDLHFDQUFxQztRQUNyQyxNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDekUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDekUseURBQXlEO1FBQ3pELE1BQU0sQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNwQyxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLHlCQUF5QixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEUsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNkRBQTZELEVBQUUsS0FBSztRQUNyRSxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckMsTUFBTSxZQUFZLEdBQUcsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztRQUVqRSxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQ2xCLEdBQUcsRUFBRSxDQUFDLElBQUEseUNBQW1CLEVBQUMsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFTLEVBQUUsTUFBTSxFQUFFLE1BQWEsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLENBQUMsRUFDdkcsQ0FBQyxHQUFVLEVBQUUsRUFBRTtZQUNiLE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSw4QkFBOEIsQ0FBQyxDQUFDO1lBQ2hFLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQyxDQUNGLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx5RUFBeUUsRUFBRSxLQUFLO1FBQ2pGLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxFQUFTLENBQUMsQ0FBQztRQUNyQyxNQUFNLFlBQVksR0FBRyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBRWpFLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FDbEIsR0FBRyxFQUFFLENBQUMsSUFBQSx5Q0FBbUIsRUFBQyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQVMsRUFBRSxNQUFNLEVBQUUsTUFBYSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsQ0FBQyxFQUN2RyxDQUFDLEdBQVUsRUFBRSxFQUFFO1lBQ2IsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLDhCQUE4QixDQUFDLENBQUM7WUFDaEUsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDLENBQ0YsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDhGQUE4RixFQUFFLEtBQUs7UUFDdEcsTUFBTSxrQkFBa0IsR0FBRztZQUN6QjtnQkFDRSxXQUFXLEVBQUUsVUFBVTtnQkFDdkIsaUJBQWlCLEVBQUUsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFlLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRTtnQkFDbEYsT0FBTyxFQUFFLEVBQUUsRUFBRSxvREFBb0Q7Z0JBQ2pFLFlBQVksRUFBRSxXQUFXO2FBQzFCO1NBQ0YsQ0FBQztRQUVGLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxrQkFBeUIsQ0FBQyxDQUFDO1FBQ3JELE1BQU0sWUFBWSxHQUFHLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7UUFFakUsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUNsQixHQUFHLEVBQUUsQ0FBQyxJQUFBLHlDQUFtQixFQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBUyxFQUFFLE1BQU0sRUFBRSxNQUFhLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxDQUFDLEVBQ3ZHLENBQUMsR0FBVSxFQUFFLEVBQUU7WUFDYixNQUFNLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsb0RBQW9ELENBQUMsQ0FBQztZQUN0RixPQUFPLElBQUksQ0FBQztRQUNkLENBQUMsQ0FDRixDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNkZBQTZGLEVBQUUsS0FBSztRQUNyRyxNQUFNLFlBQVksR0FBRztZQUNuQixNQUFNLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRTtZQUNwQixHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFDekIsU0FBUyxFQUFFLElBQUksV0FBVyxDQUFDLEVBQUUsQ0FBQztnQkFDOUIsWUFBWSxFQUFFLGlCQUFpQjtnQkFDL0IsT0FBTyxFQUFFLFNBQVM7YUFDbkIsQ0FBQztTQUNILENBQUM7UUFFRixNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFdkMsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUNsQixHQUFHLEVBQUUsQ0FBQyxJQUFBLHlDQUFtQixFQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBUyxFQUFFLE1BQU0sRUFBRSxNQUFhLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxDQUFDLEVBQ3ZHLENBQUMsR0FBVSxFQUFFLEVBQUU7WUFDYixNQUFNLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsa0RBQWtELENBQUMsQ0FBQztZQUNwRixPQUFPLElBQUksQ0FBQztRQUNkLENBQUMsQ0FDRixDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgZGVyaXZlUGFzc2tleVByZktleSB9IGZyb20gJy4uLy4uL3NyYy9kZXJpdmVQYXNza2V5UHJmS2V5JztcblxuZGVzY3JpYmUoJ2Rlcml2ZVBhc3NrZXlQcmZLZXknLCBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IG1vY2tEZXZpY2VzID0gW1xuICAgIHtcbiAgICAgIG90cERldmljZUlkOiAnZGV2aWNlLTEnLFxuICAgICAgYXV0aGVudGljYXRvckluZm86IHsgY3JlZElEOiAnY3JlZC1hYWEnLCBmbXQ6ICdub25lJyBhcyBjb25zdCwgcHVibGljS2V5OiAncGstMScgfSxcbiAgICAgIHByZlNhbHQ6ICdzYWx0LWFhYScsXG4gICAgICBlbmNyeXB0ZWRQcnY6ICdlbmMtcHJ2LTEnLFxuICAgIH0sXG4gICAge1xuICAgICAgb3RwRGV2aWNlSWQ6ICdkZXZpY2UtMicsXG4gICAgICBhdXRoZW50aWNhdG9ySW5mbzogeyBjcmVkSUQ6ICdjcmVkLWJiYicsIGZtdDogJ25vbmUnIGFzIGNvbnN0LCBwdWJsaWNLZXk6ICdway0yJyB9LFxuICAgICAgcHJmU2FsdDogJ3NhbHQtYmJiJyxcbiAgICAgIGVuY3J5cHRlZFBydjogJ2VuYy1wcnYtMicsXG4gICAgfSxcbiAgXTtcblxuICBmdW5jdGlvbiBtYWtlV2FsbGV0KGRldmljZXM6IHR5cGVvZiBtb2NrRGV2aWNlcyB8IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB7XG4gICAgICBnZXRFbmNyeXB0ZWRVc2VyS2V5Y2hhaW46IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7XG4gICAgICAgIGlkOiAna2V5Y2hhaW4taWQnLFxuICAgICAgICBwdWI6ICd4cHViMTIzJyxcbiAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkLXBydicsXG4gICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgIHdlYmF1dGhuRGV2aWNlczogZGV2aWNlcyxcbiAgICAgIH0pLFxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBtYWtlQml0R28oY2hhbGxlbmdlID0gJ2RHVnpkQzFqYUdGc2JHVnVaMlU9Jykge1xuICAgIHJldHVybiB7XG4gICAgICB1cmw6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoKHBhdGg6IHN0cmluZykgPT4gYGh0dHBzOi8vYXBwLmJpdGdvLmNvbS9hcGkvdjIke3BhdGh9YCksXG4gICAgICBnZXQ6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKHtcbiAgICAgICAgcmVzdWx0OiBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBjaGFsbGVuZ2UgfSksXG4gICAgICB9KSxcbiAgICB9O1xuICB9XG5cbiAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBzaW5vbi5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmV0dXJuIGEgaGV4IHN0cmluZyBvbiBoYXBweSBwYXRoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHByZlJlc3VsdCA9IG5ldyBVaW50OEFycmF5KFsweGRlLCAweGFkLCAweGJlLCAweGVmXSkuYnVmZmVyO1xuXG4gICAgY29uc3QgbW9ja1Byb3ZpZGVyID0ge1xuICAgICAgY3JlYXRlOiBzaW5vbi5zdHViKCksXG4gICAgICBnZXQ6IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7XG4gICAgICAgIHByZlJlc3VsdCxcbiAgICAgICAgY3JlZGVudGlhbElkOiAnY3JlZC1hYWEnLFxuICAgICAgICBvdHBDb2RlOiAnb3RwLTEyMycsXG4gICAgICB9KSxcbiAgICB9O1xuXG4gICAgY29uc3Qgd2FsbGV0ID0gbWFrZVdhbGxldChtb2NrRGV2aWNlcyk7XG4gICAgY29uc3QgbW9ja0JpdEdvID0gbWFrZUJpdEdvKCk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkZXJpdmVQYXNza2V5UHJmS2V5KHtcbiAgICAgIGJpdGdvOiBtb2NrQml0R28gYXMgYW55LFxuICAgICAgd2FsbGV0OiB3YWxsZXQgYXMgYW55LFxuICAgICAgcHJvdmlkZXI6IG1vY2tQcm92aWRlcixcbiAgICB9KTtcblxuICAgIC8vIGRlcml2ZVBhc3N3b3JkIGNvbnZlcnRzIEFycmF5QnVmZmVyIHRvIGhleFxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsICdkZWFkYmVlZicpO1xuICAgIGFzc2VydC5vayhtb2NrUHJvdmlkZXIuZ2V0LmNhbGxlZE9uY2UpO1xuICAgIC8vIFZlcmlmeSBldmFsQnlDcmVkZW50aWFsIHdhcyBwYXNzZWRcbiAgICBjb25zdCBnZXRDYWxsQXJncyA9IG1vY2tQcm92aWRlci5nZXQuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGdldENhbGxBcmdzLmV2YWxCeUNyZWRlbnRpYWxbJ2NyZWQtYWFhJ10sICdzYWx0LWFhYScpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChnZXRDYWxsQXJncy5ldmFsQnlDcmVkZW50aWFsWydjcmVkLWJiYiddLCAnc2FsdC1iYmInKTtcbiAgICAvLyBWZXJpZnkgYml0Z28gd2FzIHVzZWQgdG8gZmV0Y2ggdGhlIGFzc2VydGlvbiBjaGFsbGVuZ2VcbiAgICBhc3NlcnQub2sobW9ja0JpdEdvLmdldC5jYWxsZWRPbmNlKTtcbiAgICBhc3NlcnQub2sobW9ja0JpdEdvLnVybC5jYWxsZWRXaXRoKCcvdXNlci9vdHAvd2ViYXV0aG4vYXV0aCcsIDIpKTtcbiAgfSk7XG5cbiAgaXQoXCJzaG91bGQgdGhyb3cgJ05vIHBhc3NrZXkgZGV2aWNlcyBhdmFpbGFibGUnIHdoZW4gbm8gZGV2aWNlc1wiLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgd2FsbGV0ID0gbWFrZVdhbGxldCh1bmRlZmluZWQpO1xuICAgIGNvbnN0IG1vY2tQcm92aWRlciA9IHsgY3JlYXRlOiBzaW5vbi5zdHViKCksIGdldDogc2lub24uc3R1YigpIH07XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+IGRlcml2ZVBhc3NrZXlQcmZLZXkoeyBiaXRnbzogbWFrZUJpdEdvKCkgYXMgYW55LCB3YWxsZXQ6IHdhbGxldCBhcyBhbnksIHByb3ZpZGVyOiBtb2NrUHJvdmlkZXIgfSksXG4gICAgICAoZXJyOiBFcnJvcikgPT4ge1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXJyLm1lc3NhZ2UsICdObyBwYXNza2V5IGRldmljZXMgYXZhaWxhYmxlJyk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICk7XG4gIH0pO1xuXG4gIGl0KFwic2hvdWxkIHRocm93ICdObyBwYXNza2V5IGRldmljZXMgYXZhaWxhYmxlJyB3aGVuIGRldmljZXMgYXJyYXkgaXMgZW1wdHlcIiwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHdhbGxldCA9IG1ha2VXYWxsZXQoW10gYXMgYW55KTtcbiAgICBjb25zdCBtb2NrUHJvdmlkZXIgPSB7IGNyZWF0ZTogc2lub24uc3R1YigpLCBnZXQ6IHNpbm9uLnN0dWIoKSB9O1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PiBkZXJpdmVQYXNza2V5UHJmS2V5KHsgYml0Z286IG1ha2VCaXRHbygpIGFzIGFueSwgd2FsbGV0OiB3YWxsZXQgYXMgYW55LCBwcm92aWRlcjogbW9ja1Byb3ZpZGVyIH0pLFxuICAgICAgKGVycjogRXJyb3IpID0+IHtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVyci5tZXNzYWdlLCAnTm8gcGFzc2tleSBkZXZpY2VzIGF2YWlsYWJsZScpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICApO1xuICB9KTtcblxuICBpdChcInNob3VsZCB0aHJvdyAnTm8gcGFzc2tleSBkZXZpY2VzIGF2YWlsYWJsZSB3aXRoIGEgdmFsaWQgUFJGIHNhbHQnIHdoZW4gbm8gZGV2aWNlIGhhcyBwcmZTYWx0XCIsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBkZXZpY2VzV2l0aG91dFNhbHQgPSBbXG4gICAgICB7XG4gICAgICAgIG90cERldmljZUlkOiAnZGV2aWNlLTEnLFxuICAgICAgICBhdXRoZW50aWNhdG9ySW5mbzogeyBjcmVkSUQ6ICdjcmVkLWFhYScsIGZtdDogJ25vbmUnIGFzIGNvbnN0LCBwdWJsaWNLZXk6ICdway0xJyB9LFxuICAgICAgICBwcmZTYWx0OiAnJywgLy8gZW1wdHkg4oCUIGJ1aWxkRXZhbEJ5Q3JlZGVudGlhbCBza2lwcyBmYWxzeSBwcmZTYWx0XG4gICAgICAgIGVuY3J5cHRlZFBydjogJ2VuYy1wcnYtMScsXG4gICAgICB9LFxuICAgIF07XG5cbiAgICBjb25zdCB3YWxsZXQgPSBtYWtlV2FsbGV0KGRldmljZXNXaXRob3V0U2FsdCBhcyBhbnkpO1xuICAgIGNvbnN0IG1vY2tQcm92aWRlciA9IHsgY3JlYXRlOiBzaW5vbi5zdHViKCksIGdldDogc2lub24uc3R1YigpIH07XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+IGRlcml2ZVBhc3NrZXlQcmZLZXkoeyBiaXRnbzogbWFrZUJpdEdvKCkgYXMgYW55LCB3YWxsZXQ6IHdhbGxldCBhcyBhbnksIHByb3ZpZGVyOiBtb2NrUHJvdmlkZXIgfSksXG4gICAgICAoZXJyOiBFcnJvcikgPT4ge1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXJyLm1lc3NhZ2UsICdObyBwYXNza2V5IGRldmljZXMgYXZhaWxhYmxlIHdpdGggYSB2YWxpZCBQUkYgc2FsdCcpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICApO1xuICB9KTtcblxuICBpdChcInNob3VsZCB0aHJvdyAnQ291bGQgbm90IGlkZW50aWZ5IHdoaWNoIHBhc3NrZXkgZGV2aWNlIHdhcyB1c2VkJyB3aGVuIGNyZWRlbnRpYWxJZCBub3QgZm91bmRcIiwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG1vY2tQcm92aWRlciA9IHtcbiAgICAgIGNyZWF0ZTogc2lub24uc3R1YigpLFxuICAgICAgZ2V0OiBzaW5vbi5zdHViKCkucmVzb2x2ZXMoe1xuICAgICAgICBwcmZSZXN1bHQ6IG5ldyBBcnJheUJ1ZmZlcigzMiksXG4gICAgICAgIGNyZWRlbnRpYWxJZDogJ3Vua25vd24tY3JlZC1pZCcsXG4gICAgICAgIG90cENvZGU6ICdvdHAtMTIzJyxcbiAgICAgIH0pLFxuICAgIH07XG5cbiAgICBjb25zdCB3YWxsZXQgPSBtYWtlV2FsbGV0KG1vY2tEZXZpY2VzKTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT4gZGVyaXZlUGFzc2tleVByZktleSh7IGJpdGdvOiBtYWtlQml0R28oKSBhcyBhbnksIHdhbGxldDogd2FsbGV0IGFzIGFueSwgcHJvdmlkZXI6IG1vY2tQcm92aWRlciB9KSxcbiAgICAgIChlcnI6IEVycm9yKSA9PiB7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnIubWVzc2FnZSwgJ0NvdWxkIG5vdCBpZGVudGlmeSB3aGljaCBwYXNza2V5IGRldmljZSB3YXMgdXNlZCcpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICApO1xuICB9KTtcbn0pO1xuIl19
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=registerPasskey.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registerPasskey.test.d.ts","sourceRoot":"","sources":["../../../test/unit/registerPasskey.test.ts"],"names":[],"mappings":""}