@icure/api 7.0.0-beta.4 → 7.0.0
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/icc-api/api/IccDocumentApi.d.ts +6 -4
- package/icc-api/api/IccDocumentApi.js +8 -5
- package/icc-api/api/IccDocumentApi.js.map +1 -1
- package/icc-api/model/Address.d.ts +6 -0
- package/icc-api/model/Address.js.map +1 -1
- package/icc-api/model/Annotation.d.ts +18 -0
- package/icc-api/model/Annotation.js.map +1 -1
- package/icc-api/model/Content.js +1 -1
- package/icc-api/model/Content.js.map +1 -1
- package/icc-api/model/CryptoActorStub.d.ts +5 -0
- package/icc-api/model/CryptoActorStub.js +1 -0
- package/icc-api/model/CryptoActorStub.js.map +1 -1
- package/icc-api/model/Delegation.d.ts +3 -0
- package/icc-api/model/Delegation.js.map +1 -1
- package/icc-api/model/HealthElement.d.ts +6 -0
- package/icc-api/model/HealthElement.js.map +1 -1
- package/icc-api/model/HealthcareParty.js +1 -1
- package/icc-api/model/HealthcareParty.js.map +1 -1
- package/icc-api/model/ISO639_1.d.ts +8 -0
- package/icc-api/model/ISO639_1.js +3 -0
- package/icc-api/model/ISO639_1.js.map +1 -0
- package/icc-api/model/Patient.d.ts +7 -0
- package/icc-api/model/Patient.js +1 -1
- package/icc-api/model/Patient.js.map +1 -1
- package/icc-api/model/models.d.ts +1 -0
- package/icc-api/model/models.js.map +1 -1
- package/icc-x-api/crypto/EntitiesEncryption.d.ts +2 -1
- package/icc-x-api/crypto/EntitiesEncryption.js +13 -11
- package/icc-x-api/crypto/EntitiesEncryption.js.map +1 -1
- package/icc-x-api/filters/filters.d.ts +4 -0
- package/icc-x-api/filters/filters.js +4 -0
- package/icc-x-api/filters/filters.js.map +1 -1
- package/icc-x-api/icc-accesslog-x-api.d.ts +1 -1
- package/icc-x-api/icc-accesslog-x-api.js +9 -21
- package/icc-x-api/icc-accesslog-x-api.js.map +1 -1
- package/icc-x-api/icc-calendar-item-x-api.d.ts +1 -1
- package/icc-x-api/icc-calendar-item-x-api.js +9 -18
- package/icc-x-api/icc-calendar-item-x-api.js.map +1 -1
- package/icc-x-api/icc-classification-x-api.js +6 -17
- package/icc-x-api/icc-classification-x-api.js.map +1 -1
- package/icc-x-api/icc-contact-x-api.d.ts +16 -1
- package/icc-x-api/icc-contact-x-api.js +65 -95
- package/icc-x-api/icc-contact-x-api.js.map +1 -1
- package/icc-x-api/icc-doctemplate-x-api.js +2 -13
- package/icc-x-api/icc-doctemplate-x-api.js.map +1 -1
- package/icc-x-api/icc-document-x-api.d.ts +12 -4
- package/icc-x-api/icc-document-x-api.js +22 -23
- package/icc-x-api/icc-document-x-api.js.map +1 -1
- package/icc-x-api/icc-form-x-api.js +6 -15
- package/icc-x-api/icc-form-x-api.js.map +1 -1
- package/icc-x-api/icc-helement-x-api.d.ts +1 -1
- package/icc-x-api/icc-helement-x-api.js +8 -18
- package/icc-x-api/icc-helement-x-api.js.map +1 -1
- package/icc-x-api/icc-invoice-x-api.js +6 -17
- package/icc-x-api/icc-invoice-x-api.js.map +1 -1
- package/icc-x-api/icc-maintenance-task-x-api.d.ts +1 -1
- package/icc-x-api/icc-maintenance-task-x-api.js +7 -13
- package/icc-x-api/icc-maintenance-task-x-api.js.map +1 -1
- package/icc-x-api/icc-message-x-api.js +6 -16
- package/icc-x-api/icc-message-x-api.js.map +1 -1
- package/icc-x-api/icc-patient-x-api.d.ts +1 -1
- package/icc-x-api/icc-patient-x-api.js +9 -17
- package/icc-x-api/icc-patient-x-api.js.map +1 -1
- package/icc-x-api/icc-receipt-x-api.js +5 -15
- package/icc-x-api/icc-receipt-x-api.js.map +1 -1
- package/icc-x-api/icc-time-table-x-api.js +5 -15
- package/icc-x-api/icc-time-table-x-api.js.map +1 -1
- package/icc-x-api/index.d.ts +108 -2
- package/icc-x-api/index.js +6 -5
- package/icc-x-api/index.js.map +1 -1
- package/icc-x-api/utils/crypto-utils.d.ts +140 -11
- package/icc-x-api/utils/crypto-utils.js +285 -36
- package/icc-x-api/utils/crypto-utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -42,24 +42,153 @@ export declare function appendBuffer(buffer1: ArrayBuffer, buffer2: ArrayBuffer)
|
|
|
42
42
|
export declare function after(d1: number | null | undefined, d2: number | null | undefined): boolean;
|
|
43
43
|
export declare function before(d1: number | null | undefined, d2: number | null | undefined): boolean;
|
|
44
44
|
/**
|
|
45
|
-
*
|
|
45
|
+
* Configuration for the encryption of an object.
|
|
46
|
+
* @param topLevelFields the fields of the object to encrypt. All the fields will be encrypted in a single encryptedSelf field which is added to the
|
|
47
|
+
* object.
|
|
48
|
+
* @param nestedObjectsKeys the name of fields which are expected to contain a nested object (or undefined). Allows to specify
|
|
49
|
+
*/
|
|
50
|
+
export type EncryptedFieldsManifest = {
|
|
51
|
+
topLevelFields: {
|
|
52
|
+
fieldName: string;
|
|
53
|
+
fieldPath: string;
|
|
54
|
+
}[];
|
|
55
|
+
nestedObjectsKeys: {
|
|
56
|
+
[objectFieldName: string]: EncryptedFieldsManifest;
|
|
57
|
+
};
|
|
58
|
+
mapsValuesKeys: {
|
|
59
|
+
[mapFieldName: string]: EncryptedFieldsManifest;
|
|
60
|
+
};
|
|
61
|
+
arraysValuesKeys: {
|
|
62
|
+
[arrayFieldName: string]: EncryptedFieldsManifest;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* @internal this function is for internal use only and may be changed without notice
|
|
67
|
+
*
|
|
68
|
+
* Parse the encrypted fields configuration for a specific entity type.
|
|
69
|
+
*
|
|
70
|
+
* ## Grammar
|
|
71
|
+
*
|
|
72
|
+
* The grammar for each encrypted field is the following:
|
|
73
|
+
* ```
|
|
74
|
+
* fieldName :=
|
|
75
|
+
* regex([a-zA-Z_][a-zA-Z0-9_]+)
|
|
76
|
+
* encryptedField :=
|
|
77
|
+
* fieldName
|
|
78
|
+
* | fieldName + ("." | ".*." | "[].") + encryptedField
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* This grammar allows you to specify the fields to encrypt for the object and recursively for nested objects.
|
|
82
|
+
* - A string containing only a single `fieldName` will encrypt the field with the given name.
|
|
83
|
+
* - A string starting with `fieldName.` allows to specify the encrypted fields of a nested object. The encrypted values of the
|
|
84
|
+
* fields in the nested object will be saved in the nested object.
|
|
85
|
+
* - A string starting with `fieldName.*.` treats `fieldName` as a map/dictionary data structure and allows to specify the encrypted fields of the
|
|
86
|
+
* values of the map. Note that the values of the map must be objects as well. The encrypted content of each map value is stored in that value.
|
|
87
|
+
* - A string starting with `fieldName[].` treats `fieldName` as an array and allows to specify the encrypted fields of the values of the array.
|
|
88
|
+
* Note that the values of the array must be objects as well. The encrypted content of each array element is stored in that element.
|
|
46
89
|
*
|
|
90
|
+
* ## Example
|
|
91
|
+
*
|
|
92
|
+
* Consider the following object and encryption keys:
|
|
93
|
+
* ```javascript
|
|
94
|
+
* const obj = {
|
|
95
|
+
* a: { x: 0, y: 1 },
|
|
96
|
+
* b: "hello",
|
|
97
|
+
* c: [ { public: "a", secret: "b" }, { public: "c", secret: "d" } ],
|
|
98
|
+
* d: "ok",
|
|
99
|
+
* e: {
|
|
100
|
+
* info: "something",
|
|
101
|
+
* private: "secret",
|
|
102
|
+
* dataMap: {
|
|
103
|
+
* "en": {
|
|
104
|
+
* a: 1,
|
|
105
|
+
* b: 2
|
|
106
|
+
* },
|
|
107
|
+
* "fr": {
|
|
108
|
+
* a: 3,
|
|
109
|
+
* b: 4
|
|
110
|
+
* }
|
|
111
|
+
* }
|
|
112
|
+
* }
|
|
113
|
+
* }
|
|
114
|
+
* const encryptedFields = [
|
|
115
|
+
* "a",
|
|
116
|
+
* "c[].secret",
|
|
117
|
+
* "d",
|
|
118
|
+
* "e.private",
|
|
119
|
+
* "e.datamap.*.a"
|
|
120
|
+
* ]
|
|
121
|
+
* ```
|
|
122
|
+
* If you use them with the crypt method you will get the following result:
|
|
123
|
+
* ```json
|
|
124
|
+
* {
|
|
125
|
+
* b: "hello",
|
|
126
|
+
* c: [
|
|
127
|
+
* { public: "a", encryptedSelf: "...encrypted data of c[0]" },
|
|
128
|
+
* { public: "c", encryptedSelf: "...encrypted data of c[1]" }
|
|
129
|
+
* ],
|
|
130
|
+
* e: {
|
|
131
|
+
* info: "something",
|
|
132
|
+
* dataMap: {
|
|
133
|
+
* "en": { b: 2, encryptedSelf: "...encrypted data of e.dataMap['en']" },
|
|
134
|
+
* "fr": { b: 4, encryptedSelf: "...encrypted data of e.dataMap['fr']" }
|
|
135
|
+
* },
|
|
136
|
+
* encryptedSelf: "...encrypted data of e"
|
|
137
|
+
* },
|
|
138
|
+
* encryptedSelf: "...encrypted data of obj"
|
|
139
|
+
* }
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
* ## Shortened representation
|
|
143
|
+
*
|
|
144
|
+
* You can also group encrypted fields having the same prefix by concatenating to the prefix the JSON representation of an array of all the postfixes.
|
|
145
|
+
* For example the following encrypted fields:
|
|
146
|
+
* ```javascript
|
|
147
|
+
* const encryptedFields = ["a.b.c.d.e.f1", "a.b.c.d.e.f2", "a.b.c.d.e.f3", "a.b.c.d.e.f4"]
|
|
148
|
+
* ```
|
|
149
|
+
* can be shortened to
|
|
150
|
+
* ```javascript
|
|
151
|
+
* const encryptedFields = ['a.b.c.d.e.["f1","f2","f3","f4"]'] // Note the use of single quotes to avoid escaping the double quotes
|
|
152
|
+
* ```
|
|
153
|
+
* If you use the shortened representation you may need to escape nested json representations. In that case the use of `JSON.stringify` is
|
|
154
|
+
* recommended.
|
|
155
|
+
*
|
|
156
|
+
* @param encryptedFields
|
|
157
|
+
* @param path
|
|
158
|
+
*/
|
|
159
|
+
export declare function parseEncryptedFields(encryptedFields: string[], path: string): EncryptedFieldsManifest;
|
|
160
|
+
/**
|
|
161
|
+
* @internal this function is for internal use only and may be changed without notice
|
|
162
|
+
* Encrypt the object graph recursively. Generally return an updated SHALLOW copy, although some fields may be deep copied if they also needed to be
|
|
163
|
+
* recursively encrypted.
|
|
47
164
|
* @param obj the object to encrypt
|
|
48
|
-
* @param cryptor the
|
|
49
|
-
* @param keys the keys to
|
|
165
|
+
* @param cryptor takes in input an object consisting only of the fields to encrypt of obj, and returns the encrypted object.
|
|
166
|
+
* @param keys the keys to encrypt for the
|
|
167
|
+
* @param path path of the current object, used for error messages.
|
|
168
|
+
* @return a shallow copy of the object with a new encryptedSelfField and without the encrypted fields.
|
|
50
169
|
*/
|
|
51
|
-
export declare function
|
|
52
|
-
[key: string]:
|
|
53
|
-
}
|
|
170
|
+
export declare function encryptObject(obj: {
|
|
171
|
+
[key: string]: any;
|
|
172
|
+
}, cryptor: (obj: {
|
|
173
|
+
[key: string]: any;
|
|
174
|
+
}) => Promise<ArrayBuffer>, keys: EncryptedFieldsManifest, path?: string): Promise<{
|
|
175
|
+
[key: string]: any;
|
|
176
|
+
}>;
|
|
54
177
|
/**
|
|
55
|
-
*
|
|
178
|
+
* @internal this function is for internal use only and may be changed without notice
|
|
179
|
+
* Decrypt object graph recursively.
|
|
56
180
|
*
|
|
57
|
-
* @param obj the object to
|
|
181
|
+
* @param obj the object to decrypt
|
|
58
182
|
* @param decryptor the decryptor function (returns a promise)
|
|
183
|
+
* @return a deep copy of the object with the decrypted fields and removed encryptedSelf field
|
|
59
184
|
*/
|
|
60
|
-
export declare function
|
|
61
|
-
[key: string]:
|
|
62
|
-
}
|
|
185
|
+
export declare function decryptObject(obj: {
|
|
186
|
+
[key: string]: any;
|
|
187
|
+
}, decryptor: (obj: Uint8Array) => Promise<{
|
|
188
|
+
[key: string]: any;
|
|
189
|
+
}>): Promise<{
|
|
190
|
+
[key: string]: any;
|
|
191
|
+
}>;
|
|
63
192
|
/**
|
|
64
193
|
* Extracts the full jwk key pair from the jwk representation of the private key.
|
|
65
194
|
* @param privateKeyJwk private key in jwk representation
|
|
@@ -9,9 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.keyPairFromPrivateKeyJwk = exports.
|
|
12
|
+
exports.keyPairFromPrivateKeyJwk = exports.decryptObject = exports.encryptObject = exports.parseEncryptedFields = exports.before = exports.after = exports.appendBuffer = exports.truncateTrailingNulls = exports.pkcs8ToJwk = exports.spkiToJwk = exports.jwk2spki = exports.jwk2pkcs8 = exports.notConcurrent = void 0;
|
|
13
13
|
const mm = require("moment");
|
|
14
|
-
const _ = require("lodash");
|
|
15
14
|
const binary_utils_1 = require("../utils/binary-utils");
|
|
16
15
|
const asn1_packer_1 = require("./asn1-packer");
|
|
17
16
|
const asn1_parser_1 = require("./asn1-parser");
|
|
@@ -195,56 +194,306 @@ function moment(epochOrLongCalendar) {
|
|
|
195
194
|
}
|
|
196
195
|
}
|
|
197
196
|
/**
|
|
198
|
-
*
|
|
197
|
+
* @internal this function is for internal use only and may be changed without notice
|
|
199
198
|
*
|
|
199
|
+
* Parse the encrypted fields configuration for a specific entity type.
|
|
200
|
+
*
|
|
201
|
+
* ## Grammar
|
|
202
|
+
*
|
|
203
|
+
* The grammar for each encrypted field is the following:
|
|
204
|
+
* ```
|
|
205
|
+
* fieldName :=
|
|
206
|
+
* regex([a-zA-Z_][a-zA-Z0-9_]+)
|
|
207
|
+
* encryptedField :=
|
|
208
|
+
* fieldName
|
|
209
|
+
* | fieldName + ("." | ".*." | "[].") + encryptedField
|
|
210
|
+
* ```
|
|
211
|
+
*
|
|
212
|
+
* This grammar allows you to specify the fields to encrypt for the object and recursively for nested objects.
|
|
213
|
+
* - A string containing only a single `fieldName` will encrypt the field with the given name.
|
|
214
|
+
* - A string starting with `fieldName.` allows to specify the encrypted fields of a nested object. The encrypted values of the
|
|
215
|
+
* fields in the nested object will be saved in the nested object.
|
|
216
|
+
* - A string starting with `fieldName.*.` treats `fieldName` as a map/dictionary data structure and allows to specify the encrypted fields of the
|
|
217
|
+
* values of the map. Note that the values of the map must be objects as well. The encrypted content of each map value is stored in that value.
|
|
218
|
+
* - A string starting with `fieldName[].` treats `fieldName` as an array and allows to specify the encrypted fields of the values of the array.
|
|
219
|
+
* Note that the values of the array must be objects as well. The encrypted content of each array element is stored in that element.
|
|
220
|
+
*
|
|
221
|
+
* ## Example
|
|
222
|
+
*
|
|
223
|
+
* Consider the following object and encryption keys:
|
|
224
|
+
* ```javascript
|
|
225
|
+
* const obj = {
|
|
226
|
+
* a: { x: 0, y: 1 },
|
|
227
|
+
* b: "hello",
|
|
228
|
+
* c: [ { public: "a", secret: "b" }, { public: "c", secret: "d" } ],
|
|
229
|
+
* d: "ok",
|
|
230
|
+
* e: {
|
|
231
|
+
* info: "something",
|
|
232
|
+
* private: "secret",
|
|
233
|
+
* dataMap: {
|
|
234
|
+
* "en": {
|
|
235
|
+
* a: 1,
|
|
236
|
+
* b: 2
|
|
237
|
+
* },
|
|
238
|
+
* "fr": {
|
|
239
|
+
* a: 3,
|
|
240
|
+
* b: 4
|
|
241
|
+
* }
|
|
242
|
+
* }
|
|
243
|
+
* }
|
|
244
|
+
* }
|
|
245
|
+
* const encryptedFields = [
|
|
246
|
+
* "a",
|
|
247
|
+
* "c[].secret",
|
|
248
|
+
* "d",
|
|
249
|
+
* "e.private",
|
|
250
|
+
* "e.datamap.*.a"
|
|
251
|
+
* ]
|
|
252
|
+
* ```
|
|
253
|
+
* If you use them with the crypt method you will get the following result:
|
|
254
|
+
* ```json
|
|
255
|
+
* {
|
|
256
|
+
* b: "hello",
|
|
257
|
+
* c: [
|
|
258
|
+
* { public: "a", encryptedSelf: "...encrypted data of c[0]" },
|
|
259
|
+
* { public: "c", encryptedSelf: "...encrypted data of c[1]" }
|
|
260
|
+
* ],
|
|
261
|
+
* e: {
|
|
262
|
+
* info: "something",
|
|
263
|
+
* dataMap: {
|
|
264
|
+
* "en": { b: 2, encryptedSelf: "...encrypted data of e.dataMap['en']" },
|
|
265
|
+
* "fr": { b: 4, encryptedSelf: "...encrypted data of e.dataMap['fr']" }
|
|
266
|
+
* },
|
|
267
|
+
* encryptedSelf: "...encrypted data of e"
|
|
268
|
+
* },
|
|
269
|
+
* encryptedSelf: "...encrypted data of obj"
|
|
270
|
+
* }
|
|
271
|
+
* ```
|
|
272
|
+
*
|
|
273
|
+
* ## Shortened representation
|
|
274
|
+
*
|
|
275
|
+
* You can also group encrypted fields having the same prefix by concatenating to the prefix the JSON representation of an array of all the postfixes.
|
|
276
|
+
* For example the following encrypted fields:
|
|
277
|
+
* ```javascript
|
|
278
|
+
* const encryptedFields = ["a.b.c.d.e.f1", "a.b.c.d.e.f2", "a.b.c.d.e.f3", "a.b.c.d.e.f4"]
|
|
279
|
+
* ```
|
|
280
|
+
* can be shortened to
|
|
281
|
+
* ```javascript
|
|
282
|
+
* const encryptedFields = ['a.b.c.d.e.["f1","f2","f3","f4"]'] // Note the use of single quotes to avoid escaping the double quotes
|
|
283
|
+
* ```
|
|
284
|
+
* If you use the shortened representation you may need to escape nested json representations. In that case the use of `JSON.stringify` is
|
|
285
|
+
* recommended.
|
|
286
|
+
*
|
|
287
|
+
* @param encryptedFields
|
|
288
|
+
* @param path
|
|
289
|
+
*/
|
|
290
|
+
function parseEncryptedFields(encryptedFields, path) {
|
|
291
|
+
const groupedData = {
|
|
292
|
+
topLevelFields: new Set(),
|
|
293
|
+
nestedObjectsKeys: {},
|
|
294
|
+
mapsValuesKeys: {},
|
|
295
|
+
arraysValuesKeys: {},
|
|
296
|
+
};
|
|
297
|
+
const encryptedFieldRegex = /^([_a-zA-Z][_a-zA-Z0-9]*)(?:(\.\*\.|\[]\.|\.)(?:[_a-zA-Z].*|\[.*]))?$/;
|
|
298
|
+
const addSubkeyToGroupedData = (currFieldName, currFieldSeparator, currEncryptedField, groupedDataKey) => {
|
|
299
|
+
var _a;
|
|
300
|
+
const existingOrNew = (_a = groupedData[groupedDataKey][currFieldName]) !== null && _a !== void 0 ? _a : (groupedData[groupedDataKey][currFieldName] = []);
|
|
301
|
+
const subKey = currEncryptedField.slice(currFieldName.length + currFieldSeparator.length);
|
|
302
|
+
if (subKey.startsWith('[')) {
|
|
303
|
+
let parsedJson;
|
|
304
|
+
try {
|
|
305
|
+
parsedJson = JSON.parse(subKey);
|
|
306
|
+
}
|
|
307
|
+
catch (_b) {
|
|
308
|
+
throw new Error(`Invalid encrypted field ${path}${currEncryptedField} (not a valid JSON subkey)`);
|
|
309
|
+
}
|
|
310
|
+
if (Array.isArray(parsedJson) && parsedJson.every((x) => typeof x == 'string')) {
|
|
311
|
+
parsedJson.forEach((x) => existingOrNew.push(x));
|
|
312
|
+
}
|
|
313
|
+
else
|
|
314
|
+
throw new Error(`Invalid encrypted field ${path}${currEncryptedField} (not an array of strings)`);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
existingOrNew.push(subKey);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
for (const currEncryptedField of encryptedFields) {
|
|
321
|
+
const currFieldMatch = currEncryptedField.match(encryptedFieldRegex);
|
|
322
|
+
if (!!currFieldMatch) {
|
|
323
|
+
const currFieldName = currFieldMatch[1];
|
|
324
|
+
const currFieldSeparator = currFieldMatch[2];
|
|
325
|
+
if (!currFieldSeparator) {
|
|
326
|
+
if (groupedData.topLevelFields.has(currFieldName))
|
|
327
|
+
throw new Error(`Duplicate encrypted field ${path}${currFieldName}`);
|
|
328
|
+
if (!!groupedData.nestedObjectsKeys[currFieldName] ||
|
|
329
|
+
!!groupedData.mapsValuesKeys[currFieldName] ||
|
|
330
|
+
!!groupedData.arraysValuesKeys[currFieldName])
|
|
331
|
+
throw new Error(`Encrypted field appears multiple times as different nested types and or top-level-field: ${path}${currFieldName}`);
|
|
332
|
+
groupedData.topLevelFields.add(currFieldName);
|
|
333
|
+
}
|
|
334
|
+
else if (currFieldSeparator == '.') {
|
|
335
|
+
if (groupedData.topLevelFields.has(currFieldName) ||
|
|
336
|
+
!!groupedData.mapsValuesKeys[currFieldName] ||
|
|
337
|
+
!!groupedData.arraysValuesKeys[currFieldName])
|
|
338
|
+
throw new Error(`Encrypted field appears multiple times as different nested types and or top-level-field: ${path}${currFieldName}`);
|
|
339
|
+
addSubkeyToGroupedData(currFieldName, currFieldSeparator, currEncryptedField, 'nestedObjectsKeys');
|
|
340
|
+
}
|
|
341
|
+
else if (currFieldSeparator == '.*.') {
|
|
342
|
+
if (groupedData.topLevelFields.has(currFieldName) ||
|
|
343
|
+
!!groupedData.nestedObjectsKeys[currFieldName] ||
|
|
344
|
+
!!groupedData.arraysValuesKeys[currFieldName])
|
|
345
|
+
throw new Error(`Encrypted field appears multiple times as different nested types and or top-level-field: ${path}${currFieldName}`);
|
|
346
|
+
addSubkeyToGroupedData(currFieldName, currFieldSeparator, currEncryptedField, 'mapsValuesKeys');
|
|
347
|
+
}
|
|
348
|
+
else if (currFieldSeparator == '[].') {
|
|
349
|
+
if (groupedData.topLevelFields.has(currFieldName) ||
|
|
350
|
+
!!groupedData.nestedObjectsKeys[currFieldName] ||
|
|
351
|
+
!!groupedData.mapsValuesKeys[currFieldName])
|
|
352
|
+
throw new Error(`Encrypted field appears multiple times as different nested types and or top-level-field: ${path}${currFieldName}`);
|
|
353
|
+
addSubkeyToGroupedData(currFieldName, currFieldSeparator, currEncryptedField, 'arraysValuesKeys');
|
|
354
|
+
}
|
|
355
|
+
else
|
|
356
|
+
throw new Error(`Internal error: unknown separator ${currFieldSeparator} passed regex validation in ${path}${currEncryptedField}`);
|
|
357
|
+
}
|
|
358
|
+
else
|
|
359
|
+
throw new Error(`Invalid encrypted field ${path}${currEncryptedField}`);
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
topLevelFields: Array.from(groupedData.topLevelFields).map((fieldName) => ({ fieldName, fieldPath: path + fieldName })),
|
|
363
|
+
nestedObjectsKeys: Object.fromEntries(Object.entries(groupedData.nestedObjectsKeys).map(([fieldName, fieldNames]) => [
|
|
364
|
+
fieldName,
|
|
365
|
+
parseEncryptedFields(fieldNames, path + fieldName + '.'),
|
|
366
|
+
])),
|
|
367
|
+
mapsValuesKeys: Object.fromEntries(Object.entries(groupedData.mapsValuesKeys).map(([fieldName, fieldNames]) => [
|
|
368
|
+
fieldName,
|
|
369
|
+
parseEncryptedFields(fieldNames, path + fieldName + '.*.'),
|
|
370
|
+
])),
|
|
371
|
+
arraysValuesKeys: Object.fromEntries(Object.entries(groupedData.arraysValuesKeys).map(([fieldName, fieldNames]) => [
|
|
372
|
+
fieldName,
|
|
373
|
+
parseEncryptedFields(fieldNames, path + fieldName + '[].'),
|
|
374
|
+
])),
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
exports.parseEncryptedFields = parseEncryptedFields;
|
|
378
|
+
/**
|
|
379
|
+
* @internal this function is for internal use only and may be changed without notice
|
|
380
|
+
* Encrypt the object graph recursively. Generally return an updated SHALLOW copy, although some fields may be deep copied if they also needed to be
|
|
381
|
+
* recursively encrypted.
|
|
200
382
|
* @param obj the object to encrypt
|
|
201
|
-
* @param cryptor the
|
|
202
|
-
* @param keys the keys to
|
|
383
|
+
* @param cryptor takes in input an object consisting only of the fields to encrypt of obj, and returns the encrypted object.
|
|
384
|
+
* @param keys the keys to encrypt for the
|
|
385
|
+
* @param path path of the current object, used for error messages.
|
|
386
|
+
* @return a shallow copy of the object with a new encryptedSelfField and without the encrypted fields.
|
|
203
387
|
*/
|
|
204
|
-
function
|
|
388
|
+
function encryptObject(obj, cryptor, keys, path = 'obj') {
|
|
205
389
|
return __awaiter(this, void 0, void 0, function* () {
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
390
|
+
const shallowClone = Object.assign({}, obj);
|
|
391
|
+
const currEncryptedFields = {};
|
|
392
|
+
for (const { fieldName } of keys.topLevelFields) {
|
|
393
|
+
const fieldValue = shallowClone[fieldName];
|
|
394
|
+
if (fieldValue !== undefined) {
|
|
395
|
+
// we keep null values
|
|
396
|
+
currEncryptedFields[fieldName] = fieldValue;
|
|
397
|
+
delete shallowClone[fieldName];
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
shallowClone['encryptedSelf'] = (0, binary_utils_1.b2a)((0, binary_utils_1.ua2string)(yield cryptor(currEncryptedFields)));
|
|
401
|
+
for (const [fieldName, subKeys] of Object.entries(keys.nestedObjectsKeys)) {
|
|
402
|
+
const fieldValue = shallowClone[fieldName];
|
|
403
|
+
if (fieldValue !== undefined && fieldValue !== null) {
|
|
404
|
+
if (!isPojo(fieldValue))
|
|
405
|
+
throw new Error(`Expected field ${path}.${fieldName} to be a non-array object`);
|
|
406
|
+
shallowClone[fieldName] = yield encryptObject(fieldValue, cryptor, subKeys, path + '.' + fieldName);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
for (const [mapFieldName, subKeys] of Object.entries(keys.mapsValuesKeys)) {
|
|
410
|
+
const fieldValue = shallowClone[mapFieldName];
|
|
411
|
+
if (fieldValue !== undefined && fieldValue !== null) {
|
|
412
|
+
if (!isPojo(fieldValue))
|
|
413
|
+
throw new Error(`Expected field ${path}.${mapFieldName} to be a non-array object`);
|
|
414
|
+
const newMap = {};
|
|
415
|
+
for (const [key, value] of Object.entries(fieldValue)) {
|
|
416
|
+
if (value === null || value === undefined) {
|
|
417
|
+
newMap[key] = value;
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
if (!isPojo(value))
|
|
421
|
+
throw new Error(`Expected field ${path}.${mapFieldName}.${key} to be a non-array object`);
|
|
422
|
+
newMap[key] = yield encryptObject(value, cryptor, subKeys, path + '.' + mapFieldName + '.' + key);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
shallowClone[mapFieldName] = newMap;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
for (const [arrayFieldName, subKeys] of Object.entries(keys.arraysValuesKeys)) {
|
|
429
|
+
const fieldValue = shallowClone[arrayFieldName];
|
|
430
|
+
if (fieldValue !== undefined && fieldValue !== null) {
|
|
431
|
+
if (!Array.isArray(fieldValue))
|
|
432
|
+
throw new Error(`Expected field ${path}.${arrayFieldName} to be an array`);
|
|
433
|
+
const newArray = Array(fieldValue.length);
|
|
434
|
+
for (let i = 0; i < fieldValue.length; i++) {
|
|
435
|
+
const value = fieldValue[i];
|
|
436
|
+
if (value === null || value === undefined) {
|
|
437
|
+
newArray[i] = value;
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
if (!isPojo(value))
|
|
441
|
+
throw new Error(`Expected field ${path}.${arrayFieldName}[${i}] to be a non-array object`);
|
|
442
|
+
newArray[i] = yield encryptObject(value, cryptor, subKeys, path + '.' + arrayFieldName + '[' + i + ']');
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
shallowClone[arrayFieldName] = newArray;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
return shallowClone;
|
|
219
449
|
});
|
|
220
450
|
}
|
|
221
|
-
exports.
|
|
451
|
+
exports.encryptObject = encryptObject;
|
|
452
|
+
/**
|
|
453
|
+
* Check if value is a non-null object that is not an array.
|
|
454
|
+
*/
|
|
455
|
+
function isPojo(value) {
|
|
456
|
+
// This break if for some reason we have object versions of String/Number/Boolean
|
|
457
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
458
|
+
}
|
|
222
459
|
/**
|
|
223
|
-
*
|
|
460
|
+
* @internal this function is for internal use only and may be changed without notice
|
|
461
|
+
* Decrypt object graph recursively.
|
|
224
462
|
*
|
|
225
|
-
* @param obj the object to
|
|
463
|
+
* @param obj the object to decrypt
|
|
226
464
|
* @param decryptor the decryptor function (returns a promise)
|
|
465
|
+
* @return a deep copy of the object with the decrypted fields and removed encryptedSelf field
|
|
227
466
|
*/
|
|
228
|
-
function
|
|
467
|
+
function decryptObject(obj, decryptor) {
|
|
229
468
|
return __awaiter(this, void 0, void 0, function* () {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if (
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
469
|
+
const copy = {};
|
|
470
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
471
|
+
if (key === 'encryptedSelf') {
|
|
472
|
+
copy[key] = value;
|
|
473
|
+
}
|
|
474
|
+
else if (typeof value === 'object' && value !== null) {
|
|
475
|
+
if (Array.isArray(value)) {
|
|
476
|
+
// Note: nested arrays (and primitives) are returned as is and not they are not recursively decrypted. This is because we currently do not
|
|
477
|
+
// support encryption of elements from arrays in arrays (we only support arrays in objects in arrays). In future this may change.
|
|
478
|
+
copy[key] = yield Promise.all(value.map((v) => (isPojo(v) ? decryptObject(v, decryptor) : v)));
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
copy[key] = yield decryptObject(value, decryptor);
|
|
482
|
+
}
|
|
239
483
|
}
|
|
240
|
-
|
|
484
|
+
else {
|
|
485
|
+
copy[key] = value;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
241
488
|
if (obj.encryptedSelf) {
|
|
242
|
-
|
|
489
|
+
const decrypted = yield decryptor((0, binary_utils_1.string2ua)((0, binary_utils_1.a2b)(obj.encryptedSelf)));
|
|
490
|
+
return Object.assign(Object.assign({}, copy), decrypted);
|
|
243
491
|
}
|
|
244
|
-
|
|
492
|
+
else
|
|
493
|
+
return copy;
|
|
245
494
|
});
|
|
246
495
|
}
|
|
247
|
-
exports.
|
|
496
|
+
exports.decryptObject = decryptObject;
|
|
248
497
|
/**
|
|
249
498
|
* Extracts the full jwk key pair from the jwk representation of the private key.
|
|
250
499
|
* @param privateKeyJwk private key in jwk representation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-utils.js","sourceRoot":"","sources":["../../../icc-x-api/utils/crypto-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6BAA4B;AAE5B,4BAA2B;AAC3B,wDAA4G;AAC5G,+CAAoC;AACpC,+CAAyC;AAGzC,SAAgB,aAAa,CAAI,cAAmD,EAAE,GAAW,EAAE,IAA0B;IAC3H,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;IACpC,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,MAAM,GAAG,CAAC,GAAS,EAAE;YACzB,IAAI;gBACF,OAAO,MAAM,IAAI,EAAE,CAAA;aACpB;oBAAS;gBACR,OAAO,cAAc,CAAC,GAAG,CAAC,CAAA;aAC3B;QACH,CAAC,CAAA,CAAC,EAAE,CAAA;QACJ,cAAc,CAAC,GAAG,CAAC,GAAG,MAAM,CAAA;QAC5B,OAAO,MAAM,CAAA;KACd;SAAM;QACL,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,cAAc,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;KAChF;AACH,CAAC;AAfD,sCAeC;AAED,SAAgB,SAAS,CAAC,GAAQ;IAChC,OAAO,IAAA,kBAAI,EAAC;QACV,IAAI;QACJ;YACE,CAAC,IAAI,EAAE,IAAI,CAAC;YACZ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,oBAAoB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9C;gBACE,IAAI;gBACJ;oBACE;wBACE,IAAI;wBACJ;4BACE,CAAC,IAAI,EAAE,IAAI,CAAC;4BACZ,CAAC,IAAI,EAAE,IAAA,qBAAM,EAAC,IAAA,wBAAS,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;4BAChC,CAAC,IAAI,EAAE,IAAA,qBAAM,EAAC,IAAA,wBAAS,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;4BAChC,CAAC,IAAI,EAAE,IAAA,qBAAM,EAAC,IAAA,wBAAS,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;4BAChC,CAAC,IAAI,EAAE,IAAA,qBAAM,EAAC,IAAA,wBAAS,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;4BAChC,CAAC,IAAI,EAAE,IAAA,qBAAM,EAAC,IAAA,wBAAS,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;4BAChC,CAAC,IAAI,EAAE,IAAA,qBAAM,EAAC,IAAA,wBAAS,EAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;4BACjC,CAAC,IAAI,EAAE,IAAA,qBAAM,EAAC,IAAA,wBAAS,EAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;4BACjC,CAAC,IAAI,EAAE,IAAA,qBAAM,EAAC,IAAA,wBAAS,EAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;yBAClC;qBACF;iBACF;aACF;SACF;KACF,CAAC,CAAA;AACJ,CAAC;AA3BD,8BA2BC;AAED,SAAgB,QAAQ,CAAC,GAAQ;IAC/B,OAAO,IAAA,kBAAI,EAAC;QACV,IAAI;QACJ;YACE,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,oBAAoB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9C;gBACE,IAAI;gBACJ;oBACE;wBACE,IAAI;wBACJ;4BACE,CAAC,IAAI,EAAE,IAAA,qBAAM,EAAC,IAAA,wBAAS,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;4BAChC,CAAC,IAAI,EAAE,IAAA,qBAAM,EAAC,IAAA,wBAAS,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;yBACjC;qBACF;iBACF;aACF;SACF;KACF,CAAC,CAAA;AACJ,CAAC;AAnBD,4BAmBC;AAED,SAAgB,SAAS,CAAC,GAAe;;IACvC,MAAM,IAAI,GAAG,IAAA,uBAAS,EAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;IAE3C,IAAI,OAAO,GAA2B,SAAS,CAAA;IAC/C,IAAI,QAAQ,GAA2B,SAAS,CAAA;IAChD,IACE,IAAI,CAAC,IAAI,KAAK,IAAI;QAClB,CAAA,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAG,CAAC,CAAC,0CAAE,IAAI,MAAK,IAAI;QACjC,CAAA,MAAA,MAAA,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAG,CAAC,CAAC,0CAAE,QAAQ,0CAAG,CAAC,CAAC,0CAAE,IAAI,MAAK,IAAI;QAChD,IAAA,qBAAM,EAAC,MAAA,MAAA,MAAA,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAG,CAAC,CAAC,0CAAE,QAAQ,0CAAG,CAAC,CAAC,0CAAE,KAAK,mCAAI,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,oBAAoB,CAAC,2BAA2B;MAC1H;QACA,OAAO,GAAG,MAAA,MAAA,MAAA,MAAA,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAG,CAAC,CAAC,0CAAE,QAAQ,0CAAG,CAAC,CAAC,0CAAE,QAAQ,0CAAG,CAAC,CAAC,0CAAE,KAAK,CAAA;QACjE,QAAQ,GAAG,MAAA,MAAA,MAAA,MAAA,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAG,CAAC,CAAC,0CAAE,QAAQ,0CAAG,CAAC,CAAC,0CAAE,QAAQ,0CAAG,CAAC,CAAC,0CAAE,KAAK,CAAA;KACnE;SAAM,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,CAAA,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAG,CAAC,CAAC,0CAAE,IAAI,MAAK,IAAI,IAAI,CAAA,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAG,CAAC,CAAC,0CAAE,IAAI,MAAK,IAAI,EAAE;QACvG,OAAO,GAAG,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAG,CAAC,CAAC,0CAAE,KAAK,CAAA;QACnC,QAAQ,GAAG,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAG,CAAC,CAAC,0CAAE,KAAK,CAAA;KACrC;IAED,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE;QACzB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAA;KACvC;IACD,OAAO;QACL,GAAG,EAAE,KAAK;QACV,GAAG,EAAE,UAAU;QACf,GAAG,EAAE,IAAI;QACT,CAAC,EAAE,IAAA,wBAAS,EAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC,EAAE,IAAA,wBAAS,EAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;KACnC,CAAA;AACH,CAAC;AA5BD,8BA4BC;AAED,SAAgB,UAAU,CAAC,GAA6B;;IACtD,MAAM,MAAM,GAAG,IAAA,uBAAS,EAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;IAC7C,MAAM,GAAG,GACP,CAAA,MAAA,MAAM,CAAC,QAAQ,0CAAE,MAAM,MAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAA,MAAA,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,0CAAE,MAAM,MAAK,CAAC;QAC5G,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChC,CAAC,CAAC,MAAM,CAAA;IACZ,OAAO;QACL,GAAG,EAAE,KAAK;QACV,CAAC,EAAE,IAAA,wBAAS,EAAC,UAAU,CAAC,GAAG,CAAC,QAAS,CAAC,CAAC,CAAC,CAAC,KAAmB,CAAC,CAAC;QAC9D,CAAC,EAAE,IAAA,wBAAS,EAAC,UAAU,CAAC,GAAG,CAAC,QAAS,CAAC,CAAC,CAAC,CAAC,KAAmB,CAAC,CAAC;QAC9D,CAAC,EAAE,IAAA,wBAAS,EAAC,UAAU,CAAC,GAAG,CAAC,QAAS,CAAC,CAAC,CAAC,CAAC,KAAmB,CAAC,CAAC;QAC9D,CAAC,EAAE,IAAA,wBAAS,EAAC,UAAU,CAAC,GAAG,CAAC,QAAS,CAAC,CAAC,CAAC,CAAC,KAAmB,CAAC,CAAC;QAC9D,CAAC,EAAE,IAAA,wBAAS,EAAC,UAAU,CAAC,GAAG,CAAC,QAAS,CAAC,CAAC,CAAC,CAAC,KAAmB,CAAC,CAAC;QAC9D,EAAE,EAAE,IAAA,wBAAS,EAAC,UAAU,CAAC,GAAG,CAAC,QAAS,CAAC,CAAC,CAAC,CAAC,KAAmB,CAAC,CAAC;QAC/D,EAAE,EAAE,IAAA,wBAAS,EAAC,UAAU,CAAC,GAAG,CAAC,QAAS,CAAC,CAAC,CAAC,CAAC,KAAmB,CAAC,CAAC;QAC/D,EAAE,EAAE,IAAA,wBAAS,EAAC,UAAU,CAAC,GAAG,CAAC,QAAS,CAAC,CAAC,CAAC,CAAC,KAAmB,CAAC,CAAC;KAChE,CAAA;AACH,CAAC;AAjBD,gCAiBC;AAED,SAAS,UAAU,CAAC,CAAa;IAC/B,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;QACjB,CAAC,EAAE,CAAA;KACJ;IACD,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACnB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,qBAAqB,CAAC,CAAa;IACjD,IAAI,GAAG,GAAG,CAAC,CAAC,UAAU,GAAG,CAAC,CAAA;IAC1B,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE;QAC/B,GAAG,EAAE,CAAA;KACN;IACD,yEAAyE;IACzE,8CAA8C;IAC9C,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAA;AAC/B,CAAC;AARD,sDAQC;AAED;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,OAAoB,EAAE,OAAoB;IACrE,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACnE,GAAG,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;IACnC,GAAG,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;IACpD,OAAO,GAAG,CAAC,MAAqB,CAAA;AAClC,CAAC;AALD,oCAKC;AAED,0CAA0C;AAC1C,SAAgB,KAAK,CAAC,EAA6B,EAAE,EAA6B;IAChF,OAAO,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,SAAS,IAAI,MAAM,CAAC,EAAE,CAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAE,CAAC,CAAA;AAC/G,CAAC;AAFD,sBAEC;AAED,SAAgB,MAAM,CAAC,EAA6B,EAAE,EAA6B;IACjF,OAAO,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,SAAS,IAAI,MAAM,CAAC,EAAE,CAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAE,CAAC,CAAA;AAChH,CAAC;AAFD,wBAEC;AAED,SAAS,MAAM,CAAC,mBAA2B;IACzC,IAAI,CAAC,mBAAmB,IAAI,mBAAmB,KAAK,CAAC,EAAE;QACrD,OAAO,IAAI,CAAA;KACZ;IACD,IAAI,mBAAmB,IAAI,QAAQ,IAAI,mBAAmB,GAAG,QAAQ,EAAE;QACrE,OAAO,EAAE,CAAC,EAAE,GAAG,mBAAmB,EAAE,UAAU,CAAC,CAAA;KAChD;SAAM,IAAI,mBAAmB,IAAI,cAAc,EAAE;QAChD,OAAO,EAAE,CAAC,EAAE,GAAG,mBAAmB,EAAE,gBAAgB,CAAC,CAAA;KACtD;SAAM;QACL,OAAO,EAAE,CAAC,mBAAmB,CAAC,CAAA;KAC/B;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAsB,KAAK,CAAC,GAAQ,EAAE,OAAiE,EAAE,IAAmB;;QAC1H,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CACnB,GAAG,EACH,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CACrC,CAAA;QACD,GAAG,CAAC,aAAa,GAAG,IAAA,kBAAG,EAAC,IAAA,wBAAS,EAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACzD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QAEjD,MAAM,IAAI;aACP,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;aAC9B,MAAM,CAAC,CAAO,IAAmB,EAAE,CAAM,EAAE,EAAE;YAC5C,MAAM,IAAI,CAAA;YACV,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;YAC5B,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;YAElC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;YACzI,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;QACxB,CAAC,CAAA,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;QAEvB,OAAO,GAAG,CAAA;IACZ,CAAC;CAAA;AApBD,sBAoBC;AAED;;;;;GAKG;AACH,SAAsB,OAAO,CAAC,GAAQ,EAAE,SAAkE;;QACxG,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAO,IAAmB,EAAE,CAAM,EAAE,EAAE;YAClE,MAAM,IAAI,CAAA;YACV,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE;gBACzB,MAAO,GAAG,CAAC,CAAC,CAAgB;qBACzB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC;qBAClD,MAAM,CAAC,CAAO,IAAmB,EAAE,EAAO,EAAE,EAAE;oBAC7C,MAAM,IAAI,CAAA;oBACV,MAAM,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAA;gBAC9B,CAAC,CAAA,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;aACxB;QACH,CAAC,CAAA,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;QACrB,IAAI,GAAG,CAAC,aAAa,EAAE;YACrB,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,SAAS,CAAC,IAAA,wBAAS,EAAC,IAAA,kBAAG,EAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;SACvE;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;CAAA;AAhBD,0BAgBC;AAED;;;;GAIG;AACH,SAAgB,wBAAwB,CAAC,aAAyB;IAChE,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAA;IAClI,OAAO;QACL,UAAU,EAAE,aAAa;QACzB,SAAS,EAAE,SAAS,CAAC,IAAA,qBAAM,EAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;KACtD,CAAA;AACH,CAAC;AAND,4DAMC","sourcesContent":["import * as mm from 'moment'\nimport { Moment } from 'moment'\nimport * as _ from 'lodash'\nimport { a2b, b2a, b64Url2ua, hex2ua, string2ua, ua2b64Url, ua2hex, ua2string } from '../utils/binary-utils'\nimport { pack } from './asn1-packer'\nimport { parseAsn1 } from './asn1-parser'\nimport { KeyPair } from '../crypto/RSA'\n\nexport function notConcurrent<T>(concurrencyMap: { [key: string]: PromiseLike<any> }, key: string, proc: () => PromiseLike<T>): PromiseLike<T> {\n const inFlight = concurrencyMap[key]\n if (!inFlight) {\n const newJob = (async () => {\n try {\n return await proc()\n } finally {\n delete concurrencyMap[key]\n }\n })()\n concurrencyMap[key] = newJob\n return newJob\n } else {\n return concurrencyMap[key].then(() => notConcurrent(concurrencyMap, key, proc))\n }\n}\n\nexport function jwk2pkcs8(jwk: any): string {\n return pack([\n 0x30,\n [\n [0x02, '00'],\n [0x30, [[0x06, '2a864886f70d010101'], [0x05]]], // pragma: allowlist secret\n [\n 0x04,\n [\n [\n 0x30,\n [\n [0x02, '00'],\n [0x02, ua2hex(b64Url2ua(jwk.n))],\n [0x02, ua2hex(b64Url2ua(jwk.e))],\n [0x02, ua2hex(b64Url2ua(jwk.d))],\n [0x02, ua2hex(b64Url2ua(jwk.p))],\n [0x02, ua2hex(b64Url2ua(jwk.q))],\n [0x02, ua2hex(b64Url2ua(jwk.dp))],\n [0x02, ua2hex(b64Url2ua(jwk.dq))],\n [0x02, ua2hex(b64Url2ua(jwk.qi))],\n ],\n ],\n ],\n ],\n ],\n ])\n}\n\nexport function jwk2spki(jwk: any): string {\n return pack([\n 0x30,\n [\n [0x30, [[0x06, '2a864886f70d010101'], [0x05]]], // pragma: allowlist secret\n [\n 0x03,\n [\n [\n 0x30,\n [\n [0x02, ua2hex(b64Url2ua(jwk.n))],\n [0x02, ua2hex(b64Url2ua(jwk.e))],\n ],\n ],\n ],\n ],\n ],\n ])\n}\n\nexport function spkiToJwk(buf: Uint8Array): { kty: string; alg: string; n: string; e: string; ext: boolean } {\n const asn1 = parseAsn1(new Uint8Array(buf))\n\n var modulus: Uint8Array | undefined = undefined\n var exponent: Uint8Array | undefined = undefined\n if (\n asn1.type === 0x30 &&\n asn1.children?.[0]?.type === 0x30 &&\n asn1.children?.[0]?.children?.[0]?.type === 0x06 &&\n ua2hex(asn1.children?.[0]?.children?.[0]?.value ?? new Uint8Array(0)) === '2a864886f70d010101' // pragma: allowlist secret\n ) {\n modulus = asn1.children?.[1]?.children?.[0]?.children?.[0]?.value\n exponent = asn1.children?.[1]?.children?.[0]?.children?.[1]?.value\n } else if (asn1.type === 0x30 && asn1.children?.[0]?.type === 0x02 && asn1.children?.[1]?.type === 0x02) {\n modulus = asn1.children?.[0]?.value\n exponent = asn1.children?.[1]?.value\n }\n\n if (!modulus || !exponent) {\n throw new Error('Invalid spki format')\n }\n return {\n kty: 'RSA',\n alg: 'RSA-OAEP',\n ext: true,\n n: ua2b64Url(minimalRep(modulus)),\n e: ua2b64Url(minimalRep(exponent)),\n }\n}\n\nexport function pkcs8ToJwk(buf: Uint8Array | ArrayBuffer) {\n const parsed = parseAsn1(new Uint8Array(buf))\n const seq =\n parsed.children?.length === 3 && parsed.children[2].type === 0x04 && parsed.children[2].children?.length === 1\n ? parsed.children[2].children[0]\n : parsed\n return {\n kty: 'RSA',\n n: ua2b64Url(minimalRep(seq.children![1].value as Uint8Array)),\n e: ua2b64Url(minimalRep(seq.children![2].value as Uint8Array)),\n d: ua2b64Url(minimalRep(seq.children![3].value as Uint8Array)),\n p: ua2b64Url(minimalRep(seq.children![4].value as Uint8Array)),\n q: ua2b64Url(minimalRep(seq.children![5].value as Uint8Array)),\n dp: ua2b64Url(minimalRep(seq.children![6].value as Uint8Array)),\n dq: ua2b64Url(minimalRep(seq.children![7].value as Uint8Array)),\n qi: ua2b64Url(minimalRep(seq.children![8].value as Uint8Array)),\n }\n}\n\nfunction minimalRep(b: Uint8Array) {\n let i = 0\n while (b[i] === 0) {\n i++\n }\n return b.slice(i)\n}\n\n/**\n * Provide a view over the given Uint8Array where any trailing null bytes at\n * the end are truncated.\n *\n * This can be used to ignore null bytes at the end of a padded UTF-8 string\n * without needing to copy that string, assuming code point U+0000 is encoded\n * in one null byte according to standards rather than in a multi-byte\n * overlong form.\n */\nexport function truncateTrailingNulls(a: Uint8Array) {\n let end = a.byteLength - 1\n while (a[end] === 0 && end >= 0) {\n end--\n }\n // end is now either the last non-null position in a or -1; in the latter\n // case the returned array will have length 0.\n return a.subarray(0, end + 1)\n}\n\n/**\n *\n * @param buffer1 {Uint8Array}\n * @param buffer2{ Uint8Array}\n * @returns {ArrayBuffer}\n */\nexport function appendBuffer(buffer1: ArrayBuffer, buffer2: ArrayBuffer): ArrayBuffer {\n const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength)\n tmp.set(new Uint8Array(buffer1), 0)\n tmp.set(new Uint8Array(buffer2), buffer1.byteLength)\n return tmp.buffer as ArrayBuffer\n}\n\n//Convenience methods for dates management\nexport function after(d1: number | null | undefined, d2: number | null | undefined): boolean {\n return d1 === null || d2 === null || d1 === undefined || d2 === undefined || moment(d1)!.isAfter(moment(d2)!)\n}\n\nexport function before(d1: number | null | undefined, d2: number | null | undefined): boolean {\n return d1 === null || d2 === null || d1 === undefined || d2 === undefined || moment(d1)!.isBefore(moment(d2)!)\n}\n\nfunction moment(epochOrLongCalendar: number): Moment | null {\n if (!epochOrLongCalendar && epochOrLongCalendar !== 0) {\n return null\n }\n if (epochOrLongCalendar >= 18000101 && epochOrLongCalendar < 25400000) {\n return mm('' + epochOrLongCalendar, 'YYYYMMDD')\n } else if (epochOrLongCalendar >= 18000101000000) {\n return mm('' + epochOrLongCalendar, 'YYYYMMDDHHmmss')\n } else {\n return mm(epochOrLongCalendar)\n }\n}\n\n/**\n * Encrypt object graph recursively\n *\n * @param obj the object to encrypt\n * @param cryptor the cryptor function (returns a promise)\n * @param keys the keys to be crypted: ex for a Patient ['note', 'addresses.*.[\"street\", \"houseNumber\", \"telecoms.*.telecomNumber\"]']\n */\nexport async function crypt(obj: any, cryptor: (obj: { [key: string]: string }) => Promise<ArrayBuffer>, keys: Array<string>) {\n const subObj = _.pick(\n obj,\n keys.filter((k) => !k.includes('*'))\n )\n obj.encryptedSelf = b2a(ua2string(await cryptor(subObj)))\n Object.keys(subObj).forEach((k) => delete obj[k])\n\n await keys\n .filter((k) => k.includes('*'))\n .reduce(async (prev: Promise<void>, k: any) => {\n await prev\n const k1 = k.split('.*.')[0]\n const k2 = k.substr(k1.length + 3)\n\n const mapped = await Promise.all((_.get(obj, k1) || []).map((so: any) => crypt(so, cryptor, k2.startsWith('[') ? JSON.parse(k2) : [k2])))\n _.set(obj, k1, mapped)\n }, Promise.resolve())\n\n return obj\n}\n\n/**\n * Decrypt object graph recursively\n *\n * @param obj the object to encrypt\n * @param decryptor the decryptor function (returns a promise)\n */\nexport async function decrypt(obj: any, decryptor: (obj: Uint8Array) => Promise<{ [key: string]: string }>) {\n await Object.keys(obj).reduce(async (prev: Promise<void>, k: any) => {\n await prev\n if (Array.isArray(obj[k])) {\n await (obj[k] as Array<any>)\n .filter((o) => typeof o === 'object' && o !== null)\n .reduce(async (prev: Promise<void>, so: any) => {\n await prev\n await decrypt(so, decryptor)\n }, Promise.resolve())\n }\n }, Promise.resolve())\n if (obj.encryptedSelf) {\n Object.assign(obj, await decryptor(string2ua(a2b(obj.encryptedSelf))))\n }\n return obj\n}\n\n/**\n * Extracts the full jwk key pair from the jwk representation of the private key.\n * @param privateKeyJwk private key in jwk representation\n * @throws if the key is missing the public modulus or public exponent.\n */\nexport function keyPairFromPrivateKeyJwk(privateKeyJwk: JsonWebKey): KeyPair<JsonWebKey> {\n if (!privateKeyJwk.n || !privateKeyJwk.e) throw new Error('Incomplete private JsonWebKey: missing public modulus and/or exponent')\n return {\n privateKey: privateKeyJwk,\n publicKey: spkiToJwk(hex2ua(jwk2spki(privateKeyJwk))),\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"crypto-utils.js","sourceRoot":"","sources":["../../../icc-x-api/utils/crypto-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import * as mm from 'moment'\nimport { Moment } from 'moment'\nimport * as _ from 'lodash'\nimport { a2b, b2a, b64Url2ua, hex2ua, string2ua, ua2b64Url, ua2hex, ua2string } from '../utils/binary-utils'\nimport { pack } from './asn1-packer'\nimport { parseAsn1 } from './asn1-parser'\nimport { KeyPair } from '../crypto/RSA'\n\nexport function notConcurrent<T>(concurrencyMap: { [key: string]: PromiseLike<any> }, key: string, proc: () => PromiseLike<T>): PromiseLike<T> {\n const inFlight = concurrencyMap[key]\n if (!inFlight) {\n const newJob = (async () => {\n try {\n return await proc()\n } finally {\n delete concurrencyMap[key]\n }\n })()\n concurrencyMap[key] = newJob\n return newJob\n } else {\n return concurrencyMap[key].then(() => notConcurrent(concurrencyMap, key, proc))\n }\n}\n\nexport function jwk2pkcs8(jwk: any): string {\n return pack([\n 0x30,\n [\n [0x02, '00'],\n [0x30, [[0x06, '2a864886f70d010101'], [0x05]]], // pragma: allowlist secret\n [\n 0x04,\n [\n [\n 0x30,\n [\n [0x02, '00'],\n [0x02, ua2hex(b64Url2ua(jwk.n))],\n [0x02, ua2hex(b64Url2ua(jwk.e))],\n [0x02, ua2hex(b64Url2ua(jwk.d))],\n [0x02, ua2hex(b64Url2ua(jwk.p))],\n [0x02, ua2hex(b64Url2ua(jwk.q))],\n [0x02, ua2hex(b64Url2ua(jwk.dp))],\n [0x02, ua2hex(b64Url2ua(jwk.dq))],\n [0x02, ua2hex(b64Url2ua(jwk.qi))],\n ],\n ],\n ],\n ],\n ],\n ])\n}\n\nexport function jwk2spki(jwk: any): string {\n return pack([\n 0x30,\n [\n [0x30, [[0x06, '2a864886f70d010101'], [0x05]]], // pragma: allowlist secret\n [\n 0x03,\n [\n [\n 0x30,\n [\n [0x02, ua2hex(b64Url2ua(jwk.n))],\n [0x02, ua2hex(b64Url2ua(jwk.e))],\n ],\n ],\n ],\n ],\n ],\n ])\n}\n\nexport function spkiToJwk(buf: Uint8Array): { kty: string; alg: string; n: string; e: string; ext: boolean } {\n const asn1 = parseAsn1(new Uint8Array(buf))\n\n var modulus: Uint8Array | undefined = undefined\n var exponent: Uint8Array | undefined = undefined\n if (\n asn1.type === 0x30 &&\n asn1.children?.[0]?.type === 0x30 &&\n asn1.children?.[0]?.children?.[0]?.type === 0x06 &&\n ua2hex(asn1.children?.[0]?.children?.[0]?.value ?? new Uint8Array(0)) === '2a864886f70d010101' // pragma: allowlist secret\n ) {\n modulus = asn1.children?.[1]?.children?.[0]?.children?.[0]?.value\n exponent = asn1.children?.[1]?.children?.[0]?.children?.[1]?.value\n } else if (asn1.type === 0x30 && asn1.children?.[0]?.type === 0x02 && asn1.children?.[1]?.type === 0x02) {\n modulus = asn1.children?.[0]?.value\n exponent = asn1.children?.[1]?.value\n }\n\n if (!modulus || !exponent) {\n throw new Error('Invalid spki format')\n }\n return {\n kty: 'RSA',\n alg: 'RSA-OAEP',\n ext: true,\n n: ua2b64Url(minimalRep(modulus)),\n e: ua2b64Url(minimalRep(exponent)),\n }\n}\n\nexport function pkcs8ToJwk(buf: Uint8Array | ArrayBuffer) {\n const parsed = parseAsn1(new Uint8Array(buf))\n const seq =\n parsed.children?.length === 3 && parsed.children[2].type === 0x04 && parsed.children[2].children?.length === 1\n ? parsed.children[2].children[0]\n : parsed\n return {\n kty: 'RSA',\n n: ua2b64Url(minimalRep(seq.children![1].value as Uint8Array)),\n e: ua2b64Url(minimalRep(seq.children![2].value as Uint8Array)),\n d: ua2b64Url(minimalRep(seq.children![3].value as Uint8Array)),\n p: ua2b64Url(minimalRep(seq.children![4].value as Uint8Array)),\n q: ua2b64Url(minimalRep(seq.children![5].value as Uint8Array)),\n dp: ua2b64Url(minimalRep(seq.children![6].value as Uint8Array)),\n dq: ua2b64Url(minimalRep(seq.children![7].value as Uint8Array)),\n qi: ua2b64Url(minimalRep(seq.children![8].value as Uint8Array)),\n }\n}\n\nfunction minimalRep(b: Uint8Array) {\n let i = 0\n while (b[i] === 0) {\n i++\n }\n return b.slice(i)\n}\n\n/**\n * Provide a view over the given Uint8Array where any trailing null bytes at\n * the end are truncated.\n *\n * This can be used to ignore null bytes at the end of a padded UTF-8 string\n * without needing to copy that string, assuming code point U+0000 is encoded\n * in one null byte according to standards rather than in a multi-byte\n * overlong form.\n */\nexport function truncateTrailingNulls(a: Uint8Array) {\n let end = a.byteLength - 1\n while (a[end] === 0 && end >= 0) {\n end--\n }\n // end is now either the last non-null position in a or -1; in the latter\n // case the returned array will have length 0.\n return a.subarray(0, end + 1)\n}\n\n/**\n *\n * @param buffer1 {Uint8Array}\n * @param buffer2{ Uint8Array}\n * @returns {ArrayBuffer}\n */\nexport function appendBuffer(buffer1: ArrayBuffer, buffer2: ArrayBuffer): ArrayBuffer {\n const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength)\n tmp.set(new Uint8Array(buffer1), 0)\n tmp.set(new Uint8Array(buffer2), buffer1.byteLength)\n return tmp.buffer as ArrayBuffer\n}\n\n//Convenience methods for dates management\nexport function after(d1: number | null | undefined, d2: number | null | undefined): boolean {\n return d1 === null || d2 === null || d1 === undefined || d2 === undefined || moment(d1)!.isAfter(moment(d2)!)\n}\n\nexport function before(d1: number | null | undefined, d2: number | null | undefined): boolean {\n return d1 === null || d2 === null || d1 === undefined || d2 === undefined || moment(d1)!.isBefore(moment(d2)!)\n}\n\nfunction moment(epochOrLongCalendar: number): Moment | null {\n if (!epochOrLongCalendar && epochOrLongCalendar !== 0) {\n return null\n }\n if (epochOrLongCalendar >= 18000101 && epochOrLongCalendar < 25400000) {\n return mm('' + epochOrLongCalendar, 'YYYYMMDD')\n } else if (epochOrLongCalendar >= 18000101000000) {\n return mm('' + epochOrLongCalendar, 'YYYYMMDDHHmmss')\n } else {\n return mm(epochOrLongCalendar)\n }\n}\n\n/**\n * Configuration for the encryption of an object.\n * @param topLevelFields the fields of the object to encrypt. All the fields will be encrypted in a single encryptedSelf field which is added to the\n * object.\n * @param nestedObjectsKeys the name of fields which are expected to contain a nested object (or undefined). Allows to specify\n */\nexport type EncryptedFieldsManifest = {\n topLevelFields: { fieldName: string; fieldPath: string }[]\n nestedObjectsKeys: {\n [objectFieldName: string]: EncryptedFieldsManifest\n }\n mapsValuesKeys: {\n [mapFieldName: string]: EncryptedFieldsManifest\n }\n arraysValuesKeys: {\n [arrayFieldName: string]: EncryptedFieldsManifest\n }\n}\n\n/**\n * @internal this function is for internal use only and may be changed without notice\n *\n * Parse the encrypted fields configuration for a specific entity type.\n *\n * ## Grammar\n *\n * The grammar for each encrypted field is the following:\n * ```\n * fieldName :=\n * regex([a-zA-Z_][a-zA-Z0-9_]+)\n * encryptedField :=\n * fieldName\n * | fieldName + (\".\" | \".*.\" | \"[].\") + encryptedField\n * ```\n *\n * This grammar allows you to specify the fields to encrypt for the object and recursively for nested objects.\n * - A string containing only a single `fieldName` will encrypt the field with the given name.\n * - A string starting with `fieldName.` allows to specify the encrypted fields of a nested object. The encrypted values of the\n * fields in the nested object will be saved in the nested object.\n * - A string starting with `fieldName.*.` treats `fieldName` as a map/dictionary data structure and allows to specify the encrypted fields of the\n * values of the map. Note that the values of the map must be objects as well. The encrypted content of each map value is stored in that value.\n * - A string starting with `fieldName[].` treats `fieldName` as an array and allows to specify the encrypted fields of the values of the array.\n * Note that the values of the array must be objects as well. The encrypted content of each array element is stored in that element.\n *\n * ## Example\n *\n * Consider the following object and encryption keys:\n * ```javascript\n * const obj = {\n * a: { x: 0, y: 1 },\n * b: \"hello\",\n * c: [ { public: \"a\", secret: \"b\" }, { public: \"c\", secret: \"d\" } ],\n * d: \"ok\",\n * e: {\n * info: \"something\",\n * private: \"secret\",\n * dataMap: {\n * \"en\": {\n * a: 1,\n * b: 2\n * },\n * \"fr\": {\n * a: 3,\n * b: 4\n * }\n * }\n * }\n * }\n * const encryptedFields = [\n * \"a\",\n * \"c[].secret\",\n * \"d\",\n * \"e.private\",\n * \"e.datamap.*.a\"\n * ]\n * ```\n * If you use them with the crypt method you will get the following result:\n * ```json\n * {\n * b: \"hello\",\n * c: [\n * { public: \"a\", encryptedSelf: \"...encrypted data of c[0]\" },\n * { public: \"c\", encryptedSelf: \"...encrypted data of c[1]\" }\n * ],\n * e: {\n * info: \"something\",\n * dataMap: {\n * \"en\": { b: 2, encryptedSelf: \"...encrypted data of e.dataMap['en']\" },\n * \"fr\": { b: 4, encryptedSelf: \"...encrypted data of e.dataMap['fr']\" }\n * },\n * encryptedSelf: \"...encrypted data of e\"\n * },\n * encryptedSelf: \"...encrypted data of obj\"\n * }\n * ```\n *\n * ## Shortened representation\n *\n * You can also group encrypted fields having the same prefix by concatenating to the prefix the JSON representation of an array of all the postfixes.\n * For example the following encrypted fields:\n * ```javascript\n * const encryptedFields = [\"a.b.c.d.e.f1\", \"a.b.c.d.e.f2\", \"a.b.c.d.e.f3\", \"a.b.c.d.e.f4\"]\n * ```\n * can be shortened to\n * ```javascript\n * const encryptedFields = ['a.b.c.d.e.[\"f1\",\"f2\",\"f3\",\"f4\"]'] // Note the use of single quotes to avoid escaping the double quotes\n * ```\n * If you use the shortened representation you may need to escape nested json representations. In that case the use of `JSON.stringify` is\n * recommended.\n *\n * @param encryptedFields\n * @param path\n */\nexport function parseEncryptedFields(encryptedFields: string[], path: string): EncryptedFieldsManifest {\n const groupedData = {\n topLevelFields: new Set<string>(),\n nestedObjectsKeys: {} as { [objectFieldName: string]: string[] },\n mapsValuesKeys: {} as { [mapFieldName: string]: string[] },\n arraysValuesKeys: {} as { [arrayFieldName: string]: string[] },\n }\n const encryptedFieldRegex = /^([_a-zA-Z][_a-zA-Z0-9]*)(?:(\\.\\*\\.|\\[]\\.|\\.)(?:[_a-zA-Z].*|\\[.*]))?$/\n const addSubkeyToGroupedData = (\n currFieldName: string,\n currFieldSeparator: string,\n currEncryptedField: string,\n groupedDataKey: 'nestedObjectsKeys' | 'mapsValuesKeys' | 'arraysValuesKeys'\n ) => {\n const existingOrNew = groupedData[groupedDataKey][currFieldName] ?? (groupedData[groupedDataKey][currFieldName] = [])\n const subKey = currEncryptedField.slice(currFieldName.length + currFieldSeparator.length)\n if (subKey.startsWith('[')) {\n let parsedJson: any[]\n try {\n parsedJson = JSON.parse(subKey)\n } catch {\n throw new Error(`Invalid encrypted field ${path}${currEncryptedField} (not a valid JSON subkey)`)\n }\n if (Array.isArray(parsedJson) && parsedJson.every((x) => typeof x == 'string')) {\n parsedJson.forEach((x) => existingOrNew.push(x))\n } else throw new Error(`Invalid encrypted field ${path}${currEncryptedField} (not an array of strings)`)\n } else {\n existingOrNew.push(subKey)\n }\n }\n for (const currEncryptedField of encryptedFields) {\n const currFieldMatch = currEncryptedField.match(encryptedFieldRegex)\n if (!!currFieldMatch) {\n const currFieldName = currFieldMatch[1]\n const currFieldSeparator = currFieldMatch[2]\n if (!currFieldSeparator) {\n if (groupedData.topLevelFields.has(currFieldName)) throw new Error(`Duplicate encrypted field ${path}${currFieldName}`)\n if (\n !!groupedData.nestedObjectsKeys[currFieldName] ||\n !!groupedData.mapsValuesKeys[currFieldName] ||\n !!groupedData.arraysValuesKeys[currFieldName]\n )\n throw new Error(`Encrypted field appears multiple times as different nested types and or top-level-field: ${path}${currFieldName}`)\n groupedData.topLevelFields.add(currFieldName)\n } else if (currFieldSeparator == '.') {\n if (\n groupedData.topLevelFields.has(currFieldName) ||\n !!groupedData.mapsValuesKeys[currFieldName] ||\n !!groupedData.arraysValuesKeys[currFieldName]\n )\n throw new Error(`Encrypted field appears multiple times as different nested types and or top-level-field: ${path}${currFieldName}`)\n addSubkeyToGroupedData(currFieldName, currFieldSeparator, currEncryptedField, 'nestedObjectsKeys')\n } else if (currFieldSeparator == '.*.') {\n if (\n groupedData.topLevelFields.has(currFieldName) ||\n !!groupedData.nestedObjectsKeys[currFieldName] ||\n !!groupedData.arraysValuesKeys[currFieldName]\n )\n throw new Error(`Encrypted field appears multiple times as different nested types and or top-level-field: ${path}${currFieldName}`)\n addSubkeyToGroupedData(currFieldName, currFieldSeparator, currEncryptedField, 'mapsValuesKeys')\n } else if (currFieldSeparator == '[].') {\n if (\n groupedData.topLevelFields.has(currFieldName) ||\n !!groupedData.nestedObjectsKeys[currFieldName] ||\n !!groupedData.mapsValuesKeys[currFieldName]\n )\n throw new Error(`Encrypted field appears multiple times as different nested types and or top-level-field: ${path}${currFieldName}`)\n addSubkeyToGroupedData(currFieldName, currFieldSeparator, currEncryptedField, 'arraysValuesKeys')\n } else throw new Error(`Internal error: unknown separator ${currFieldSeparator} passed regex validation in ${path}${currEncryptedField}`)\n } else throw new Error(`Invalid encrypted field ${path}${currEncryptedField}`)\n }\n return {\n topLevelFields: Array.from(groupedData.topLevelFields).map((fieldName) => ({ fieldName, fieldPath: path + fieldName })),\n nestedObjectsKeys: Object.fromEntries(\n Object.entries(groupedData.nestedObjectsKeys).map(([fieldName, fieldNames]) => [\n fieldName,\n parseEncryptedFields(fieldNames, path + fieldName + '.'),\n ])\n ),\n mapsValuesKeys: Object.fromEntries(\n Object.entries(groupedData.mapsValuesKeys).map(([fieldName, fieldNames]) => [\n fieldName,\n parseEncryptedFields(fieldNames, path + fieldName + '.*.'),\n ])\n ),\n arraysValuesKeys: Object.fromEntries(\n Object.entries(groupedData.arraysValuesKeys).map(([fieldName, fieldNames]) => [\n fieldName,\n parseEncryptedFields(fieldNames, path + fieldName + '[].'),\n ])\n ),\n }\n}\n\n/**\n * @internal this function is for internal use only and may be changed without notice\n * Encrypt the object graph recursively. Generally return an updated SHALLOW copy, although some fields may be deep copied if they also needed to be\n * recursively encrypted.\n * @param obj the object to encrypt\n * @param cryptor takes in input an object consisting only of the fields to encrypt of obj, and returns the encrypted object.\n * @param keys the keys to encrypt for the\n * @param path path of the current object, used for error messages.\n * @return a shallow copy of the object with a new encryptedSelfField and without the encrypted fields.\n */\nexport async function encryptObject(\n obj: { [key: string]: any },\n cryptor: (obj: { [key: string]: any }) => Promise<ArrayBuffer>,\n keys: EncryptedFieldsManifest,\n path: string = 'obj'\n): Promise<{ [key: string]: any }> {\n const shallowClone = { ...obj }\n const currEncryptedFields: { [key: string]: any } = {}\n for (const { fieldName } of keys.topLevelFields) {\n const fieldValue = shallowClone[fieldName]\n if (fieldValue !== undefined) {\n // we keep null values\n currEncryptedFields[fieldName] = fieldValue\n delete shallowClone[fieldName]\n }\n }\n shallowClone['encryptedSelf'] = b2a(ua2string(await cryptor(currEncryptedFields)))\n for (const [fieldName, subKeys] of Object.entries(keys.nestedObjectsKeys)) {\n const fieldValue = shallowClone[fieldName]\n if (fieldValue !== undefined && fieldValue !== null) {\n if (!isPojo(fieldValue)) throw new Error(`Expected field ${path}.${fieldName} to be a non-array object`)\n shallowClone[fieldName] = await encryptObject(fieldValue, cryptor, subKeys, path + '.' + fieldName)\n }\n }\n for (const [mapFieldName, subKeys] of Object.entries(keys.mapsValuesKeys)) {\n const fieldValue = shallowClone[mapFieldName]\n if (fieldValue !== undefined && fieldValue !== null) {\n if (!isPojo(fieldValue)) throw new Error(`Expected field ${path}.${mapFieldName} to be a non-array object`)\n const newMap: { [key: string]: any } = {}\n for (const [key, value] of Object.entries(fieldValue as object)) {\n if (value === null || value === undefined) {\n newMap[key] = value\n } else {\n if (!isPojo(value)) throw new Error(`Expected field ${path}.${mapFieldName}.${key} to be a non-array object`)\n newMap[key] = await encryptObject(value, cryptor, subKeys, path + '.' + mapFieldName + '.' + key)\n }\n }\n shallowClone[mapFieldName] = newMap\n }\n }\n for (const [arrayFieldName, subKeys] of Object.entries(keys.arraysValuesKeys)) {\n const fieldValue = shallowClone[arrayFieldName]\n if (fieldValue !== undefined && fieldValue !== null) {\n if (!Array.isArray(fieldValue)) throw new Error(`Expected field ${path}.${arrayFieldName} to be an array`)\n const newArray: any[] = Array(fieldValue.length)\n for (let i = 0; i < fieldValue.length; i++) {\n const value = fieldValue[i]\n if (value === null || value === undefined) {\n newArray[i] = value\n } else {\n if (!isPojo(value)) throw new Error(`Expected field ${path}.${arrayFieldName}[${i}] to be a non-array object`)\n newArray[i] = await encryptObject(value, cryptor, subKeys, path + '.' + arrayFieldName + '[' + i + ']')\n }\n }\n shallowClone[arrayFieldName] = newArray\n }\n }\n return shallowClone\n}\n\n/**\n * Check if value is a non-null object that is not an array.\n */\nfunction isPojo(value: any): boolean {\n // This break if for some reason we have object versions of String/Number/Boolean\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\n/**\n * @internal this function is for internal use only and may be changed without notice\n * Decrypt object graph recursively.\n *\n * @param obj the object to decrypt\n * @param decryptor the decryptor function (returns a promise)\n * @return a deep copy of the object with the decrypted fields and removed encryptedSelf field\n */\nexport async function decryptObject(\n obj: { [key: string]: any },\n decryptor: (obj: Uint8Array) => Promise<{ [key: string]: any }>\n): Promise<{ [key: string]: any }> {\n const copy: { [key: string]: any } = {}\n for (const [key, value] of Object.entries(obj)) {\n if (key === 'encryptedSelf') {\n copy[key] = value\n } else if (typeof value === 'object' && value !== null) {\n if (Array.isArray(value)) {\n // Note: nested arrays (and primitives) are returned as is and not they are not recursively decrypted. This is because we currently do not\n // support encryption of elements from arrays in arrays (we only support arrays in objects in arrays). In future this may change.\n copy[key] = await Promise.all(value.map((v) => (isPojo(v) ? decryptObject(v, decryptor) : v)))\n } else {\n copy[key] = await decryptObject(value, decryptor)\n }\n } else {\n copy[key] = value\n }\n }\n if (obj.encryptedSelf) {\n const decrypted = await decryptor(string2ua(a2b(obj.encryptedSelf)))\n return { ...copy, ...decrypted }\n } else return copy\n}\n\n/**\n * Extracts the full jwk key pair from the jwk representation of the private key.\n * @param privateKeyJwk private key in jwk representation\n * @throws if the key is missing the public modulus or public exponent.\n */\nexport function keyPairFromPrivateKeyJwk(privateKeyJwk: JsonWebKey): KeyPair<JsonWebKey> {\n if (!privateKeyJwk.n || !privateKeyJwk.e) throw new Error('Incomplete private JsonWebKey: missing public modulus and/or exponent')\n return {\n privateKey: privateKeyJwk,\n publicKey: spkiToJwk(hex2ua(jwk2spki(privateKeyJwk))),\n }\n}\n"]}
|