@decaf-ts/for-fabric 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +22 -0
- package/README.md +647 -0
- package/dist/for-fabric.cjs +6223 -0
- package/dist/for-fabric.esm.cjs +6180 -0
- package/lib/client/FabricClientAdapter.cjs +760 -0
- package/lib/client/FabricClientAdapter.d.ts +381 -0
- package/lib/client/FabricClientDispatch.cjs +186 -0
- package/lib/client/FabricClientDispatch.d.ts +125 -0
- package/lib/client/FabricClientRepository.cjs +131 -0
- package/lib/client/FabricClientRepository.d.ts +100 -0
- package/lib/client/erc20/erc20ClientRepository.cjs +343 -0
- package/lib/client/erc20/erc20ClientRepository.d.ts +254 -0
- package/lib/client/fabric-fs.cjs +234 -0
- package/lib/client/fabric-fs.d.ts +92 -0
- package/lib/client/index.cjs +30 -0
- package/lib/client/index.d.ts +13 -0
- package/lib/client/logging.cjs +102 -0
- package/lib/client/logging.d.ts +60 -0
- package/lib/client/services/LoggedService.cjs +47 -0
- package/lib/client/services/LoggedService.d.ts +42 -0
- package/lib/client/services/constants.cjs +3 -0
- package/lib/client/services/constants.d.ts +15 -0
- package/lib/client/services/enrollementService.cjs +344 -0
- package/lib/client/services/enrollementService.d.ts +176 -0
- package/lib/client/services/index.cjs +18 -0
- package/lib/client/services/index.d.ts +1 -0
- package/lib/contracts/ContractAdapter.cjs +730 -0
- package/lib/contracts/ContractAdapter.d.ts +296 -0
- package/lib/contracts/ContractContext.cjs +85 -0
- package/lib/contracts/ContractContext.d.ts +64 -0
- package/lib/contracts/ContractPrivateDataAdapter.cjs +281 -0
- package/lib/contracts/ContractPrivateDataAdapter.d.ts +74 -0
- package/lib/contracts/FabricConstruction.cjs +441 -0
- package/lib/contracts/FabricConstruction.d.ts +304 -0
- package/lib/contracts/FabricContractRepository.cjs +306 -0
- package/lib/contracts/FabricContractRepository.d.ts +162 -0
- package/lib/contracts/FabricContractRepositoryObservableHandler.cjs +85 -0
- package/lib/contracts/FabricContractRepositoryObservableHandler.d.ts +62 -0
- package/lib/contracts/FabricContractSequence.cjs +139 -0
- package/lib/contracts/FabricContractSequence.d.ts +61 -0
- package/lib/contracts/FabricContractStatement.cjs +119 -0
- package/lib/contracts/FabricContractStatement.d.ts +34 -0
- package/lib/contracts/PrivateSequence.cjs +36 -0
- package/lib/contracts/PrivateSequence.d.ts +15 -0
- package/lib/contracts/crud/crud-contract.cjs +257 -0
- package/lib/contracts/crud/crud-contract.d.ts +168 -0
- package/lib/contracts/crud/index.cjs +19 -0
- package/lib/contracts/crud/index.d.ts +2 -0
- package/lib/contracts/crud/serialized-crud-contract.cjs +172 -0
- package/lib/contracts/crud/serialized-crud-contract.d.ts +37 -0
- package/lib/contracts/erc20/erc20contract.cjs +569 -0
- package/lib/contracts/erc20/erc20contract.d.ts +151 -0
- package/lib/contracts/erc20/index.cjs +21 -0
- package/lib/contracts/erc20/index.d.ts +2 -0
- package/lib/contracts/erc20/models.cjs +209 -0
- package/lib/contracts/erc20/models.d.ts +114 -0
- package/lib/contracts/index.cjs +32 -0
- package/lib/contracts/index.d.ts +15 -0
- package/lib/contracts/logging.cjs +96 -0
- package/lib/contracts/logging.d.ts +49 -0
- package/lib/contracts/private-data.cjs +121 -0
- package/lib/contracts/private-data.d.ts +16 -0
- package/lib/contracts/types.cjs +3 -0
- package/lib/contracts/types.d.ts +26 -0
- package/lib/esm/client/FabricClientAdapter.d.ts +381 -0
- package/lib/esm/client/FabricClientAdapter.js +723 -0
- package/lib/esm/client/FabricClientDispatch.d.ts +125 -0
- package/lib/esm/client/FabricClientDispatch.js +182 -0
- package/lib/esm/client/FabricClientRepository.d.ts +100 -0
- package/lib/esm/client/FabricClientRepository.js +127 -0
- package/lib/esm/client/erc20/erc20ClientRepository.d.ts +254 -0
- package/lib/esm/client/erc20/erc20ClientRepository.js +339 -0
- package/lib/esm/client/fabric-fs.d.ts +92 -0
- package/lib/esm/client/fabric-fs.js +191 -0
- package/lib/esm/client/index.d.ts +13 -0
- package/lib/esm/client/index.js +14 -0
- package/lib/esm/client/logging.d.ts +60 -0
- package/lib/esm/client/logging.js +98 -0
- package/lib/esm/client/services/LoggedService.d.ts +42 -0
- package/lib/esm/client/services/LoggedService.js +43 -0
- package/lib/esm/client/services/constants.d.ts +15 -0
- package/lib/esm/client/services/constants.js +2 -0
- package/lib/esm/client/services/enrollementService.d.ts +176 -0
- package/lib/esm/client/services/enrollementService.js +337 -0
- package/lib/esm/client/services/index.d.ts +1 -0
- package/lib/esm/client/services/index.js +2 -0
- package/lib/esm/contracts/ContractAdapter.d.ts +296 -0
- package/lib/esm/contracts/ContractAdapter.js +724 -0
- package/lib/esm/contracts/ContractContext.d.ts +64 -0
- package/lib/esm/contracts/ContractContext.js +81 -0
- package/lib/esm/contracts/ContractPrivateDataAdapter.d.ts +74 -0
- package/lib/esm/contracts/ContractPrivateDataAdapter.js +277 -0
- package/lib/esm/contracts/FabricConstruction.d.ts +304 -0
- package/lib/esm/contracts/FabricConstruction.js +433 -0
- package/lib/esm/contracts/FabricContractRepository.d.ts +162 -0
- package/lib/esm/contracts/FabricContractRepository.js +302 -0
- package/lib/esm/contracts/FabricContractRepositoryObservableHandler.d.ts +62 -0
- package/lib/esm/contracts/FabricContractRepositoryObservableHandler.js +81 -0
- package/lib/esm/contracts/FabricContractSequence.d.ts +61 -0
- package/lib/esm/contracts/FabricContractSequence.js +135 -0
- package/lib/esm/contracts/FabricContractStatement.d.ts +34 -0
- package/lib/esm/contracts/FabricContractStatement.js +115 -0
- package/lib/esm/contracts/PrivateSequence.d.ts +15 -0
- package/lib/esm/contracts/PrivateSequence.js +33 -0
- package/lib/esm/contracts/crud/crud-contract.d.ts +168 -0
- package/lib/esm/contracts/crud/crud-contract.js +253 -0
- package/lib/esm/contracts/crud/index.d.ts +2 -0
- package/lib/esm/contracts/crud/index.js +3 -0
- package/lib/esm/contracts/crud/serialized-crud-contract.d.ts +37 -0
- package/lib/esm/contracts/crud/serialized-crud-contract.js +168 -0
- package/lib/esm/contracts/erc20/erc20contract.d.ts +151 -0
- package/lib/esm/contracts/erc20/erc20contract.js +565 -0
- package/lib/esm/contracts/erc20/index.d.ts +2 -0
- package/lib/esm/contracts/erc20/index.js +4 -0
- package/lib/esm/contracts/erc20/models.d.ts +114 -0
- package/lib/esm/contracts/erc20/models.js +206 -0
- package/lib/esm/contracts/index.d.ts +15 -0
- package/lib/esm/contracts/index.js +16 -0
- package/lib/esm/contracts/logging.d.ts +49 -0
- package/lib/esm/contracts/logging.js +92 -0
- package/lib/esm/contracts/private-data.d.ts +16 -0
- package/lib/esm/contracts/private-data.js +113 -0
- package/lib/esm/contracts/types.d.ts +26 -0
- package/lib/esm/contracts/types.js +2 -0
- package/lib/esm/index.d.ts +8 -0
- package/lib/esm/index.js +9 -0
- package/lib/esm/shared/ClientSerializer.d.ts +52 -0
- package/lib/esm/shared/ClientSerializer.js +80 -0
- package/lib/esm/shared/DeterministicSerializer.d.ts +40 -0
- package/lib/esm/shared/DeterministicSerializer.js +50 -0
- package/lib/esm/shared/SimpleDeterministicSerializer.d.ts +7 -0
- package/lib/esm/shared/SimpleDeterministicSerializer.js +42 -0
- package/lib/esm/shared/constants.d.ts +39 -0
- package/lib/esm/shared/constants.js +42 -0
- package/lib/esm/shared/crypto.d.ts +107 -0
- package/lib/esm/shared/crypto.js +331 -0
- package/lib/esm/shared/decorators.d.ts +24 -0
- package/lib/esm/shared/decorators.js +98 -0
- package/lib/esm/shared/erc20/erc20-constants.d.ts +25 -0
- package/lib/esm/shared/erc20/erc20-constants.js +27 -0
- package/lib/esm/shared/errors.d.ts +116 -0
- package/lib/esm/shared/errors.js +132 -0
- package/lib/esm/shared/events.d.ts +39 -0
- package/lib/esm/shared/events.js +47 -0
- package/lib/esm/shared/fabric-types.d.ts +33 -0
- package/lib/esm/shared/fabric-types.js +2 -0
- package/lib/esm/shared/index.d.ts +13 -0
- package/lib/esm/shared/index.js +14 -0
- package/lib/esm/shared/interfaces/Checkable.d.ts +21 -0
- package/lib/esm/shared/interfaces/Checkable.js +2 -0
- package/lib/esm/shared/math.d.ts +34 -0
- package/lib/esm/shared/math.js +61 -0
- package/lib/esm/shared/model/Identity.d.ts +42 -0
- package/lib/esm/shared/model/Identity.js +78 -0
- package/lib/esm/shared/model/IdentityCredentials.d.ts +41 -0
- package/lib/esm/shared/model/IdentityCredentials.js +74 -0
- package/lib/esm/shared/model/index.d.ts +1 -0
- package/lib/esm/shared/model/index.js +2 -0
- package/lib/esm/shared/model/utils.d.ts +60 -0
- package/lib/esm/shared/model/utils.js +108 -0
- package/lib/esm/shared/types.d.ts +79 -0
- package/lib/esm/shared/types.js +2 -0
- package/lib/esm/shared/utils.d.ts +55 -0
- package/lib/esm/shared/utils.js +148 -0
- package/lib/index.cjs +25 -0
- package/lib/index.d.ts +8 -0
- package/lib/shared/ClientSerializer.cjs +84 -0
- package/lib/shared/ClientSerializer.d.ts +52 -0
- package/lib/shared/DeterministicSerializer.cjs +54 -0
- package/lib/shared/DeterministicSerializer.d.ts +40 -0
- package/lib/shared/SimpleDeterministicSerializer.cjs +46 -0
- package/lib/shared/SimpleDeterministicSerializer.d.ts +7 -0
- package/lib/shared/constants.cjs +45 -0
- package/lib/shared/constants.d.ts +39 -0
- package/lib/shared/crypto.cjs +369 -0
- package/lib/shared/crypto.d.ts +107 -0
- package/lib/shared/decorators.cjs +105 -0
- package/lib/shared/decorators.d.ts +24 -0
- package/lib/shared/erc20/erc20-constants.cjs +30 -0
- package/lib/shared/erc20/erc20-constants.d.ts +25 -0
- package/lib/shared/errors.cjs +142 -0
- package/lib/shared/errors.d.ts +116 -0
- package/lib/shared/events.cjs +51 -0
- package/lib/shared/events.d.ts +39 -0
- package/lib/shared/fabric-types.cjs +4 -0
- package/lib/shared/fabric-types.d.ts +33 -0
- package/lib/shared/index.cjs +30 -0
- package/lib/shared/index.d.ts +13 -0
- package/lib/shared/interfaces/Checkable.cjs +3 -0
- package/lib/shared/interfaces/Checkable.d.ts +21 -0
- package/lib/shared/math.cjs +66 -0
- package/lib/shared/math.d.ts +34 -0
- package/lib/shared/model/Identity.cjs +81 -0
- package/lib/shared/model/Identity.d.ts +42 -0
- package/lib/shared/model/IdentityCredentials.cjs +77 -0
- package/lib/shared/model/IdentityCredentials.d.ts +41 -0
- package/lib/shared/model/index.cjs +18 -0
- package/lib/shared/model/index.d.ts +1 -0
- package/lib/shared/model/utils.cjs +114 -0
- package/lib/shared/model/utils.d.ts +60 -0
- package/lib/shared/types.cjs +3 -0
- package/lib/shared/types.d.ts +79 -0
- package/lib/shared/utils.cjs +185 -0
- package/lib/shared/utils.d.ts +55 -0
- package/package.json +166 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { CryptoKey } from "@peculiar/webcrypto";
|
|
2
|
+
export declare enum BASE_ALPHABET {
|
|
3
|
+
BASE2 = "01",
|
|
4
|
+
BASE8 = "01234567",
|
|
5
|
+
BASE11 = "0123456789a",
|
|
6
|
+
BASE16 = "0123456789abcdef",
|
|
7
|
+
BASE32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ",
|
|
8
|
+
BASE32_Z = "ybndrfg8ejkmcpqxot1uwisza345h769",
|
|
9
|
+
BASE36 = "0123456789abcdefghijklmnopqrstuvwxyz",
|
|
10
|
+
BASE58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
|
|
11
|
+
BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
|
12
|
+
BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
|
|
13
|
+
BASE67 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.!~"
|
|
14
|
+
}
|
|
15
|
+
export type keyObject = {
|
|
16
|
+
iv: ArrayBuffer;
|
|
17
|
+
key: CryptoKey;
|
|
18
|
+
};
|
|
19
|
+
export declare enum CRYPTO {
|
|
20
|
+
HASH = "SHA-256",
|
|
21
|
+
ITERATIONS = 1000,
|
|
22
|
+
KEYLENGTH = 48,
|
|
23
|
+
DERIVED_IV_LENGTH = 16,
|
|
24
|
+
DERIVED_KEY_LENGTH = 32,// Because SHA-256 used has a native size of 32 bytes
|
|
25
|
+
ALGORYTHM = "AES-GCM",
|
|
26
|
+
KEY_ALGORYTHM = "PBKDF2"
|
|
27
|
+
}
|
|
28
|
+
export declare class BaseEncoder {
|
|
29
|
+
private alphabet;
|
|
30
|
+
private readonly baseMap;
|
|
31
|
+
private readonly base;
|
|
32
|
+
private readonly leader;
|
|
33
|
+
private readonly factor;
|
|
34
|
+
private readonly iFactor;
|
|
35
|
+
constructor(alphabet: BASE_ALPHABET);
|
|
36
|
+
encode(source: Uint8Array | DataView | any[] | string): string;
|
|
37
|
+
private decodeUnsafe;
|
|
38
|
+
decode(source: string): Uint8Array<ArrayBufferLike>;
|
|
39
|
+
}
|
|
40
|
+
export declare class CryptoUtils {
|
|
41
|
+
private static readonly b58encoder;
|
|
42
|
+
private static readonly logger;
|
|
43
|
+
private constructor();
|
|
44
|
+
static fabricIdFromCertificate(certificate: string): string;
|
|
45
|
+
static encode(str: string): string;
|
|
46
|
+
static decode(str: string): string;
|
|
47
|
+
static stringToArrayBuffer(str: string): ArrayBuffer;
|
|
48
|
+
private static extractKey;
|
|
49
|
+
static extractPrivateKey(pem: Buffer | string, usages?: any[]): Promise<any>;
|
|
50
|
+
static extractPublicKey(pem: Buffer | string, usages?: any[]): Promise<any>;
|
|
51
|
+
static sign(privateKey: string, data: Buffer): Promise<string>;
|
|
52
|
+
static verify(certificate: string, signature: Buffer | string, data: Buffer | string): Promise<boolean>;
|
|
53
|
+
static encrypt(certificate: string, data: string | Buffer): Promise<string>;
|
|
54
|
+
private static getSubtleCrypto;
|
|
55
|
+
static decrypt(privateKey: string, data: string | Buffer): Promise<any>;
|
|
56
|
+
/**
|
|
57
|
+
* @summary Util function to get a random master key
|
|
58
|
+
*
|
|
59
|
+
* @description If data is not passed, a random ArrayBuffer will be generated
|
|
60
|
+
*
|
|
61
|
+
* @param {ArrayBuffer} data encrytion data
|
|
62
|
+
*
|
|
63
|
+
* @function getMaster
|
|
64
|
+
*/
|
|
65
|
+
static getMaster(data?: ArrayBuffer): Promise<keyObject>;
|
|
66
|
+
/**
|
|
67
|
+
* @summary Util function to derive a key from another key
|
|
68
|
+
*
|
|
69
|
+
* @param {string} salt
|
|
70
|
+
* @param {CryptoKey} key Original key
|
|
71
|
+
*
|
|
72
|
+
* @function getDerivationKey
|
|
73
|
+
*/
|
|
74
|
+
static getDerivationKey(salt: string, key: CryptoKey): Promise<{
|
|
75
|
+
key: any;
|
|
76
|
+
iv: ArrayBuffer;
|
|
77
|
+
}>;
|
|
78
|
+
/**
|
|
79
|
+
* @summary Util function to get the key and IV from the CrytoKey array
|
|
80
|
+
*
|
|
81
|
+
* @param {ArrayBuffer} derivation
|
|
82
|
+
*
|
|
83
|
+
* @function getKey
|
|
84
|
+
*/
|
|
85
|
+
static getKey(derivation: ArrayBuffer): Promise<{
|
|
86
|
+
key: any;
|
|
87
|
+
iv: ArrayBuffer;
|
|
88
|
+
}>;
|
|
89
|
+
/**
|
|
90
|
+
* @summary Util function to decrypt data
|
|
91
|
+
*
|
|
92
|
+
* @param {string} text
|
|
93
|
+
* @param {keyObject} keyObject
|
|
94
|
+
*
|
|
95
|
+
* @function encrypt
|
|
96
|
+
*/
|
|
97
|
+
static encryptPin(text: string, keyObject: keyObject): Promise<ArrayBuffer>;
|
|
98
|
+
/**
|
|
99
|
+
* @summary Util function to decrypt data
|
|
100
|
+
*
|
|
101
|
+
* @param {BufferSource} encryptedText
|
|
102
|
+
* @param {keyObject} keyObject
|
|
103
|
+
*
|
|
104
|
+
* @function decrypt
|
|
105
|
+
*/
|
|
106
|
+
static decryptPin(encryptedText: ArrayBuffer, keyObject: keyObject): Promise<string>;
|
|
107
|
+
}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import * as x509 from "@peculiar/x509";
|
|
2
|
+
import { Crypto } from "@peculiar/webcrypto";
|
|
3
|
+
import { stringFormat } from "@decaf-ts/decorator-validation";
|
|
4
|
+
import { Logging } from "@decaf-ts/logging";
|
|
5
|
+
import { isBrowser } from "@decaf-ts/utils";
|
|
6
|
+
const crypto = new Crypto();
|
|
7
|
+
x509.cryptoProvider.set(crypto);
|
|
8
|
+
export var BASE_ALPHABET;
|
|
9
|
+
(function (BASE_ALPHABET) {
|
|
10
|
+
BASE_ALPHABET["BASE2"] = "01";
|
|
11
|
+
BASE_ALPHABET["BASE8"] = "01234567";
|
|
12
|
+
BASE_ALPHABET["BASE11"] = "0123456789a";
|
|
13
|
+
BASE_ALPHABET["BASE16"] = "0123456789abcdef";
|
|
14
|
+
BASE_ALPHABET["BASE32"] = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
15
|
+
BASE_ALPHABET["BASE32_Z"] = "ybndrfg8ejkmcpqxot1uwisza345h769";
|
|
16
|
+
BASE_ALPHABET["BASE36"] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
17
|
+
BASE_ALPHABET["BASE58"] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
18
|
+
BASE_ALPHABET["BASE62"] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
19
|
+
BASE_ALPHABET["BASE64"] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
20
|
+
BASE_ALPHABET["BASE67"] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.!~";
|
|
21
|
+
})(BASE_ALPHABET || (BASE_ALPHABET = {}));
|
|
22
|
+
export var CRYPTO;
|
|
23
|
+
(function (CRYPTO) {
|
|
24
|
+
CRYPTO["HASH"] = "SHA-256";
|
|
25
|
+
CRYPTO[CRYPTO["ITERATIONS"] = 1000] = "ITERATIONS";
|
|
26
|
+
CRYPTO[CRYPTO["KEYLENGTH"] = 48] = "KEYLENGTH";
|
|
27
|
+
CRYPTO[CRYPTO["DERIVED_IV_LENGTH"] = 16] = "DERIVED_IV_LENGTH";
|
|
28
|
+
CRYPTO[CRYPTO["DERIVED_KEY_LENGTH"] = 32] = "DERIVED_KEY_LENGTH";
|
|
29
|
+
CRYPTO["ALGORYTHM"] = "AES-GCM";
|
|
30
|
+
CRYPTO["KEY_ALGORYTHM"] = "PBKDF2";
|
|
31
|
+
})(CRYPTO || (CRYPTO = {}));
|
|
32
|
+
export class BaseEncoder {
|
|
33
|
+
constructor(alphabet) {
|
|
34
|
+
this.alphabet = alphabet;
|
|
35
|
+
this.baseMap = new Uint8Array(256);
|
|
36
|
+
if (this.alphabet.length >= 255)
|
|
37
|
+
throw new Error("Alphabet too long");
|
|
38
|
+
for (let j = 0; j < this.baseMap.length; j++)
|
|
39
|
+
this.baseMap[j] = 255;
|
|
40
|
+
for (let i = 0; i < alphabet.length; i++) {
|
|
41
|
+
const x = alphabet.charAt(i);
|
|
42
|
+
const xc = x.charCodeAt(0);
|
|
43
|
+
if (this.baseMap[xc] !== 255)
|
|
44
|
+
throw new Error(x + " is ambiguous");
|
|
45
|
+
this.baseMap[xc] = i;
|
|
46
|
+
}
|
|
47
|
+
this.base = this.alphabet.length;
|
|
48
|
+
this.leader = this.alphabet.charAt(0);
|
|
49
|
+
this.factor = Math.log(this.base) / Math.log(256); // log(BASE) / log(256), rounded up
|
|
50
|
+
this.iFactor = Math.log(256) / Math.log(this.base); // log(256) / log(BASE), rounded up
|
|
51
|
+
}
|
|
52
|
+
encode(source) {
|
|
53
|
+
if (typeof source === "string") {
|
|
54
|
+
source = Buffer.from(source);
|
|
55
|
+
}
|
|
56
|
+
else if (ArrayBuffer.isView(source)) {
|
|
57
|
+
source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
|
|
58
|
+
}
|
|
59
|
+
else if (Array.isArray(source)) {
|
|
60
|
+
source = Uint8Array.from(source);
|
|
61
|
+
}
|
|
62
|
+
if (source.length === 0)
|
|
63
|
+
return "";
|
|
64
|
+
// Skip & count leading zeroes.
|
|
65
|
+
let zeroes = 0;
|
|
66
|
+
let length = 0;
|
|
67
|
+
let pbegin = 0;
|
|
68
|
+
const pend = source.length;
|
|
69
|
+
while (pbegin !== pend && source[pbegin] === 0) {
|
|
70
|
+
pbegin++;
|
|
71
|
+
zeroes++;
|
|
72
|
+
}
|
|
73
|
+
// Allocate enough space in big-endian base58 representation.
|
|
74
|
+
const size = ((pend - pbegin) * this.iFactor + 1) >>> 0;
|
|
75
|
+
const b58 = new Uint8Array(size);
|
|
76
|
+
// Process the bytes.
|
|
77
|
+
while (pbegin !== pend) {
|
|
78
|
+
let carry = source[pbegin];
|
|
79
|
+
// Apply "b58 = b58 * 256 + ch".
|
|
80
|
+
let i = 0;
|
|
81
|
+
for (let it1 = size - 1; (carry !== 0 || i < length) && it1 !== -1; it1--, i++) {
|
|
82
|
+
carry += (256 * b58[it1]) >>> 0;
|
|
83
|
+
b58[it1] = carry % this.base >>> 0;
|
|
84
|
+
carry = (carry / this.base) >>> 0;
|
|
85
|
+
}
|
|
86
|
+
if (carry !== 0)
|
|
87
|
+
throw new Error("Non-zero carry");
|
|
88
|
+
length = i;
|
|
89
|
+
pbegin++;
|
|
90
|
+
}
|
|
91
|
+
// Skip leading zeroes in base58 result.
|
|
92
|
+
let it2 = size - length;
|
|
93
|
+
while (it2 !== size && b58[it2] === 0)
|
|
94
|
+
it2++;
|
|
95
|
+
// Translate the result into a string.
|
|
96
|
+
let str = this.leader.repeat(zeroes);
|
|
97
|
+
for (; it2 < size; ++it2) {
|
|
98
|
+
str += this.alphabet.charAt(b58[it2]);
|
|
99
|
+
}
|
|
100
|
+
return str;
|
|
101
|
+
}
|
|
102
|
+
decodeUnsafe(source) {
|
|
103
|
+
if (source.length === 0)
|
|
104
|
+
return new Uint8Array(0);
|
|
105
|
+
let psz = 0;
|
|
106
|
+
// Skip and count leading '1's.
|
|
107
|
+
let zeroes = 0;
|
|
108
|
+
let length = 0;
|
|
109
|
+
while (source[psz] === this.leader) {
|
|
110
|
+
zeroes++;
|
|
111
|
+
psz++;
|
|
112
|
+
}
|
|
113
|
+
// Allocate enough space in big-endian base256 representation.
|
|
114
|
+
const size = ((source.length - psz) * this.factor + 1) >>> 0; // log(58) / log(256), rounded up.
|
|
115
|
+
const b256 = new Uint8Array(size);
|
|
116
|
+
// Process the characters.
|
|
117
|
+
while (source[psz]) {
|
|
118
|
+
// Decode character
|
|
119
|
+
let carry = this.baseMap[source.charCodeAt(psz)];
|
|
120
|
+
// Invalid character
|
|
121
|
+
if (carry === 255)
|
|
122
|
+
return;
|
|
123
|
+
let i = 0;
|
|
124
|
+
for (let it3 = size - 1; (carry !== 0 || i < length) && it3 !== -1; it3--, i++) {
|
|
125
|
+
carry += (this.base * b256[it3]) >>> 0;
|
|
126
|
+
b256[it3] = carry % 256 >>> 0;
|
|
127
|
+
carry = (carry / 256) >>> 0;
|
|
128
|
+
}
|
|
129
|
+
if (carry !== 0)
|
|
130
|
+
throw new Error("Non-zero carry");
|
|
131
|
+
length = i;
|
|
132
|
+
psz++;
|
|
133
|
+
}
|
|
134
|
+
// Skip leading zeroes in b256.
|
|
135
|
+
let it4 = size - length;
|
|
136
|
+
while (it4 !== size && b256[it4] === 0)
|
|
137
|
+
it4++;
|
|
138
|
+
const vch = new Uint8Array(zeroes + (size - it4));
|
|
139
|
+
let j = zeroes;
|
|
140
|
+
while (it4 !== size)
|
|
141
|
+
vch[j++] = b256[it4++];
|
|
142
|
+
return vch;
|
|
143
|
+
}
|
|
144
|
+
decode(source) {
|
|
145
|
+
const buffer = this.decodeUnsafe(source);
|
|
146
|
+
if (buffer)
|
|
147
|
+
return buffer;
|
|
148
|
+
throw new Error("Non-base" + this.base + " character");
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
export class CryptoUtils {
|
|
152
|
+
static { this.b58encoder = new BaseEncoder(BASE_ALPHABET.BASE58); }
|
|
153
|
+
static { this.logger = Logging.for(CryptoUtils.name); }
|
|
154
|
+
constructor() { }
|
|
155
|
+
static fabricIdFromCertificate(certificate) {
|
|
156
|
+
this.logger.debug(stringFormat("Parsing certificate: {0}", certificate));
|
|
157
|
+
const cert = new x509.X509Certificate(certificate);
|
|
158
|
+
const { subject, issuer } = cert;
|
|
159
|
+
this.logger.debug(stringFormat("Certificate parsed with subject {0} and issuer {1}", subject, issuer));
|
|
160
|
+
return `x509::/${subject.replaceAll(", ", "/")}::/${issuer.replaceAll(", ", "/")}`;
|
|
161
|
+
}
|
|
162
|
+
static encode(str) {
|
|
163
|
+
return this.b58encoder.encode(str);
|
|
164
|
+
}
|
|
165
|
+
static decode(str) {
|
|
166
|
+
const decoded = this.b58encoder.decode(str);
|
|
167
|
+
const result = new TextDecoder().decode(decoded);
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
static stringToArrayBuffer(str) {
|
|
171
|
+
const buf = new ArrayBuffer(str.length);
|
|
172
|
+
const bufView = new Uint8Array(buf);
|
|
173
|
+
for (let i = 0, strLen = str.length; i < strLen; i++) {
|
|
174
|
+
bufView[i] = str.charCodeAt(i);
|
|
175
|
+
}
|
|
176
|
+
return buf;
|
|
177
|
+
}
|
|
178
|
+
static async extractKey(type, pem, usages) {
|
|
179
|
+
const subtle = crypto.subtle;
|
|
180
|
+
const str = pem
|
|
181
|
+
.toString("utf8")
|
|
182
|
+
.replace(new RegExp(`-----BEGIN (${type.toUpperCase()} KEY|CERTIFICATE)-----`), "")
|
|
183
|
+
.replaceAll("\n", "")
|
|
184
|
+
.replace(new RegExp(`-----END (${type.toUpperCase()} KEY|CERTIFICATE)-----`), "");
|
|
185
|
+
const decoded = Buffer.from(str, "base64").toString("binary");
|
|
186
|
+
const binaryDer = this.stringToArrayBuffer(decoded);
|
|
187
|
+
const key = await subtle.importKey("pkcs8", binaryDer, {
|
|
188
|
+
name: "ECDSA",
|
|
189
|
+
namedCurve: "P-256",
|
|
190
|
+
}, true, usages ? usages : ["sign"]);
|
|
191
|
+
return key;
|
|
192
|
+
}
|
|
193
|
+
static async extractPrivateKey(pem, usages) {
|
|
194
|
+
return this.extractKey("private", pem, usages);
|
|
195
|
+
}
|
|
196
|
+
static async extractPublicKey(pem, usages) {
|
|
197
|
+
return this.extractKey("public", pem, usages);
|
|
198
|
+
}
|
|
199
|
+
static async sign(privateKey, data) {
|
|
200
|
+
const key = await this.extractPrivateKey(privateKey);
|
|
201
|
+
const buff = (await crypto.subtle.sign({
|
|
202
|
+
name: "ECDSA",
|
|
203
|
+
hash: "SHA-256",
|
|
204
|
+
}, key, data));
|
|
205
|
+
return Array.from(new Uint8Array(buff))
|
|
206
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
207
|
+
.join("");
|
|
208
|
+
}
|
|
209
|
+
static async verify(certificate, signature, data) {
|
|
210
|
+
const cert = new x509.X509Certificate(certificate);
|
|
211
|
+
const key = await cert.publicKey.export();
|
|
212
|
+
signature = (typeof signature === "string" ? Buffer.from(signature, "hex") : signature);
|
|
213
|
+
data = (typeof data === "string" ? Buffer.from(data) : data);
|
|
214
|
+
return crypto.subtle.verify({
|
|
215
|
+
name: "ECDSA",
|
|
216
|
+
hash: "SHA-256",
|
|
217
|
+
}, key, signature, data);
|
|
218
|
+
}
|
|
219
|
+
static async encrypt(certificate, data) {
|
|
220
|
+
const cert = new x509.X509Certificate(certificate);
|
|
221
|
+
const key = await cert.publicKey.export();
|
|
222
|
+
data = (typeof data === "string" ? Buffer.from(data) : data);
|
|
223
|
+
const buff = await this.getSubtleCrypto().encrypt({
|
|
224
|
+
name: "ECDSA",
|
|
225
|
+
}, key, data);
|
|
226
|
+
return Array.from(new Uint8Array(buff))
|
|
227
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
228
|
+
.join("");
|
|
229
|
+
}
|
|
230
|
+
static getSubtleCrypto() {
|
|
231
|
+
return isBrowser()
|
|
232
|
+
? globalThis.window.crypto.subtle
|
|
233
|
+
: crypto.subtle;
|
|
234
|
+
}
|
|
235
|
+
static async decrypt(privateKey, data) {
|
|
236
|
+
const key = await this.extractPrivateKey(privateKey);
|
|
237
|
+
data = (typeof data === "string" ? Buffer.from(data, "hex") : data);
|
|
238
|
+
return this.getSubtleCrypto().decrypt({
|
|
239
|
+
name: "ECDSA",
|
|
240
|
+
}, key, data);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* @summary Util function to get a random master key
|
|
244
|
+
*
|
|
245
|
+
* @description If data is not passed, a random ArrayBuffer will be generated
|
|
246
|
+
*
|
|
247
|
+
* @param {ArrayBuffer} data encrytion data
|
|
248
|
+
*
|
|
249
|
+
* @function getMaster
|
|
250
|
+
*/
|
|
251
|
+
static async getMaster(data) {
|
|
252
|
+
const textEncoder = new TextEncoder();
|
|
253
|
+
if (data === undefined) {
|
|
254
|
+
const genGenesis = crypto.randomUUID();
|
|
255
|
+
data = textEncoder.encode(genGenesis);
|
|
256
|
+
}
|
|
257
|
+
const importedKey = await this.getSubtleCrypto().importKey("raw", data, CRYPTO.KEY_ALGORYTHM, false, ["deriveBits"]);
|
|
258
|
+
return {
|
|
259
|
+
key: importedKey,
|
|
260
|
+
iv: data,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* @summary Util function to derive a key from another key
|
|
265
|
+
*
|
|
266
|
+
* @param {string} salt
|
|
267
|
+
* @param {CryptoKey} key Original key
|
|
268
|
+
*
|
|
269
|
+
* @function getDerivationKey
|
|
270
|
+
*/
|
|
271
|
+
static async getDerivationKey(salt, key) {
|
|
272
|
+
const textEncoder = new TextEncoder();
|
|
273
|
+
const saltBuffer = textEncoder.encode(salt);
|
|
274
|
+
const saltHashed = await this.getSubtleCrypto().digest("SHA-256", saltBuffer);
|
|
275
|
+
const params = {
|
|
276
|
+
name: CRYPTO.KEY_ALGORYTHM,
|
|
277
|
+
hash: CRYPTO.HASH,
|
|
278
|
+
salt: saltHashed,
|
|
279
|
+
iterations: CRYPTO.ITERATIONS,
|
|
280
|
+
};
|
|
281
|
+
const derivation = await this.getSubtleCrypto().deriveBits(params, key, CRYPTO.KEYLENGTH * 8);
|
|
282
|
+
return this.getKey(derivation);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* @summary Util function to get the key and IV from the CrytoKey array
|
|
286
|
+
*
|
|
287
|
+
* @param {ArrayBuffer} derivation
|
|
288
|
+
*
|
|
289
|
+
* @function getKey
|
|
290
|
+
*/
|
|
291
|
+
static async getKey(derivation) {
|
|
292
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
293
|
+
const ivlen = 16;
|
|
294
|
+
const keylen = 32;
|
|
295
|
+
const derivedKey = derivation.slice(0, keylen);
|
|
296
|
+
const iv = derivation.slice(keylen);
|
|
297
|
+
const importedEncryptionKey = await this.getSubtleCrypto().importKey("raw", derivedKey, { name: CRYPTO.ALGORYTHM }, false, ["encrypt", "decrypt"]);
|
|
298
|
+
return {
|
|
299
|
+
key: importedEncryptionKey,
|
|
300
|
+
iv: iv,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* @summary Util function to decrypt data
|
|
305
|
+
*
|
|
306
|
+
* @param {string} text
|
|
307
|
+
* @param {keyObject} keyObject
|
|
308
|
+
*
|
|
309
|
+
* @function encrypt
|
|
310
|
+
*/
|
|
311
|
+
static async encryptPin(text, keyObject) {
|
|
312
|
+
const textEncoder = new TextEncoder();
|
|
313
|
+
const textBuffer = textEncoder.encode(text);
|
|
314
|
+
const encryptedText = await this.getSubtleCrypto().encrypt({ name: CRYPTO.ALGORYTHM, iv: keyObject.iv }, keyObject.key, textBuffer);
|
|
315
|
+
return encryptedText;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* @summary Util function to decrypt data
|
|
319
|
+
*
|
|
320
|
+
* @param {BufferSource} encryptedText
|
|
321
|
+
* @param {keyObject} keyObject
|
|
322
|
+
*
|
|
323
|
+
* @function decrypt
|
|
324
|
+
*/
|
|
325
|
+
static async decryptPin(encryptedText, keyObject) {
|
|
326
|
+
const textDecoder = new TextDecoder();
|
|
327
|
+
const decryptedText = await this.getSubtleCrypto().decrypt({ name: CRYPTO.ALGORYTHM, iv: keyObject.iv }, keyObject.key, encryptedText);
|
|
328
|
+
return textDecoder.decode(decryptedText);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3J5cHRvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NoYXJlZC9jcnlwdG8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLElBQUksTUFBTSxnQkFBZ0IsQ0FBQztBQUN2QyxPQUFPLEVBQUUsTUFBTSxFQUFhLE1BQU0scUJBQXFCLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzlELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM1QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFNUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxNQUFNLEVBQUUsQ0FBQztBQUM1QixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUVoQyxNQUFNLENBQU4sSUFBWSxhQVlYO0FBWkQsV0FBWSxhQUFhO0lBQ3ZCLDZCQUFZLENBQUE7SUFDWixtQ0FBa0IsQ0FBQTtJQUNsQix1Q0FBc0IsQ0FBQTtJQUN0Qiw0Q0FBMkIsQ0FBQTtJQUMzQiw0REFBMkMsQ0FBQTtJQUMzQyw4REFBNkMsQ0FBQTtJQUM3QyxnRUFBK0MsQ0FBQTtJQUMvQyxzRkFBcUUsQ0FBQTtJQUNyRSwwRkFBeUUsQ0FBQTtJQUN6RSw0RkFBMkUsQ0FBQTtJQUMzRSwrRkFBOEUsQ0FBQTtBQUNoRixDQUFDLEVBWlcsYUFBYSxLQUFiLGFBQWEsUUFZeEI7QUFPRCxNQUFNLENBQU4sSUFBWSxNQVFYO0FBUkQsV0FBWSxNQUFNO0lBQ2hCLDBCQUFnQixDQUFBO0lBQ2hCLGtEQUFpQixDQUFBO0lBQ2pCLDhDQUFjLENBQUE7SUFDZCw4REFBc0IsQ0FBQTtJQUN0QixnRUFBdUIsQ0FBQTtJQUN2QiwrQkFBcUIsQ0FBQTtJQUNyQixrQ0FBd0IsQ0FBQTtBQUMxQixDQUFDLEVBUlcsTUFBTSxLQUFOLE1BQU0sUUFRakI7QUFFRCxNQUFN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QUFJLENBQUMsQ0FBQztRQUM1QyxNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQyxPQUFPLENBQ3hELEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxTQUFtQixFQUFFLEVBQUUsRUFBRSxTQUFTLENBQUMsRUFBRSxFQUFFLEVBQ3RELFNBQVMsQ0FBQyxHQUFHLEVBQ2IsVUFBVSxDQUNYLENBQUM7UUFDRixPQUFPLGFBQWEsQ0FBQztJQUN2QixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUNyQixhQUEwQixFQUMxQixTQUFvQjtRQUVwQixNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQ3RDLE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLE9BQU8sQ0FDeEQsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLFNBQW1CLEVBQUUsRUFBRSxFQUFFLFNBQVMsQ0FBQyxFQUFFLEVBQUUsRUFDdEQsU0FBUyxDQUFDLEdBQUcsRUFDYixhQUFhLENBQ2QsQ0FBQztRQUNGLE9BQU8sV0FBVyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUMzQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgeDUwOSBmcm9tIFwiQHBlY3VsaWFyL3g1MDlcIjtcbmltcG9ydCB7IENyeXB0bywgQ3J5cHRvS2V5IH0gZnJvbSBcIkBwZWN1bGlhci93ZWJjcnlwdG9cIjtcbmltcG9ydCB7IHN0cmluZ0Zvcm1hdCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IExvZ2dpbmcgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcbmltcG9ydCB7IGlzQnJvd3NlciB9IGZyb20gXCJAZGVjYWYtdHMvdXRpbHNcIjtcblxuY29uc3QgY3J5cHRvID0gbmV3IENyeXB0bygpO1xueDUwOS5jcnlwdG9Qcm92aWRlci5zZXQoY3J5cHRvKTtcblxuZXhwb3J0IGVudW0gQkFTRV9BTFBIQUJFVCB7XG4gIEJBU0UyID0gXCIwMVwiLFxuICBCQVNFOCA9IFwiMDEyMzQ1NjdcIixcbiAgQkFTRTExID0gXCIwMTIzNDU2Nzg5YVwiLFxuICBCQVNFMTYgPSBcIjAxMjM0NTY3ODlhYmNkZWZcIixcbiAgQkFTRTMyID0gXCIwMTIzNDU2Nzg5QUJDREVGR0hKS01OUFFSU1RWV1hZWlwiLFxuICBCQVNFMzJfWiA9IFwieWJuZHJmZzhlamttY3BxeG90MXV3aXN6YTM0NWg3NjlcIixcbiAgQkFTRTM2ID0gXCIwMTIzNDU2Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIixcbiAgQkFTRTU4ID0gXCIxMjM0NTY3ODlBQkNERUZHSEpLTE1OUFFSU1RVVldYWVphYmNkZWZnaGlqa21ub3BxcnN0dXZ3eHl6XCIsXG4gIEJBU0U2MiA9IFwiMDEyMzQ1Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpcIixcbiAgQkFTRTY0ID0gXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvXCIsXG4gIEJBU0U2NyA9IFwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODktXy4hflwiLFxufVxuXG5leHBvcnQgdHlwZSBrZXlPYmplY3QgPSB7XG4gIGl2OiBBcnJheUJ1ZmZlcjtcbiAga2V5OiBDcnlwdG9LZXk7XG59O1xuXG5leHBvcnQgZW51bSBDUllQVE8ge1xuICBIQVNIID0gXCJTSEEtMjU2XCIsXG4gIElURVJBVElPTlMgPSAxMDAwLFxuICBLRVlMRU5HVEggPSA0OCxcbiAgREVSSVZFRF9JVl9MRU5HVEggPSAxNixcbiAgREVSSVZFRF9LRVlfTEVOR1RIID0gMzIsIC8vIEJlY2F1c2UgU0hBLTI1NiB1c2VkIGhhcyBhIG5hdGl2ZSBzaXplIG9mIDMyIGJ5dGVzXG4gIEFMR09SWVRITSA9IFwiQUVTLUdDTVwiLFxuICBLRVlfQUxHT1JZVEhNID0gXCJQQktERjJcIixcbn1cblxuZXhwb3J0IGNsYXNzIEJhc2VFbmNvZGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBiYXNlTWFwOiBVaW50OEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoMjU2KTtcbiAgcHJpdmF0ZSByZWFkb25seSBiYXNlOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbGVhZGVyOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmFjdG9yOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgaUZhY3RvcjogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYWxwaGFiZXQ6IEJBU0VfQUxQSEFCRVQpIHtcbiAgICBpZiAodGhpcy5hbHBoYWJldC5sZW5ndGggPj0gMjU1KSB0aHJvdyBuZXcgRXJyb3IoXCJBbHBoYWJldCB0b28gbG9uZ1wiKTtcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5iYXNlTWFwLmxlbmd0aDsgaisrKSB0aGlzLmJhc2VNYXBbal0gPSAyNTU7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFscGhhYmV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB4ID0gYWxwaGFiZXQuY2hhckF0KGkpO1xuICAgICAgY29uc3QgeGMgPSB4LmNoYXJDb2RlQXQoMCk7XG4gICAgICBpZiAodGhpcy5iYXNlTWFwW3hjXSAhPT0gMjU1KSB0aHJvdyBuZXcgRXJyb3IoeCArIFwiIGlzIGFtYmlndW91c1wiKTtcblxuICAgICAgdGhpcy5iYXNlTWFwW3hjXSA9IGk7XG4gICAgfVxuXG4gICAgdGhpcy5iYXNlID0gdGhpcy5hbHBoYWJldC5sZW5ndGg7XG4gICAgdGhpcy5sZWFkZXIgPSB0aGlzLmFscGhhYmV0LmNoYXJBdCgwKTtcbiAgICB0aGlzLmZhY3RvciA9IE1hdGgubG9nKHRoaXMuYmFzZSkgLyBNYXRoLmxvZygyNTYpOyAvLyBsb2coQkFTRSkgLyBsb2coMjU2KSwgcm91bmRlZCB1cFxuICAgIHRoaXMuaUZhY3RvciA9IE1hdGgubG9nKDI1NikgLyBNYXRoLmxvZyh0aGlzLmJhc2UpOyAvLyBsb2coMjU2KSAvIGxvZyhCQVNFKSwgcm91bmRlZCB1cFxuICB9XG5cbiAgZW5jb2RlKHNvdXJjZTogVWludDhBcnJheSB8IERhdGFWaWV3IHwgYW55W10gfCBzdHJpbmcpIHtcbiAgICBpZiAodHlwZW9mIHNvdXJjZSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgc291cmNlID0gQnVmZmVyLmZyb20oc291cmNlKTtcbiAgICB9IGVsc2UgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhzb3VyY2UpKSB7XG4gICAgICBzb3VyY2UgPSBuZXcgVWludDhBcnJheShcbiAgICAgICAgc291cmNlLmJ1ZmZlcixcbiAgICAgICAgc291cmNlLmJ5dGVPZmZzZXQsXG4gICAgICAgIHNvdXJjZS5ieXRlTGVuZ3RoXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShzb3VyY2UpKSB7XG4gICAgICBzb3VyY2UgPSBVaW50OEFycmF5LmZyb20oc291cmNlKTtcbiAgICB9XG5cbiAgICBpZiAoc291cmNlLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiXCI7XG5cbiAgICAvLyBTa2lwICYgY291bnQgbGVhZGluZyB6ZXJvZXMuXG4gICAgbGV0IHplcm9lcyA9IDA7XG4gICAgbGV0IGxlbmd0aCA9IDA7XG4gICAgbGV0IHBiZWdpbiA9IDA7XG4gICAgY29uc3QgcGVuZCA9IHNvdXJjZS5sZW5ndGg7XG4gICAgd2hpbGUgKHBiZWdpbiAhPT0gcGVuZCAmJiBzb3VyY2VbcGJlZ2luXSA9PT0gMCkge1xuICAgICAgcGJlZ2luKys7XG4gICAgICB6ZXJvZXMrKztcbiAgICB9XG4gICAgLy8gQWxsb2NhdGUgZW5vdWdoIHNwYWNlIGluIGJpZy1lbmRpYW4gYmFzZTU4IHJlcHJlc2VudGF0aW9uLlxuICAgIGNvbnN0IHNpemUgPSAoKHBlbmQgLSBwYmVnaW4pICogdGhpcy5pRmFjdG9yICsgMSkgPj4+IDA7XG4gICAgY29uc3QgYjU4ID0gbmV3IFVpbnQ4QXJyYXkoc2l6ZSk7XG4gICAgLy8gUHJvY2VzcyB0aGUgYnl0ZXMuXG4gICAgd2hpbGUgKHBiZWdpbiAhPT0gcGVuZCkge1xuICAgICAgbGV0IGNhcnJ5ID0gc291cmNlW3BiZWdpbl07XG4gICAgICAvLyBBcHBseSBcImI1OCA9IGI1OCAqIDI1NiArIGNoXCIuXG4gICAgICBsZXQgaSA9IDA7XG4gICAgICBmb3IgKFxuICAgICAgICBsZXQgaXQxID0gc2l6ZSAtIDE7XG4gICAgICAgIChjYXJyeSAhPT0gMCB8fCBpIDwgbGVuZ3RoKSAmJiBpdDEgIT09IC0xO1xuICAgICAgICBpdDEtLSwgaSsrXG4gICAgICApIHtcbiAgICAgICAgY2FycnkgKz0gKDI1NiAqIGI1OFtpdDFdKSA+Pj4gMDtcbiAgICAgICAgYjU4W2l0MV0gPSBjYXJyeSAlIHRoaXMuYmFzZSA+Pj4gMDtcbiAgICAgICAgY2FycnkgPSAoY2FycnkgLyB0aGlzLmJhc2UpID4+PiAwO1xuICAgICAgfVxuICAgICAgaWYgKGNhcnJ5ICE9PSAwKSB0aHJvdyBuZXcgRXJyb3IoXCJOb24temVybyBjYXJyeVwiKTtcblxuICAgICAgbGVuZ3RoID0gaTtcbiAgICAgIHBiZWdpbisrO1xuICAgIH1cbiAgICAvLyBTa2lwIGxlYWRpbmcgemVyb2VzIGluIGJhc2U1OCByZXN1bHQuXG4gICAgbGV0IGl0MiA9IHNpemUgLSBsZW5ndGg7XG4gICAgd2hpbGUgKGl0MiAhPT0gc2l6ZSAmJiBiNThbaXQyXSA9PT0gMCkgaXQyKys7XG5cbiAgICAvLyBUcmFuc2xhdGUgdGhlIHJlc3VsdCBpbnRvIGEgc3RyaW5nLlxuICAgIGxldCBzdHIgPSB0aGlzLmxlYWRlci5yZXBlYXQoemVyb2VzKTtcbiAgICBmb3IgKDsgaXQyIDwgc2l6ZTsgKytpdDIpIHtcbiAgICAgIHN0ciArPSB0aGlzLmFscGhhYmV0LmNoYXJBdChiNThbaXQyXSk7XG4gICAgfVxuICAgIHJldHVybiBzdHI7XG4gIH1cblxuICBwcml2YXRlIGRlY29kZVVuc2FmZShzb3VyY2U6IHN0cmluZyk6IFVpbnQ4QXJyYXkgfCB1bmRlZmluZWQge1xuICAgIGlmIChzb3VyY2UubGVuZ3RoID09PSAwKSByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoMCk7XG5cbiAgICBsZXQgcHN6ID0gMDtcbiAgICAvLyBTa2lwIGFuZCBjb3VudCBsZWFkaW5nICcxJ3MuXG4gICAgbGV0IHplcm9lcyA9IDA7XG4gICAgbGV0IGxlbmd0aCA9IDA7XG4gICAgd2hpbGUgKHNvdXJjZVtwc3pdID09PSB0aGlzLmxlYWRlcikge1xuICAgICAgemVyb2VzKys7XG4gICAgICBwc3orKztcbiAgICB9XG4gICAgLy8gQWxsb2NhdGUgZW5vdWdoIHNwYWNlIGluIGJpZy1lbmRpYW4gYmFzZTI1NiByZXByZXNlbnRhdGlvbi5cbiAgICBjb25zdCBzaXplID0gKChzb3VyY2UubGVuZ3RoIC0gcHN6KSAqIHRoaXMuZmFjdG9yICsgMSkgPj4+IDA7IC8vIGxvZyg1OCkgLyBsb2coMjU2KSwgcm91bmRlZCB1cC5cbiAgICBjb25zdCBiMjU2ID0gbmV3IFVpbnQ4QXJyYXkoc2l6ZSk7XG4gICAgLy8gUHJvY2VzcyB0aGUgY2hhcmFjdGVycy5cbiAgICB3aGlsZSAoc291cmNlW3Bzel0pIHtcbiAgICAgIC8vIERlY29kZSBjaGFyYWN0ZXJcbiAgICAgIGxldCBjYXJyeSA9IHRoaXMuYmFzZU1hcFtzb3VyY2UuY2hhckNvZGVBdChwc3opXTtcbiAgICAgIC8vIEludmFsaWQgY2hhcmFjdGVyXG4gICAgICBpZiAoY2FycnkgPT09IDI1NSkgcmV0dXJuO1xuXG4gICAgICBsZXQgaSA9IDA7XG4gICAgICBmb3IgKFxuICAgICAgICBsZXQgaXQzID0gc2l6ZSAtIDE7XG4gICAgICAgIChjYXJyeSAhPT0gMCB8fCBpIDwgbGVuZ3RoKSAmJiBpdDMgIT09IC0xO1xuICAgICAgICBpdDMtLSwgaSsrXG4gICAgICApIHtcbiAgICAgICAgY2FycnkgKz0gKHRoaXMuYmFzZSAqIGIyNTZbaXQzXSkgPj4+IDA7XG4gICAgICAgIGIyNTZbaXQzXSA9IGNhcnJ5ICUgMjU2ID4+PiAwO1xuICAgICAgICBjYXJyeSA9IChjYXJyeSAvIDI1NikgPj4+IDA7XG4gICAgICB9XG4gICAgICBpZiAoY2FycnkgIT09IDApIHRocm93IG5ldyBFcnJvcihcIk5vbi16ZXJvIGNhcnJ5XCIpO1xuXG4gICAgICBsZW5ndGggPSBpO1xuICAgICAgcHN6Kys7XG4gICAgfVxuICAgIC8vIFNraXAgbGVhZGluZyB6ZXJvZXMgaW4gYjI1Ni5cbiAgICBsZXQgaXQ0ID0gc2l6ZSAtIGxlbmd0aDtcbiAgICB3aGlsZSAoaXQ0ICE9PSBzaXplICYmIGIyNTZbaXQ0XSA9PT0gMCkgaXQ0Kys7XG5cbiAgICBjb25zdCB2Y2ggPSBuZXcgVWludDhBcnJheSh6ZXJvZXMgKyAoc2l6ZSAtIGl0NCkpO1xuICAgIGxldCBqID0gemVyb2VzO1xuICAgIHdoaWxlIChpdDQgIT09IHNpemUpIHZjaFtqKytdID0gYjI1NltpdDQrK107XG5cbiAgICByZXR1cm4gdmNoO1xuICB9XG5cbiAgZGVjb2RlKHNvdXJjZTogc3RyaW5nKSB7XG4gICAgY29uc3QgYnVmZmVyID0gdGhpcy5kZWNvZGVVbnNhZmUoc291cmNlKTtcbiAgICBpZiAoYnVmZmVyKSByZXR1cm4gYnVmZmVyO1xuICAgIHRocm93IG5ldyBFcnJvcihcIk5vbi1iYXNlXCIgKyB0aGlzLmJhc2UgKyBcIiBjaGFyYWN0ZXJcIik7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIENyeXB0b1V0aWxzIHtcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgYjU4ZW5jb2RlciA9IG5ldyBCYXNlRW5jb2RlcihCQVNFX0FMUEhBQkVULkJBU0U1OCk7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IGxvZ2dlciA9IExvZ2dpbmcuZm9yKENyeXB0b1V0aWxzLm5hbWUpO1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICBzdGF0aWMgZmFicmljSWRGcm9tQ2VydGlmaWNhdGUoY2VydGlmaWNhdGU6IHN0cmluZykge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKHN0cmluZ0Zvcm1hdChcIlBhcnNpbmcgY2VydGlmaWNhdGU6IHswfVwiLCBjZXJ0aWZpY2F0ZSkpO1xuICAgIGNvbnN0IGNlcnQgPSBuZXcgeDUwOS5YNTA5Q2VydGlmaWNhdGUoY2VydGlmaWNhdGUpO1xuICAgIGNvbnN0IHsgc3ViamVjdCwgaXNzdWVyIH0gPSBjZXJ0O1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgc3RyaW5nRm9ybWF0KFxuICAgICAgICBcIkNlcnRpZmljYXRlIHBhcnNlZCB3aXRoIHN1YmplY3QgezB9IGFuZCBpc3N1ZXIgezF9XCIsXG4gICAgICAgIHN1YmplY3QsXG4gICAgICAgIGlzc3VlclxuICAgICAgKVxuICAgICk7XG4gICAgcmV0dXJuIGB4NTA5OjovJHtzdWJqZWN0LnJlcGxhY2VBbGwoXCIsIFwiLCBcIi9cIil9OjovJHtpc3N1ZXIucmVwbGFjZUFsbChcIiwgXCIsIFwiL1wiKX1gO1xuICB9XG5cbiAgc3RhdGljIGVuY29kZShzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuYjU4ZW5jb2Rlci5lbmNvZGUoc3RyKTtcbiAgfVxuICBzdGF0aWMgZGVjb2RlKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBkZWNvZGVkID0gdGhpcy5iNThlbmNvZGVyLmRlY29kZShzdHIpO1xuICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShkZWNvZGVkKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgc3RhdGljIHN0cmluZ1RvQXJyYXlCdWZmZXIoc3RyOiBzdHJpbmcpIHtcbiAgICBjb25zdCBidWYgPSBuZXcgQXJyYXlCdWZmZXIoc3RyLmxlbmd0aCk7XG4gICAgY29uc3QgYnVmVmlldyA9IG5ldyBVaW50OEFycmF5KGJ1Zik7XG4gICAgZm9yIChsZXQgaSA9IDAsIHN0ckxlbiA9IHN0ci5sZW5ndGg7IGkgPCBzdHJMZW47IGkrKykge1xuICAgICAgYnVmVmlld1tpXSA9IHN0ci5jaGFyQ29kZUF0KGkpO1xuICAgIH1cbiAgICByZXR1cm4gYnVmO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgZXh0cmFjdEtleShcbiAgICB0eXBlOiBcInByaXZhdGVcIiB8IFwicHVibGljXCIsXG4gICAgcGVtOiBCdWZmZXIgfCBzdHJpbmcsXG4gICAgdXNhZ2VzPzogYW55W11cbiAgKSB7XG4gICAgY29uc3Qgc3VidGxlID0gY3J5cHRvLnN1YnRsZTtcblxuICAgIGNvbnN0IHN0ciA9IHBlbVxuICAgICAgLnRvU3RyaW5nKFwidXRmOFwiKVxuICAgICAgLnJlcGxhY2UoXG4gICAgICAgIG5ldyBSZWdFeHAoYC0tLS0tQkVHSU4gKCR7dHlwZS50b1VwcGVyQ2FzZSgpfSBLRVl8Q0VSVElGSUNBVEUpLS0tLS1gKSxcbiAgICAgICAgXCJcIlxuICAgICAgKVxuICAgICAgLnJlcGxhY2VBbGwoXCJcXG5cIiwgXCJcIilcbiAgICAgIC5yZXBsYWNlKFxuICAgICAgICBuZXcgUmVnRXhwKGAtLS0tLUVORCAoJHt0eXBlLnRvVXBwZXJDYXNlKCl9IEtFWXxDRVJUSUZJQ0FURSktLS0tLWApLFxuICAgICAgICBcIlwiXG4gICAgICApO1xuICAgIGNvbnN0IGRlY29kZWQgPSBCdWZmZXIuZnJvbShzdHIsIFwiYmFzZTY0XCIpLnRvU3RyaW5nKFwiYmluYXJ5XCIpO1xuICAgIGNvbnN0IGJpbmFyeURlciA9IHRoaXMuc3RyaW5nVG9BcnJheUJ1ZmZlcihkZWNvZGVkKTtcbiAgICBjb25zdCBrZXkgPSBhd2FpdCBzdWJ0bGUuaW1wb3J0S2V5KFxuICAgICAgXCJwa2NzOFwiLFxuICAgICAgYmluYXJ5RGVyLFxuICAgICAge1xuICAgICAgICBuYW1lOiBcIkVDRFNBXCIsXG4gICAgICAgIG5hbWVkQ3VydmU6IFwiUC0yNTZcIixcbiAgICAgIH0sXG4gICAgICB0cnVlLFxuICAgICAgdXNhZ2VzID8gdXNhZ2VzIDogW1wic2lnblwiXVxuICAgICk7XG5cbiAgICByZXR1cm4ga2V5O1xuICB9XG5cbiAgc3RhdGljIGFzeW5jIGV4dHJhY3RQcml2YXRlS2V5KHBlbTogQnVmZmVyIHwgc3RyaW5nLCB1c2FnZXM/OiBhbnlbXSkge1xuICAgIHJldHVybiB0aGlzLmV4dHJhY3RLZXkoXCJwcml2YXRlXCIsIHBlbSwgdXNhZ2VzKTtcbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBleHRyYWN0UHVibGljS2V5KHBlbTogQnVmZmVyIHwgc3RyaW5nLCB1c2FnZXM/OiBhbnlbXSkge1xuICAgIHJldHVybiB0aGlzLmV4dHJhY3RLZXkoXCJwdWJsaWNcIiwgcGVtLCB1c2FnZXMpO1xuICB9XG5cbiAgc3RhdGljIGFzeW5jIHNpZ24ocHJpdmF0ZUtleTogc3RyaW5nLCBkYXRhOiBCdWZmZXIpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGtleSA9IGF3YWl0IHRoaXMuZXh0cmFjdFByaXZhdGVLZXkocHJpdmF0ZUtleSk7XG4gICAgY29uc3QgYnVmZiA9IChhd2FpdCBjcnlwdG8uc3VidGxlLnNpZ24oXG4gICAgICB7XG4gICAgICAgIG5hbWU6IFwiRUNEU0FcIixcbiAgICAgICAgaGFzaDogXCJTSEEtMjU2XCIsXG4gICAgICB9LFxuICAgICAga2V5LFxuICAgICAgZGF0YVxuICAgICkpIGFzIEFycmF5QnVmZmVyO1xuXG4gICAgcmV0dXJuIEFycmF5LmZyb20obmV3IFVpbnQ4QXJyYXkoYnVmZikpXG4gICAgICAubWFwKChiKSA9PiBiLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCBcIjBcIikpXG4gICAgICAuam9pbihcIlwiKTtcbiAgfVxuXG4gIHN0YXRpYyBhc3luYyB2ZXJpZnkoXG4gICAgY2VydGlmaWNhdGU6IHN0cmluZyxcbiAgICBzaWduYXR1cmU6IEJ1ZmZlciB8IHN0cmluZyxcbiAgICBkYXRhOiBCdWZmZXIgfCBzdHJpbmdcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgY2VydCA9IG5ldyB4NTA5Llg1MDlDZXJ0aWZpY2F0ZShjZXJ0aWZpY2F0ZSk7XG4gICAgY29uc3Qga2V5ID0gYXdhaXQgY2VydC5wdWJsaWNLZXkuZXhwb3J0KCk7XG4gICAgc2lnbmF0dXJlID0gKFxuICAgICAgdHlwZW9mIHNpZ25hdHVyZSA9PT0gXCJzdHJpbmdcIiA/IEJ1ZmZlci5mcm9tKHNpZ25hdHVyZSwgXCJoZXhcIikgOiBzaWduYXR1cmVcbiAgICApIGFzIEJ1ZmZlcjtcbiAgICBkYXRhID0gKHR5cGVvZiBkYXRhID09PSBcInN0cmluZ1wiID8gQnVmZmVyLmZyb20oZGF0YSkgOiBkYXRhKSBhcyBCdWZmZXI7XG4gICAgcmV0dXJuIGNyeXB0by5zdWJ0bGUudmVyaWZ5KFxuICAgICAge1xuICAgICAgICBuYW1lOiBcIkVDRFNBXCIsXG4gICAgICAgIGhhc2g6IFwiU0hBLTI1NlwiLFxuICAgICAgfSxcbiAgICAgIGtleSxcbiAgICAgIHNpZ25hdHVyZSxcbiAgICAgIGRhdGFcbiAgICApO1xuICB9XG5cbiAgc3RhdGljIGFzeW5jIGVuY3J5cHQoY2VydGlmaWNhdGU6IHN0cmluZywgZGF0YTogc3RyaW5nIHwgQnVmZmVyKSB7XG4gICAgY29uc3QgY2VydCA9IG5ldyB4NTA5Llg1MDlDZXJ0aWZpY2F0ZShjZXJ0aWZpY2F0ZSk7XG4gICAgY29uc3Qga2V5ID0gYXdhaXQgY2VydC5wdWJsaWNLZXkuZXhwb3J0KCk7XG4gICAgZGF0YSA9ICh0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIiA/IEJ1ZmZlci5mcm9tKGRhdGEpIDogZGF0YSkgYXMgQnVmZmVyO1xuICAgIGNvbnN0IGJ1ZmYgPSBhd2FpdCB0aGlzLmdldFN1YnRsZUNyeXB0bygpLmVuY3J5cHQoXG4gICAgICB7XG4gICAgICAgIG5hbWU6IFwiRUNEU0FcIixcbiAgICAgIH0sXG4gICAgICBrZXksXG4gICAgICBkYXRhXG4gICAgKTtcblxuICAgIHJldHVybiBBcnJheS5mcm9tKG5ldyBVaW50OEFycmF5KGJ1ZmYpKVxuICAgICAgLm1hcCgoYikgPT4gYi50b1N0cmluZygxNikucGFkU3RhcnQoMiwgXCIwXCIpKVxuICAgICAgLmpvaW4oXCJcIik7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRTdWJ0bGVDcnlwdG8oKSB7XG4gICAgcmV0dXJuIGlzQnJvd3NlcigpXG4gICAgICA/IChnbG9iYWxUaGlzIGFzIGFueSkud2luZG93LmNyeXB0by5zdWJ0bGVcbiAgICAgIDogY3J5cHRvLnN1YnRsZTtcbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBkZWNyeXB0KHByaXZhdGVLZXk6IHN0cmluZywgZGF0YTogc3RyaW5nIHwgQnVmZmVyKSB7XG4gICAgY29uc3Qga2V5ID0gYXdhaXQgdGhpcy5leHRyYWN0UHJpdmF0ZUtleShwcml2YXRlS2V5KTtcbiAgICBkYXRhID0gKFxuICAgICAgdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIgPyBCdWZmZXIuZnJvbShkYXRhLCBcImhleFwiKSA6IGRhdGFcbiAgICApIGFzIEJ1ZmZlcjtcbiAgICByZXR1cm4gdGhpcy5nZXRTdWJ0bGVDcnlwdG8oKS5kZWNyeXB0KFxuICAgICAge1xuICAgICAgICBuYW1lOiBcIkVDRFNBXCIsXG4gICAgICB9LFxuICAgICAga2V5LFxuICAgICAgZGF0YVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVXRpbCBmdW5jdGlvbiB0byBnZXQgYSByYW5kb20gbWFzdGVyIGtleVxuICAgKlxuICAgKiBAZGVzY3JpcHRpb24gSWYgZGF0YSBpcyBub3QgcGFzc2VkLCBhIHJhbmRvbSBBcnJheUJ1ZmZlciB3aWxsIGJlIGdlbmVyYXRlZFxuICAgKlxuICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBkYXRhIGVuY3J5dGlvbiBkYXRhXG4gICAqXG4gICAqIEBmdW5jdGlvbiBnZXRNYXN0ZXJcbiAgICovXG4gIHN0YXRpYyBhc3luYyBnZXRNYXN0ZXIoZGF0YT86IEFycmF5QnVmZmVyKTogUHJvbWlzZTxrZXlPYmplY3Q+IHtcbiAgICBjb25zdCB0ZXh0RW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpO1xuICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGdlbkdlbmVzaXMgPSBjcnlwdG8ucmFuZG9tVVVJRCgpO1xuICAgICAgZGF0YSA9IHRleHRFbmNvZGVyLmVuY29kZShnZW5HZW5lc2lzKTtcbiAgICB9XG5cbiAgICBjb25zdCBpbXBvcnRlZEtleSA9IGF3YWl0IHRoaXMuZ2V0U3VidGxlQ3J5cHRvKCkuaW1wb3J0S2V5KFxuICAgICAgXCJyYXdcIixcbiAgICAgIGRhdGEsXG4gICAgICBDUllQVE8uS0VZX0FMR09SWVRITSBhcyBzdHJpbmcsXG4gICAgICBmYWxzZSxcbiAgICAgIFtcImRlcml2ZUJpdHNcIl1cbiAgICApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGtleTogaW1wb3J0ZWRLZXksXG4gICAgICBpdjogZGF0YSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gZGVyaXZlIGEga2V5IGZyb20gYW5vdGhlciBrZXlcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHNhbHRcbiAgICogQHBhcmFtIHtDcnlwdG9LZXl9IGtleSBPcmlnaW5hbCBrZXlcbiAgICpcbiAgICogQGZ1bmN0aW9uIGdldERlcml2YXRpb25LZXlcbiAgICovXG4gIHN0YXRpYyBhc3luYyBnZXREZXJpdmF0aW9uS2V5KHNhbHQ6IHN0cmluZywga2V5OiBDcnlwdG9LZXkpIHtcbiAgICBjb25zdCB0ZXh0RW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpO1xuICAgIGNvbnN0IHNhbHRCdWZmZXIgPSB0ZXh0RW5jb2Rlci5lbmNvZGUoc2FsdCk7XG4gICAgY29uc3Qgc2FsdEhhc2hlZCA9IGF3YWl0IHRoaXMuZ2V0U3VidGxlQ3J5cHRvKCkuZGlnZXN0KFxuICAgICAgXCJTSEEtMjU2XCIsXG4gICAgICBzYWx0QnVmZmVyXG4gICAgKTtcbiAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICBuYW1lOiBDUllQVE8uS0VZX0FMR09SWVRITSBhcyBzdHJpbmcsXG4gICAgICBoYXNoOiBDUllQVE8uSEFTSCxcbiAgICAgIHNhbHQ6IHNhbHRIYXNoZWQsXG4gICAgICBpdGVyYXRpb25zOiBDUllQVE8uSVRFUkFUSU9OUyxcbiAgICB9O1xuICAgIGNvbnN0IGRlcml2YXRpb24gPSBhd2FpdCB0aGlzLmdldFN1YnRsZUNyeXB0bygpLmRlcml2ZUJpdHMoXG4gICAgICBwYXJhbXMsXG4gICAgICBrZXksXG4gICAgICBDUllQVE8uS0VZTEVOR1RIICogOFxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0S2V5KGRlcml2YXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXkgYW5kIElWIGZyb20gdGhlIENyeXRvS2V5IGFycmF5XG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGRlcml2YXRpb25cbiAgICpcbiAgICogQGZ1bmN0aW9uIGdldEtleVxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGdldEtleShkZXJpdmF0aW9uOiBBcnJheUJ1ZmZlcikge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBjb25zdCBpdmxlbiA9IDE2O1xuICAgIGNvbnN0IGtleWxlbiA9IDMyO1xuICAgIGNvbnN0IGRlcml2ZWRLZXkgPSBkZXJpdmF0aW9uLnNsaWNlKDAsIGtleWxlbik7XG4gICAgY29uc3QgaXYgPSBkZXJpdmF0aW9uLnNsaWNlKGtleWxlbik7XG4gICAgY29uc3QgaW1wb3J0ZWRFbmNyeXB0aW9uS2V5ID0gYXdhaXQgdGhpcy5nZXRTdWJ0bGVDcnlwdG8oKS5pbXBvcnRLZXkoXG4gICAgICBcInJhd1wiLFxuICAgICAgZGVyaXZlZEtleSxcbiAgICAgIHsgbmFtZTogQ1JZUFRPLkFMR09SWVRITSBhcyBzdHJpbmcgfSxcbiAgICAgIGZhbHNlLFxuICAgICAgW1wiZW5jcnlwdFwiLCBcImRlY3J5cHRcIl1cbiAgICApO1xuICAgIHJldHVybiB7XG4gICAgICBrZXk6IGltcG9ydGVkRW5jcnlwdGlvbktleSxcbiAgICAgIGl2OiBpdixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gZGVjcnlwdCBkYXRhXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gICAqIEBwYXJhbSB7a2V5T2JqZWN0fSBrZXlPYmplY3RcbiAgICpcbiAgICogQGZ1bmN0aW9uIGVuY3J5cHRcbiAgICovXG4gIHN0YXRpYyBhc3luYyBlbmNyeXB0UGluKFxuICAgIHRleHQ6IHN0cmluZyxcbiAgICBrZXlPYmplY3Q6IGtleU9iamVjdFxuICApOiBQcm9taXNlPEFycmF5QnVmZmVyPiB7XG4gICAgY29uc3QgdGV4dEVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgICBjb25zdCB0ZXh0QnVmZmVyID0gdGV4dEVuY29kZXIuZW5jb2RlKHRleHQpO1xuICAgIGNvbnN0IGVuY3J5cHRlZFRleHQgPSBhd2FpdCB0aGlzLmdldFN1YnRsZUNyeXB0bygpLmVuY3J5cHQoXG4gICAgICB7IG5hbWU6IENSWVBUTy5BTEdPUllUSE0gYXMgc3RyaW5nLCBpdjoga2V5T2JqZWN0Lml2IH0sXG4gICAgICBrZXlPYmplY3Qua2V5LFxuICAgICAgdGV4dEJ1ZmZlclxuICAgICk7XG4gICAgcmV0dXJuIGVuY3J5cHRlZFRleHQ7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVXRpbCBmdW5jdGlvbiB0byBkZWNyeXB0IGRhdGFcbiAgICpcbiAgICogQHBhcmFtIHtCdWZmZXJTb3VyY2V9IGVuY3J5cHRlZFRleHRcbiAgICogQHBhcmFtIHtrZXlPYmplY3R9IGtleU9iamVjdFxuICAgKlxuICAgKiBAZnVuY3Rpb24gZGVjcnlwdFxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGRlY3J5cHRQaW4oXG4gICAgZW5jcnlwdGVkVGV4dDogQXJyYXlCdWZmZXIsXG4gICAga2V5T2JqZWN0OiBrZXlPYmplY3RcbiAgKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCB0ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpO1xuICAgIGNvbnN0IGRlY3J5cHRlZFRleHQgPSBhd2FpdCB0aGlzLmdldFN1YnRsZUNyeXB0bygpLmRlY3J5cHQoXG4gICAgICB7IG5hbWU6IENSWVBUTy5BTEdPUllUSE0gYXMgc3RyaW5nLCBpdjoga2V5T2JqZWN0Lml2IH0sXG4gICAgICBrZXlPYmplY3Qua2V5LFxuICAgICAgZW5jcnlwdGVkVGV4dFxuICAgICk7XG4gICAgcmV0dXJuIHRleHREZWNvZGVyLmRlY29kZShkZWNyeXB0ZWRUZXh0KTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Repo } from "@decaf-ts/core";
|
|
2
|
+
import { Context, RepositoryFlags } from "@decaf-ts/db-decorators";
|
|
3
|
+
import { Model } from "@decaf-ts/decorator-validation";
|
|
4
|
+
/**
|
|
5
|
+
* Decorator for marking methods that require ownership authorization.
|
|
6
|
+
* Checks the owner of the token before allowing the method to be executed.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* class TokenContract extends Contract {
|
|
11
|
+
* @Owner()
|
|
12
|
+
* async Mint(ctx: Context, amount: number) {
|
|
13
|
+
* // Mint token logic
|
|
14
|
+
* }
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @returns {MethodDecorator} A method decorator that checks ownership authorization.
|
|
19
|
+
*/
|
|
20
|
+
export declare function Owner(): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
21
|
+
export declare function ownedByOnCreate<M extends Model, R extends Repo<M, F, C>, V, F extends RepositoryFlags, C extends Context<F>>(this: R, context: Context<F>, data: V, key: keyof M, model: M): Promise<void>;
|
|
22
|
+
export declare function OwnedBy(): (target: any, propertyKey?: any, descriptor?: TypedPropertyDescriptor<any>) => any;
|
|
23
|
+
export declare function getFabricModelKey(key: string): string;
|
|
24
|
+
export declare function privateData(collection?: string): (model: any, attribute?: any) => void;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { AuthorizationError } from "@decaf-ts/core";
|
|
2
|
+
import { NotFoundError, onCreate, readonly, transient, } from "@decaf-ts/db-decorators";
|
|
3
|
+
import { Decoration, Model, ModelKeys, propMetadata, required, } from "@decaf-ts/decorator-validation";
|
|
4
|
+
import { FabricModelKeys } from "./constants.js";
|
|
5
|
+
import { apply } from "@decaf-ts/reflection";
|
|
6
|
+
/**
|
|
7
|
+
* Decorator for marking methods that require ownership authorization.
|
|
8
|
+
* Checks the owner of the token before allowing the method to be executed.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* class TokenContract extends Contract {
|
|
13
|
+
* @Owner()
|
|
14
|
+
* async Mint(ctx: Context, amount: number) {
|
|
15
|
+
* // Mint token logic
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @returns {MethodDecorator} A method decorator that checks ownership authorization.
|
|
21
|
+
*/
|
|
22
|
+
export function Owner() {
|
|
23
|
+
return function (target, propertyKey, descriptor) {
|
|
24
|
+
const originalMethod = descriptor.value;
|
|
25
|
+
descriptor.value = async function (...args) {
|
|
26
|
+
const ctx = args[0];
|
|
27
|
+
const acountId = ctx.clientIdentity.getID();
|
|
28
|
+
const select = await this["tokenRepository"].selectWithContext(undefined, ctx);
|
|
29
|
+
const tokens = await select.execute();
|
|
30
|
+
if (tokens.length == 0) {
|
|
31
|
+
throw new NotFoundError("No tokens avaialble");
|
|
32
|
+
}
|
|
33
|
+
if (tokens.length > 1) {
|
|
34
|
+
throw new NotFoundError(`To many token available : ${tokens.length}`);
|
|
35
|
+
}
|
|
36
|
+
if (tokens[0].owner != acountId) {
|
|
37
|
+
throw new AuthorizationError(`User not authorized to run ${propertyKey} on the token`);
|
|
38
|
+
}
|
|
39
|
+
return await originalMethod.apply(this, args);
|
|
40
|
+
};
|
|
41
|
+
return descriptor;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export async function ownedByOnCreate(context, data, key, model) {
|
|
45
|
+
const { stub } = context;
|
|
46
|
+
const creator = await stub.getCreator();
|
|
47
|
+
const owner = creator.mspid;
|
|
48
|
+
const setOwnedByKeyValue = function (target, propertyKey, value) {
|
|
49
|
+
Object.defineProperty(target, propertyKey, {
|
|
50
|
+
enumerable: true,
|
|
51
|
+
writable: false,
|
|
52
|
+
configurable: true,
|
|
53
|
+
value: value,
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
setOwnedByKeyValue(model, key, owner);
|
|
57
|
+
}
|
|
58
|
+
export function OwnedBy() {
|
|
59
|
+
const key = getFabricModelKey(FabricModelKeys.OWNEDBY);
|
|
60
|
+
function ownedBy() {
|
|
61
|
+
return function (obj, attribute) {
|
|
62
|
+
return apply(required(), readonly(), onCreate(ownedByOnCreate), propMetadata(getFabricModelKey(FabricModelKeys.OWNEDBY), attribute))(obj, attribute);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return Decoration.for(key)
|
|
66
|
+
.define({
|
|
67
|
+
decorator: ownedBy,
|
|
68
|
+
args: [],
|
|
69
|
+
})
|
|
70
|
+
.apply();
|
|
71
|
+
}
|
|
72
|
+
export function getFabricModelKey(key) {
|
|
73
|
+
return Model.key(FabricModelKeys.FABRIC + key);
|
|
74
|
+
}
|
|
75
|
+
export function privateData(collection) {
|
|
76
|
+
if (!collection) {
|
|
77
|
+
throw new Error("Collection name is required");
|
|
78
|
+
}
|
|
79
|
+
const key = getFabricModelKey(FabricModelKeys.PRIVATE);
|
|
80
|
+
return function privateData(model, attribute) {
|
|
81
|
+
const propertyKey = attribute || undefined;
|
|
82
|
+
const meta = Reflect.getMetadata(key, model[ModelKeys.ANCHOR] || model, propertyKey);
|
|
83
|
+
const data = meta?.collections || [];
|
|
84
|
+
propMetadata(getFabricModelKey(FabricModelKeys.PRIVATE), {
|
|
85
|
+
...(!attribute && {
|
|
86
|
+
collections: data ? [...new Set([...data, collection])] : [collection],
|
|
87
|
+
}),
|
|
88
|
+
isPrivate: !attribute,
|
|
89
|
+
})(attribute ? model.constructor : model[ModelKeys.ANCHOR] || model);
|
|
90
|
+
if (attribute) {
|
|
91
|
+
propMetadata(getFabricModelKey(FabricModelKeys.PRIVATE), {
|
|
92
|
+
collections: data ? [...new Set([...data, collection])] : [collection],
|
|
93
|
+
})(model, attribute);
|
|
94
|
+
transient()(model, attribute);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjb3JhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zaGFyZWQvZGVjb3JhdG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsa0JBQWtCLEVBQVEsTUFBTSxnQkFBZ0IsQ0FBQztBQUUxRCxPQUFPLEVBRUwsYUFBYSxFQUNiLFFBQVEsRUFDUixRQUFRLEVBRVIsU0FBUyxHQUNWLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxFQUNMLFVBQVUsRUFDVixLQUFLLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixRQUFRLEdBQ1QsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN4QyxPQUFPLEVBQUUsZUFBZSxFQUFFLHVCQUFvQjtBQUU5QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFN0M7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsTUFBTSxVQUFVLEtBQUs7SUFDbkIsT0FBTyxVQUNMLE1BQVcsRUFDWCxXQUFtQixFQUNuQixVQUE4QjtRQUU5QixNQUFNLGNBQWMsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDO1FBRXhDLFVBQVUsQ0FBQyxLQUFLLEdBQUcsS0FBSyxXQUV0QixHQUFHLElBQVc7WUFFZCxNQUFNLEdBQUcsR0FBYyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0IsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUU1QyxNQUFNLE1BQU0sR0FBRyxNQUFPLElBQTRCLENBQ2hELGlCQUFpQixDQUNsQixDQUFDLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUVwQyxNQUFNLE1BQU0sR0FBRyxNQUFNLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUV0QyxJQUFJLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZCLE1BQU0sSUFBSSxhQUFhLENBQUMscUJBQXFC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LENBQ3RCLENBQUM7UUFDRixNQUFNLElBQUksR0FBRyxJQUFJLEVBQUUsV0FBVyxJQUFJLEVBQUUsQ0FBQztRQUVyQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ3ZELEdBQUcsQ0FBQyxDQUFDLFNBQVMsSUFBSTtnQkFDaEIsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQzthQUN2RSxDQUFDO1lBQ0YsU0FBUyxFQUFFLENBQUMsU0FBUztTQUN0QixDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDO1FBRXJFLElBQUksU0FBUyxFQUFFLENBQUM7WUFDZCxZQUFZLENBQUMsaUJBQWlCLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUN2RCxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO2FBQ3ZFLENBQUMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDckIsU0FBUyxFQUFFLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ2hDLENBQUM7SUFDSCxDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXV0aG9yaXphdGlvbkVycm9yLCBSZXBvIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBGYWJyaWNFUkMyMENvbnRyYWN0IH0gZnJvbSBcIi4uL2NvbnRyYWN0c1wiO1xuaW1wb3J0IHtcbiAgQ29udGV4dCxcbiAgTm90Rm91bmRFcnJvcixcbiAgb25DcmVhdGUsXG4gIHJlYWRvbmx5LFxuICBSZXBvc2l0b3J5RmxhZ3MsXG4gIHRyYW5zaWVudCxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQge1xuICBEZWNvcmF0aW9uLFxuICBNb2RlbCxcbiAgTW9kZWxLZXlzLFxuICBwcm9wTWV0YWRhdGEsXG4gIHJlcXVpcmVkLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBGYWJyaWNNb2RlbEtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IENvbnRleHQgYXMgSExDb250ZXh0IH0gZnJvbSBcImZhYnJpYy1jb250cmFjdC1hcGlcIjtcbmltcG9ydCB7IGFwcGx5IH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5cbi8qKlxuICogRGVjb3JhdG9yIGZvciBtYXJraW5nIG1ldGhvZHMgdGhhdCByZXF1aXJlIG93bmVyc2hpcCBhdXRob3JpemF0aW9uLlxuICogQ2hlY2tzIHRoZSBvd25lciBvZiB0aGUgdG9rZW4gYmVmb3JlIGFsbG93aW5nIHRoZSBtZXRob2QgdG8gYmUgZXhlY3V0ZWQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNsYXNzIFRva2VuQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7XG4gKiAgIEBPd25lcigpXG4gKiAgIGFzeW5jIE1pbnQoY3R4OiBDb250ZXh0LCBhbW91bnQ6IG51bWJlcikge1xuICogICAgIC8vIE1pbnQgdG9rZW4gbG9naWNcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogQHJldHVybnMge01ldGhvZERlY29yYXRvcn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgY2hlY2tzIG93bmVyc2hpcCBhdXRob3JpemF0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gT3duZXIoKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoXG4gICAgdGFyZ2V0OiBhbnksXG4gICAgcHJvcGVydHlLZXk6IHN0cmluZyxcbiAgICBkZXNjcmlwdG9yOiBQcm9wZXJ0eURlc2NyaXB0b3JcbiAgKSB7XG4gICAgY29uc3Qgb3JpZ2luYWxNZXRob2QgPSBkZXNjcmlwdG9yLnZhbHVlO1xuXG4gICAgZGVzY3JpcHRvci52YWx1ZSA9IGFzeW5jIGZ1bmN0aW9uIChcbiAgICAgIHRoaXM6IEZhYnJpY0VSQzIwQ29udHJhY3QsXG4gICAgICAuLi5hcmdzOiBhbnlbXVxuICAgICkge1xuICAgICAgY29uc3QgY3R4OiBITENvbnRleHQgPSBhcmdzWzBdO1xuICAgICAgY29uc3QgYWNvdW50SWQgPSBjdHguY2xpZW50SWRlbnRpdHkuZ2V0SUQoKTtcblxuICAgICAgY29uc3Qgc2VsZWN0ID0gYXdhaXQgKHRoaXMgYXMgRmFicmljRVJDMjBDb250cmFjdClbXG4gICAgICAgIFwidG9rZW5SZXBvc2l0b3J5XCJcbiAgICAgIF0uc2VsZWN0V2l0aENvbnRleHQodW5kZWZpbmVkLCBjdHgpO1xuXG4gICAgICBjb25zdCB0b2tlbnMgPSBhd2FpdCBzZWxlY3QuZXhlY3V0ZSgpO1xuXG4gICAgICBpZiAodG9rZW5zLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEVycm9yKFwiTm8gdG9rZW5zIGF2YWlhbGJsZVwiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRva2Vucy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEVycm9yKGBUbyBtYW55IHRva2VuIGF2YWlsYWJsZSA6ICR7dG9rZW5zLmxlbmd0aH1gKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRva2Vuc1swXS5vd25lciAhPSBhY291bnRJZCkge1xuICAgICAgICB0aHJvdyBuZXcgQXV0aG9yaXphdGlvbkVycm9yKFxuICAgICAgICAgIGBVc2VyIG5vdCBhdXRob3JpemVkIHRvIHJ1biAke3Byb3BlcnR5S2V5fSBvbiB0aGUgdG9rZW5gXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhd2FpdCBvcmlnaW5hbE1ldGhvZC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvd25lZEJ5T25DcmVhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgZGF0YTogVixcbiAga2V5OiBrZXlvZiBNLFxuICBtb2RlbDogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgc3R1YiB9ID0gY29udGV4dCBhcyBhbnk7XG5cbiAgY29uc3QgY3JlYXRvciA9IGF3YWl0IHN0dWIuZ2V0Q3JlYXRvcigpO1xuICBjb25zdCBvd25lciA9IGNyZWF0b3IubXNwaWQ7XG5cbiAgY29uc3Qgc2V0T3duZWRCeUtleVZhbHVlID0gZnVuY3Rpb24gPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgdGFyZ2V0OiBNLFxuICAgIHByb3BlcnR5S2V5OiBzdHJpbmcsXG4gICAgdmFsdWU6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludFxuICApIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwge1xuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICB9KTtcbiAgfTtcblxuICBzZXRPd25lZEJ5S2V5VmFsdWUobW9kZWwsIGtleSBhcyBzdHJpbmcsIG93bmVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIE93bmVkQnkoKSB7XG4gIGNvbnN0IGtleSA9IGdldEZhYnJpY01vZGVsS2V5KEZhYnJpY01vZGVsS2V5cy5PV05FREJZKTtcblxuICBmdW5jdGlvbiBvd25lZEJ5KCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAob2JqOiBhbnksIGF0dHJpYnV0ZT86IGFueSkge1xuICAgICAgcmV0dXJuIGFwcGx5KFxuICAgICAgICByZXF1aXJlZCgpLFxuICAgICAgICByZWFkb25seSgpLFxuICAgICAgICBvbkNyZWF0ZShvd25lZEJ5T25DcmVhdGUpLFxuICAgICAgICBwcm9wTWV0YWRhdGEoZ2V0RmFicmljTW9kZWxLZXkoRmFicmljTW9kZWxLZXlzLk9XTkVEQlkpLCBhdHRyaWJ1dGUpXG4gICAgICApKG9iaiwgYXR0cmlidXRlKTtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIERlY29yYXRpb24uZm9yKGtleSlcbiAgICAuZGVmaW5lKHtcbiAgICAgIGRlY29yYXRvcjogb3duZWRCeSxcbiAgICAgIGFyZ3M6IFtdLFxuICAgIH0pXG4gICAgLmFwcGx5KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGYWJyaWNNb2RlbEtleShrZXk6IHN0cmluZykge1xuICByZXR1cm4gTW9kZWwua2V5KEZhYnJpY01vZGVsS2V5cy5GQUJSSUMgKyBrZXkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJpdmF0ZURhdGEoY29sbGVjdGlvbj86IHN0cmluZykge1xuICBpZiAoIWNvbGxlY3Rpb24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb2xsZWN0aW9uIG5hbWUgaXMgcmVxdWlyZWRcIik7XG4gIH1cblxuICBjb25zdCBrZXk6IHN0cmluZyA9IGdldEZhYnJpY01vZGVsS2V5KEZhYnJpY01vZGVsS2V5cy5QUklWQVRFKTtcblxuICByZXR1cm4gZnVuY3Rpb24gcHJpdmF0ZURhdGEobW9kZWw6IGFueSwgYXR0cmlidXRlPzogYW55KSB7XG4gICAgY29uc3QgcHJvcGVydHlLZXkgPSBhdHRyaWJ1dGUgfHwgdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgbWV0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBrZXksXG4gICAgICBtb2RlbFtNb2RlbEtleXMuQU5DSE9SXSB8fCBtb2RlbCxcbiAgICAgIHByb3BlcnR5S2V5IGFzIHN0cmluZ1xuICAgICk7XG4gICAgY29uc3QgZGF0YSA9IG1ldGE/LmNvbGxlY3Rpb25zIHx8IFtdO1xuXG4gICAgcHJvcE1ldGFkYXRhKGdldEZhYnJpY01vZGVsS2V5KEZhYnJpY01vZGVsS2V5cy5QUklWQVRFKSwge1xuICAgICAgLi4uKCFhdHRyaWJ1dGUgJiYge1xuICAgICAgICBjb2xsZWN0aW9uczogZGF0YSA/IFsuLi5uZXcgU2V0KFsuLi5kYXRhLCBjb2xsZWN0aW9uXSldIDogW2NvbGxlY3Rpb25dLFxuICAgICAgfSksXG4gICAgICBpc1ByaXZhdGU6ICFhdHRyaWJ1dGUsXG4gICAgfSkoYXR0cmlidXRlID8gbW9kZWwuY29uc3RydWN0b3IgOiBtb2RlbFtNb2RlbEtleXMuQU5DSE9SXSB8fCBtb2RlbCk7XG5cbiAgICBpZiAoYXR0cmlidXRlKSB7XG4gICAgICBwcm9wTWV0YWRhdGEoZ2V0RmFicmljTW9kZWxLZXkoRmFicmljTW9kZWxLZXlzLlBSSVZBVEUpLCB7XG4gICAgICAgIGNvbGxlY3Rpb25zOiBkYXRhID8gWy4uLm5ldyBTZXQoWy4uLmRhdGEsIGNvbGxlY3Rpb25dKV0gOiBbY29sbGVjdGlvbl0sXG4gICAgICB9KShtb2RlbCwgYXR0cmlidXRlKTtcbiAgICAgIHRyYW5zaWVudCgpKG1vZGVsLCBhdHRyaWJ1dGUpO1xuICAgIH1cbiAgfTtcbn1cbiJdfQ==
|