@lifeready/core 6.1.3 → 6.1.4
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/bundles/lifeready-core.umd.js +301 -293
- package/bundles/lifeready-core.umd.js.map +1 -1
- package/bundles/lifeready-core.umd.min.js +1 -1
- package/bundles/lifeready-core.umd.min.js.map +1 -1
- package/esm2015/lib/auth/auth.config.js +57 -0
- package/esm2015/lib/auth/auth.gql.private.js +85 -0
- package/esm2015/lib/auth/auth.service.js +602 -0
- package/esm2015/lib/auth/auth.types.js +21 -0
- package/esm2015/lib/item/item.gql.js +164 -0
- package/esm2015/lib/item/item.gql.private.js +23 -0
- package/esm2015/lib/item/item.service.js +592 -0
- package/esm2015/lib/item/item.types.js +2 -0
- package/esm2015/lib/key-exchange/key-exchange.gql.js +174 -0
- package/esm2015/lib/key-exchange/key-exchange.service.js +480 -0
- package/esm2015/lib/lbop/lbop.service.js +7 -15
- package/esm2015/lib/life-ready.module.js +2 -2
- package/esm2015/lib/password/password.service.js +1 -1
- package/esm2015/lib/plan/plan.gql.js +91 -0
- package/esm2015/lib/plan/plan.service.js +191 -0
- package/esm2015/lib/plan/plan.types.js +2 -0
- package/esm2015/lib/profile/profile.gql.js +2 -2
- package/esm2015/lib/profile/profile.service.js +1 -8
- package/esm2015/lib/profile/profile.types.js +1 -8
- package/esm2015/lib/scenario/scenario.service.js +8 -8
- package/esm2015/lib/shared-contact-card/shared-contact-card2.service.js +1 -1
- package/esm2015/lib/trusted-party/trusted-party.gql.js +64 -0
- package/esm2015/lib/trusted-party/trusted-party.gql.private.js +25 -0
- package/esm2015/lib/trusted-party/trusted-party.service.js +240 -0
- package/esm2015/lib/trusted-party/trusted-party.types.js +2 -0
- package/esm2015/public-api.js +17 -12
- package/fesm2015/lifeready-core.js +189 -211
- package/fesm2015/lifeready-core.js.map +1 -1
- package/lib/{auth2/auth2.service.d.ts → auth/auth.service.d.ts} +2 -2
- package/lib/{item2/item2.service.d.ts → item/item.service.d.ts} +39 -39
- package/lib/key-exchange/{key-exchange2.service.d.ts → key-exchange.service.d.ts} +2 -2
- package/lib/lbop/lbop.service.d.ts +1 -5
- package/lib/password/password.service.d.ts +1 -1
- package/lib/{plan2/plan2.service.d.ts → plan/plan.service.d.ts} +20 -20
- package/lib/profile/profile.service.d.ts +1 -2
- package/lib/profile/profile.types.d.ts +2 -15
- package/lib/scenario/scenario.service.d.ts +3 -3
- package/lib/shared-contact-card/shared-contact-card2.service.d.ts +1 -1
- package/lib/trusted-party/{trusted-party2.service.d.ts → trusted-party.service.d.ts} +6 -6
- package/lifeready-core.metadata.json +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +16 -11
- package/esm2015/lib/auth2/auth.config.js +0 -57
- package/esm2015/lib/auth2/auth2.gql.private.js +0 -85
- package/esm2015/lib/auth2/auth2.service.js +0 -602
- package/esm2015/lib/auth2/auth2.types.js +0 -21
- package/esm2015/lib/item2/item2.gql.js +0 -164
- package/esm2015/lib/item2/item2.gql.private.js +0 -23
- package/esm2015/lib/item2/item2.service.js +0 -592
- package/esm2015/lib/item2/item2.types.js +0 -2
- package/esm2015/lib/key-exchange/key-exchange2.gql.js +0 -174
- package/esm2015/lib/key-exchange/key-exchange2.service.js +0 -480
- package/esm2015/lib/plan2/plan2.gql.js +0 -91
- package/esm2015/lib/plan2/plan2.service.js +0 -191
- package/esm2015/lib/plan2/plan2.types.js +0 -2
- package/esm2015/lib/trusted-party/trusted-party2.gql.js +0 -64
- package/esm2015/lib/trusted-party/trusted-party2.gql.private.js +0 -25
- package/esm2015/lib/trusted-party/trusted-party2.service.js +0 -240
- package/esm2015/lib/trusted-party/trusted-party2.types.js +0 -2
- /package/lib/{auth2 → auth}/auth.config.d.ts +0 -0
- /package/lib/{auth2/auth2.gql.private.d.ts → auth/auth.gql.private.d.ts} +0 -0
- /package/lib/{auth2/auth2.types.d.ts → auth/auth.types.d.ts} +0 -0
- /package/lib/{item2/item2.gql.d.ts → item/item.gql.d.ts} +0 -0
- /package/lib/{item2/item2.gql.private.d.ts → item/item.gql.private.d.ts} +0 -0
- /package/lib/{item2/item2.types.d.ts → item/item.types.d.ts} +0 -0
- /package/lib/key-exchange/{key-exchange2.gql.d.ts → key-exchange.gql.d.ts} +0 -0
- /package/lib/{plan2/plan2.gql.d.ts → plan/plan.gql.d.ts} +0 -0
- /package/lib/{plan2/plan2.types.d.ts → plan/plan.types.d.ts} +0 -0
- /package/lib/trusted-party/{trusted-party2.gql.d.ts → trusted-party.gql.d.ts} +0 -0
- /package/lib/trusted-party/{trusted-party2.gql.private.d.ts → trusted-party.gql.private.d.ts} +0 -0
- /package/lib/trusted-party/{trusted-party2.types.d.ts → trusted-party.types.d.ts} +0 -0
|
@@ -1,592 +0,0 @@
|
|
|
1
|
-
var Item2Service_1;
|
|
2
|
-
import { __awaiter, __decorate } from "tslib";
|
|
3
|
-
import { Injectable, Injector, NgZone } from '@angular/core';
|
|
4
|
-
import { LrMutation, LrService } from '../api/lr-graphql';
|
|
5
|
-
import { Auth2Service } from '../auth2/auth2.service';
|
|
6
|
-
import { FileUploadService } from '../file-upload/file-upload.service';
|
|
7
|
-
import { KeyFactoryService } from '../key/key-factory.service';
|
|
8
|
-
import { KeyGraphService } from '../key/key-graph.service';
|
|
9
|
-
import { KeyService } from '../key/key.service';
|
|
10
|
-
import { PayloadType } from '../key/key.types';
|
|
11
|
-
import { LockService } from '../lock/lock.service';
|
|
12
|
-
import { KcBadArgumentException } from '../_common/exceptions';
|
|
13
|
-
import { RunOutsideAngular } from '../_common/run-outside-angular';
|
|
14
|
-
import { ArchiveDirectoryMutation, ArchiveFileMutation, BeginDeleteChildItemLinksWindowMutation, ChangeDirectoryParentsMutation, ChangeFileParentsMutation, CreateDirectoryMutation, CreateFileMutation, DeleteDirectoryMutation, DeleteFileMutation, RevertFileMutation, SetDirectoryConfidentialMutation, SetFileConfidentialMutation, TempDirectoryQuery, UnarchiveDirectoryMutation, UnarchiveFileMutation, UpdateDirectoryMutation, UpdateFileMutation, } from './item2.gql';
|
|
15
|
-
import { DirectoryKeyQuery, FileKeyQuery, FileStateKeyQuery, } from './item2.gql.private';
|
|
16
|
-
import * as i0 from "@angular/core";
|
|
17
|
-
import * as i1 from "../file-upload/file-upload.service";
|
|
18
|
-
import * as i2 from "../key/key.service";
|
|
19
|
-
import * as i3 from "../key/key-factory.service";
|
|
20
|
-
import * as i4 from "../key/key-graph.service";
|
|
21
|
-
import * as i5 from "../lock/lock.service";
|
|
22
|
-
import * as i6 from "../auth2/auth2.service";
|
|
23
|
-
let Item2Service = Item2Service_1 = class Item2Service extends LrService {
|
|
24
|
-
constructor(ngZone, injector, fileUploadService, keyService, keyFactory, keyGraph, lockService, auth2Service) {
|
|
25
|
-
super(injector);
|
|
26
|
-
this.ngZone = ngZone;
|
|
27
|
-
this.injector = injector;
|
|
28
|
-
this.fileUploadService = fileUploadService;
|
|
29
|
-
this.keyService = keyService;
|
|
30
|
-
this.keyFactory = keyFactory;
|
|
31
|
-
this.keyGraph = keyGraph;
|
|
32
|
-
this.lockService = lockService;
|
|
33
|
-
this.auth2Service = auth2Service;
|
|
34
|
-
// Caching the temp directory.
|
|
35
|
-
this.tempDirectory = null;
|
|
36
|
-
this.auth2Service.addLogoutListener(() => this.onLogout());
|
|
37
|
-
}
|
|
38
|
-
downloadFileContent(options) {
|
|
39
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
40
|
-
const fileContent = yield this.fileUploadService.downloadEncryptedFile(options.fileStateNodeId);
|
|
41
|
-
const fileStateKey = yield this.keyGraph.getKey(options.fileStateKeyId, () => this.getFileStateKeyId(options.fileStateNodeId));
|
|
42
|
-
return this.keyGraph.decryptFromString(fileStateKey, fileContent, {
|
|
43
|
-
payloadType: PayloadType.UINT_8_ARRAY,
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
getDirectoryKeyId(directoryId) {
|
|
48
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
-
return (yield this.query({
|
|
50
|
-
query: DirectoryKeyQuery,
|
|
51
|
-
variables: {
|
|
52
|
-
id: directoryId,
|
|
53
|
-
},
|
|
54
|
-
})).directory.keyId;
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
getFileKeyId(fileId) {
|
|
58
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
-
return (yield this.query({
|
|
60
|
-
query: FileKeyQuery,
|
|
61
|
-
variables: {
|
|
62
|
-
id: fileId,
|
|
63
|
-
},
|
|
64
|
-
})).file.keyId;
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
getDirectoryKey(directoryId, directoryKeyId) {
|
|
68
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
-
return this.keyGraph.getKey(directoryKeyId, () => this.getDirectoryKeyId(directoryId));
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
getFileKey(fileId, fileKeyId) {
|
|
73
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
74
|
-
return this.keyGraph.getKey(fileKeyId, () => this.getFileKeyId(fileId));
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
createDirectory(options) {
|
|
78
|
-
return this.mutate(this.createDirectoryMutation(options));
|
|
79
|
-
}
|
|
80
|
-
createDirectoryMutation(options) {
|
|
81
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
82
|
-
return new LrMutation({
|
|
83
|
-
mutation: CreateDirectoryMutation,
|
|
84
|
-
variables: {
|
|
85
|
-
input: yield this.prepareCreateDirectory(options),
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
updateDirectory(options) {
|
|
91
|
-
return this.mutate(this.updateDirectoryMutation(options));
|
|
92
|
-
}
|
|
93
|
-
updateDirectoryMutation(options) {
|
|
94
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
95
|
-
return new LrMutation({
|
|
96
|
-
mutation: UpdateDirectoryMutation,
|
|
97
|
-
variables: {
|
|
98
|
-
input: yield this.prepareUpdateDirectory(options),
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
deleteDirectory(id) {
|
|
104
|
-
return this.mutate(this.deleteDirectoryMutation(id));
|
|
105
|
-
}
|
|
106
|
-
deleteDirectoryMutation(id) {
|
|
107
|
-
return new LrMutation({
|
|
108
|
-
mutation: DeleteDirectoryMutation,
|
|
109
|
-
variables: {
|
|
110
|
-
input: {
|
|
111
|
-
directoryId: id,
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
createFile(options) {
|
|
117
|
-
return this.mutate(this.createFileMutation(options));
|
|
118
|
-
}
|
|
119
|
-
createFileMutation(options) {
|
|
120
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
121
|
-
return new LrMutation({
|
|
122
|
-
mutation: CreateFileMutation,
|
|
123
|
-
variables: {
|
|
124
|
-
input: yield this.prepareCreateFile(options),
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
updateFile(options) {
|
|
130
|
-
return this.mutate(this.updateFileMutation(options));
|
|
131
|
-
}
|
|
132
|
-
updateFileMutation(options) {
|
|
133
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
134
|
-
return new LrMutation({
|
|
135
|
-
mutation: UpdateFileMutation,
|
|
136
|
-
variables: {
|
|
137
|
-
input: yield this.prepareUpdateFile(options),
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
revertFile(options) {
|
|
143
|
-
return this.mutate(this.revertFileMutation(options));
|
|
144
|
-
}
|
|
145
|
-
revertFileMutation(options) {
|
|
146
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
147
|
-
return new LrMutation({
|
|
148
|
-
mutation: RevertFileMutation,
|
|
149
|
-
variables: {
|
|
150
|
-
input: options,
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
deleteFile(id) {
|
|
156
|
-
return this.mutate(this.deleteFileMutation(id));
|
|
157
|
-
}
|
|
158
|
-
deleteFileMutation(id) {
|
|
159
|
-
return new LrMutation({
|
|
160
|
-
mutation: DeleteFileMutation,
|
|
161
|
-
variables: {
|
|
162
|
-
input: {
|
|
163
|
-
fileId: id,
|
|
164
|
-
},
|
|
165
|
-
},
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
archiveDirectory(directoryId, options) {
|
|
169
|
-
return this.mutate(this.archiveDirectoryMutation(directoryId, options));
|
|
170
|
-
}
|
|
171
|
-
archiveDirectoryMutation(directoryId, options) {
|
|
172
|
-
return new LrMutation({
|
|
173
|
-
mutation: ArchiveDirectoryMutation,
|
|
174
|
-
variables: {
|
|
175
|
-
input: {
|
|
176
|
-
directoryId,
|
|
177
|
-
recursive: options.recursive,
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
archiveFile(fileId) {
|
|
183
|
-
return this.mutate(this.archiveFileMutation(fileId));
|
|
184
|
-
}
|
|
185
|
-
archiveFileMutation(fileId) {
|
|
186
|
-
return new LrMutation({
|
|
187
|
-
mutation: ArchiveFileMutation,
|
|
188
|
-
variables: {
|
|
189
|
-
input: {
|
|
190
|
-
fileId,
|
|
191
|
-
},
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
unarchiveDirectory(directoryId, options) {
|
|
196
|
-
return this.mutate(this.unarchiveDirectoryMutation(directoryId, options));
|
|
197
|
-
}
|
|
198
|
-
unarchiveDirectoryMutation(directoryId, options) {
|
|
199
|
-
return new LrMutation({
|
|
200
|
-
mutation: UnarchiveDirectoryMutation,
|
|
201
|
-
variables: {
|
|
202
|
-
input: {
|
|
203
|
-
directoryId,
|
|
204
|
-
recursive: options.recursive,
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
unarchiveFile(fileId) {
|
|
210
|
-
return this.mutate(this.unarchiveFileMutation(fileId));
|
|
211
|
-
}
|
|
212
|
-
unarchiveFileMutation(fileId) {
|
|
213
|
-
return new LrMutation({
|
|
214
|
-
mutation: UnarchiveFileMutation,
|
|
215
|
-
variables: {
|
|
216
|
-
input: {
|
|
217
|
-
fileId,
|
|
218
|
-
},
|
|
219
|
-
},
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
changeDirectoryParents(options) {
|
|
223
|
-
return this.mutate(this.changeDirectoryParentsMutation(options));
|
|
224
|
-
}
|
|
225
|
-
changeDirectoryParentsMutation(options) {
|
|
226
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
227
|
-
return new LrMutation({
|
|
228
|
-
mutation: ChangeDirectoryParentsMutation,
|
|
229
|
-
variables: {
|
|
230
|
-
input: yield this.prepareChangeDirectoryParents(options),
|
|
231
|
-
},
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
changeFileParents(options) {
|
|
236
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
237
|
-
return this.mutate(this.changeFileParentsMutation(options));
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
changeFileParentsMutation(options) {
|
|
241
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
242
|
-
return new LrMutation({
|
|
243
|
-
mutation: ChangeFileParentsMutation,
|
|
244
|
-
variables: {
|
|
245
|
-
input: yield this.prepareChangeFileParents(options),
|
|
246
|
-
},
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
beginDeleteChildItemLinksWindow(options) {
|
|
251
|
-
return this.mutate(this.beginDeleteChildItemLinksWindowMutation(options));
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Schedule cleanup of the hard links in a directory.
|
|
255
|
-
* The server will delete all hard link within the directory within a time window: starting from now and
|
|
256
|
-
* ending at requestWindowMs after now.
|
|
257
|
-
* The server decides _when_ it will perform the delete. It's not guaranteed that it will perform
|
|
258
|
-
* the delete at "now + requestWindowMs", but it will happen at some time after "now + requestWindowMs".
|
|
259
|
-
* This allows multiple overlapping calls to this function and the server allocates enough for each request.
|
|
260
|
-
* The server has a setting that allows for a maximum value on requestWindowMs. If the requested value
|
|
261
|
-
* is larger than this maximum, the call will fail.
|
|
262
|
-
*/
|
|
263
|
-
beginDeleteChildItemLinksWindowMutation(options) {
|
|
264
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
265
|
-
return new LrMutation({
|
|
266
|
-
mutation: BeginDeleteChildItemLinksWindowMutation,
|
|
267
|
-
variables: {
|
|
268
|
-
input: options,
|
|
269
|
-
},
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
*
|
|
275
|
-
* This method may raise VERSION_MISMATCH exception if there is a race condition
|
|
276
|
-
* when multiple clients try to create the temp directory.
|
|
277
|
-
*
|
|
278
|
-
* TODO There is a retry mechanism in graphql with exponential back off but that's internal.
|
|
279
|
-
* But need to use an exponential back off lib if we want to retry here.
|
|
280
|
-
*
|
|
281
|
-
* @returns The ID of the temp directory
|
|
282
|
-
*
|
|
283
|
-
*/
|
|
284
|
-
ensureTempDirectory() {
|
|
285
|
-
var _a;
|
|
286
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
287
|
-
if (this.tempDirectory) {
|
|
288
|
-
return this.tempDirectory;
|
|
289
|
-
}
|
|
290
|
-
const existing = yield this.query({
|
|
291
|
-
query: TempDirectoryQuery,
|
|
292
|
-
variables: {
|
|
293
|
-
plainMeta: Item2Service_1.TEMP_DIRECTORY_PLAIN_META_FILTER,
|
|
294
|
-
},
|
|
295
|
-
});
|
|
296
|
-
if (existing.rootDirectories.edges.length > 1) {
|
|
297
|
-
console.error(`There is more than 1 temp directory (plainMeta filter: ${Item2Service_1.TEMP_DIRECTORY_PLAIN_META_FILTER})`);
|
|
298
|
-
}
|
|
299
|
-
if (existing.rootDirectories.edges.length === 0) {
|
|
300
|
-
// Doesn't exist yet, create it
|
|
301
|
-
const createDirectory = yield this.createDirectoryMutation({
|
|
302
|
-
asRootDirectory: true,
|
|
303
|
-
plainMetaJson: Item2Service_1.TEMP_DIRECTORY_PLAIN_META,
|
|
304
|
-
});
|
|
305
|
-
// Optimistic lock on the current user.
|
|
306
|
-
const updateLock = this.lockService.updateLockMutation({
|
|
307
|
-
version: (_a = existing.lock) === null || _a === void 0 ? void 0 : _a.version,
|
|
308
|
-
});
|
|
309
|
-
// Because this.mutate() only handles simple types we need to use the more
|
|
310
|
-
// advanced this.lrGraphQL.lrMutate()
|
|
311
|
-
const [createDirectoryResult] = yield this.lrGraphQL.lrMutate([
|
|
312
|
-
createDirectory,
|
|
313
|
-
updateLock,
|
|
314
|
-
]);
|
|
315
|
-
const { id, keyId } = createDirectoryResult.createDirectory.directory;
|
|
316
|
-
this.tempDirectory = {
|
|
317
|
-
id,
|
|
318
|
-
keyId,
|
|
319
|
-
};
|
|
320
|
-
}
|
|
321
|
-
else {
|
|
322
|
-
// Return existing temp
|
|
323
|
-
const { id, keyId } = existing.rootDirectories.edges[0].node;
|
|
324
|
-
this.tempDirectory = {
|
|
325
|
-
id,
|
|
326
|
-
keyId,
|
|
327
|
-
};
|
|
328
|
-
}
|
|
329
|
-
return this.tempDirectory;
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
createDirectoryTree(options) {
|
|
333
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
334
|
-
return this.mutate(this.createDirectoryTreeMutation(options));
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* You must run this mutation within the temp directory cleanup window on the
|
|
339
|
-
* server, otherwise the temp directory will get cleaned up.
|
|
340
|
-
*
|
|
341
|
-
*/
|
|
342
|
-
createDirectoryTreeMutation(options) {
|
|
343
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
344
|
-
const tempDir = yield this.ensureTempDirectory();
|
|
345
|
-
// Clear the temp directory of the ones we are about to create.
|
|
346
|
-
// NOTE: this mutation can not be merged into a single mutation with the
|
|
347
|
-
// the createDirectory mutation because it uses the current server time to
|
|
348
|
-
// clean up. So it must successfully complete before the creation of the
|
|
349
|
-
// directories.
|
|
350
|
-
yield this.beginDeleteChildItemLinksWindow({
|
|
351
|
-
directoryId: tempDir.id,
|
|
352
|
-
requestWindowMs: options.requestWindowMs,
|
|
353
|
-
});
|
|
354
|
-
// Create the directory that has contents
|
|
355
|
-
const directory = (yield this.createDirectory({
|
|
356
|
-
cipherMetaClearJson: options.cipherMetaClearJson,
|
|
357
|
-
parentDirectories: [
|
|
358
|
-
{
|
|
359
|
-
directoryId: tempDir.id,
|
|
360
|
-
wrappingKeyId: tempDir.keyId,
|
|
361
|
-
},
|
|
362
|
-
],
|
|
363
|
-
plainMetaJson: options.plainMetaJson,
|
|
364
|
-
})).createDirectory.directory;
|
|
365
|
-
// Create the contents
|
|
366
|
-
yield options.createContent({
|
|
367
|
-
id: directory.id,
|
|
368
|
-
keyId: directory.keyId,
|
|
369
|
-
});
|
|
370
|
-
// TODO client-side check for timeout on requestWindowMs
|
|
371
|
-
// TODO return the server time where delete is scheduled. Expirable mutation
|
|
372
|
-
// Return the mutation that moves the directory into the dst directories
|
|
373
|
-
return this.changeDirectoryParentsMutation({
|
|
374
|
-
directoryId: directory.id,
|
|
375
|
-
directoryKeyId: directory.keyId,
|
|
376
|
-
parentsToRemove: [tempDir.id],
|
|
377
|
-
parentsToAdd: options.parentDirectories,
|
|
378
|
-
});
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
setFileConfidential(options) {
|
|
382
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
383
|
-
return this.mutate(this.setFileConfidentialMutation(options));
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
setFileConfidentialMutation(options) {
|
|
387
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
388
|
-
return new LrMutation({
|
|
389
|
-
mutation: SetFileConfidentialMutation,
|
|
390
|
-
variables: {
|
|
391
|
-
input: {
|
|
392
|
-
fileId: options.fileId,
|
|
393
|
-
confidential: options.confidential,
|
|
394
|
-
},
|
|
395
|
-
},
|
|
396
|
-
});
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
setDirectoryConfidential(options) {
|
|
400
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
401
|
-
return this.mutate(this.setDirectoryConfidentialMutation(options));
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
setDirectoryConfidentialMutation(options) {
|
|
405
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
406
|
-
return new LrMutation({
|
|
407
|
-
mutation: SetDirectoryConfidentialMutation,
|
|
408
|
-
variables: {
|
|
409
|
-
input: {
|
|
410
|
-
directoryId: options.directoryId,
|
|
411
|
-
confidential: options.confidential,
|
|
412
|
-
},
|
|
413
|
-
},
|
|
414
|
-
});
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
// ------------------------------------------------------------------------------
|
|
418
|
-
// ------------------------------------------------------------------------------
|
|
419
|
-
// Helpers
|
|
420
|
-
// ------------------------------------------------------------------------------
|
|
421
|
-
// ------------------------------------------------------------------------------
|
|
422
|
-
prepareParentDirectory(options, newKey) {
|
|
423
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
424
|
-
// If directory's key is not already in the key graph, then need to
|
|
425
|
-
// fetch the directory's key.
|
|
426
|
-
const wrappingKey = yield this.getDirectoryKey(options.directoryId, options.wrappingKeyId);
|
|
427
|
-
return {
|
|
428
|
-
directoryId: options.directoryId,
|
|
429
|
-
wrappingKeyId: wrappingKey.id,
|
|
430
|
-
wrappedKey: yield this.keyGraph.wrapKey(wrappingKey, newKey),
|
|
431
|
-
linkType: options.linkType,
|
|
432
|
-
};
|
|
433
|
-
});
|
|
434
|
-
}
|
|
435
|
-
getFileStateKeyId(fileStateNodeId) {
|
|
436
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
437
|
-
return (yield this.query({
|
|
438
|
-
query: FileStateKeyQuery,
|
|
439
|
-
variables: {
|
|
440
|
-
id: fileStateNodeId,
|
|
441
|
-
},
|
|
442
|
-
})).fileState.keyId;
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
prepareCreateFileState(fileKey, options) {
|
|
446
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
447
|
-
// Each version of the file is encrypted using a new key.
|
|
448
|
-
const fileStateKey = yield this.keyFactory.createKey();
|
|
449
|
-
const fileContent = options.file && (yield this.fileUploadService.loadFile(options.file));
|
|
450
|
-
let contentResource;
|
|
451
|
-
if (fileContent) {
|
|
452
|
-
const cipherFileContent = yield this.keyGraph.encryptToString(fileStateKey, fileContent);
|
|
453
|
-
if (options.upload) {
|
|
454
|
-
contentResource = yield options.upload(cipherFileContent);
|
|
455
|
-
}
|
|
456
|
-
else {
|
|
457
|
-
contentResource = yield this.fileUploadService.uploadEncryptedFile({
|
|
458
|
-
encryptedContent: cipherFileContent,
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
return Object.assign(Object.assign({}, (yield this.prepareItem(fileStateKey, options))), { wrappedStateKey: yield this.keyGraph.wrapKey(fileKey, fileStateKey), contentResource });
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
prepareChangeItemParents(options, itemKey) {
|
|
466
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
467
|
-
const parentsToAdd = options.parentsToAdd
|
|
468
|
-
? yield Promise.all(options.parentsToAdd.map((t) => this.prepareParentDirectory(t, itemKey)))
|
|
469
|
-
: [];
|
|
470
|
-
return {
|
|
471
|
-
directoriesToRemove: options.parentsToRemove || [],
|
|
472
|
-
directoriesToAdd: parentsToAdd,
|
|
473
|
-
};
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
prepareItem(key, options) {
|
|
477
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
478
|
-
const { plainMetaJson, cipherMetaClearJson } = options;
|
|
479
|
-
return {
|
|
480
|
-
plainMeta: plainMetaJson && JSON.stringify(plainMetaJson),
|
|
481
|
-
cipherMeta: cipherMetaClearJson &&
|
|
482
|
-
(yield this.keyGraph.encryptToString(key, cipherMetaClearJson)),
|
|
483
|
-
};
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
prepareCreateDirectory(options) {
|
|
487
|
-
var _a, _b, _c;
|
|
488
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
489
|
-
const directoryKey = yield this.keyFactory.createKey();
|
|
490
|
-
options.parentDirectories = options.parentDirectories || [];
|
|
491
|
-
if (!options.asRootDirectory && !((_a = options.parentDirectories) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
492
|
-
throw new KcBadArgumentException('A new directory must be either a root directory or a sub-directory. So you must provide either parentDirectories or asRootDirectory parameter.');
|
|
493
|
-
}
|
|
494
|
-
if (options.asRootDirectory && ((_b = options.parentDirectories) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
495
|
-
throw new KcBadArgumentException('A new directory must be either a root directory or a sub-directory. So you can only provide either parentDirectories or asRootDirectory parameter.');
|
|
496
|
-
}
|
|
497
|
-
const parentDirectories = yield Promise.all((_c = options.parentDirectories) === null || _c === void 0 ? void 0 : _c.map((t) => this.prepareParentDirectory(t, directoryKey)));
|
|
498
|
-
// TODO this is rather an unfortunate name, change it to asRootDirectory.
|
|
499
|
-
let parentRootDirectory;
|
|
500
|
-
if (options.asRootDirectory) {
|
|
501
|
-
const rootKey = this.keyService.currentRootKey;
|
|
502
|
-
parentRootDirectory = {
|
|
503
|
-
wrappingKeyId: rootKey.id,
|
|
504
|
-
wrappedKey: yield this.keyGraph.wrapKey(rootKey, directoryKey),
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
const itemInput = yield this.prepareItem(directoryKey, options);
|
|
508
|
-
return Object.assign(Object.assign({}, itemInput), { parentDirectories,
|
|
509
|
-
parentRootDirectory });
|
|
510
|
-
});
|
|
511
|
-
}
|
|
512
|
-
prepareUpdateDirectory(options) {
|
|
513
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
514
|
-
const directoryKey = yield this.getDirectoryKey(options.directoryId, options.directoryKeyId);
|
|
515
|
-
const itemInput = yield this.prepareItem(directoryKey.jwk, options);
|
|
516
|
-
return Object.assign(Object.assign({}, itemInput), { directoryId: options.directoryId });
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
prepareCreateFile(options) {
|
|
520
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
521
|
-
const fileKey = yield this.keyFactory.createKey();
|
|
522
|
-
const parentDirectories = yield Promise.all(options.parentDirectories.map((t) => __awaiter(this, void 0, void 0, function* () {
|
|
523
|
-
const { directoryId, wrappingKeyId, wrappedKey } = yield this.prepareParentDirectory(t, fileKey);
|
|
524
|
-
// remap from ParentDirectoryInput to FileParentDirectoryInput
|
|
525
|
-
// TODO the server should really just use wrappedKey instead of wrappedFileKey
|
|
526
|
-
return {
|
|
527
|
-
directoryId,
|
|
528
|
-
wrappingKeyId,
|
|
529
|
-
wrappedFileKey: wrappedKey,
|
|
530
|
-
};
|
|
531
|
-
})));
|
|
532
|
-
const input = yield this.prepareCreateFileState(fileKey, options);
|
|
533
|
-
return Object.assign(Object.assign({}, input), { parentDirectories });
|
|
534
|
-
});
|
|
535
|
-
}
|
|
536
|
-
prepareUpdateFile(options) {
|
|
537
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
538
|
-
const fileKey = yield this.getFileKey(options.fileId, options.fileKeyId);
|
|
539
|
-
const input = yield this.prepareCreateFileState(fileKey.jwk, options);
|
|
540
|
-
return Object.assign(Object.assign({}, input), { fileId: options.fileId });
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
prepareChangeDirectoryParents(options) {
|
|
544
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
545
|
-
const directoryKey = yield this.getDirectoryKey(options.directoryId, options.directoryKeyId);
|
|
546
|
-
const input = yield this.prepareChangeItemParents(options, directoryKey.jwk);
|
|
547
|
-
return Object.assign(Object.assign({}, input), { directoryId: options.directoryId });
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
prepareChangeFileParents(options) {
|
|
551
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
552
|
-
const fileKey = yield this.getFileKey(options.fileId, options.fileKeyId);
|
|
553
|
-
const input = yield this.prepareChangeItemParents(options, fileKey.jwk);
|
|
554
|
-
return Object.assign(Object.assign({}, input), { fileId: options.fileId });
|
|
555
|
-
});
|
|
556
|
-
}
|
|
557
|
-
onLogout() {
|
|
558
|
-
// Clear all cached data.
|
|
559
|
-
this.tempDirectory = null;
|
|
560
|
-
}
|
|
561
|
-
};
|
|
562
|
-
Item2Service.TEMP_DIRECTORY_PLAIN_META = { kcType: 'temp' };
|
|
563
|
-
Item2Service.TEMP_DIRECTORY_PLAIN_META_FILTER = JSON.stringify({
|
|
564
|
-
filter: [
|
|
565
|
-
{
|
|
566
|
-
contains: Item2Service_1.TEMP_DIRECTORY_PLAIN_META,
|
|
567
|
-
},
|
|
568
|
-
],
|
|
569
|
-
});
|
|
570
|
-
Item2Service.ɵprov = i0.ɵɵdefineInjectable({ factory: function Item2Service_Factory() { return new Item2Service(i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i0.INJECTOR), i0.ɵɵinject(i1.FileUploadService), i0.ɵɵinject(i2.KeyService), i0.ɵɵinject(i3.KeyFactoryService), i0.ɵɵinject(i4.KeyGraphService), i0.ɵɵinject(i5.LockService), i0.ɵɵinject(i6.Auth2Service)); }, token: Item2Service, providedIn: "root" });
|
|
571
|
-
Item2Service.decorators = [
|
|
572
|
-
{ type: Injectable, args: [{
|
|
573
|
-
providedIn: 'root',
|
|
574
|
-
},] }
|
|
575
|
-
];
|
|
576
|
-
Item2Service.ctorParameters = () => [
|
|
577
|
-
{ type: NgZone },
|
|
578
|
-
{ type: Injector },
|
|
579
|
-
{ type: FileUploadService },
|
|
580
|
-
{ type: KeyService },
|
|
581
|
-
{ type: KeyFactoryService },
|
|
582
|
-
{ type: KeyGraphService },
|
|
583
|
-
{ type: LockService },
|
|
584
|
-
{ type: Auth2Service }
|
|
585
|
-
];
|
|
586
|
-
Item2Service = Item2Service_1 = __decorate([
|
|
587
|
-
RunOutsideAngular({
|
|
588
|
-
ngZoneName: 'ngZone',
|
|
589
|
-
})
|
|
590
|
-
], Item2Service);
|
|
591
|
-
export { Item2Service };
|
|
592
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlbTIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvcmUvc3JjL2xpYi9pdGVtMi9pdGVtMi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTdELE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFMUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3RELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNuRSxPQUFPLEVBQ0wsd0JBQXdCLEVBQ3hCLG1CQUFtQixFQUNuQix1Q0FBdUMsRUFDdkMsOEJBQThCLEVBQzlCLHlCQUF5QixFQUN6Qix1QkFBdUIsRUFDdkIsa0JBQWtCLEVBQ2xCLHVCQUF1QixFQUN2QixrQkFBa0IsRUFDbEIsa0JBQWtCLEVBQ2xCLGdDQUFnQyxFQUNoQywyQkFBMkIsRUFDM0Isa0JBQWtCLEVBQ2xCLDBCQUEwQixFQUMxQixxQkFBcUIsRUFDckIsdUJBQXVCLEVBQ3ZCLGtCQUFrQixHQUNu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ZWN0YWJsZSwgSW5qZWN0b3IsIE5nWm9uZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSldLIH0gZnJvbSAnbm9kZS1qb3NlJztcbmltcG9ydCB7IExyTXV0YXRpb24sIExyU2VydmljZSB9IGZyb20gJy4uL2FwaS9sci1ncmFwaHFsJztcbmltcG9ydCB7IElELCBKU09OT2JqZWN0LCBMclJlbGF5SWRJbnB1dCB9IGZyb20gJy4uL2FwaS90eXBlcyc7XG5pbXBvcnQgeyBBdXRoMlNlcnZpY2UgfSBmcm9tICcuLi9hdXRoMi9hdXRoMi5zZXJ2aWNlJztcbmltcG9ydCB7IEZpbGVVcGxvYWRTZXJ2aWNlIH0gZnJvbSAnLi4vZmlsZS11cGxvYWQvZmlsZS11cGxvYWQuc2VydmljZSc7XG5pbXBvcnQgeyBLZXlGYWN0b3J5U2VydmljZSB9IGZyb20gJy4uL2tleS9rZXktZmFjdG9yeS5zZXJ2aWNlJztcbmltcG9ydCB7IEtleUdyYXBoU2VydmljZSB9IGZyb20gJy4uL2tleS9rZXktZ3JhcGguc2VydmljZSc7XG5pbXBvcnQgeyBLZXlTZXJ2aWNlIH0gZnJvbSAnLi4va2V5L2tleS5zZXJ2aWNlJztcbmltcG9ydCB7IFBheWxvYWRUeXBlIH0gZnJvbSAnLi4va2V5L2tleS50eXBlcyc7XG5pbXBvcnQgeyBMb2NrU2VydmljZSB9IGZyb20gJy4uL2xvY2svbG9jay5zZXJ2aWNlJztcbmltcG9ydCB7IEtjQmFkQXJndW1lbnRFeGNlcHRpb24gfSBmcm9tICcuLi9fY29tbW9uL2V4Y2VwdGlvbnMnO1xuaW1wb3J0IHsgUnVuT3V0c2lkZUFuZ3VsYXIgfSBmcm9tICcuLi9fY29tbW9uL3J1bi1vdXRzaWRlLWFuZ3VsYXInO1xuaW1wb3J0IHtcbiAgQXJjaGl2ZURpcmVjdG9yeU11dGF0aW9uLFxuICBBcmNoaXZlRmlsZU11dGF0aW9uLFxuICBCZWdpbkRlbGV0ZUNoaWxkSXRlbUxpbmtzV2luZG93TXV0YXRpb24sXG4gIENoYW5nZURpcmVjdG9yeVBhcmVudHNNdXRhdGlvbixcbiAgQ2hhbmdlRmlsZVBhcmVudHNNdXRhdGlvbixcbiAgQ3JlYXRlRGlyZWN0b3J5TXV0YXRpb24sXG4gIENyZWF0ZUZpbGVNdXRhdGlvbixcbiAgRGVsZXRlRGlyZWN0b3J5TXV0YXRpb24sXG4gIERlbGV0ZUZpbGVNdXRhdGlvbixcbiAgUmV2ZXJ0RmlsZU11dGF0aW9uLFxuICBTZXREaXJlY3RvcnlDb25maWRlbnRpYWxNdXRhdGlvbixcbiAgU2V0RmlsZUNvbmZpZGVudGlhbE11dGF0aW9uLFxuICBUZW1wRGlyZWN0b3J5UXVlcnksXG4gIFVuYXJjaGl2ZURpcmVjdG9yeU11dGF0aW9uLFxuICBVbmFyY2hpdmVGaWxlTXV0YXRpb24sXG4gIFVwZGF0ZURpcmVjdG9yeU11dGF0aW9uLFxuICBVcGRhdGVGaWxlTXV0YXRpb24sXG59IGZyb20gJy4vaXRlbTIuZ3FsJztcbmltcG9ydCB7XG4gIERpcmVjdG9yeUtleVF1ZXJ5LFxuICBGaWxlS2V5UXVlcnksXG4gIEZpbGVTdGF0ZUtleVF1ZXJ5LFxufSBmcm9tICcuL2l0ZW0yLmdxbC5wcml2YXRlJztcbmltcG9ydCB7XG4gIEFyY2hpdmVEaXJlY3RvcnlPcHRpb25zLFxuICBCZWdpbkRlbGV0ZUNoaWxkSXRlbUxpbmtzV2luZG93T3B0aW9ucyxcbiAgQ2hhbmdlRGlyZWN0b3J5UGFyZW50c09wdGlvbnMsXG4gIENoYW5nZUZpbGVQYXJlbnRzT3B0aW9ucyxcbiAgQ2hhbmdlSXRlbVBhcmVudHNPcHRpb25zLFxuICBDcmVhdGVEaXJlY3RvcnlPcHRpb25zLFxuICBDcmVhdGVEaXJlY3RvcnlUcmVlT3B0aW9ucyxcbiAgQ3JlYXRlRmlsZU9wdGlvbnMsXG4gIERvd25sb2FkRmlsZUNvbnRlbnRPcHRpb25zLFxuICBGaWxlUGFyZW50RGlyZWN0b3J5SW5wdXQsXG4gIElkS2V5UGFpcixcbiAgUGFyZW50RGlyZWN0b3J5SW5wdXQsXG4gIFBhcmVudERpcmVjdG9yeU9wdGlvbnMsXG4gIFBhcmVudFJvb3REaXJlY3RvcnlJbnB1dCxcbiAgUmV2ZXJ0RmlsZU9wdGlvbnMsXG4gIFNldERpcmVjdG9yeUNvbmZpZGVudGlhbE9wdGlvbnMsXG4gIFNldEZpbGVDb25maWRlbnRpYWxPcHRpb25zLFxuICBVbmFyY2hpdmVEaXJlY3RvcnlPcHRpb25zLFxuICBVcGRhdGVEaXJlY3RvcnlPcHRpb25zLFxuICBVcGRhdGVGaWxlT3B0aW9ucyxcbn0gZnJvbSAnLi9pdGVtMi50eXBlcyc7XG5cbkBSdW5PdXRzaWRlQW5ndWxhcih7XG4gIG5nWm9uZU5hbWU6ICduZ1pvbmUnLFxufSlcbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBJdGVtMlNlcnZpY2UgZXh0ZW5kcyBMclNlcnZpY2Uge1xuICAvLyBDYWNoaW5nIHRoZSB0ZW1wIGRpcmVjdG9yeS5cbiAgcHJpdmF0ZSB0ZW1wRGlyZWN0b3J5OiBJZEtleVBhaXIgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgcHJpdmF0ZSBmaWxlVXBsb2FkU2VydmljZTogRmlsZVVwbG9hZFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBrZXlTZXJ2aWNlOiBLZXlTZXJ2aWNlLFxuICAgIHByaXZhdGUga2V5RmFjdG9yeTogS2V5RmFjdG9yeVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBrZXlHcmFwaDogS2V5R3JhcGhTZXJ2aWNlLFxuICAgIHByaXZhdGUgbG9ja1NlcnZpY2U6IExvY2tTZXJ2aWNlLFxuICAgIHByaXZhdGUgYXV0aDJTZXJ2aWNlOiBBdXRoMlNlcnZpY2VcbiAgKSB7XG4gICAgc3VwZXIoaW5qZWN0b3IpO1xuICAgIHRoaXMuYXV0aDJTZXJ2aWNlLmFkZExvZ291dExpc3RlbmVyKCgpID0+IHRoaXMub25Mb2dvdXQoKSk7XG4gIH1cblxuICBzdGF0aWMgVEVNUF9ESVJFQ1RPUllfUExBSU5fTUVUQSA9IHsga2NUeXBlOiAndGVtcCcgfTtcbiAgc3RhdGljIFRFTVBfRElSRUNUT1JZX1BMQUlOX01FVEFfRklMVEVSID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgIGZpbHRlcjogW1xuICAgICAge1xuICAgICAgICBjb250YWluczogSXRlbTJTZXJ2aWNlLlRFTVBfRElSRUNUT1JZX1BMQUlOX01FVEEsXG4gICAgICB9LFxuICAgIF0sXG4gIH0pO1xuXG4gIGFzeW5jIGRvd25sb2FkRmlsZUNvbnRlbnQoXG4gICAgb3B0aW9uczogRG93bmxvYWRGaWxlQ29udGVudE9wdGlvbnNcbiAgKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gICAgY29uc3QgZmlsZUNvbnRlbnQgPSBhd2FpdCB0aGlzLmZpbGVVcGxvYWRTZXJ2aWNlLmRvd25sb2FkRW5jcnlwdGVkRmlsZShcbiAgICAgIG9wdGlvbnMuZmlsZVN0YXRlTm9kZUlkXG4gICAgKTtcblxuICAgIGNvbnN0IGZpbGVTdGF0ZUtleSA9IGF3YWl0IHRoaXMua2V5R3JhcGguZ2V0S2V5KFxuICAgICAgb3B0aW9ucy5maWxlU3RhdGVLZXlJZCxcbiAgICAgICgpID0+IHRoaXMuZ2V0RmlsZVN0YXRlS2V5SWQob3B0aW9ucy5maWxlU3RhdGVOb2RlSWQpXG4gICAgKTtcblxuICAgIHJldHVybiB0aGlzLmtleUdyYXBoLmRlY3J5cHRGcm9tU3RyaW5nKGZpbGVTdGF0ZUtleSwgZmlsZUNvbnRlbnQsIHtcbiAgICAgIHBheWxvYWRUeXBlOiBQYXlsb2FkVHlwZS5VSU5UXzhfQVJSQVksXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBnZXREaXJlY3RvcnlLZXlJZChkaXJlY3RvcnlJZDogTHJSZWxheUlkSW5wdXQpIHtcbiAgICByZXR1cm4gKFxuICAgICAgYXdhaXQgdGhpcy5xdWVyeSh7XG4gICAgICAgIHF1ZXJ5OiBEaXJlY3RvcnlLZXlRdWVyeSxcbiAgICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgICAgaWQ6IGRpcmVjdG9yeUlkLFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICApLmRpcmVjdG9yeS5rZXlJZDtcbiAgfVxuXG4gIGFzeW5jIGdldEZpbGVLZXlJZChmaWxlSWQ6IExyUmVsYXlJZElucHV0KSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGF3YWl0IHRoaXMucXVlcnkoe1xuICAgICAgICBxdWVyeTogRmlsZUtleVF1ZXJ5LFxuICAgICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgICBpZDogZmlsZUlkLFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICApLmZpbGUua2V5SWQ7XG4gIH1cblxuICBhc3luYyBnZXREaXJlY3RvcnlLZXkoXG4gICAgZGlyZWN0b3J5SWQ6IExyUmVsYXlJZElucHV0LFxuICAgIGRpcmVjdG9yeUtleUlkPzogTHJSZWxheUlkSW5wdXRcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMua2V5R3JhcGguZ2V0S2V5KGRpcmVjdG9yeUtleUlkLCAoKSA9PlxuICAgICAgdGhpcy5nZXREaXJlY3RvcnlLZXlJZChkaXJlY3RvcnlJZClcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZ2V0RmlsZUtleShmaWxlSWQ6IExyUmVsYXlJZElucHV0LCBmaWxlS2V5SWQ/OiBMclJlbGF5SWRJbnB1dCkge1xuICAgIHJldHVybiB0aGlzLmtleUdyYXBoLmdldEtleShmaWxlS2V5SWQsICgpID0+IHRoaXMuZ2V0RmlsZUtleUlkKGZpbGVJZCkpO1xuICB9XG5cbiAgY3JlYXRlRGlyZWN0b3J5KG9wdGlvbnM6IENyZWF0ZURpcmVjdG9yeU9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5tdXRhdGUodGhpcy5jcmVhdGVEaXJlY3RvcnlNdXRhdGlvbihvcHRpb25zKSk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVEaXJlY3RvcnlNdXRhdGlvbihvcHRpb25zOiBDcmVhdGVEaXJlY3RvcnlPcHRpb25zKSB7XG4gICAgcmV0dXJuIG5ldyBMck11dGF0aW9uKHtcbiAgICAgIG11dGF0aW9uOiBDcmVhdGVEaXJlY3RvcnlNdXRhdGlvbixcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBpbnB1dDogYXdhaXQgdGhpcy5wcmVwYXJlQ3JlYXRlRGlyZWN0b3J5KG9wdGlvbnMpLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZURpcmVjdG9yeShvcHRpb25zOiBVcGRhdGVEaXJlY3RvcnlPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMubXV0YXRlKHRoaXMudXBkYXRlRGlyZWN0b3J5TXV0YXRpb24ob3B0aW9ucykpO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlRGlyZWN0b3J5TXV0YXRpb24ob3B0aW9uczogVXBkYXRlRGlyZWN0b3J5T3B0aW9ucykge1xuICAgIHJldHVybiBuZXcgTHJNdXRhdGlvbih7XG4gICAgICBtdXRhdGlvbjogVXBkYXRlRGlyZWN0b3J5TXV0YXRpb24sXG4gICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgaW5wdXQ6IGF3YWl0IHRoaXMucHJlcGFyZVVwZGF0ZURpcmVjdG9yeShvcHRpb25zKSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBkZWxldGVEaXJlY3RvcnkoaWQ6IElEKSB7XG4gICAgcmV0dXJuIHRoaXMubXV0YXRlKHRoaXMuZGVsZXRlRGlyZWN0b3J5TXV0YXRpb24oaWQpKTtcbiAgfVxuXG4gIGRlbGV0ZURpcmVjdG9yeU11dGF0aW9uKGlkOiBJRCkge1xuICAgIHJldHVybiBuZXcgTHJNdXRhdGlvbih7XG4gICAgICBtdXRhdGlvbjogRGVsZXRlRGlyZWN0b3J5TXV0YXRpb24sXG4gICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgaW5wdXQ6IHtcbiAgICAgICAgICBkaXJlY3RvcnlJZDogaWQsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlRmlsZShvcHRpb25zOiBDcmVhdGVGaWxlT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm11dGF0ZSh0aGlzLmNyZWF0ZUZpbGVNdXRhdGlvbihvcHRpb25zKSk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVGaWxlTXV0YXRpb24ob3B0aW9uczogQ3JlYXRlRmlsZU9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IExyTXV0YXRpb24oe1xuICAgICAgbXV0YXRpb246IENyZWF0ZUZpbGVNdXRhdGlvbixcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBpbnB1dDogYXdhaXQgdGhpcy5wcmVwYXJlQ3JlYXRlRmlsZShvcHRpb25zKSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICB1cGRhdGVGaWxlKG9wdGlvbnM6IFVwZGF0ZUZpbGVPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMubXV0YXRlKHRoaXMudXBkYXRlRmlsZU11dGF0aW9uKG9wdGlvbnMpKTtcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZUZpbGVNdXRhdGlvbihvcHRpb25zOiBVcGRhdGVGaWxlT3B0aW9ucykge1xuICAgIHJldHVybiBuZXcgTHJNdXRhdGlvbih7XG4gICAgICBtdXRhdGlvbjogVXBkYXRlRmlsZU11dGF0aW9uLFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIGlucHV0OiBhd2FpdCB0aGlzLnByZXBhcmVVcGRhdGVGaWxlKG9wdGlvbnMpLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHJldmVydEZpbGUob3B0aW9uczogUmV2ZXJ0RmlsZU9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5tdXRhdGUodGhpcy5yZXZlcnRGaWxlTXV0YXRpb24ob3B0aW9ucykpO1xuICB9XG5cbiAgYXN5bmMgcmV2ZXJ0RmlsZU11dGF0aW9uKG9wdGlvbnM6IFJldmVydEZpbGVPcHRpb25zKSB7XG4gICAgcmV0dXJuIG5ldyBMck11dGF0aW9uKHtcbiAgICAgIG11dGF0aW9uOiBSZXZlcnRGaWxlTXV0YXRpb24sXG4gICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgaW5wdXQ6IG9wdGlvbnMsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgZGVsZXRlRmlsZShpZDogSUQpIHtcbiAgICByZXR1cm4gdGhpcy5tdXRhdGUodGhpcy5kZWxldGVGaWxlTXV0YXRpb24oaWQpKTtcbiAgfVxuXG4gIGRlbGV0ZUZpbGVNdXRhdGlvbihpZDogSUQpIHtcbiAgICByZXR1cm4gbmV3IExyTXV0YXRpb24oe1xuICAgICAgbXV0YXRpb246IERlbGV0ZUZpbGVNdXRhdGlvbixcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBpbnB1dDoge1xuICAgICAgICAgIGZpbGVJZDogaWQsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgYXJjaGl2ZURpcmVjdG9yeShkaXJlY3RvcnlJZDogc3RyaW5nLCBvcHRpb25zOiBBcmNoaXZlRGlyZWN0b3J5T3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm11dGF0ZSh0aGlzLmFyY2hpdmVEaXJlY3RvcnlNdXRhdGlvbihkaXJlY3RvcnlJZCwgb3B0aW9ucykpO1xuICB9XG5cbiAgYXJjaGl2ZURpcmVjdG9yeU11dGF0aW9uKFxuICAgIGRpcmVjdG9yeUlkOiBzdHJpbmcsXG4gICAgb3B0aW9uczogQXJjaGl2ZURpcmVjdG9yeU9wdGlvbnNcbiAgKSB7XG4gICAgcmV0dXJuIG5ldyBMck11dGF0aW9uKHtcbiAgICAgIG11dGF0aW9uOiBBcmNoaXZlRGlyZWN0b3J5TXV0YXRpb24sXG4gICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgaW5wdXQ6IHtcbiAgICAgICAgICBkaXJlY3RvcnlJZCxcbiAgICAgICAgICByZWN1cnNpdmU6IG9wdGlvbnMucmVjdXJzaXZlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIGFyY2hpdmVGaWxlKGZpbGVJZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMubXV0YXRlKHRoaXMuYXJjaGl2ZUZpbGVNdXRhdGlvbihmaWxlSWQpKTtcbiAgfVxuXG4gIGFyY2hpdmVGaWxlTXV0YXRpb24oZmlsZUlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gbmV3IExyTXV0YXRpb24oe1xuICAgICAgbXV0YXRpb246IEFyY2hpdmVGaWxlTXV0YXRpb24sXG4gICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgaW5wdXQ6IHtcbiAgICAgICAgICBmaWxlSWQsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgdW5hcmNoaXZlRGlyZWN0b3J5KGRpcmVjdG9yeUlkOiBzdHJpbmcsIG9wdGlvbnM6IFVuYXJjaGl2ZURpcmVjdG9yeU9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5tdXRhdGUodGhpcy51bmFyY2hpdmVEaXJlY3RvcnlNdXRhdGlvbihkaXJlY3RvcnlJZCwgb3B0aW9ucykpO1xuICB9XG5cbiAgdW5hcmNoaXZlRGlyZWN0b3J5TXV0YXRpb24oXG4gICAgZGlyZWN0b3J5SWQ6IHN0cmluZyxcbiAgICBvcHRpb25zOiBVbmFyY2hpdmVEaXJlY3RvcnlPcHRpb25zXG4gICkge1xuICAgIHJldHVybiBuZXcgTHJNdXRhdGlvbih7XG4gICAgICBtdXRhdGlvbjogVW5hcmNoaXZlRGlyZWN0b3J5TXV0YXRpb24sXG4gICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgaW5wdXQ6IHtcbiAgICAgICAgICBkaXJlY3RvcnlJZCxcbiAgICAgICAgICByZWN1cnNpdmU6IG9wdGlvbnMucmVjdXJzaXZlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHVuYXJjaGl2ZUZpbGUoZmlsZUlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5tdXRhdGUodGhpcy51bmFyY2hpdmVGaWxlTXV0YXRpb24oZmlsZUlkKSk7XG4gIH1cblxuICB1bmFyY2hpdmVGaWxlTXV0YXRpb24oZmlsZUlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gbmV3IExyTXV0YXRpb24oe1xuICAgICAgbXV0YXRpb246IFVuYXJjaGl2ZUZpbGVNdXRhdGlvbixcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBpbnB1dDoge1xuICAgICAgICAgIGZpbGVJZCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBjaGFuZ2VEaXJlY3RvcnlQYXJlbnRzKG9wdGlvbnM6IENoYW5nZURpcmVjdG9yeVBhcmVudHNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMubXV0YXRlKHRoaXMuY2hhbmdlRGlyZWN0b3J5UGFyZW50c011dGF0aW9uKG9wdGlvbnMpKTtcbiAgfVxuXG4gIGFzeW5jIGNoYW5nZURpcmVjdG9yeVBhcmVudHNNdXRhdGlvbihvcHRpb25zOiBDaGFuZ2VEaXJlY3RvcnlQYXJlbnRzT3B0aW9ucykge1xuICAgIHJldHVybiBuZXcgTHJNdXRhdGlvbih7XG4gICAgICBtdXRhdGlvbjogQ2hhbmdlRGlyZWN0b3J5UGFyZW50c011dGF0aW9uLFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIGlucHV0OiBhd2FpdCB0aGlzLnByZXBhcmVDaGFuZ2VEaXJlY3RvcnlQYXJlbnRzKG9wdGlvbnMpLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGNoYW5nZUZpbGVQYXJlbnRzKG9wdGlvbnM6IENoYW5nZUZpbGVQYXJlbnRzT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm11dGF0ZSh0aGlzLmNoYW5nZUZpbGVQYXJlbnRzTXV0YXRpb24ob3B0aW9ucykpO1xuICB9XG5cbiAgYXN5bmMgY2hhbmdlRmlsZVBhcmVudHNNdXRhdGlvbihvcHRpb25zOiBDaGFuZ2VGaWxlUGFyZW50c09wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IExyTXV0YXRpb24oe1xuICAgICAgbXV0YXRpb246IENoYW5nZUZpbGVQYXJlbnRzTXV0YXRpb24sXG4gICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgaW5wdXQ6IGF3YWl0IHRoaXMucHJlcGFyZUNoYW5nZUZpbGVQYXJlbnRzKG9wdGlvbnMpLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIGJlZ2luRGVsZXRlQ2hpbGRJdGVtTGlua3NXaW5kb3coXG4gICAgb3B0aW9uczogQmVnaW5EZWxldGVDaGlsZEl0ZW1MaW5rc1dpbmRvd09wdGlvbnNcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMubXV0YXRlKHRoaXMuYmVnaW5EZWxldGVDaGlsZEl0ZW1MaW5rc1dpbmRvd011dGF0aW9uKG9wdGlvbnMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTY2hlZHVsZSBjbGVhbnVwIG9mIHRoZSBoYXJkIGxpbmtzIGluIGEgZGlyZWN0b3J5LlxuICAgKiBUaGUgc2VydmVyIHdpbGwgZGVsZXRlIGFsbCBoYXJkIGxpbmsgd2l0aGluIHRoZSBkaXJlY3Rvcnkgd2l0aGluIGEgdGltZSB3aW5kb3c6IHN0YXJ0aW5nIGZyb20gbm93IGFuZFxuICAgKiBlbmRpbmcgYXQgcmVxdWVzdFdpbmRvd01zIGFmdGVyIG5vdy5cbiAgICogVGhlIHNlcnZlciBkZWNpZGVzIF93aGVuXyBpdCB3aWxsIHBlcmZvcm0gdGhlIGRlbGV0ZS4gSXQncyBub3QgZ3VhcmFudGVlZCB0aGF0IGl0IHdpbGwgcGVyZm9ybVxuICAgKiB0aGUgZGVsZXRlIGF0IFwibm93ICsgcmVxdWVzdFdpbmRvd01zXCIsIGJ1dCBpdCB3aWxsIGhhcHBlbiBhdCBzb21lIHRpbWUgYWZ0ZXIgXCJub3cgKyByZXF1ZXN0V2luZG93TXNcIi5cbiAgICogVGhpcyBhbGxvd3MgbXVsdGlwbGUgb3ZlcmxhcHBpbmcgY2FsbHMgdG8gdGhpcyBmdW5jdGlvbiBhbmQgdGhlIHNlcnZlciBhbGxvY2F0ZXMgZW5vdWdoIGZvciBlYWNoIHJlcXVlc3QuXG4gICAqIFRoZSBzZXJ2ZXIgaGFzIGEgc2V0dGluZyB0aGF0IGFsbG93cyBmb3IgYSBtYXhpbXVtIHZhbHVlIG9uIHJlcXVlc3RXaW5kb3dNcy4gSWYgdGhlIHJlcXVlc3RlZCB2YWx1ZVxuICAgKiBpcyBsYXJnZXIgdGhhbiB0aGlzIG1heGltdW0sIHRoZSBjYWxsIHdpbGwgZmFpbC5cbiAgICovXG4gIGFzeW5jIGJlZ2luRGVsZXRlQ2hpbGRJdGVtTGlua3NXaW5kb3dNdXRhdGlvbihcbiAgICBvcHRpb25zOiBCZWdpbkRlbGV0ZUNoaWxkSXRlbUxpbmtzV2luZG93T3B0aW9uc1xuICApIHtcbiAgICByZXR1cm4gbmV3IExyTXV0YXRpb24oe1xuICAgICAgbXV0YXRpb246IEJlZ2luRGVsZXRlQ2hpbGRJdGVtTGlua3NXaW5kb3dNdXRhdGlvbixcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBpbnB1dDogb3B0aW9ucyxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogVGhpcyBtZXRob2QgbWF5IHJhaXNlIFZFUlNJT05fTUlTTUFUQ0ggZXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcmFjZSBjb25kaXRpb25cbiAgICogd2hlbiBtdWx0aXBsZSBjbGllbnRzIHRyeSB0byBjcmVhdGUgdGhlIHRlbXAgZGlyZWN0b3J5LlxuICAgKlxuICAgKiBUT0RPIFRoZXJlIGlzIGEgcmV0cnkgbWVjaGFuaXNtIGluIGdyYXBocWwgd2l0aCBleHBvbmVudGlhbCBiYWNrIG9mZiBidXQgdGhhdCdzIGludGVybmFsLlxuICAgKiBCdXQgbmVlZCB0byB1c2UgYW4gZXhwb25lbnRpYWwgYmFjayBvZmYgbGliIGlmIHdlIHdhbnQgdG8gcmV0cnkgaGVyZS5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIElEIG9mIHRoZSB0ZW1wIGRpcmVjdG9yeVxuICAgKlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlVGVtcERpcmVjdG9yeSgpOiBQcm9taXNlPElkS2V5UGFpcj4ge1xuICAgIGlmICh0aGlzLnRlbXBEaXJlY3RvcnkpIHtcbiAgICAgIHJldHVybiB0aGlzLnRlbXBEaXJlY3Rvcnk7XG4gICAgfVxuXG4gICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCB0aGlzLnF1ZXJ5KHtcbiAgICAgIHF1ZXJ5OiBUZW1wRGlyZWN0b3J5UXVlcnksXG4gICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgcGxhaW5NZXRhOiBJdGVtMlNlcnZpY2UuVEVNUF9ESVJFQ1RPUllfUExBSU5fTUVUQV9GSUxURVIsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKGV4aXN0aW5nLnJvb3REaXJlY3Rvcmllcy5lZGdlcy5sZW5ndGggPiAxKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICBgVGhlcmUgaXMgbW9yZSB0aGFuIDEgdGVtcCBkaXJlY3RvcnkgKHBsYWluTWV0YSBmaWx0ZXI6ICR7SXRlbTJTZXJ2aWNlLlRFTVBfRElSRUNUT1JZX1BMQUlOX01FVEFfRklMVEVSfSlgXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChleGlzdGluZy5yb290RGlyZWN0b3JpZXMuZWRnZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBEb2Vzbid0IGV4aXN0IHlldCwgY3JlYXRlIGl0XG4gICAgICBjb25zdCBjcmVhdGVEaXJlY3RvcnkgPSBhd2FpdCB0aGlzLmNyZWF0ZURpcmVjdG9yeU11dGF0aW9uKHtcbiAgICAgICAgYXNSb290RGlyZWN0b3J5OiB0cnVlLFxuICAgICAgICBwbGFpbk1ldGFKc29uOiBJdGVtMlNlcnZpY2UuVEVNUF9ESVJFQ1RPUllfUExBSU5fTUVUQSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBPcHRpbWlzdGljIGxvY2sgb24gdGhlIGN1cnJlbnQgdXNlci5cbiAgICAgIGNvbnN0IHVwZGF0ZUxvY2sgPSB0aGlzLmxvY2tTZXJ2aWNlLnVwZGF0ZUxvY2tNdXRhdGlvbih7XG4gICAgICAgIHZlcnNpb246IGV4aXN0aW5nLmxvY2s/LnZlcnNpb24sXG4gICAgICB9KTtcblxuICAgICAgLy8gQmVjYXVzZSB0aGlzLm11dGF0ZSgpIG9ubHkgaGFuZGxlcyBzaW1wbGUgdHlwZXMgd2UgbmVlZCB0byB1c2UgdGhlIG1vcmVcbiAgICAgIC8vIGFkdmFuY2VkIHRoaXMubHJHcmFwaFFMLmxyTXV0YXRlKClcbiAgICAgIGNvbnN0IFtjcmVhdGVEaXJlY3RvcnlSZXN1bHRdID0gYXdhaXQgdGhpcy5sckdyYXBoUUwubHJNdXRhdGUoW1xuICAgICAgICBjcmVhdGVEaXJlY3RvcnksXG4gICAgICAgIHVwZGF0ZUxvY2ssXG4gICAgICBdKTtcblxuICAgICAgY29uc3QgeyBpZCwga2V5SWQgfSA9IGNyZWF0ZURpcmVjdG9yeVJlc3VsdC5jcmVhdGVEaXJlY3RvcnkuZGlyZWN0b3J5O1xuXG4gICAgICB0aGlzLnRlbXBEaXJlY3RvcnkgPSB7XG4gICAgICAgIGlkLFxuICAgICAgICBrZXlJZCxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFJldHVybiBleGlzdGluZyB0ZW1wXG4gICAgICBjb25zdCB7IGlkLCBrZXlJZCB9ID0gZXhpc3Rpbmcucm9vdERpcmVjdG9yaWVzLmVkZ2VzWzBdLm5vZGU7XG5cbiAgICAgIHRoaXMudGVtcERpcmVjdG9yeSA9IHtcbiAgICAgICAgaWQsXG4gICAgICAgIGtleUlkLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy50ZW1wRGlyZWN0b3J5O1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlRGlyZWN0b3J5VHJlZShvcHRpb25zOiBDcmVhdGVEaXJlY3RvcnlUcmVlT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm11dGF0ZSh0aGlzLmNyZWF0ZURpcmVjdG9yeVRyZWVNdXRhdGlvbihvcHRpb25zKSk7XG4gIH1cblxuICAvKipcbiAgICogWW91IG11c3QgcnVuIHRoaXMgbXV0YXRpb24gd2l0aGluIHRoZSB0ZW1wIGRpcmVjdG9yeSBjbGVhbnVwIHdpbmRvdyBvbiB0aGVcbiAgICogc2VydmVyLCBvdGhlcndpc2UgdGhlIHRlbXAgZGlyZWN0b3J5IHdpbGwgZ2V0IGNsZWFuZWQgdXAuXG4gICAqXG4gICAqL1xuICBhc3luYyBjcmVhdGVEaXJlY3RvcnlUcmVlTXV0YXRpb24ob3B0aW9uczogQ3JlYXRlRGlyZWN0b3J5VHJlZU9wdGlvbnMpIHtcbiAgICBjb25zdCB0ZW1wRGlyID0gYXdhaXQgdGhpcy5lbnN1cmVUZW1wRGlyZWN0b3J5KCk7XG5cbiAgICAvLyBDbGVhciB0aGUgdGVtcCBkaXJlY3Rvcnkgb2YgdGhlIG9uZXMgd2UgYXJlIGFib3V0IHRvIGNyZWF0ZS5cbiAgICAvLyBOT1RFOiB0aGlzIG11dGF0aW9uIGNhbiBub3QgYmUgbWVyZ2VkIGludG8gYSBzaW5nbGUgbXV0YXRpb24gd2l0aCB0aGVcbiAgICAvLyB0aGUgY3JlYXRlRGlyZWN0b3J5IG11dGF0aW9uIGJlY2F1c2UgaXQgdXNlcyB0aGUgY3VycmVudCBzZXJ2ZXIgdGltZSB0b1xuICAgIC8vIGNsZWFuIHVwLiBTbyBpdCBtdXN0IHN1Y2Nlc3NmdWxseSBjb21wbGV0ZSBiZWZvcmUgdGhlIGNyZWF0aW9uIG9mIHRoZVxuICAgIC8vIGRpcmVjdG9yaWVzLlxuICAgIGF3YWl0IHRoaXMuYmVnaW5EZWxldGVDaGlsZEl0ZW1MaW5rc1dpbmRvdyh7XG4gICAgICBkaXJlY3RvcnlJZDogdGVtcERpci5pZCxcbiAgICAgIHJlcXVlc3RXaW5kb3dNczogb3B0aW9ucy5yZXF1ZXN0V2luZG93TXMsXG4gICAgfSk7XG5cbiAgICAvLyBDcmVhdGUgdGhlIGRpcmVjdG9yeSB0aGF0IGhhcyBjb250ZW50c1xuICAgIGNvbnN0IGRpcmVjdG9yeSA9IChcbiAgICAgIGF3YWl0IHRoaXMuY3JlYXRlRGlyZWN0b3J5KHtcbiAgICAgICAgY2lwaGVyTWV0YUNsZWFySnNvbjogb3B0aW9ucy5jaXBoZXJNZXRhQ2xlYXJKc29uLFxuICAgICAgICBwYXJlbnREaXJlY3RvcmllczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpcmVjdG9yeUlkOiB0ZW1wRGlyLmlkLFxuICAgICAgICAgICAgd3JhcHBpbmdLZXlJZDogdGVtcERpci5rZXlJZCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBwbGFpbk1ldGFKc29uOiBvcHRpb25zLnBsYWluTWV0YUpzb24sXG4gICAgICB9KVxuICAgICkuY3JlYXRlRGlyZWN0b3J5LmRpcmVjdG9yeTtcblxuICAgIC8vIENyZWF0ZSB0aGUgY29udGVudHNcbiAgICBhd2FpdCBvcHRpb25zLmNyZWF0ZUNvbnRlbnQoe1xuICAgICAgaWQ6IGRpcmVjdG9yeS5pZCxcbiAgICAgIGtleUlkOiBkaXJlY3Rvcnkua2V5SWQsXG4gICAgfSk7XG5cbiAgICAvLyBUT0RPIGNsaWVudC1zaWRlIGNoZWNrIGZvciB0aW1lb3V0IG9uIHJlcXVlc3RXaW5kb3dNc1xuICAgIC8vIFRPRE8gcmV0dXJuIHRoZSBzZXJ2ZXIgdGltZSB3aGVyZSBkZWxldGUgaXMgc2NoZWR1bGVkLiBFeHBpcmFibGUgbXV0YXRpb25cblxuICAgIC8vIFJldHVybiB0aGUgbXV0YXRpb24gdGhhdCBtb3ZlcyB0aGUgZGlyZWN0b3J5IGludG8gdGhlIGRzdCBkaXJlY3Rvcmllc1xuICAgIHJldHVybiB0aGlzLmNoYW5nZURpcmVjdG9yeVBhcmVudHNNdXRhdGlvbih7XG4gICAgICBkaXJlY3RvcnlJZDogZGlyZWN0b3J5LmlkLFxuICAgICAgZGlyZWN0b3J5S2V5SWQ6IGRpcmVjdG9yeS5rZXlJZCxcbiAgICAgIHBhcmVudHNUb1JlbW92ZTogW3RlbXBEaXIuaWRdLFxuICAgICAgcGFyZW50c1RvQWRkOiBvcHRpb25zLnBhcmVudERpcmVjdG9yaWVzLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgc2V0RmlsZUNvbmZpZGVudGlhbChvcHRpb25zOiBTZXRGaWxlQ29uZmlkZW50aWFsT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm11dGF0ZSh0aGlzLnNldEZpbGVDb25maWRlbnRpYWxNdXRhdGlvbihvcHRpb25zKSk7XG4gIH1cblxuICBhc3luYyBzZXRGaWxlQ29uZmlkZW50aWFsTXV0YXRpb24ob3B0aW9uczogU2V0RmlsZUNvbmZpZGVudGlhbE9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IExyTXV0YXRpb24oe1xuICAgICAgbXV0YXRpb246IFNldEZpbGVDb25maWRlbnRpYWxNdXRhdGlvbixcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBpbnB1dDoge1xuICAgICAgICAgIGZpbGVJZDogb3B0aW9ucy5maWxlSWQsXG4gICAgICAgICAgY29uZmlkZW50aWFsOiBvcHRpb25zLmNvbmZpZGVudGlhbCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBzZXREaXJlY3RvcnlDb25maWRlbnRpYWwob3B0aW9uczogU2V0RGlyZWN0b3J5Q29uZmlkZW50aWFsT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm11dGF0ZSh0aGlzLnNldERpcmVjdG9yeUNvbmZpZGVudGlhbE11dGF0aW9uKG9wdGlvbnMpKTtcbiAgfVxuXG4gIGFzeW5jIHNldERpcmVjdG9yeUNvbmZpZGVudGlhbE11dGF0aW9uKFxuICAgIG9wdGlvbnM6IFNldERpcmVjdG9yeUNvbmZpZGVudGlhbE9wdGlvbnNcbiAgKSB7XG4gICAgcmV0dXJuIG5ldyBMck11dGF0aW9uKHtcbiAgICAgIG11dGF0aW9uOiBTZXREaXJlY3RvcnlDb25maWRlbnRpYWxNdXRhdGlvbixcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBpbnB1dDoge1xuICAgICAgICAgIGRpcmVjdG9yeUlkOiBvcHRpb25zLmRpcmVjdG9yeUlkLFxuICAgICAgICAgIGNvbmZpZGVudGlhbDogb3B0aW9ucy5jb25maWRlbnRpYWwsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBIZWxwZXJzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwcml2YXRlIGFzeW5jIHByZXBhcmVQYXJlbnREaXJlY3RvcnkoXG4gICAgb3B0aW9uczogUGFyZW50RGlyZWN0b3J5T3B0aW9ucyxcbiAgICBuZXdLZXk6IEpXSy5LZXlcbiAgKTogUHJvbWlzZTxQYXJlbnREaXJlY3RvcnlJbnB1dD4ge1xuICAgIC8vIElmIGRpcmVjdG9yeSdzIGtleSBpcyBub3QgYWxyZWFkeSBpbiB0aGUga2V5IGdyYXBoLCB0aGVuIG5lZWQgdG9cbiAgICAvLyBmZXRjaCB0aGUgZGlyZWN0b3J5J3Mga2V5LlxuICAgIGNvbnN0IHdyYXBwaW5nS2V5ID0gYXdhaXQgdGhpcy5nZXREaXJlY3RvcnlLZXkoXG4gICAgICBvcHRpb25zLmRpcmVjdG9yeUlkLFxuICAgICAgb3B0aW9ucy53cmFwcGluZ0tleUlkXG4gICAgKTtcblxuICAgIHJldHVybiB7XG4gICAgICBkaXJlY3RvcnlJZDogb3B0aW9ucy5kaXJlY3RvcnlJZCxcbiAgICAgIHdyYXBwaW5nS2V5SWQ6IHdyYXBwaW5nS2V5LmlkLFxuICAgICAgd3JhcHBlZEtleTogYXdhaXQgdGhpcy5rZXlHcmFwaC53cmFwS2V5KHdyYXBwaW5nS2V5LCBuZXdLZXkpLFxuICAgICAgbGlua1R5cGU6IG9wdGlvbnMubGlua1R5cGUsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0RmlsZVN0YXRlS2V5SWQoZmlsZVN0YXRlTm9kZUlkOiBMclJlbGF5SWRJbnB1dCkge1xuICAgIHJldHVybiAoXG4gICAgICBhd2FpdCB0aGlzLnF1ZXJ5KHtcbiAgICAgICAgcXVlcnk6IEZpbGVTdGF0ZUtleVF1ZXJ5LFxuICAgICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgICBpZDogZmlsZVN0YXRlTm9kZUlkLFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICApLmZpbGVTdGF0ZS5rZXlJZDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcHJlcGFyZUNyZWF0ZUZpbGVTdGF0ZShcbiAgICBmaWxlS2V5OiBKV0suS2V5LFxuICAgIG9wdGlvbnM6IENyZWF0ZUZpbGVPcHRpb25zIHwgVXBkYXRlRmlsZU9wdGlvbnNcbiAgKSB7XG4gICAgLy8gRWFjaCB2ZXJzaW9uIG9mIHRoZSBmaWxlIGlzIGVuY3J5cHRlZCB1c2luZyBhIG5ldyBrZXkuXG4gICAgY29uc3QgZmlsZVN0YXRlS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xuXG4gICAgY29uc3QgZmlsZUNvbnRlbnQgPVxuICAgICAgb3B0aW9ucy5maWxlICYmIChhd2FpdCB0aGlzLmZpbGVVcGxvYWRTZXJ2aWNlLmxvYWRGaWxlKG9wdGlvbnMuZmlsZSkpO1xuXG4gICAgbGV0IGNvbnRlbnRSZXNvdXJjZTogc3RyaW5nO1xuICAgIGlmIChmaWxlQ29udGVudCkge1xuICAgICAgY29uc3QgY2lwaGVyRmlsZUNvbnRlbnQgPSBhd2FpdCB0aGlzLmtleUdyYXBoLmVuY3J5cHRUb1N0cmluZyhcbiAgICAgICAgZmlsZVN0YXRlS2V5LFxuICAgICAgICBmaWxlQ29udGVudFxuICAgICAgKTtcbiAgICAgIGlmIChvcHRpb25zLnVwbG9hZCkge1xuICAgICAgICBjb250ZW50UmVzb3VyY2UgPSBhd2FpdCBvcHRpb25zLnVwbG9hZChjaXBoZXJGaWxlQ29udGVudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250ZW50UmVzb3VyY2UgPSBhd2FpdCB0aGlzLmZpbGVVcGxvYWRTZXJ2aWNlLnVwbG9hZEVuY3J5cHRlZEZpbGUoe1xuICAgICAgICAgIGVuY3J5cHRlZENvbnRlbnQ6IGNpcGhlckZpbGVDb250ZW50LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uKGF3YWl0IHRoaXMucHJlcGFyZUl0ZW0oZmlsZVN0YXRlS2V5LCBvcHRpb25zKSksXG4gICAgICB3cmFwcGVkU3RhdGVLZXk6IGF3YWl0IHRoaXMua2V5R3JhcGgud3JhcEtleShmaWxlS2V5LCBmaWxlU3RhdGVLZXkpLFxuICAgICAgY29udGVudFJlc291cmNlLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHByZXBhcmVDaGFuZ2VJdGVtUGFyZW50cyhcbiAgICBvcHRpb25zOiBDaGFuZ2VJdGVtUGFyZW50c09wdGlvbnMsXG4gICAgaXRlbUtleTogSldLLktleVxuICApIHtcbiAgICBjb25zdCBwYXJlbnRzVG9BZGQgPSBvcHRpb25zLnBhcmVudHNUb0FkZFxuICAgICAgPyBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBvcHRpb25zLnBhcmVudHNUb0FkZC5tYXAoKHQpID0+XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVQYXJlbnREaXJlY3RvcnkodCwgaXRlbUtleSlcbiAgICAgICAgICApXG4gICAgICAgIClcbiAgICAgIDogW107XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGlyZWN0b3JpZXNUb1JlbW92ZTogb3B0aW9ucy5wYXJlbnRzVG9SZW1vdmUgfHwgW10sXG4gICAgICBkaXJlY3Rvcmllc1RvQWRkOiBwYXJlbnRzVG9BZGQsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcHJlcGFyZUl0ZW0oXG4gICAga2V5OiBKV0suS2V5LFxuICAgIG9wdGlvbnM6IHsgcGxhaW5NZXRhSnNvbj86IEpTT05PYmplY3Q7IGNpcGhlck1ldGFDbGVhckpzb24/OiBKU09OT2JqZWN0IH1cbiAgKSB7XG4gICAgY29uc3QgeyBwbGFpbk1ldGFKc29uLCBjaXBoZXJNZXRhQ2xlYXJKc29uIH0gPSBvcHRpb25zO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHBsYWluTWV0YTogcGxhaW5NZXRhSnNvbiAmJiBKU09OLnN0cmluZ2lmeShwbGFpbk1ldGFKc29uKSxcbiAgICAgIGNpcGhlck1ldGE6XG4gICAgICAgIGNpcGhlck1ldGFDbGVhckpzb24gJiZcbiAgICAgICAgKGF3YWl0IHRoaXMua2V5R3JhcGguZW5jcnlwdFRvU3RyaW5nKGtleSwgY2lwaGVyTWV0YUNsZWFySnNvbikpLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHByZXBhcmVDcmVhdGVEaXJlY3Rvcnkob3B0aW9uczogQ3JlYXRlRGlyZWN0b3J5T3B0aW9ucykge1xuICAgIGNvbnN0IGRpcmVjdG9yeUtleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcbiAgICBvcHRpb25zLnBhcmVudERpcmVjdG9yaWVzID0gb3B0aW9ucy5wYXJlbnREaXJlY3RvcmllcyB8fCBbXTtcbiAgICBpZiAoIW9wdGlvbnMuYXNSb290RGlyZWN0b3J5ICYmICFvcHRpb25zLnBhcmVudERpcmVjdG9yaWVzPy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBLY0JhZEFyZ3VtZW50RXhjZXB0aW9uKFxuICAgICAgICAnQSBuZXcgZGlyZWN0b3J5IG11c3QgYmUgZWl0aGVyIGEgcm9vdCBkaXJlY3Rvcnkgb3IgYSBzdWItZGlyZWN0b3J5LiBTbyB5b3UgbXVzdCBwcm92aWRlIGVpdGhlciBwYXJlbnREaXJlY3RvcmllcyBvciBhc1Jvb3REaXJlY3RvcnkgcGFyYW1ldGVyLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuYXNSb290RGlyZWN0b3J5ICYmIG9wdGlvbnMucGFyZW50RGlyZWN0b3JpZXM/Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEtjQmFkQXJndW1lbnRFeGNlcHRpb24oXG4gICAgICAgICdBIG5ldyBkaXJlY3RvcnkgbXVzdCBiZSBlaXRoZXIgYSByb290IGRpcmVjdG9yeSBvciBhIHN1Yi1kaXJlY3RvcnkuIFNvIHlvdSBjYW4gb25seSBwcm92aWRlIGVpdGhlciBwYXJlbnREaXJlY3RvcmllcyBvciBhc1Jvb3REaXJlY3RvcnkgcGFyYW1ldGVyLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcGFyZW50RGlyZWN0b3JpZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG9wdGlvbnMucGFyZW50RGlyZWN0b3JpZXM/Lm1hcCgodCkgPT5cbiAgICAgICAgdGhpcy5wcmVwYXJlUGFyZW50RGlyZWN0b3J5KHQsIGRpcmVjdG9yeUtleSlcbiAgICAgIClcbiAgICApO1xuXG4gICAgLy8gVE9ETyB0aGlzIGlzIHJhdGhlciBhbiB1bmZvcnR1bmF0ZSBuYW1lLCBjaGFuZ2UgaXQgdG8gYXNSb290RGlyZWN0b3J5LlxuICAgIGxldCBwYXJlbnRSb290RGlyZWN0b3J5OiBQYXJlbnRSb290RGlyZWN0b3J5SW5wdXQ7XG4gICAgaWYgKG9wdGlvbnMuYXNSb290RGlyZWN0b3J5KSB7XG4gICAgICBjb25zdCByb290S2V5ID0gdGhpcy5rZXlTZXJ2aWNlLmN1cnJlbnRSb290S2V5O1xuICAgICAgcGFyZW50Um9vdERpcmVjdG9yeSA9IHtcbiAgICAgICAgd3JhcHBpbmdLZXlJZDogcm9vdEtleS5pZCxcbiAgICAgICAgd3JhcHBlZEtleTogYXdhaXQgdGhpcy5rZXlHcmFwaC53cmFwS2V5KHJvb3RLZXksIGRpcmVjdG9yeUtleSksXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IGl0ZW1JbnB1dCA9IGF3YWl0IHRoaXMucHJlcGFyZUl0ZW0oZGlyZWN0b3J5S2V5LCBvcHRpb25zKTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5pdGVtSW5wdXQsXG4gICAgICBwYXJlbnREaXJlY3RvcmllcyxcbiAgICAgIHBhcmVudFJvb3REaXJlY3RvcnksXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcHJlcGFyZVVwZGF0ZURpcmVjdG9yeShvcHRpb25zOiBVcGRhdGVEaXJlY3RvcnlPcHRpb25zKSB7XG4gICAgY29uc3QgZGlyZWN0b3J5S2V5ID0gYXdhaXQgdGhpcy5nZXREaXJlY3RvcnlLZXkoXG4gICAgICBvcHRpb25zLmRpcmVjdG9yeUlkLFxuICAgICAgb3B0aW9ucy5kaXJlY3RvcnlLZXlJZFxuICAgICk7XG5cbiAgICBjb25zdCBpdGVtSW5wdXQgPSBhd2FpdCB0aGlzLnByZXBhcmVJdGVtKGRpcmVjdG9yeUtleS5qd2ssIG9wdGlvbnMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLml0ZW1JbnB1dCxcbiAgICAgIGRpcmVjdG9yeUlkOiBvcHRpb25zLmRpcmVjdG9yeUlkLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHByZXBhcmVDcmVhdGVGaWxlKG9wdGlvbnM6IENyZWF0ZUZpbGVPcHRpb25zKSB7XG4gICAgY29uc3QgZmlsZUtleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcblxuICAgIGNvbnN0IHBhcmVudERpcmVjdG9yaWVzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBvcHRpb25zLnBhcmVudERpcmVjdG9yaWVzLm1hcChhc3luYyAodCkgPT4ge1xuICAgICAgICBjb25zdCB7IGRpcmVjdG9yeUlkLCB3cmFwcGluZ0tleUlkLCB3cmFwcGVkS2V5IH0gPVxuICAgICAgICAgIGF3YWl0IHRoaXMucHJlcGFyZVBhcmVudERpcmVjdG9yeSh0LCBmaWxlS2V5KTtcbiAgICAgICAgLy8gcmVtYXAgZnJvbSBQYXJlbnREaXJlY3RvcnlJbnB1dCB0byBGaWxlUGFyZW50RGlyZWN0b3J5SW5wdXRcbiAgICAgICAgLy8gVE9ETyB0aGUgc2VydmVyIHNob3VsZCByZWFsbHkganVzdCB1c2Ugd3JhcHBlZEtleSBpbnN0ZWFkIG9mIHdyYXBwZWRGaWxlS2V5XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGlyZWN0b3J5SWQsXG4gICAgICAgICAgd3JhcHBpbmdLZXlJZCxcbiAgICAgICAgICB3cmFwcGVkRmlsZUtleTogd3JhcHBlZEtleSxcbiAgICAgICAgfSBhcyBGaWxlUGFyZW50RGlyZWN0b3J5SW5wdXQ7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICBjb25zdCBpbnB1dCA9IGF3YWl0IHRoaXMucHJlcGFyZUNyZWF0ZUZpbGVTdGF0ZShmaWxlS2V5LCBvcHRpb25zKTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5pbnB1dCxcbiAgICAgIHBhcmVudERpcmVjdG9yaWVzLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHByZXBhcmVVcGRhdGVGaWxlKG9wdGlvbnM6IFVwZGF0ZUZpbGVPcHRpb25zKSB7XG4gICAgY29uc3QgZmlsZUtleSA9IGF3YWl0IHRoaXMuZ2V0RmlsZUtleShvcHRpb25zLmZpbGVJZCwgb3B0aW9ucy5maWxlS2V5SWQpO1xuICAgIGNvbnN0IGlucHV0ID0gYXdhaXQgdGhpcy5wcmVwYXJlQ3JlYXRlRmlsZVN0YXRlKGZpbGVLZXkuandrLCBvcHRpb25zKTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5pbnB1dCxcbiAgICAgIGZpbGVJZDogb3B0aW9ucy5maWxlSWQsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcHJlcGFyZUNoYW5nZURpcmVjdG9yeVBhcmVudHMoXG4gICAgb3B0aW9uczogQ2hhbmdlRGlyZWN0b3J5UGFyZW50c09wdGlvbnNcbiAgKSB7XG4gICAgY29uc3QgZGlyZWN0b3J5S2V5ID0gYXdhaXQgdGhpcy5nZXREaXJlY3RvcnlLZXkoXG4gICAgICBvcHRpb25zLmRpcmVjdG9yeUlkLFxuICAgICAgb3B0aW9ucy5kaXJlY3RvcnlLZXlJZFxuICAgICk7XG5cbiAgICBjb25zdCBpbnB1dCA9IGF3YWl0IHRoaXMucHJlcGFyZUNoYW5nZUl0ZW1QYXJlbnRzKFxuICAgICAgb3B0aW9ucyxcbiAgICAgIGRpcmVjdG9yeUtleS5qd2tcbiAgICApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmlucHV0LFxuICAgICAgZGlyZWN0b3J5SWQ6IG9wdGlvbnMuZGlyZWN0b3J5SWQsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcHJlcGFyZUNoYW5nZUZpbGVQYXJlbnRzKG9wdGlvbnM6IENoYW5nZUZpbGVQYXJlbnRzT3B0aW9ucykge1xuICAgIGNvbnN0IGZpbGVLZXkgPSBhd2FpdCB0aGlzLmdldEZpbGVLZXkob3B0aW9ucy5maWxlSWQsIG9wdGlvbnMuZmlsZUtleUlkKTtcblxuICAgIGNvbnN0IGlucHV0ID0gYXdhaXQgdGhpcy5wcmVwYXJlQ2hhbmdlSXRlbVBhcmVudHMob3B0aW9ucywgZmlsZUtleS5qd2spO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmlucHV0LFxuICAgICAgZmlsZUlkOiBvcHRpb25zLmZpbGVJZCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBvbkxvZ291dCgpIHtcbiAgICAvLyBDbGVhciBhbGwgY2FjaGVkIGRhdGEuXG4gICAgdGhpcy50ZW1wRGlyZWN0b3J5ID0gbnVsbDtcbiAgfVxufVxuIl19
|