@keetanetwork/anchor 0.0.1

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 (76) hide show
  1. package/.done +0 -0
  2. package/LICENSE +35 -0
  3. package/client/index.d.ts +10 -0
  4. package/client/index.d.ts.map +1 -0
  5. package/client/index.js +11 -0
  6. package/client/index.js.map +1 -0
  7. package/config.d.ts +10 -0
  8. package/config.d.ts.map +1 -0
  9. package/config.js +36 -0
  10. package/config.js.map +1 -0
  11. package/lib/certificates.d.ts +106 -0
  12. package/lib/certificates.d.ts.map +1 -0
  13. package/lib/certificates.js +463 -0
  14. package/lib/certificates.js.map +1 -0
  15. package/lib/encrypted-container.d.ts +106 -0
  16. package/lib/encrypted-container.d.ts.map +1 -0
  17. package/lib/encrypted-container.js +594 -0
  18. package/lib/encrypted-container.js.map +1 -0
  19. package/lib/index.d.ts +5 -0
  20. package/lib/index.d.ts.map +1 -0
  21. package/lib/index.js +5 -0
  22. package/lib/index.js.map +1 -0
  23. package/lib/log/common.d.ts +35 -0
  24. package/lib/log/common.d.ts.map +1 -0
  25. package/lib/log/common.js +19 -0
  26. package/lib/log/common.js.map +1 -0
  27. package/lib/log/index.d.ts +59 -0
  28. package/lib/log/index.d.ts.map +1 -0
  29. package/lib/log/index.js +207 -0
  30. package/lib/log/index.js.map +1 -0
  31. package/lib/log/target_console.d.ts +13 -0
  32. package/lib/log/target_console.d.ts.map +1 -0
  33. package/lib/log/target_console.js +44 -0
  34. package/lib/log/target_console.js.map +1 -0
  35. package/lib/resolver.d.ts +308 -0
  36. package/lib/resolver.d.ts.map +1 -0
  37. package/lib/resolver.js +1429 -0
  38. package/lib/resolver.js.map +1 -0
  39. package/lib/utils/array.d.ts +10 -0
  40. package/lib/utils/array.d.ts.map +1 -0
  41. package/lib/utils/array.js +12 -0
  42. package/lib/utils/array.js.map +1 -0
  43. package/lib/utils/asn1.d.ts +13 -0
  44. package/lib/utils/asn1.d.ts.map +1 -0
  45. package/lib/utils/asn1.js +8 -0
  46. package/lib/utils/asn1.js.map +1 -0
  47. package/lib/utils/buffer.d.ts +4 -0
  48. package/lib/utils/buffer.d.ts.map +1 -0
  49. package/lib/utils/buffer.js +3 -0
  50. package/lib/utils/buffer.js.map +1 -0
  51. package/lib/utils/crypto.d.ts +4 -0
  52. package/lib/utils/crypto.d.ts.map +1 -0
  53. package/lib/utils/crypto.js +4 -0
  54. package/lib/utils/crypto.js.map +1 -0
  55. package/lib/utils/index.d.ts +5 -0
  56. package/lib/utils/index.d.ts.map +1 -0
  57. package/lib/utils/index.js +5 -0
  58. package/lib/utils/index.js.map +1 -0
  59. package/lib/utils/json.d.ts +8 -0
  60. package/lib/utils/json.d.ts.map +1 -0
  61. package/lib/utils/json.js +164 -0
  62. package/lib/utils/json.js.map +1 -0
  63. package/lib/utils/never.d.ts +8 -0
  64. package/lib/utils/never.d.ts.map +1 -0
  65. package/lib/utils/never.js +14 -0
  66. package/lib/utils/never.js.map +1 -0
  67. package/npm-shrinkwrap.json +16517 -0
  68. package/package.json +42 -0
  69. package/services/kyc/client.d.ts +139 -0
  70. package/services/kyc/client.d.ts.map +1 -0
  71. package/services/kyc/client.js +390 -0
  72. package/services/kyc/client.js.map +1 -0
  73. package/services/kyc/common.d.ts +65 -0
  74. package/services/kyc/common.d.ts.map +1 -0
  75. package/services/kyc/common.js +2 -0
  76. package/services/kyc/common.js.map +1 -0
@@ -0,0 +1,594 @@
1
+ import crypto from './utils/crypto.js';
2
+ import { lib as KeetaNetLib } from '@keetanetwork/keetanet-client';
3
+ import { Buffer } from './utils/buffer.js';
4
+ import { isArray } from './utils/array.js';
5
+ const zlibDeflate = KeetaNetLib.Utils.Buffer.ZlibDeflate; /* XXX:TODO: Change this to ZlibDeflateAsync when merged in */
6
+ const zlibInflate = KeetaNetLib.Utils.Buffer.ZlibInflate; /* XXX:TODO: Change this to ZlibInflateAsync when merged in */
7
+ const ASN1toJS = KeetaNetLib.Utils.ASN1.ASN1toJS;
8
+ const JStoASN1 = KeetaNetLib.Utils.ASN1.JStoASN1;
9
+ const Account = KeetaNetLib.Account;
10
+ const bufferToArrayBuffer = KeetaNetLib.Utils.Helper.bufferToArrayBuffer;
11
+ const oidDB = {
12
+ 'aes-256-cbc': '2.16.840.1.101.3.4.1.42'
13
+ };
14
+ /**
15
+ * Compiles the ASN.1 for the container
16
+ *
17
+ * @returns The ASN.1 DER data
18
+ */
19
+ async function buildASN1(plaintext, encryptionOptions) {
20
+ const compressedPlaintext = Buffer.from(zlibDeflate(plaintext));
21
+ const sequence = [];
22
+ /*
23
+ * Version v2 (1)
24
+ */
25
+ sequence[0] = 1;
26
+ /*
27
+ * Encrypted container box
28
+ */
29
+ if (encryptionOptions) {
30
+ const { keys, cipherKey, cipherIV, cipherAlgo } = encryptionOptions;
31
+ if (keys === undefined || keys.length === 0 || cipherKey === undefined || cipherIV === undefined || cipherAlgo === undefined) {
32
+ throw (new Error('internal error: Unsupported method invocation'));
33
+ }
34
+ if (!(cipherAlgo in oidDB)) {
35
+ throw (new Error(`Unsupported algorithm: ${cipherAlgo}`));
36
+ }
37
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
38
+ const algorithmOID = oidDB[cipherAlgo];
39
+ const cipher = crypto.createCipheriv(cipherAlgo, cipherKey, cipherIV);
40
+ const encryptedData = Buffer.concat([
41
+ cipher.update(compressedPlaintext),
42
+ cipher.final()
43
+ ]);
44
+ const cipherKeyArrayBuffer = bufferToArrayBuffer(cipherKey);
45
+ const encryptionKeysSequence = await Promise.all(keys.map(async function (key) {
46
+ const encryptedSymmetricKey = Buffer.from(await key.encrypt(cipherKeyArrayBuffer));
47
+ const retval = [
48
+ key.publicKeyAndType,
49
+ encryptedSymmetricKey
50
+ ];
51
+ return (retval);
52
+ }));
53
+ sequence[1] = {
54
+ type: 'context',
55
+ value: 0,
56
+ kind: 'explicit',
57
+ contains: [
58
+ encryptionKeysSequence,
59
+ { type: 'oid', oid: algorithmOID },
60
+ cipherIV,
61
+ encryptedData
62
+ ]
63
+ };
64
+ }
65
+ else {
66
+ /*
67
+ * Otherwise we simply pass in the compressed data
68
+ */
69
+ sequence[1] = {
70
+ type: 'context',
71
+ value: 1,
72
+ kind: 'explicit',
73
+ contains: [compressedPlaintext]
74
+ };
75
+ }
76
+ const outputASN1 = JStoASN1(sequence);
77
+ const outputDER = Buffer.from(outputASN1.toBER(false));
78
+ return (outputDER);
79
+ }
80
+ function parseASN1Bare(input, acceptableEncryptionAlgorithms = ['aes-256-cbc', 'null']) {
81
+ const inputSequence = ASN1toJS(bufferToArrayBuffer(input));
82
+ if (!isArray(inputSequence, 2)) {
83
+ throw (new Error('Malformed data detected (incorrect base format)'));
84
+ }
85
+ const version = inputSequence[0];
86
+ if (typeof version !== 'bigint') {
87
+ throw (new Error('Malformed data detected (version expected at position 0)'));
88
+ }
89
+ if (version !== 1n) {
90
+ throw (new Error('Malformed data detected (unsupported version)'));
91
+ }
92
+ const valueBox = inputSequence[1];
93
+ if (typeof valueBox !== 'object' || valueBox === null) {
94
+ throw (new Error('Malformed data detected (data expected at position 1)'));
95
+ }
96
+ if (!('type' in valueBox) || typeof valueBox.type !== 'string') {
97
+ throw (new Error('Malformed data detected (expected type at position 1)'));
98
+ }
99
+ if (valueBox.type !== 'context') {
100
+ throw (new Error('Malformed data detected (expected context at position 1)'));
101
+ }
102
+ if (!('value' in valueBox) || typeof valueBox.value !== 'number') {
103
+ throw (new Error('Malformed data detected (expected context value at position 1)'));
104
+ }
105
+ if (valueBox.value !== 0 && valueBox.value !== 1) {
106
+ throw (new Error('Malformed data detected (expected context value of 0 or 1)'));
107
+ }
108
+ if (!('contains' in valueBox) || typeof valueBox.contains !== 'object' || valueBox.contains === null) {
109
+ throw (new Error('Malformed data detected (expected contents at position 1)'));
110
+ }
111
+ let isEncrypted;
112
+ if (valueBox.value === 0) {
113
+ isEncrypted = true;
114
+ }
115
+ else {
116
+ isEncrypted = false;
117
+ }
118
+ const value = valueBox.contains;
119
+ let containedCompressed;
120
+ let cipherInfo;
121
+ if (isEncrypted) {
122
+ if (!isArray(value, 4)) {
123
+ throw (new Error('Malformed data (incorrect number of elements within position 1 -- expected 4)'));
124
+ }
125
+ const keyInfoUnchecked = value[0];
126
+ if (!isArray(keyInfoUnchecked)) {
127
+ throw (new Error('Malformed data (expected sequence at position 2.0)'));
128
+ }
129
+ const keyInfo = keyInfoUnchecked.map(function (checkKeyInfo) {
130
+ if (!isArray(checkKeyInfo, 2)) {
131
+ throw (new Error('Malformed key information (expected sequence of 2 at position 1.0.x)'));
132
+ }
133
+ const publicKeyBuffer = checkKeyInfo[0];
134
+ if (!Buffer.isBuffer(publicKeyBuffer)) {
135
+ throw (new Error('Malformed key information (expected octet string for public key at position 1.0.x)'));
136
+ }
137
+ const publicKey = Account.fromPublicKeyAndType(publicKeyBuffer);
138
+ const encryptedSymmetricKey = checkKeyInfo[1];
139
+ if (!Buffer.isBuffer(encryptedSymmetricKey)) {
140
+ throw (new Error('Malformed key information (expected octet string for cipher key at position 1.0.x)'));
141
+ }
142
+ return ({
143
+ publicKey,
144
+ encryptedSymmetricKey
145
+ });
146
+ });
147
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
148
+ const encryptionAlgorithmOID = value[1];
149
+ /* XXX:TODO: Lookup the encryption algorithm from the OID */
150
+ const encryptionAlgorithm = 'aes-256-cbc';
151
+ const cipherIV = value[2];
152
+ if (!Buffer.isBuffer(cipherIV)) {
153
+ throw (new Error('Malformed data (cipher IV expected at position 1.2)'));
154
+ }
155
+ const encryptedCompressedValue = value[3];
156
+ if (!Buffer.isBuffer(encryptedCompressedValue)) {
157
+ throw (new Error('Malformed data (encrypted compressed buffer expected at position 1.3)'));
158
+ }
159
+ cipherInfo = {
160
+ keys: keyInfo,
161
+ cipherIV: cipherIV,
162
+ encryptedData: encryptedCompressedValue,
163
+ encryptionAlgorithm: encryptionAlgorithm
164
+ };
165
+ containedCompressed = encryptedCompressedValue;
166
+ }
167
+ else {
168
+ if (!isArray(value, 1)) {
169
+ throw (new Error('Malformed data (incorrect number of elements within position 1 -- expected 1)'));
170
+ }
171
+ const containedCompressedUnchecked = value[0];
172
+ if (!Buffer.isBuffer(containedCompressedUnchecked)) {
173
+ throw (new Error('Malformed data (compressed buffer expected at position 1.0)'));
174
+ }
175
+ if (!acceptableEncryptionAlgorithms.includes('null')) {
176
+ throw (new Error('Malformed data (plaintext found but the null encryption algorithm is not acceptable)'));
177
+ }
178
+ containedCompressed = containedCompressedUnchecked;
179
+ }
180
+ return ({
181
+ version: version,
182
+ isEncrypted: isEncrypted,
183
+ innerValue: containedCompressed,
184
+ ...cipherInfo
185
+ });
186
+ }
187
+ async function parseASN1Decrypt(inputInfo, keys) {
188
+ let containedCompressed;
189
+ let cipherInfo;
190
+ if (inputInfo.isEncrypted) {
191
+ if (keys === undefined || keys.length === 0) {
192
+ throw (new Error('Encrypted Container found with encryption but no keys for decryption supplied'));
193
+ }
194
+ const algorithm = inputInfo.encryptionAlgorithm;
195
+ if (algorithm === undefined) {
196
+ throw (new Error('Encrypted Container found with encryption but no algorithm supplied'));
197
+ }
198
+ const keyInfo = inputInfo.keys;
199
+ if (keyInfo === undefined) {
200
+ throw (new Error('internal error: Encrypted container found with missing keys'));
201
+ }
202
+ let decryptionKeyInfo;
203
+ for (const checkKeyInfo of keyInfo) {
204
+ for (const key of keys) {
205
+ if (!key.hasPrivateKey) {
206
+ continue;
207
+ }
208
+ if (key.comparePublicKey(checkKeyInfo.publicKey)) {
209
+ decryptionKeyInfo = {
210
+ ...checkKeyInfo,
211
+ privateKey: key
212
+ };
213
+ break;
214
+ }
215
+ }
216
+ }
217
+ if (decryptionKeyInfo === undefined) {
218
+ throw (new Error('No keys found which can perform decryption on the supplied encryption box'));
219
+ }
220
+ const cipherKey = Buffer.from(await decryptionKeyInfo.privateKey.decrypt(bufferToArrayBuffer(decryptionKeyInfo.encryptedSymmetricKey)));
221
+ const cipherIV = inputInfo.cipherIV;
222
+ if (cipherIV === undefined) {
223
+ throw (new Error('internal error: No Cipher IV found'));
224
+ }
225
+ const encryptedCompressedValue = inputInfo.innerValue;
226
+ const decipher = crypto.createDecipheriv(algorithm, cipherKey, cipherIV);
227
+ containedCompressed = Buffer.concat([
228
+ decipher.update(encryptedCompressedValue),
229
+ decipher.final()
230
+ ]);
231
+ cipherInfo = {
232
+ isEncrypted: true,
233
+ keys: keyInfo,
234
+ cipherIV: cipherIV,
235
+ cipherKey: cipherKey,
236
+ encryptedData: encryptedCompressedValue
237
+ };
238
+ }
239
+ else {
240
+ containedCompressed = inputInfo.innerValue;
241
+ cipherInfo = {
242
+ isEncrypted: false
243
+ };
244
+ }
245
+ const plaintext = Buffer.from(zlibInflate(containedCompressed));
246
+ return ({
247
+ version: inputInfo.version,
248
+ plaintext: plaintext,
249
+ ...cipherInfo
250
+ });
251
+ }
252
+ async function parseASN1(input, keys) {
253
+ const inputInfo = parseASN1Bare(input);
254
+ const retval = await parseASN1Decrypt(inputInfo, keys);
255
+ return (retval);
256
+ }
257
+ export class EncryptedContainer {
258
+ static algorithm = 'aes-256-cbc';
259
+ /**
260
+ * Flag indicating whether we support exporting the plaintext
261
+ */
262
+ #mayAccessPlaintext = true;
263
+ /**
264
+ * Encryption details
265
+ */
266
+ _internalState;
267
+ /**
268
+ * The plaintext or encoded (and possibly encrypted) data
269
+ */
270
+ #data;
271
+ constructor(principals) {
272
+ if (principals === null) {
273
+ this._internalState = {
274
+ principals: null
275
+ };
276
+ }
277
+ else {
278
+ this._internalState = {
279
+ principals: principals,
280
+ cipherAlgo: EncryptedContainer.algorithm
281
+ };
282
+ }
283
+ ;
284
+ this.#data = { plaintext: Buffer.alloc(0) };
285
+ }
286
+ get encrypted() {
287
+ return (this._internalState.principals !== null);
288
+ }
289
+ #isEncrypted() {
290
+ return (this.encrypted);
291
+ }
292
+ /**
293
+ * Create an instance of the EncryptedContainer from an encrypted blob,
294
+ * it will need to be decryptable with one of the specified principals
295
+ *
296
+ * After decryption happens, the list of principals with access to the
297
+ * resource will be reset to what is contained within the encrypted
298
+ * container
299
+ */
300
+ static fromEncryptedBuffer(data, principals) {
301
+ const retval = new EncryptedContainer(principals);
302
+ retval.#setEncodedBuffer(data);
303
+ retval.#computeAndSetKeyInfo(true);
304
+ return (retval);
305
+ }
306
+ static fromEncodedBuffer(data, principals) {
307
+ const retval = new EncryptedContainer(principals);
308
+ retval.#setEncodedBuffer(data);
309
+ retval.#computeAndSetKeyInfo(false);
310
+ return (retval);
311
+ }
312
+ /**
313
+ * Create an instance of the EncryptedContainer from a plaintext.
314
+ *
315
+ * It will be decryptable by any one of the specified principals
316
+ *
317
+ * @param data The plaintext data to encrypt or encode
318
+ * @param principals The list of principals who can access the data if it is null then the data is not encrypted
319
+ * @param locked If true, the plaintext data will not be accessible from this instance; otherwise it will be -- default depends on principals
320
+ * @returns The EncryptedContainer instance with the plaintext data and principals set
321
+ */
322
+ static fromPlaintext(data, principals, locked) {
323
+ const retval = new EncryptedContainer(principals);
324
+ if (locked === undefined) {
325
+ locked = true;
326
+ if (principals === null) {
327
+ locked = false;
328
+ }
329
+ }
330
+ if (locked) {
331
+ retval.disablePlaintext();
332
+ }
333
+ retval.setPlaintext(data);
334
+ return (retval);
335
+ }
336
+ /**
337
+ * Set the plaintext buffer to the specified value
338
+ */
339
+ setPlaintext(data) {
340
+ if (typeof data === 'string') {
341
+ data = Buffer.from(data, 'utf-8');
342
+ }
343
+ this.#data = { plaintext: data };
344
+ }
345
+ /**
346
+ * Set the encoded blob to the specified value
347
+ */
348
+ #setEncodedBuffer(data) {
349
+ this.#data = { encoded: data };
350
+ }
351
+ get _encoded() {
352
+ if ('encoded' in this.#data && this.#data.encoded !== undefined) {
353
+ return (this.#data.encoded);
354
+ }
355
+ return (undefined);
356
+ }
357
+ get _plaintext() {
358
+ if ('plaintext' in this.#data && this.#data.plaintext !== undefined) {
359
+ return (this.#data.plaintext);
360
+ }
361
+ return (undefined);
362
+ }
363
+ /*
364
+ * Return the decoded data from the encoded blob
365
+ * and populate the symmetric key parameters from the encoded blob if it is encrypted
366
+ */
367
+ #computeAndSetKeyInfo(mustBeEncrypted) {
368
+ if (this._encoded === undefined) {
369
+ throw (new Error('No encoded data available'));
370
+ }
371
+ const plaintextWrapper = parseASN1Bare(this._encoded);
372
+ if (mustBeEncrypted && !plaintextWrapper.isEncrypted) {
373
+ throw (new Error('Unable to set key information from plaintext -- it is not encrypted but that was required'));
374
+ }
375
+ if (plaintextWrapper.isEncrypted) {
376
+ const principals = this._internalState.principals;
377
+ if (principals === null) {
378
+ throw (new Error('May not encrypt data with a null set of principals'));
379
+ }
380
+ /*
381
+ * Compute the new accounts by merging the input from the
382
+ * data and the existing list of principals
383
+ */
384
+ /**
385
+ * The existing principals from the blob, with existing
386
+ * principals substituted in where appropriate
387
+ */
388
+ const blobPrincipals = (plaintextWrapper.keys ?? []).map((keyInfo) => {
389
+ const currentPublicKey = keyInfo.publicKey;
390
+ if (!currentPublicKey.isAccount()) {
391
+ throw (new Error('internal error: Non-account found within the encryption key list'));
392
+ }
393
+ for (const checkExistingKey of principals) {
394
+ if (checkExistingKey.comparePublicKey(currentPublicKey)) {
395
+ return (checkExistingKey);
396
+ }
397
+ }
398
+ return (currentPublicKey);
399
+ });
400
+ this._internalState.principals = blobPrincipals;
401
+ // Confirm updated principals are populated correctly which sets container to encrypted
402
+ if (!this.encrypted) {
403
+ throw (new Error('internal error: Encrypted data found but not marked as encrypted'));
404
+ }
405
+ }
406
+ else {
407
+ this._internalState.principals = null;
408
+ if (this.encrypted) {
409
+ throw (new Error('internal error: Plaintext data found but marked as encrypted'));
410
+ }
411
+ }
412
+ return (plaintextWrapper);
413
+ }
414
+ /**
415
+ * Populate the plaintext (as well as symmetric key parameters) from
416
+ * the encoded blob
417
+ */
418
+ async #computePlaintext() {
419
+ if (this._plaintext) {
420
+ return (this._plaintext);
421
+ }
422
+ if (this._encoded === undefined) {
423
+ throw (new Error('No plaintext or encoded data available'));
424
+ }
425
+ const info = this.#computeAndSetKeyInfo(this.encrypted);
426
+ let principals = this._internalState.principals;
427
+ if (info.isEncrypted) {
428
+ if (principals === null) {
429
+ throw (new Error('May not decrypt data with a null set of principals'));
430
+ }
431
+ }
432
+ else {
433
+ principals = [];
434
+ }
435
+ const plaintextWrapper = await parseASN1Decrypt(info, principals);
436
+ const plaintext = plaintextWrapper.plaintext;
437
+ this.#data = { ...this.#data, plaintext };
438
+ return (plaintext);
439
+ }
440
+ /**
441
+ * Compute the encoded version of the plaintext data
442
+ */
443
+ async #computePlaintextEncoded() {
444
+ if (this._plaintext === undefined) {
445
+ throw (new Error('No plaintext data available'));
446
+ }
447
+ const structuredData = await buildASN1(this._plaintext);
448
+ return (structuredData);
449
+ }
450
+ /**
451
+ * Populate the encrypted blob from the plaintext and symmetric key
452
+ * parameters. If the symmetric key parameters have not been
453
+ * initialized they will be initialized at this time.
454
+ */
455
+ async #computeEncryptedEncoded() {
456
+ if (this._plaintext === undefined) {
457
+ throw (new Error('No encrypted nor plaintext data available'));
458
+ }
459
+ if (!this.#isEncrypted()) {
460
+ throw (new Error('internal error: Asked to encrypt a plaintext buffer'));
461
+ }
462
+ /**
463
+ * structured data is the ASN.1 encoded structure
464
+ */
465
+ const structuredData = await buildASN1(this._plaintext, {
466
+ keys: this._internalState.principals,
467
+ cipherKey: crypto.randomBytes(32),
468
+ cipherIV: crypto.randomBytes(16),
469
+ cipherAlgo: this._internalState.cipherAlgo
470
+ });
471
+ return (structuredData);
472
+ }
473
+ async #computeEncoded() {
474
+ if (this._encoded !== undefined) {
475
+ return (this._encoded);
476
+ }
477
+ let computed;
478
+ if (!this.encrypted) {
479
+ computed = await this.#computePlaintextEncoded();
480
+ }
481
+ else {
482
+ computed = await this.#computeEncryptedEncoded();
483
+ }
484
+ this.#data = { ...this.#data, encoded: computed };
485
+ return (computed);
486
+ }
487
+ /**
488
+ * Grant access to the secret for account(s) synchronously. This
489
+ * assumes the plaintext has already been computed and will fail
490
+ * if it is not
491
+ */
492
+ grantAccessSync(accounts) {
493
+ if (this._plaintext === undefined) {
494
+ throw (new Error('Unable to grant access, plaintext not available'));
495
+ }
496
+ if (!this.#isEncrypted()) {
497
+ throw (new Error('May not manage access to a plaintext container'));
498
+ }
499
+ if (!Array.isArray(accounts)) {
500
+ accounts = [accounts];
501
+ }
502
+ // Encoded data is invalidated with the new permissions so set only the plaintext data
503
+ this.setPlaintext(this._plaintext);
504
+ this._internalState.principals.push(...accounts);
505
+ }
506
+ /**
507
+ * Grant access to the secret for account(s).
508
+ */
509
+ async grantAccess(accounts) {
510
+ await this.#computePlaintext();
511
+ this.grantAccessSync(accounts);
512
+ }
513
+ /**
514
+ * Revoke access to the secret for an account synchronously. This
515
+ * assumes the plaintext has already been computed and will fail
516
+ * if it is not
517
+ */
518
+ revokeAccessSync(account) {
519
+ if (this._plaintext === undefined) {
520
+ throw (new Error('Unable to revoke access, plaintext not available'));
521
+ }
522
+ if (!this.#isEncrypted()) {
523
+ throw (new Error('May not manage access to a plaintext container'));
524
+ }
525
+ // Encoded data is invalidated with the new permissions so set only the plaintext data
526
+ this.setPlaintext(this._plaintext);
527
+ this._internalState.principals = this._internalState.principals.filter(function (checkAccount) {
528
+ return (!checkAccount.comparePublicKey(account));
529
+ });
530
+ }
531
+ /**
532
+ * Revoke access to the secret for an account
533
+ */
534
+ async revokeAccess(account) {
535
+ await this.#computePlaintext();
536
+ this.revokeAccessSync(account);
537
+ }
538
+ /**
539
+ * Disable access to the plaintext from this instance
540
+ */
541
+ disablePlaintext() {
542
+ this.#mayAccessPlaintext = false;
543
+ }
544
+ /**
545
+ * Get the plaintext for this instance
546
+ */
547
+ async getPlaintext() {
548
+ if (!this.#mayAccessPlaintext) {
549
+ throw (new Error('May not access plaintext'));
550
+ }
551
+ const plaintext = await this.#computePlaintext();
552
+ if (plaintext === undefined) {
553
+ throw (new Error('internal error: Plaintext could not be decoded'));
554
+ }
555
+ /*
556
+ * Make a copy of our internal buffer so that any changes made
557
+ * to either our internal buffer or by our caller do not
558
+ * interfere
559
+ */
560
+ return (Buffer.from(plaintext));
561
+ }
562
+ /**
563
+ * Get the serializable buffer which can be stored and reconstructed
564
+ */
565
+ async getEncodedBuffer() {
566
+ const serialized = await this.#computeEncoded();
567
+ if (serialized === undefined) {
568
+ throw (new Error('internal error: Could not encode data'));
569
+ }
570
+ /*
571
+ * Make a copy of our internal buffer so that any changes made
572
+ * to either our internal buffer or by our caller do not
573
+ * interfere
574
+ */
575
+ return (Buffer.from(serialized));
576
+ }
577
+ /**
578
+ * Get the list of accounts which have access to read the plaintext of
579
+ * this container
580
+ */
581
+ get principals() {
582
+ if (!this.#isEncrypted()) {
583
+ throw (new Error('May not manage access to a plaintext container'));
584
+ }
585
+ return (this._internalState.principals);
586
+ }
587
+ }
588
+ /** @internal */
589
+ export const _Testing = {
590
+ buildASN1: buildASN1,
591
+ parseASN1: parseASN1
592
+ };
593
+ export default EncryptedContainer;
594
+ //# sourceMappingURL=encrypted-container.js.map