@bitgo-beta/sdk-core 8.2.1-beta.1792 → 8.2.1-beta.1793

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.
@@ -0,0 +1,2 @@
1
+ import 'should';
2
+ //# sourceMappingURL=initiate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initiate.d.ts","sourceRoot":"","sources":["../../../../../test/unit/bitgo/recovery/initiate.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAC"}
@@ -0,0 +1,230 @@
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
+ require("should");
37
+ const sinon = __importStar(require("sinon"));
38
+ const sjcl = __importStar(require("@bitgo-beta/sjcl"));
39
+ const initiate_1 = require("../../../../src/bitgo/recovery/initiate");
40
+ // A deterministic xprv used across all tests.
41
+ const TEST_XPRV = 'xprv9s21ZrQH143K2fJ91S4BRsupcYrE6mmY96fcX5HkhoTrrwmwjd16Cn87cWinJjByrfpojjx7ezsJLx7TAKLT8m8hM5Kax9YcoxnBeJZ3t2k';
42
+ const TEST_XPUB = 'xpub661MyMwAqRbcF9Nc7TbBo1rZAagiWEVPWKbDKThNG8zqjk76HAKLkaSbTn6dK2dQPfuD7xjicxCZVWvj67fP5nQ9W7QURmoMVAX8m6jZsGp';
43
+ /**
44
+ * Encrypt plaintext with SJCL (same algorithm as BitGoAPI.encrypt).
45
+ */
46
+ function sjclEncrypt(password, input) {
47
+ return sjcl.encrypt(password, input);
48
+ }
49
+ function makeMockBitGo(decryptImpl) {
50
+ return {
51
+ decrypt: sinon.stub().callsFake(decryptImpl),
52
+ decryptAsync: sinon.stub().callsFake(async (params) => decryptImpl(params)),
53
+ encrypt: sinon.stub(),
54
+ encryptAsync: sinon.stub(),
55
+ };
56
+ }
57
+ describe('validateKey', () => {
58
+ afterEach(() => {
59
+ sinon.restore();
60
+ });
61
+ it('returns a BIP32 node directly when key starts with xprv (bypasses decrypt)', () => {
62
+ const bitgo = makeMockBitGo(() => {
63
+ throw new Error('should not be called');
64
+ });
65
+ const node = (0, initiate_1.validateKey)(bitgo, {
66
+ key: TEST_XPRV,
67
+ source: 'user',
68
+ passphrase: 'secret',
69
+ isUnsignedSweep: false,
70
+ isKrsRecovery: false,
71
+ });
72
+ node.toBase58().should.equal(TEST_XPRV);
73
+ bitgo.decrypt.callCount.should.equal(0);
74
+ });
75
+ it('calls decrypt and returns BIP32 node when key is encrypted (not xprv)', () => {
76
+ const passphrase = 'hunter2';
77
+ const encryptedKey = sjclEncrypt(passphrase, TEST_XPRV);
78
+ const bitgo = makeMockBitGo(({ password, input }) => {
79
+ if (input === encryptedKey && password === passphrase)
80
+ return TEST_XPRV;
81
+ throw new Error('unexpected decrypt call');
82
+ });
83
+ const node = (0, initiate_1.validateKey)(bitgo, {
84
+ key: encryptedKey,
85
+ source: 'user',
86
+ passphrase,
87
+ isUnsignedSweep: false,
88
+ isKrsRecovery: false,
89
+ });
90
+ node.toBase58().should.equal(TEST_XPRV);
91
+ bitgo.decrypt.callCount.should.equal(1);
92
+ });
93
+ it('throws with friendly message when decrypt fails (wrong passphrase)', () => {
94
+ const bitgo = makeMockBitGo(() => {
95
+ throw new Error('sjcl: ccm: tag does not match');
96
+ });
97
+ (() => (0, initiate_1.validateKey)(bitgo, {
98
+ key: 'notAnXprv',
99
+ source: 'user',
100
+ passphrase: 'wrong',
101
+ isUnsignedSweep: false,
102
+ isKrsRecovery: false,
103
+ })).should.throw('Failed to decrypt user key with passcode - try again!');
104
+ });
105
+ });
106
+ describe('validateKeyAsync', () => {
107
+ afterEach(() => {
108
+ sinon.restore();
109
+ });
110
+ it('returns a BIP32 node directly when key starts with xprv (bypasses decryptAsync)', async () => {
111
+ const bitgo = makeMockBitGo(() => {
112
+ throw new Error('should not be called');
113
+ });
114
+ const node = await (0, initiate_1.validateKeyAsync)(bitgo, {
115
+ key: TEST_XPRV,
116
+ source: 'user',
117
+ passphrase: 'secret',
118
+ isUnsignedSweep: false,
119
+ isKrsRecovery: false,
120
+ });
121
+ node.toBase58().should.equal(TEST_XPRV);
122
+ bitgo.decryptAsync.callCount.should.equal(0);
123
+ });
124
+ it('calls decryptAsync and returns BIP32 node when key is encrypted (not xprv)', async () => {
125
+ const passphrase = 'hunter2';
126
+ const encryptedKey = sjclEncrypt(passphrase, TEST_XPRV);
127
+ const bitgo = makeMockBitGo(({ password, input }) => {
128
+ if (input === encryptedKey && password === passphrase)
129
+ return TEST_XPRV;
130
+ throw new Error('unexpected decrypt call');
131
+ });
132
+ const node = await (0, initiate_1.validateKeyAsync)(bitgo, {
133
+ key: encryptedKey,
134
+ source: 'user',
135
+ passphrase,
136
+ isUnsignedSweep: false,
137
+ isKrsRecovery: false,
138
+ });
139
+ node.toBase58().should.equal(TEST_XPRV);
140
+ bitgo.decryptAsync.callCount.should.equal(1);
141
+ });
142
+ it('rejects with friendly message when decryptAsync fails (wrong passphrase)', async () => {
143
+ const bitgo = makeMockBitGo(() => {
144
+ throw new Error('sjcl: ccm: tag does not match');
145
+ });
146
+ await (0, initiate_1.validateKeyAsync)(bitgo, {
147
+ key: 'notAnXprv',
148
+ source: 'user',
149
+ passphrase: 'wrong',
150
+ isUnsignedSweep: false,
151
+ isKrsRecovery: false,
152
+ }).should.be.rejectedWith('Failed to decrypt user key with passcode - try again!');
153
+ });
154
+ it('skips decryptAsync for unsigned sweep (isUnsignedSweep = true)', async () => {
155
+ const bitgo = makeMockBitGo(() => {
156
+ throw new Error('should not be called');
157
+ });
158
+ const node = await (0, initiate_1.validateKeyAsync)(bitgo, {
159
+ key: TEST_XPUB,
160
+ source: 'user',
161
+ passphrase: 'secret',
162
+ isUnsignedSweep: true,
163
+ isKrsRecovery: false,
164
+ });
165
+ node.neutered().toBase58().should.equal(TEST_XPUB);
166
+ bitgo.decryptAsync.callCount.should.equal(0);
167
+ });
168
+ });
169
+ describe('getBip32Keys', () => {
170
+ afterEach(() => {
171
+ sinon.restore();
172
+ });
173
+ it('returns [userKey, backupKey] when both are provided as xprv', () => {
174
+ const bitgo = makeMockBitGo(() => {
175
+ throw new Error('should not be called');
176
+ });
177
+ const keys = (0, initiate_1.getBip32Keys)(bitgo, { userKey: TEST_XPRV, backupKey: TEST_XPRV, recoveryDestination: 'addr' }, { requireBitGoXpub: false });
178
+ keys.should.have.length(2);
179
+ keys[0].toBase58().should.equal(TEST_XPRV);
180
+ keys[1].toBase58().should.equal(TEST_XPRV);
181
+ });
182
+ it('throws when requireBitGoXpub is true but bitgoKey is missing', () => {
183
+ const bitgo = makeMockBitGo(() => {
184
+ throw new Error('should not be called');
185
+ });
186
+ (() => (0, initiate_1.getBip32Keys)(bitgo, { userKey: TEST_XPRV, backupKey: TEST_XPRV, recoveryDestination: 'addr' }, { requireBitGoXpub: true })).should.throw('BitGo xpub required but not provided');
187
+ });
188
+ });
189
+ describe('getBip32KeysAsync', () => {
190
+ afterEach(() => {
191
+ sinon.restore();
192
+ });
193
+ it('returns [userKey, backupKey] when both are provided as xprv', async () => {
194
+ const bitgo = makeMockBitGo(() => {
195
+ throw new Error('should not be called');
196
+ });
197
+ const keys = await (0, initiate_1.getBip32KeysAsync)(bitgo, { userKey: TEST_XPRV, backupKey: TEST_XPRV, recoveryDestination: 'addr' }, { requireBitGoXpub: false });
198
+ keys.should.have.length(2);
199
+ keys[0].toBase58().should.equal(TEST_XPRV);
200
+ keys[1].toBase58().should.equal(TEST_XPRV);
201
+ });
202
+ it('returns three keys when requireBitGoXpub is true and bitgoKey is valid', async () => {
203
+ const bitgo = makeMockBitGo(() => {
204
+ throw new Error('should not be called');
205
+ });
206
+ const keys = await (0, initiate_1.getBip32KeysAsync)(bitgo, { userKey: TEST_XPRV, backupKey: TEST_XPRV, bitgoKey: TEST_XPUB, recoveryDestination: 'addr' }, { requireBitGoXpub: true });
207
+ keys.should.have.length(3);
208
+ keys[2].neutered().toBase58().should.equal(TEST_XPUB);
209
+ });
210
+ it('calls decryptAsync for encrypted user key', async () => {
211
+ const passphrase = 'pass1';
212
+ const encryptedUserKey = sjclEncrypt(passphrase, TEST_XPRV);
213
+ const bitgo = makeMockBitGo(({ password, input }) => {
214
+ if (input === encryptedUserKey && password === passphrase)
215
+ return TEST_XPRV;
216
+ throw new Error('unexpected decrypt call');
217
+ });
218
+ const keys = await (0, initiate_1.getBip32KeysAsync)(bitgo, { userKey: encryptedUserKey, backupKey: TEST_XPRV, walletPassphrase: passphrase, recoveryDestination: 'addr' }, { requireBitGoXpub: false });
219
+ keys.should.have.length(2);
220
+ keys[0].toBase58().should.equal(TEST_XPRV);
221
+ bitgo.decryptAsync.callCount.should.equal(1);
222
+ });
223
+ it('rejects when requireBitGoXpub is true but bitgoKey is missing', async () => {
224
+ const bitgo = makeMockBitGo(() => {
225
+ throw new Error('should not be called');
226
+ });
227
+ await (0, initiate_1.getBip32KeysAsync)(bitgo, { userKey: TEST_XPRV, backupKey: TEST_XPRV, recoveryDestination: 'addr' }, { requireBitGoXpub: true }).should.be.rejectedWith('BitGo xpub required but not provided');
228
+ });
229
+ });
230
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdGlhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi90ZXN0L3VuaXQvYml0Z28vcmVjb3ZlcnkvaW5pdGlhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxrQkFBZ0I7QUFDaEIsNkNBQStCO0FBQy9CLHVEQUF5QztBQUN6QyxzRUFLaUQ7QUFHakQsOENBQThDO0FBQzlDLE1BQU0sU0FBUyxHQUNiLGlIQUFpSCxDQUFDO0FBQ3BILE1BQU0sU0FBUyxHQUNiLGlIQUFpSCxDQUFDO0FBRXBIOztHQUVHO0FBQ0gsU0FBUyxXQUFXLENBQUMsUUFBZ0IsRUFBRSxLQUFhO0lBQ2xELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFzQixDQUFDO0FBQzVELENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxXQUFxRTtJQUMxRixPQUFPO1FBQ0wsT0FBTyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDO1FBQzVDLFlBQVksRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxNQUE0QyxFQUFFLEVBQUUsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDakgsT0FBTyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUU7UUFDckIsWUFBWSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUU7S0FDSCxDQUFDO0FBQzVCLENBQUM7QUFFRCxRQUFRLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRTtJQUMzQixTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2IsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2xCLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDRFQUE0RSxFQUFFLEdBQUcsRUFBRTtRQUNwRixNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsR0FB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QUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMxQyxLQUFLLENBQUMsWUFBZ0MsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywrREFBK0QsRUFBRSxLQUFLLElBQUksRUFBRTtRQUM3RSxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsR0FBRyxFQUFFO1lBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUMxQyxDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sSUFBQSw0QkFBaUIsRUFDckIsS0FBSyxFQUNMLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxFQUN6RSxFQUFFLGdCQUFnQixFQUFFLElBQUksRUFBRSxDQUMzQixDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7SUFDbkUsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAnc2hvdWxkJztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCAqIGFzIHNqY2wgZnJvbSAnQGJpdGdvLWJldGEvc2pjbCc7XG5pbXBvcnQge1xuICB2YWxpZGF0ZUtleSxcbiAgdmFsaWRhdGVLZXlBc3luYyxcbiAgZ2V0QmlwMzJLZXlzLFxuICBnZXRCaXAzMktleXNBc3luYyxcbn0gZnJvbSAnLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3JlY292ZXJ5L2luaXRpYXRlJztcbmltcG9ydCB7IEJpdEdvQmFzZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NyYy9iaXRnby9iaXRnb0Jhc2UnO1xuXG4vLyBBIGRldGVybWluaXN0aWMgeHBydiB1c2VkIGFjcm9zcyBhbGwgdGVzdHMuXG5jb25zdCBURVNUX1hQUlYgPVxuICAneHBydjlzMjFaclFIMTQzSzJmSjkxUzRCUnN1cGNZckU2bW1ZOTZmY1g1SGtob1Rycndtd2pkMTZDbjg3Y1dpbkpqQnlyZnBvamp4N2V6c0pMeDdUQUtMVDhtOGhNNUtheDlZY294bkJlSlozdDJrJztcbmNvbnN0IFRFU1RfWFBVQiA9XG4gICd4cHViNjYxTXlNd0FxUmJjRjlOYzdUYkJvMXJaQWFnaVdFVlBXS2JES1RoTkc4enFqazc2SEFLTGthU2JUbjZkSzJkUVBmdUQ3eGppY3hDWlZXdmo2N2ZQNW5ROVc3UVVSbW9NVkFYOG02alpzR3AnO1xuXG4vKipcbiAqIEVuY3J5cHQgcGxhaW50ZXh0IHdpdGggU0pDTCAoc2FtZSBhbGdvcml0aG0gYXMgQml0R29BUEkuZW5jcnlwdCkuXG4gKi9cbmZ1bmN0aW9uIHNqY2xFbmNyeXB0KHBhc3N3b3JkOiBzdHJpbmcsIGlucHV0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gc2pjbC5lbmNyeXB0KHBhc3N3b3JkLCBpbnB1dCkgYXMgdW5rbm93biBhcyBzdHJpbmc7XG59XG5cbmZ1bmN0aW9uIG1ha2VNb2NrQml0R28oZGVjcnlwdEltcGw6IChwYXJhbXM6IHsgcGFzc3dvcmQ/OiBzdHJpbmc7IGlucHV0OiBzdHJpbmcgfSkgPT4gc3RyaW5nKTogQml0R29CYXNlIHtcbiAgcmV0dXJuIHtcbiAgICBkZWNyeXB0OiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGRlY3J5cHRJbXBsKSxcbiAgICBkZWNyeXB0QXN5bmM6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoYXN5bmMgKHBhcmFtczogeyBwYXNzd29yZD86IHN0cmluZzsgaW5wdXQ6IHN0cmluZyB9KSA9PiBkZWNyeXB0SW1wbChwYXJhbXMpKSxcbiAgICBlbmNyeXB0OiBzaW5vbi5zdHViKCksXG4gICAgZW5jcnlwdEFzeW5jOiBzaW5vbi5zdHViKCksXG4gIH0gYXMgdW5rbm93biBhcyBCaXRHb0Jhc2U7XG59XG5cbmRlc2NyaWJlKCd2YWxpZGF0ZUtleScsICgpID0+IHtcbiAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICBzaW5vbi5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIGEgQklQMzIgbm9kZSBkaXJlY3RseSB3aGVuIGtleSBzdGFydHMgd2l0aCB4cHJ2IChieXBhc3NlcyBkZWNyeXB0KScsICgpID0+IHtcbiAgICBjb25zdCBiaXRnbyA9IG1ha2VNb2NrQml0R28oKCkgPT4ge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzaG91bGQgbm90IGJlIGNhbGxlZCcpO1xuICAgIH0pO1xuICAgIGNvbnN0IG5vZGUgPSB2YWxpZGF0ZUtleShiaXRnbywge1xuICAgICAga2V5OiBURVNUX1hQUlYsXG4gICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgIHBhc3NwaHJhc2U6ICdzZWNyZXQnLFxuICAgICAgaXNVbnNpZ25lZFN3ZWVwOiBmYWxzZSxcbiAgICAgIGlzS3JzUmVjb3Zlcnk6IGZhbHNlLFxuICAgIH0pO1xuICAgIG5vZGUudG9CYXNlNTgoKS5zaG91bGQuZXF1YWwoVEVTVF9YUFJWKTtcbiAgICAoYml0Z28uZGVjcnlwdCBhcyBzaW5vbi5TaW5vblN0dWIpLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMCk7XG4gIH0pO1xuXG4gIGl0KCdjYWxscyBkZWNyeXB0IGFuZCByZXR1cm5zIEJJUDMyIG5vZGUgd2hlbiBrZXkgaXMgZW5jcnlwdGVkIChub3QgeHBydiknLCAoKSA9PiB7XG4gICAgY29uc3QgcGFzc3BocmFzZSA9ICdodW50ZXIyJztcbiAgICBjb25zdCBlbmNyeXB0ZWRLZXkgPSBzamNsRW5jcnlwdChwYXNzcGhyYXNlLCBURVNUX1hQUlYpO1xuICAgIGNvbnN0IGJpdGdvID0gbWFrZU1vY2tCaXRHbygoeyBwYXNzd29yZCwgaW5wdXQgfSkgPT4ge1xuICAgICAgaWYgKGlucHV0ID09PSBlbmNyeXB0ZWRLZXkgJiYgcGFzc3dvcmQgPT09IHBhc3NwaHJhc2UpIHJldHVybiBURVNUX1hQUlY7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VuZXhwZWN0ZWQgZGVjcnlwdCBjYWxsJyk7XG4gICAgfSk7XG4gICAgY29uc3Qgbm9kZSA9IHZhbGlkYXRlS2V5KGJpdGdvLCB7XG4gICAgICBrZXk6IGVuY3J5cHRlZEtleSxcbiAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgcGFzc3BocmFzZSxcbiAgICAgIGlzVW5zaWduZWRTd2VlcDogZmFsc2UsXG4gICAgICBpc0tyc1JlY292ZXJ5OiBmYWxzZSxcbiAgICB9KTtcbiAgICBub2RlLnRvQmFzZTU4KCkuc2hvdWxkLmVxdWFsKFRFU1RfWFBSVik7XG4gICAgKGJpdGdvLmRlY3J5cHQgYXMgc2lub24uU2lub25TdHViKS5jYWxsQ291bnQuc2hvdWxkLmVxdWFsKDEpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIHdpdGggZnJpZW5kbHkgbWVzc2FnZSB3aGVuIGRlY3J5cHQgZmFpbHMgKHdyb25nIHBhc3NwaHJhc2UpJywgKCkgPT4ge1xuICAgIGNvbnN0IGJpdGdvID0gbWFrZU1vY2tCaXRHbygoKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NqY2w6IGNjbTogdGFnIGRvZXMgbm90IG1hdGNoJyk7XG4gICAgfSk7XG4gICAgKCgpID0+XG4gICAgICB2YWxpZGF0ZUtleShiaXRnbywge1xuICAgICAgICBrZXk6ICdub3RBblhwcnYnLFxuICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3dyb25nJyxcbiAgICAgICAgaXNVbnNpZ25lZFN3ZWVwOiBmYWxzZSxcbiAgICAgICAgaXNLcnNSZWNvdmVyeTogZmFsc2UsXG4gICAgICB9KSkuc2hvdWxkLnRocm93KCdGYWlsZWQgdG8gZGVjcnlwdCB1c2VyIGtleSB3aXRoIHBhc3Njb2RlIC0gdHJ5IGFnYWluIScpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgndmFsaWRhdGVLZXlBc3luYycsICgpID0+IHtcbiAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICBzaW5vbi5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIGEgQklQMzIgbm9kZSBkaXJlY3RseSB3aGVuIGtleSBzdGFydHMgd2l0aCB4cHJ2IChieXBhc3NlcyBkZWNyeXB0QXN5bmMpJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGJpdGdvID0gbWFrZU1vY2tCaXRHbygoKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Nob3VsZCBub3QgYmUgY2FsbGVkJyk7XG4gICAgfSk7XG4gICAgY29uc3Qgbm9kZSA9IGF3YWl0IHZhbGlkYXRlS2V5QXN5bmMoYml0Z28sIHtcbiAgICAgIGtleTogVEVTVF9YUFJWLFxuICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICBwYXNzcGhyYXNlOiAnc2VjcmV0JyxcbiAgICAgIGlzVW5zaWduZWRTd2VlcDogZmFsc2UsXG4gICAgICBpc0tyc1JlY292ZXJ5OiBmYWxzZSxcbiAgICB9KTtcbiAgICBub2RlLnRvQmFzZTU4KCkuc2hvdWxkLmVxdWFsKFRFU1RfWFBSVik7XG4gICAgKGJpdGdvLmRlY3J5cHRBc3luYyBhcyBzaW5vbi5TaW5vblN0dWIpLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMCk7XG4gIH0pO1xuXG4gIGl0KCdjYWxscyBkZWNyeXB0QXN5bmMgYW5kIHJldHVybnMgQklQMzIgbm9kZSB3aGVuIGtleSBpcyBlbmNyeXB0ZWQgKG5vdCB4cHJ2KScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBwYXNzcGhyYXNlID0gJ2h1bnRlcjInO1xuICAgIGNvbnN0IGVuY3J5cHRlZEtleSA9IHNqY2xFbmNyeXB0KHBhc3NwaHJhc2UsIFRFU1RfWFBSVik7XG4gICAgY29uc3QgYml0Z28gPSBtYWtlTW9ja0JpdEdvKCh7IHBhc3N3b3JkLCBpbnB1dCB9KSA9PiB7XG4gICAgICBpZiAoaW5wdXQgPT09IGVuY3J5cHRlZEtleSAmJiBwYXNzd29yZCA9PT0gcGFzc3BocmFzZSkgcmV0dXJuIFRFU1RfWFBSVjtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5leHBlY3RlZCBkZWNyeXB0IGNhbGwnKTtcbiAgICB9KTtcbiAgICBjb25zdCBub2RlID0gYXdhaXQgdmFsaWRhdGVLZXlBc3luYyhiaXRnbywge1xuICAgICAga2V5OiBlbmNyeXB0ZWRLZXksXG4gICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgIHBhc3NwaHJhc2UsXG4gICAgICBpc1Vuc2lnbmVkU3dlZXA6IGZhbHNlLFxuICAgICAgaXNLcnNSZWNvdmVyeTogZmFsc2UsXG4gICAgfSk7XG4gICAgbm9kZS50b0Jhc2U1OCgpLnNob3VsZC5lcXVhbChURVNUX1hQUlYpO1xuICAgIChiaXRnby5kZWNyeXB0QXN5bmMgYXMgc2lub24uU2lub25TdHViKS5jYWxsQ291bnQuc2hvdWxkLmVxdWFsKDEpO1xuICB9KTtcblxuICBpdCgncmVqZWN0cyB3aXRoIGZyaWVuZGx5IG1lc3NhZ2Ugd2hlbiBkZWNyeXB0QXN5bmMgZmFpbHMgKHdyb25nIHBhc3NwaHJhc2UpJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGJpdGdvID0gbWFrZU1vY2tCaXRHbygoKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NqY2w6IGNjbTogdGFnIGRvZXMgbm90IG1hdGNoJyk7XG4gICAgfSk7XG4gICAgYXdhaXQgdmFsaWRhdGVLZXlBc3luYyhiaXRnbywge1xuICAgICAga2V5OiAnbm90QW5YcHJ2JyxcbiAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgcGFzc3BocmFzZTogJ3dyb25nJyxcbiAgICAgIGlzVW5zaWduZWRTd2VlcDogZmFsc2UsXG4gICAgICBpc0tyc1JlY292ZXJ5OiBmYWxzZSxcbiAgICB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdGYWlsZWQgdG8gZGVjcnlwdCB1c2VyIGtleSB3aXRoIHBhc3Njb2RlIC0gdHJ5IGFnYWluIScpO1xuICB9KTtcblxuICBpdCgnc2tpcHMgZGVjcnlwdEFzeW5jIGZvciB1bnNpZ25lZCBzd2VlcCAoaXNVbnNpZ25lZFN3ZWVwID0gdHJ1ZSknLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYml0Z28gPSBtYWtlTW9ja0JpdEdvKCgpID0+IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc2hvdWxkIG5vdCBiZSBjYWxsZWQnKTtcbiAgICB9KTtcbiAgICBjb25zdCBub2RlID0gYXdhaXQgdmFsaWRhdGVLZXlBc3luYyhiaXRnbywge1xuICAgICAga2V5OiBURVNUX1hQVUIsXG4gICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgIHBhc3NwaHJhc2U6ICdzZWNyZXQnLFxuICAgICAgaXNVbnNpZ25lZFN3ZWVwOiB0cnVlLFxuICAgICAgaXNLcnNSZWNvdmVyeTogZmFsc2UsXG4gICAgfSk7XG4gICAgbm9kZS5uZXV0ZXJlZCgpLnRvQmFzZTU4KCkuc2hvdWxkLmVxdWFsKFRFU1RfWFBVQik7XG4gICAgKGJpdGdvLmRlY3J5cHRBc3luYyBhcyBzaW5vbi5TaW5vblN0dWIpLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMCk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdnZXRCaXAzMktleXMnLCAoKSA9PiB7XG4gIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgc2lub24ucmVzdG9yZSgpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyBbdXNlcktleSwgYmFja3VwS2V5XSB3aGVuIGJvdGggYXJlIHByb3ZpZGVkIGFzIHhwcnYnLCAoKSA9PiB7XG4gICAgY29uc3QgYml0Z28gPSBtYWtlTW9ja0JpdEdvKCgpID0+IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc2hvdWxkIG5vdCBiZSBjYWxsZWQnKTtcbiAgICB9KTtcbiAgICBjb25zdCBrZXlzID0gZ2V0QmlwMzJLZXlzKFxuICAgICAgYml0Z28sXG4gICAgICB7IHVzZXJLZXk6IFRFU1RfWFBSViwgYmFja3VwS2V5OiBURVNUX1hQUlYsIHJlY292ZXJ5RGVzdGluYXRpb246ICdhZGRyJyB9LFxuICAgICAgeyByZXF1aXJlQml0R29YcHViOiBmYWxzZSB9XG4gICAgKTtcbiAgICBrZXlzLnNob3VsZC5oYXZlLmxlbmd0aCgyKTtcbiAgICBrZXlzWzBdLnRvQmFzZTU4KCkuc2hvdWxkLmVxdWFsKFRFU1RfWFBSVik7XG4gICAga2V5c1sxXS50b0Jhc2U1OCgpLnNob3VsZC5lcXVhbChURVNUX1hQUlYpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIHdoZW4gcmVxdWlyZUJpdEdvWHB1YiBpcyB0cnVlIGJ1dCBiaXRnb0tleSBpcyBtaXNzaW5nJywgKCkgPT4ge1xuICAgIGNvbnN0IGJpdGdvID0gbWFrZU1vY2tCaXRHbygoKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Nob3VsZCBub3QgYmUgY2FsbGVkJyk7XG4gICAgfSk7XG4gICAgKCgpID0+XG4gICAgICBnZXRCaXAzMktleXMoXG4gICAgICAgIGJpdGdvLFxuICAgICAgICB7IHVzZXJLZXk6IFRFU1RfWFBSViwgYmFja3VwS2V5OiBURVNUX1hQUlYsIHJlY292ZXJ5RGVzdGluYXRpb246ICdhZGRyJyB9LFxuICAgICAgICB7IHJlcXVpcmVCaXRHb1hwdWI6IHRydWUgfVxuICAgICAgKSkuc2hvdWxkLnRocm93KCdCaXRHbyB4cHViIHJlcXVpcmVkIGJ1dCBub3QgcHJvdmlkZWQnKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ2dldEJpcDMyS2V5c0FzeW5jJywgKCkgPT4ge1xuICBhZnRlckVhY2goKCkgPT4ge1xuICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgW3VzZXJLZXksIGJhY2t1cEtleV0gd2hlbiBib3RoIGFyZSBwcm92aWRlZCBhcyB4cHJ2JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGJpdGdvID0gbWFrZU1vY2tCaXRHbygoKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Nob3VsZCBub3QgYmUgY2FsbGVkJyk7XG4gICAgfSk7XG4gICAgY29uc3Qga2V5cyA9IGF3YWl0IGdldEJpcDMyS2V5c0FzeW5jKFxuICAgICAgYml0Z28sXG4gICAgICB7IHVzZXJLZXk6IFRFU1RfWFBSViwgYmFja3VwS2V5OiBURVNUX1hQUlYsIHJlY292ZXJ5RGVzdGluYXRpb246ICdhZGRyJyB9LFxuICAgICAgeyByZXF1aXJlQml0R29YcHViOiBmYWxzZSB9XG4gICAgKTtcbiAgICBrZXlzLnNob3VsZC5oYXZlLmxlbmd0aCgyKTtcbiAgICBrZXlzWzBdLnRvQmFzZTU4KCkuc2hvdWxkLmVxdWFsKFRFU1RfWFBSVik7XG4gICAga2V5c1sxXS50b0Jhc2U1OCgpLnNob3VsZC5lcXVhbChURVNUX1hQUlYpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyB0aHJlZSBrZXlzIHdoZW4gcmVxdWlyZUJpdEdvWHB1YiBpcyB0cnVlIGFuZCBiaXRnb0tleSBpcyB2YWxpZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBiaXRnbyA9IG1ha2VNb2NrQml0R28oKCkgPT4ge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzaG91bGQgbm90IGJlIGNhbGxlZCcpO1xuICAgIH0pO1xuICAgIGNvbnN0IGtleXMgPSBhd2FpdCBnZXRCaXAzMktleXNBc3luYyhcbiAgICAgIGJpdGdvLFxuICAgICAgeyB1c2VyS2V5OiBURVNUX1hQUlYsIGJhY2t1cEtleTogVEVTVF9YUFJWLCBiaXRnb0tleTogVEVTVF9YUFVCLCByZWNvdmVyeURlc3RpbmF0aW9uOiAnYWRkcicgfSxcbiAgICAgIHsgcmVxdWlyZUJpdEdvWHB1YjogdHJ1ZSB9XG4gICAgKTtcbiAgICBrZXlzLnNob3VsZC5oYXZlLmxlbmd0aCgzKTtcbiAgICBrZXlzWzJdLm5ldXRlcmVkKCkudG9CYXNlNTgoKS5zaG91bGQuZXF1YWwoVEVTVF9YUFVCKTtcbiAgfSk7XG5cbiAgaXQoJ2NhbGxzIGRlY3J5cHRBc3luYyBmb3IgZW5jcnlwdGVkIHVzZXIga2V5JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHBhc3NwaHJhc2UgPSAncGFzczEnO1xuICAgIGNvbnN0IGVuY3J5cHRlZFVzZXJLZXkgPSBzamNsRW5jcnlwdChwYXNzcGhyYXNlLCBURVNUX1hQUlYpO1xuICAgIGNvbnN0IGJpdGdvID0gbWFrZU1vY2tCaXRHbygoeyBwYXNzd29yZCwgaW5wdXQgfSkgPT4ge1xuICAgICAgaWYgKGlucHV0ID09PSBlbmNyeXB0ZWRVc2VyS2V5ICYmIHBhc3N3b3JkID09PSBwYXNzcGhyYXNlKSByZXR1cm4gVEVTVF9YUFJWO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmV4cGVjdGVkIGRlY3J5cHQgY2FsbCcpO1xuICAgIH0pO1xuICAgIGNvbnN0IGtleXMgPSBhd2FpdCBnZXRCaXAzMktleXNBc3luYyhcbiAgICAgIGJpdGdvLFxuICAgICAgeyB1c2VyS2V5OiBlbmNyeXB0ZWRVc2VyS2V5LCBiYWNrdXBLZXk6IFRFU1RfWFBSViwgd2FsbGV0UGFzc3BocmFzZTogcGFzc3BocmFzZSwgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ2FkZHInIH0sXG4gICAgICB7IHJlcXVpcmVCaXRHb1hwdWI6IGZhbHNlIH1cbiAgICApO1xuICAgIGtleXMuc2hvdWxkLmhhdmUubGVuZ3RoKDIpO1xuICAgIGtleXNbMF0udG9CYXNlNTgoKS5zaG91bGQuZXF1YWwoVEVTVF9YUFJWKTtcbiAgICAoYml0Z28uZGVjcnlwdEFzeW5jIGFzIHNpbm9uLlNpbm9uU3R1YikuY2FsbENvdW50LnNob3VsZC5lcXVhbCgxKTtcbiAgfSk7XG5cbiAgaXQoJ3JlamVjdHMgd2hlbiByZXF1aXJlQml0R29YcHViIGlzIHRydWUgYnV0IGJpdGdvS2V5IGlzIG1pc3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYml0Z28gPSBtYWtlTW9ja0JpdEdvKCgpID0+IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc2hvdWxkIG5vdCBiZSBjYWxsZWQnKTtcbiAgICB9KTtcbiAgICBhd2FpdCBnZXRCaXAzMktleXNBc3luYyhcbiAgICAgIGJpdGdvLFxuICAgICAgeyB1c2VyS2V5OiBURVNUX1hQUlYsIGJhY2t1cEtleTogVEVTVF9YUFJWLCByZWNvdmVyeURlc3RpbmF0aW9uOiAnYWRkcicgfSxcbiAgICAgIHsgcmVxdWlyZUJpdEdvWHB1YjogdHJ1ZSB9XG4gICAgKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdCaXRHbyB4cHViIHJlcXVpcmVkIGJ1dCBub3QgcHJvdmlkZWQnKTtcbiAgfSk7XG59KTtcbiJdfQ==