@lifeready/core 1.0.15 → 1.0.16
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/README.md +62 -62
- package/bundles/lifeready-core.umd.js +14315 -14315
- package/bundles/lifeready-core.umd.js.map +1 -1
- package/bundles/lifeready-core.umd.min.js.map +1 -1
- package/esm2015/lib/_common/ast.js +40 -40
- package/esm2015/lib/_common/deferred-promise.js +24 -24
- package/esm2015/lib/_common/exceptions.js +157 -157
- package/esm2015/lib/_common/queries.gql.js +190 -190
- package/esm2015/lib/_common/run-outside-angular.js +79 -79
- package/esm2015/lib/_common/types.js +1 -1
- package/esm2015/lib/_common/utils.js +52 -52
- package/esm2015/lib/api/contact-card.gql.js +79 -79
- package/esm2015/lib/api/contact-card.service.js +154 -154
- package/esm2015/lib/api/contact-card2.gql.js +60 -60
- package/esm2015/lib/api/contact-card2.service.js +103 -103
- package/esm2015/lib/api/file.service.js +74 -74
- package/esm2015/lib/api/key-exchange.gql.js +188 -188
- package/esm2015/lib/api/key-exchange.service.js +442 -442
- package/esm2015/lib/api/key-exchange.types.js +18 -18
- package/esm2015/lib/api/key-exchange2.gql.js +171 -171
- package/esm2015/lib/api/key-exchange2.service.js +479 -479
- package/esm2015/lib/api/lock.gql.js +40 -40
- package/esm2015/lib/api/lock.service.js +64 -64
- package/esm2015/lib/api/lr-apollo.service.js +46 -46
- package/esm2015/lib/api/lr-graphql/index.js +6 -6
- package/esm2015/lib/api/lr-graphql/lr-graphql.service.js +155 -155
- package/esm2015/lib/api/lr-graphql/lr-merged-mutation.js +213 -213
- package/esm2015/lib/api/lr-graphql/lr-mutation-base.js +51 -51
- package/esm2015/lib/api/lr-graphql/lr-mutation.js +48 -48
- package/esm2015/lib/api/lr-graphql/lr.service.js +18 -18
- package/esm2015/lib/api/message.service.js +138 -138
- package/esm2015/lib/api/persist.service.js +181 -181
- package/esm2015/lib/api/query-processor/common-processors.service.js +93 -93
- package/esm2015/lib/api/query-processor/index.js +3 -3
- package/esm2015/lib/api/query-processor/query-processor.service.js +262 -262
- package/esm2015/lib/api/query-processor/tp-password-reset-processor.service.js +109 -109
- package/esm2015/lib/api/shared-contact-card.service.js +119 -119
- package/esm2015/lib/api/shared-contact-card2.gql.js +41 -41
- package/esm2015/lib/api/shared-contact-card2.service.js +117 -117
- package/esm2015/lib/api/time.service.js +146 -146
- package/esm2015/lib/api/types/graphql.types.js +7 -7
- package/esm2015/lib/api/types/index.js +3 -3
- package/esm2015/lib/api/types/lr-graphql.types.js +101 -101
- package/esm2015/lib/auth/auth.config.js +57 -57
- package/esm2015/lib/auth/auth.gql.js +48 -48
- package/esm2015/lib/auth/auth.types.js +27 -27
- package/esm2015/lib/auth/idle.service.js +168 -168
- package/esm2015/lib/auth/idle.types.js +7 -7
- package/esm2015/lib/auth/lbop.service.js +355 -355
- package/esm2015/lib/auth/life-ready-auth.service.js +488 -488
- package/esm2015/lib/auth/password.service.js +320 -320
- package/esm2015/lib/auth/register.service.js +172 -172
- package/esm2015/lib/auth/two-factor.service.js +74 -74
- package/esm2015/lib/category/category-meta.service.js +99 -99
- package/esm2015/lib/category/category.gql.js +406 -406
- package/esm2015/lib/category/category.service.js +390 -390
- package/esm2015/lib/category/category.types.js +29 -29
- package/esm2015/lib/cryptography/cryptography.types.js +11 -11
- package/esm2015/lib/cryptography/encryption.service.js +189 -189
- package/esm2015/lib/cryptography/key-factory.service.js +237 -237
- package/esm2015/lib/cryptography/key-graph.service.js +299 -299
- package/esm2015/lib/cryptography/key-meta.service.js +200 -200
- package/esm2015/lib/cryptography/key.service.js +124 -124
- package/esm2015/lib/cryptography/slip39.service.js +169 -169
- package/esm2015/lib/cryptography/web-crypto.service.js +29 -29
- package/esm2015/lib/items2/item2.gql.js +139 -139
- package/esm2015/lib/items2/item2.service.js +498 -498
- package/esm2015/lib/items2/item2.types.js +1 -1
- package/esm2015/lib/life-ready.config.js +84 -84
- package/esm2015/lib/life-ready.module.js +74 -74
- package/esm2015/lib/notification/notification.gql.js +43 -43
- package/esm2015/lib/notification/notification.service.js +118 -118
- package/esm2015/lib/plan/plan.gql.js +123 -123
- package/esm2015/lib/plan/plan.service.js +149 -149
- package/esm2015/lib/plan/plan.types.js +11 -11
- package/esm2015/lib/record/record-attachment.service.js +101 -101
- package/esm2015/lib/record/record.gql.js +179 -179
- package/esm2015/lib/record/record.service.js +206 -206
- package/esm2015/lib/record/record.types.js +15 -15
- package/esm2015/lib/record-type/record-type.service.js +75 -75
- package/esm2015/lib/record-type/record-type.types.js +28 -28
- package/esm2015/lib/scenario/scenario.constants.js +2 -2
- package/esm2015/lib/scenario/scenario.controller.js +34 -34
- package/esm2015/lib/scenario/scenario.gql.js +72 -72
- package/esm2015/lib/scenario/scenario.gql.private.js +198 -198
- package/esm2015/lib/scenario/scenario.service.js +538 -538
- package/esm2015/lib/scenario/scenario.types.js +1 -1
- package/esm2015/lib/trusted-parties/tp-assembly.gql.private.js +22 -22
- package/esm2015/lib/trusted-parties/tp-assembly.js +362 -362
- package/esm2015/lib/trusted-parties/tp-assembly.types.js +1 -1
- package/esm2015/lib/trusted-parties/tp-password-reset-request.service.js +113 -113
- package/esm2015/lib/trusted-parties/tp-password-reset-user.service.js +129 -129
- package/esm2015/lib/trusted-parties/tp-password-reset.constants.js +4 -4
- package/esm2015/lib/trusted-parties/tp-password-reset.controller.js +34 -34
- package/esm2015/lib/trusted-parties/tp-password-reset.gql.js +236 -236
- package/esm2015/lib/trusted-parties/tp-password-reset.service.js +95 -95
- package/esm2015/lib/trusted-parties/trusted-party.gql.js +148 -148
- package/esm2015/lib/trusted-parties/trusted-party.service.js +326 -326
- package/esm2015/lib/trusted-parties/trusted-party.types.js +41 -41
- package/esm2015/lib/trusted-parties/trusted-party2.gql.js +87 -87
- package/esm2015/lib/trusted-parties/trusted-party2.service.js +215 -215
- package/esm2015/lib/users/profile-details.service.js +214 -214
- package/esm2015/lib/users/profile.gql.js +97 -97
- package/esm2015/lib/users/profile.service.js +169 -169
- package/esm2015/lib/users/profile.types.js +34 -34
- package/esm2015/lib/users/user.gql.js +60 -60
- package/esm2015/lib/users/user.service.js +79 -79
- package/esm2015/lib/users/user.types.js +5 -5
- package/esm2015/lifeready-core.js +13 -13
- package/esm2015/public-api.js +71 -71
- package/fesm2015/lifeready-core.js +12258 -12258
- package/fesm2015/lifeready-core.js.map +1 -1
- package/lib/_common/ast.d.ts +11 -11
- package/lib/_common/deferred-promise.d.ts +12 -12
- package/lib/_common/exceptions.d.ts +109 -109
- package/lib/_common/queries.gql.d.ts +10 -10
- package/lib/_common/run-outside-angular.d.ts +14 -14
- package/lib/_common/types.d.ts +10 -10
- package/lib/_common/utils.d.ts +9 -9
- package/lib/api/contact-card.gql.d.ts +7 -7
- package/lib/api/contact-card.service.d.ts +52 -52
- package/lib/api/contact-card2.gql.d.ts +34 -34
- package/lib/api/contact-card2.service.d.ts +49 -49
- package/lib/api/file.service.d.ts +18 -18
- package/lib/api/key-exchange.gql.d.ts +9 -9
- package/lib/api/key-exchange.service.d.ts +39 -39
- package/lib/api/key-exchange.types.d.ts +196 -196
- package/lib/api/key-exchange2.gql.d.ts +125 -125
- package/lib/api/key-exchange2.service.d.ts +187 -187
- package/lib/api/lock.gql.d.ts +27 -27
- package/lib/api/lock.service.d.ts +34 -34
- package/lib/api/lr-apollo.service.d.ts +15 -15
- package/lib/api/lr-graphql/index.d.ts +5 -5
- package/lib/api/lr-graphql/lr-graphql.service.d.ts +60 -60
- package/lib/api/lr-graphql/lr-merged-mutation.d.ts +28 -28
- package/lib/api/lr-graphql/lr-mutation-base.d.ts +28 -28
- package/lib/api/lr-graphql/lr-mutation.d.ts +8 -8
- package/lib/api/lr-graphql/lr.service.d.ts +9 -9
- package/lib/api/message.service.d.ts +58 -58
- package/lib/api/persist.service.d.ts +31 -31
- package/lib/api/query-processor/common-processors.service.d.ts +36 -36
- package/lib/api/query-processor/index.d.ts +2 -2
- package/lib/api/query-processor/query-processor.service.d.ts +18 -18
- package/lib/api/query-processor/tp-password-reset-processor.service.d.ts +15 -15
- package/lib/api/shared-contact-card.service.d.ts +33 -33
- package/lib/api/shared-contact-card2.gql.d.ts +36 -36
- package/lib/api/shared-contact-card2.service.d.ts +45 -45
- package/lib/api/time.service.d.ts +16 -16
- package/lib/api/types/graphql.types.d.ts +29 -29
- package/lib/api/types/index.d.ts +2 -2
- package/lib/api/types/lr-graphql.types.d.ts +502 -502
- package/lib/auth/auth.config.d.ts +5 -5
- package/lib/auth/auth.gql.d.ts +15 -15
- package/lib/auth/auth.types.d.ts +66 -66
- package/lib/auth/idle.service.d.ts +40 -40
- package/lib/auth/idle.types.d.ts +10 -10
- package/lib/auth/lbop.service.d.ts +91 -91
- package/lib/auth/life-ready-auth.service.d.ts +61 -61
- package/lib/auth/password.service.d.ts +78 -78
- package/lib/auth/register.service.d.ts +25 -25
- package/lib/auth/two-factor.service.d.ts +15 -15
- package/lib/category/category-meta.service.d.ts +23 -23
- package/lib/category/category.gql.d.ts +45 -45
- package/lib/category/category.service.d.ts +67 -67
- package/lib/category/category.types.d.ts +79 -79
- package/lib/cryptography/cryptography.types.d.ts +83 -83
- package/lib/cryptography/encryption.service.d.ts +41 -41
- package/lib/cryptography/key-factory.service.d.ts +38 -38
- package/lib/cryptography/key-graph.service.d.ts +41 -41
- package/lib/cryptography/key-meta.service.d.ts +44 -44
- package/lib/cryptography/key.service.d.ts +36 -36
- package/lib/cryptography/slip39.service.d.ts +43 -43
- package/lib/cryptography/web-crypto.service.d.ts +5 -5
- package/lib/items2/item2.gql.d.ts +123 -123
- package/lib/items2/item2.service.d.ts +203 -203
- package/lib/items2/item2.types.d.ts +70 -70
- package/lib/life-ready.config.d.ts +14 -14
- package/lib/life-ready.module.d.ts +5 -5
- package/lib/notification/notification.gql.d.ts +37 -37
- package/lib/notification/notification.service.d.ts +63 -63
- package/lib/plan/plan.gql.d.ts +11 -11
- package/lib/plan/plan.service.d.ts +33 -33
- package/lib/plan/plan.types.d.ts +31 -31
- package/lib/record/record-attachment.service.d.ts +16 -16
- package/lib/record/record.gql.d.ts +14 -14
- package/lib/record/record.service.d.ts +25 -25
- package/lib/record/record.types.d.ts +57 -57
- package/lib/record-type/record-type.service.d.ts +11 -11
- package/lib/record-type/record-type.types.d.ts +50 -50
- package/lib/scenario/scenario.constants.d.ts +1 -1
- package/lib/scenario/scenario.controller.d.ts +10 -10
- package/lib/scenario/scenario.gql.d.ts +62 -62
- package/lib/scenario/scenario.gql.private.d.ts +16 -16
- package/lib/scenario/scenario.service.d.ts +233 -233
- package/lib/scenario/scenario.types.d.ts +50 -50
- package/lib/trusted-parties/tp-assembly.d.ts +177 -177
- package/lib/trusted-parties/tp-assembly.gql.private.d.ts +5 -5
- package/lib/trusted-parties/tp-assembly.types.d.ts +38 -38
- package/lib/trusted-parties/tp-password-reset-request.service.d.ts +20 -20
- package/lib/trusted-parties/tp-password-reset-user.service.d.ts +35 -35
- package/lib/trusted-parties/tp-password-reset.constants.d.ts +3 -3
- package/lib/trusted-parties/tp-password-reset.controller.d.ts +10 -10
- package/lib/trusted-parties/tp-password-reset.gql.d.ts +223 -223
- package/lib/trusted-parties/tp-password-reset.service.d.ts +188 -188
- package/lib/trusted-parties/trusted-party.gql.d.ts +9 -9
- package/lib/trusted-parties/trusted-party.service.d.ts +44 -44
- package/lib/trusted-parties/trusted-party.types.d.ts +102 -102
- package/lib/trusted-parties/trusted-party2.gql.d.ts +79 -79
- package/lib/trusted-parties/trusted-party2.service.d.ts +114 -114
- package/lib/users/profile-details.service.d.ts +21 -21
- package/lib/users/profile.gql.d.ts +11 -11
- package/lib/users/profile.service.d.ts +35 -35
- package/lib/users/profile.types.d.ts +96 -96
- package/lib/users/user.gql.d.ts +9 -9
- package/lib/users/user.service.d.ts +12 -12
- package/lib/users/user.types.d.ts +23 -23
- package/lifeready-core.d.ts +12 -12
- package/package.json +1 -1
- package/public-api.d.ts +67 -67
|
@@ -1,355 +1,355 @@
|
|
|
1
|
-
import { __awaiter } from "tslib";
|
|
2
|
-
import { LrApolloService } from '../api/lr-apollo.service';
|
|
3
|
-
import { HttpClient } from '@angular/common/http';
|
|
4
|
-
import { Inject, Injectable } from '@angular/core';
|
|
5
|
-
import { AuthClass } from '@aws-amplify/auth/lib-esm/Auth';
|
|
6
|
-
import gql from 'graphql-tag';
|
|
7
|
-
import { EncryptionService } from '../cryptography/encryption.service';
|
|
8
|
-
import { KeyGraphService } from '../cryptography/key-graph.service';
|
|
9
|
-
import { KeyService } from '../cryptography/key.service';
|
|
10
|
-
import { LR_CONFIG } from '../life-ready.config';
|
|
11
|
-
import { LrException, LrBadLogicException, } from '../_common/exceptions';
|
|
12
|
-
import { LifeReadyAuthService } from './life-ready-auth.service';
|
|
13
|
-
import { PasswordService } from './password.service';
|
|
14
|
-
import { Slip39Helper } from 'slip39';
|
|
15
|
-
import { KeyFactoryService as KFS } from '../cryptography/key-factory.service';
|
|
16
|
-
import * as i0 from "@angular/core";
|
|
17
|
-
import * as i1 from "../life-ready.config";
|
|
18
|
-
import * as i2 from "@angular/common/http";
|
|
19
|
-
import * as i3 from "../api/lr-apollo.service";
|
|
20
|
-
import * as i4 from "@aws-amplify/auth/lib-esm/Auth";
|
|
21
|
-
import * as i5 from "./life-ready-auth.service";
|
|
22
|
-
import * as i6 from "../cryptography/key-factory.service";
|
|
23
|
-
import * as i7 from "../cryptography/key.service";
|
|
24
|
-
import * as i8 from "../cryptography/encryption.service";
|
|
25
|
-
import * as i9 from "../cryptography/key-graph.service";
|
|
26
|
-
import * as i10 from "./password.service";
|
|
27
|
-
export const CreateLbopQuery = gql `
|
|
28
|
-
mutation CreateLbop($input: CreateLbopInput!) {
|
|
29
|
-
createLbop(input: $input) {
|
|
30
|
-
lbop {
|
|
31
|
-
id
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
`;
|
|
36
|
-
export const DeleteLbopQuery = gql `
|
|
37
|
-
mutation DeleteLbop($input: DeleteLbopInput!) {
|
|
38
|
-
deleteLbop(input: $input) {
|
|
39
|
-
id
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
`;
|
|
43
|
-
export const UpdateLbopQuery = gql `
|
|
44
|
-
mutation UpdateLbop($input: UpdateLbopInput!) {
|
|
45
|
-
updateLbop(input: $input) {
|
|
46
|
-
lbop {
|
|
47
|
-
id
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
`;
|
|
52
|
-
export const LbopQuery = gql `
|
|
53
|
-
query Lbop($id: LrRelayIdInput!) {
|
|
54
|
-
lbop(id: $id) {
|
|
55
|
-
id
|
|
56
|
-
cipherMeta
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
`;
|
|
60
|
-
export const LbopsQuery = gql `
|
|
61
|
-
query Lbops {
|
|
62
|
-
lbops {
|
|
63
|
-
edges {
|
|
64
|
-
node {
|
|
65
|
-
id
|
|
66
|
-
cipherMeta
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
`;
|
|
72
|
-
export class LbopService {
|
|
73
|
-
constructor(config, http, lrApollo, auth, authService, keyFactory, keyService, encryptionService, keyGraph, passwordService) {
|
|
74
|
-
this.config = config;
|
|
75
|
-
this.http = http;
|
|
76
|
-
this.lrApollo = lrApollo;
|
|
77
|
-
this.auth = auth;
|
|
78
|
-
this.authService = authService;
|
|
79
|
-
this.keyFactory = keyFactory;
|
|
80
|
-
this.keyService = keyService;
|
|
81
|
-
this.encryptionService = encryptionService;
|
|
82
|
-
this.keyGraph = keyGraph;
|
|
83
|
-
this.passwordService = passwordService;
|
|
84
|
-
this.CLIENT_NONCE_LENGTH = 32;
|
|
85
|
-
// There are 1024 words (10 bits), so 25 words should give ~256 bits of entropy.
|
|
86
|
-
this.LBOP_WORDS = 25;
|
|
87
|
-
}
|
|
88
|
-
getPartial(lbopString) {
|
|
89
|
-
return lbopString.split(' ')[0];
|
|
90
|
-
}
|
|
91
|
-
remove(id) {
|
|
92
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
-
const res = yield this.lrApollo.mutate({
|
|
94
|
-
mutation: DeleteLbopQuery,
|
|
95
|
-
variables: {
|
|
96
|
-
input: {
|
|
97
|
-
id,
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
return res.deleteLbop.id;
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
update({ id, name }) {
|
|
105
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
106
|
-
const lbop = yield this.get(id);
|
|
107
|
-
lbop.name = name;
|
|
108
|
-
const masterKey = yield this.keyService.getCurrentMasterKey();
|
|
109
|
-
const cipherMeta = yield this.encryptionService.encrypt(masterKey.jwk, lbop);
|
|
110
|
-
const res = yield this.lrApollo.mutate({
|
|
111
|
-
mutation: UpdateLbopQuery,
|
|
112
|
-
variables: {
|
|
113
|
-
input: {
|
|
114
|
-
id,
|
|
115
|
-
cipherMeta: JSON.stringify(cipherMeta),
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
return res.updateLbop;
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
get(id) {
|
|
123
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
124
|
-
const res = yield this.lrApollo.query({
|
|
125
|
-
query: LbopQuery,
|
|
126
|
-
variables: {
|
|
127
|
-
id,
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
const masterKey = yield this.keyService.getCurrentMasterKey();
|
|
131
|
-
const plainCipherMeta = yield this.encryptionService.decrypt(masterKey.jwk, JSON.parse(res.lbop.cipherMeta));
|
|
132
|
-
return Object.assign({ id: res.id }, plainCipherMeta);
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
list() {
|
|
136
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
137
|
-
const res = yield this.lrApollo.query({
|
|
138
|
-
query: LbopsQuery,
|
|
139
|
-
});
|
|
140
|
-
const masterKey = yield this.keyService.getCurrentMasterKey();
|
|
141
|
-
return Promise.all(res.lbops.edges.map((edge) => __awaiter(this, void 0, void 0, function* () {
|
|
142
|
-
const plainCipherMeta = yield this.encryptionService.decrypt(masterKey.jwk, JSON.parse(edge.node.cipherMeta));
|
|
143
|
-
return Object.assign({ id: edge.node.id }, plainCipherMeta);
|
|
144
|
-
})));
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
create({ name }) {
|
|
148
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
-
if (Slip39Helper.WORD_LIST.length !== 1024) {
|
|
150
|
-
throw new LrBadLogicException('Slip39Helper.WORD_LIST.length != 1024');
|
|
151
|
-
}
|
|
152
|
-
// Get existing to make sure there are not duplicate first words
|
|
153
|
-
const lbops = yield this.list();
|
|
154
|
-
// Generate new one
|
|
155
|
-
let lbopString;
|
|
156
|
-
while (true) {
|
|
157
|
-
lbopString = this.keyFactory
|
|
158
|
-
.randomChoices(Slip39Helper.WORD_LIST, this.LBOP_WORDS)
|
|
159
|
-
.join(' ');
|
|
160
|
-
const partial = this.getPartial(lbopString);
|
|
161
|
-
if (!lbops.some((lbop) => lbop.partial === partial)) {
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
const lbopKeyParams = yield this.keyFactory.createLbopKeyParams();
|
|
166
|
-
const lbopKey = (yield this.keyFactory.deriveLbopKey(Object.assign({ password: lbopString }, lbopKeyParams))).jwk;
|
|
167
|
-
const lbopKeyVerifier = yield this.keyFactory.createSignKey();
|
|
168
|
-
const wrappedLbopKeyVerifier = yield this.encryptionService.encrypt(lbopKey, lbopKeyVerifier.toJSON(true));
|
|
169
|
-
// Re-encrypt master key with new key
|
|
170
|
-
const currentUser = yield this.authService.getUser();
|
|
171
|
-
const masterKey = yield this.keyGraph.getKey(currentUser.currentUserKey.masterKey.id);
|
|
172
|
-
const wrappedMasterKey = yield this.encryptionService.encrypt(lbopKey, masterKey.jwk.toJSON(true));
|
|
173
|
-
const meta = Object.assign(Object.assign({}, (name && { name })), { partial: this.getPartial(lbopString) });
|
|
174
|
-
const cipherMeta = yield this.encryptionService.encrypt(masterKey.jwk, meta);
|
|
175
|
-
const res = yield this.lrApollo.mutate({
|
|
176
|
-
mutation: CreateLbopQuery,
|
|
177
|
-
variables: {
|
|
178
|
-
input: {
|
|
179
|
-
cipherMeta: JSON.stringify(cipherMeta),
|
|
180
|
-
lbopKeyParams: JSON.stringify(lbopKeyParams),
|
|
181
|
-
lbopKeyVerifier: JSON.stringify(lbopKeyVerifier.toJSON(true)),
|
|
182
|
-
wrappedLbopKeyVerifier: JSON.stringify(wrappedLbopKeyVerifier),
|
|
183
|
-
masterKeyId: currentUser.currentUserKey.masterKey.id,
|
|
184
|
-
wrappedMasterKey: JSON.stringify(wrappedMasterKey),
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
});
|
|
188
|
-
return Object.assign(Object.assign({}, res.createLbop.lbop), { lbopString });
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
// --------------------------------------------------------------------------------------------------------------------
|
|
192
|
-
// --------------------------------------------------------------------------------------------------------------------
|
|
193
|
-
// Flow below are for password reset via LBOP
|
|
194
|
-
//
|
|
195
|
-
// --Potential Failure Point xxx--
|
|
196
|
-
//
|
|
197
|
-
// Look for the above and you can test by interrupting at these points.
|
|
198
|
-
//
|
|
199
|
-
// The LBOP reset process can be restarted at any point before the call to "set-password/". Once "set-password/" has been
|
|
200
|
-
// called, we assume the client has a short period of time to change the Idp password to the one they've chosen. The "set-password/"
|
|
201
|
-
// will set the Idp password to a temporary random password. The user can no longer login using their current password. If the Idp
|
|
202
|
-
// password change process does not complete or takes longer than the lockout period, the account will not be accessible and a new
|
|
203
|
-
// LBOP password reset must be carried out.
|
|
204
|
-
// --------------------------------------------------------------------------------------------------------------------
|
|
205
|
-
// --------------------------------------------------------------------------------------------------------------------
|
|
206
|
-
verifyLbops(challengeResult, lbopString) {
|
|
207
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
208
|
-
const clientNonce = this.keyFactory.randomString(this.CLIENT_NONCE_LENGTH);
|
|
209
|
-
for (const lbop of challengeResult.lbops) {
|
|
210
|
-
const lbopKey = (yield this.keyFactory.deriveLbopKey(Object.assign({ password: lbopString }, lbop.lbopKeyParams))).jwk;
|
|
211
|
-
// If decoding successful then it's the correct lbop
|
|
212
|
-
try {
|
|
213
|
-
const lbopKeyVerifier = (yield this.encryptionService.decrypt(lbopKey, lbop.wrappedLbopKeyVerifier));
|
|
214
|
-
// Force a bad signature.
|
|
215
|
-
// const serverNonce = challengeResult.challenge.serverNonce + "1",
|
|
216
|
-
const serverNonce = challengeResult.challenge.serverNonce;
|
|
217
|
-
const signedChallenge = yield this.encryptionService.sign(lbopKeyVerifier, {
|
|
218
|
-
serverNonce,
|
|
219
|
-
clientNonce,
|
|
220
|
-
});
|
|
221
|
-
return {
|
|
222
|
-
lbop,
|
|
223
|
-
signedChallenge,
|
|
224
|
-
lbopKey,
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
catch (error) {
|
|
228
|
-
continue;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
throw new LrException({
|
|
232
|
-
source: 'LBOP',
|
|
233
|
-
code: 'INVALID_PASSPHRASE',
|
|
234
|
-
message: 'Invalid passphrase.',
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
verifyContact(params) {
|
|
239
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
240
|
-
const ret = this.http
|
|
241
|
-
.post(`${this.config.authUrl}users/lbop-reset/verify-contact/`, params)
|
|
242
|
-
.toPromise();
|
|
243
|
-
// --Potential Failure Point 1 --
|
|
244
|
-
// The contact verifications are throttled. But otherwise harmless.
|
|
245
|
-
return ret;
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
confirmContact(params) {
|
|
249
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
250
|
-
return this.http
|
|
251
|
-
.post(`${this.config.authUrl}cove/respond/`, {
|
|
252
|
-
claim_id: params.claimId,
|
|
253
|
-
v_code: params.vCode,
|
|
254
|
-
})
|
|
255
|
-
.toPromise();
|
|
256
|
-
// --Potential Failure Point 2 --
|
|
257
|
-
// A verified claim for a contact does not prevent new ones from being generated. So it should be fine to just start again.
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
verify(params) {
|
|
261
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
262
|
-
const challengeResult = yield this.http
|
|
263
|
-
.post(`${this.config.authUrl}users/lbop-reset/get-challenge/`, {
|
|
264
|
-
claimId: params.claimId,
|
|
265
|
-
claimToken: params.claimToken,
|
|
266
|
-
})
|
|
267
|
-
.toPromise();
|
|
268
|
-
// --Potential Failure Point 3 --
|
|
269
|
-
// This does not lock anything. A second call to "get-challenge/" will create a new challenge amd invalidate the first one.
|
|
270
|
-
const { signedChallenge, lbop, lbopKey } = yield this.verifyLbops(challengeResult, params.lbop);
|
|
271
|
-
const res = yield this.http
|
|
272
|
-
.post(`${this.config.authUrl}users/lbop-reset/verify-challenge/`, {
|
|
273
|
-
lbopId: lbop.lbopId,
|
|
274
|
-
signedChallenge,
|
|
275
|
-
})
|
|
276
|
-
.toPromise();
|
|
277
|
-
// --Potential Failure Point 4 --
|
|
278
|
-
// This does not lock anything. So ok to restart.
|
|
279
|
-
return {
|
|
280
|
-
lbopId: lbop.lbopId,
|
|
281
|
-
verifiedToken: res.verifiedToken,
|
|
282
|
-
masterKeyId: res.masterKeyId,
|
|
283
|
-
masterKey: yield KFS.asKey(yield this.encryptionService.decrypt(lbopKey, res.wrappedMasterKey)),
|
|
284
|
-
};
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
setPassword(params) {
|
|
288
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
289
|
-
// Generate the new password derived keys
|
|
290
|
-
const passKeyBundle = yield this.passwordService.createPassKeyBundle(params.newPassword);
|
|
291
|
-
// Re-encrypt master key with new key
|
|
292
|
-
const newWrappedMasterKey = yield this.encryptionService.encrypt(passKeyBundle.passKey, params.masterKey.toJSON(true));
|
|
293
|
-
const result = yield this.http
|
|
294
|
-
.post(`${this.config.authUrl}users/lbop-reset/set-password/`, {
|
|
295
|
-
lbopId: params.lbopId,
|
|
296
|
-
verifiedToken: params.verifiedToken,
|
|
297
|
-
masterKeyId: params.masterKeyId,
|
|
298
|
-
newWrappedMasterKey,
|
|
299
|
-
newPassKey: {
|
|
300
|
-
passKeyParams: passKeyBundle.passKeyParams,
|
|
301
|
-
passIdpParams: passKeyBundle.passIdpParams,
|
|
302
|
-
passIdpVerifierPbk: passKeyBundle.passIdpVerifier.toJSON(),
|
|
303
|
-
wrappedPassIdpVerifierPrk: passKeyBundle.wrappedPassIdpVerifierPrk,
|
|
304
|
-
},
|
|
305
|
-
})
|
|
306
|
-
.toPromise();
|
|
307
|
-
// --Potential Failure Point 5 --
|
|
308
|
-
// A timed mutex is locked. The Idp password change must occur within a period of time.
|
|
309
|
-
// If interrupted here, the user can not login with their old password again. They must
|
|
310
|
-
// start the whole LBOP password reset process again.
|
|
311
|
-
// This call will go through the LR proxy which is OK since the LR server knows
|
|
312
|
-
// the temporary password anyway.
|
|
313
|
-
let user = yield this.auth.signIn(result.username, result.idpPassword, {
|
|
314
|
-
noProxy: 'true',
|
|
315
|
-
});
|
|
316
|
-
if (user.challengeName !== 'NEW_PASSWORD_REQUIRED') {
|
|
317
|
-
throw new LrException({
|
|
318
|
-
message: 'Internal error. Expecting Cognito to have done a password reset.',
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
// --Potential Failure Point 6 --
|
|
322
|
-
// Must restart the LBOP password reset process again.
|
|
323
|
-
// Set new password on Idp
|
|
324
|
-
user = yield this.auth.completeNewPassword(user, this.passwordService.getPassIdpString(passKeyBundle.passIdp), {});
|
|
325
|
-
// --Potential Failure Point 7 --
|
|
326
|
-
// Must restart the LBOP password reset process again.
|
|
327
|
-
yield this.auth.signOut();
|
|
328
|
-
return yield this.http
|
|
329
|
-
.post(`${this.config.authUrl}users/lbop-reset/complete/`, {
|
|
330
|
-
lbopId: params.lbopId,
|
|
331
|
-
setPasswordToken: result.setPasswordToken,
|
|
332
|
-
})
|
|
333
|
-
.toPromise();
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
LbopService.ɵprov = i0.ɵɵdefineInjectable({ factory: function LbopService_Factory() { return new LbopService(i0.ɵɵinject(i1.LR_CONFIG), i0.ɵɵinject(i2.HttpClient), i0.ɵɵinject(i3.LrApolloService), i0.ɵɵinject(i4.AuthClass), i0.ɵɵinject(i5.LifeReadyAuthService), i0.ɵɵinject(i6.KeyFactoryService), i0.ɵɵinject(i7.KeyService), i0.ɵɵinject(i8.EncryptionService), i0.ɵɵinject(i9.KeyGraphService), i0.ɵɵinject(i10.PasswordService)); }, token: LbopService, providedIn: "root" });
|
|
338
|
-
LbopService.decorators = [
|
|
339
|
-
{ type: Injectable, args: [{
|
|
340
|
-
providedIn: 'root',
|
|
341
|
-
},] }
|
|
342
|
-
];
|
|
343
|
-
LbopService.ctorParameters = () => [
|
|
344
|
-
{ type: undefined, decorators: [{ type: Inject, args: [LR_CONFIG,] }] },
|
|
345
|
-
{ type: HttpClient },
|
|
346
|
-
{ type: LrApolloService },
|
|
347
|
-
{ type: AuthClass },
|
|
348
|
-
{ type: LifeReadyAuthService },
|
|
349
|
-
{ type: KFS },
|
|
350
|
-
{ type: KeyService },
|
|
351
|
-
{ type: EncryptionService },
|
|
352
|
-
{ type: KeyGraphService },
|
|
353
|
-
{ type: PasswordService }
|
|
354
|
-
];
|
|
355
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGJvcC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IkM6L1Byb2plY3RzL2tjLWNsaWVudC9wcm9qZWN0cy9jb3JlL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9hdXRoL2xib3Auc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDM0QsT0FBTyxHQUFHLE1BQU0sYUFBYSxDQUFDO0FBRTlCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDekQsT0FBTyxFQUFtQixTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRSxPQUFPLEVBQ0wsV0FBVyxFQUVYLG1CQUFtQixHQUNwQixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxpQkFBaUIsSUFBSSxHQUFHLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7Ozs7Ozs7Ozs7O0FBeUUvRSxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsR0FBRyxDQUFBOzs7Ozs7OztDQVFqQyxDQUFDO0FBTUYsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLEdBQUcsQ0FBQTs7Ozs7O0NB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Q2pCLENBQUM7S0FBQTs7OztZQTNYRixVQUFVLFNBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7Ozs0Q0FPSSxNQUFNLFNBQUMsU0FBUztZQXRLWixVQUFVO1lBRFYsZUFBZTtZQUdmLFNBQVM7WUFZVCxvQkFBb0I7WUFHQyxHQUFHO1lBVnhCLFVBQVU7WUFGVixpQkFBaUI7WUFDakIsZUFBZTtZQVNmLGVBQWUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMckFwb2xsb1NlcnZpY2UgfSBmcm9tICcuLi9hcGkvbHItYXBvbGxvLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQXV0aENsYXNzIH0gZnJvbSAnQGF3cy1hbXBsaWZ5L2F1dGgvbGliLWVzbS9BdXRoJztcclxuaW1wb3J0IGdxbCBmcm9tICdncmFwaHFsLXRhZyc7XHJcbmltcG9ydCB7IEpXSyB9IGZyb20gJ25vZGUtam9zZSc7XHJcbmltcG9ydCB7IEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vY3J5cHRvZ3JhcGh5L2VuY3J5cHRpb24uc2VydmljZSc7XHJcbmltcG9ydCB7IEtleUdyYXBoU2VydmljZSB9IGZyb20gJy4uL2NyeXB0b2dyYXBoeS9rZXktZ3JhcGguc2VydmljZSc7XHJcbmltcG9ydCB7IEtleVNlcnZpY2UgfSBmcm9tICcuLi9jcnlwdG9ncmFwaHkva2V5LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMaWZlUmVhZHlDb25maWcsIExSX0NPTkZJRyB9IGZyb20gJy4uL2xpZmUtcmVhZHkuY29uZmlnJztcclxuaW1wb3J0IHtcclxuICBMckV4Y2VwdGlvbixcclxuICBMckVycm9yQ29kZSxcclxuICBMckJhZExvZ2ljRXhjZXB0aW9uLFxyXG59IGZyb20gJy4uL19jb21tb24vZXhjZXB0aW9ucyc7XHJcbmltcG9ydCB7IExpZmVSZWFkeUF1dGhTZXJ2aWNlIH0gZnJvbSAnLi9saWZlLXJlYWR5LWF1dGguc2VydmljZSc7XHJcbmltcG9ydCB7IFBhc3N3b3JkU2VydmljZSB9IGZyb20gJy4vcGFzc3dvcmQuc2VydmljZSc7XHJcbmltcG9ydCB7IFNsaXAzOUhlbHBlciB9IGZyb20gJ3NsaXAzOSc7XHJcbmltcG9ydCB7IEtleUZhY3RvcnlTZXJ2aWNlIGFzIEtGUyB9IGZyb20gJy4uL2NyeXB0b2dyYXBoeS9rZXktZmFjdG9yeS5zZXJ2aWNlJztcclxuXHJcbmludGVyZmFjZSBTZXRQYXNzd29yZEFwaVJlc3VsdCB7XHJcbiAgdXNlcm5hbWU6IHN0cmluZztcclxuICBpZHBQYXNzd29yZDogc3RyaW5nO1xyXG4gIHNldFBhc3N3b3JkVG9rZW46IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBTZXRQYXNzd29yZFBhcmFtcyB7XHJcbiAgbGJvcElkOiBzdHJpbmc7XHJcbiAgbmV3UGFzc3dvcmQ6IHN0cmluZztcclxuICB2ZXJpZmllZFRva2VuOiBzdHJpbmc7XHJcbiAgbWFzdGVyS2V5SWQ6IHN0cmluZztcclxuICBtYXN0ZXJLZXk6IEpXSy5LZXk7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVmVyaWZ5Q29udGFjdFBhcmFtcyB7XHJcbiAgZW1haWw/OiBzdHJpbmc7XHJcbiAgcGhvbmU/OiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVmVyaWZ5Q29udGFjdFJlc3VsdCB7XHJcbiAgLy8gVGhlIGNsYWltX2lkIGlkZW50aWZpZXMgdGhlIEVtYWlsL1NNUyBjb25maXJtYXRpb25cclxuICBjbGFpbUlkOiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQ29uZmlybUNvbnRhY3RQYXJhbXMge1xyXG4gIGNsYWltSWQ6IHN0cmluZztcclxuICB2Q29kZTogc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIENvbmZpcm1Db250YWN0UmVzdWx0IHtcclxuICAvLyBUaGUgdG9rZW4gdG8gcHJvdmUgdGhlIGNsaWVudCBoYWQgdGhlIGNvcnJlY3QgY29uZmlybWF0aW9uIGNvZGUuXHJcbiAgdG9rZW46IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBWZXJpZnlQYXJhbXMge1xyXG4gIGNsYWltSWQ6IHN0cmluZztcclxuICBjbGFpbVRva2VuOiBzdHJpbmc7XHJcbiAgbGJvcDogc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFZlcmlmeVJlc3VsdCB7XHJcbiAgLy8gdXNlcklkOiBzdHJpbmc7XHJcbiAgbGJvcElkOiBzdHJpbmc7XHJcbiAgdmVyaWZpZWRUb2tlbjogc3RyaW5nO1xyXG4gIG1hc3RlcktleUlkOiBzdHJpbmc7XHJcbiAgbWFzdGVyS2V5OiBKV0suS2V5O1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIENoYWxsZW5nZVJlc3VsdCB7XHJcbiAgY2hhbGxlbmdlOiBhbnk7XHJcbiAgbGJvcHM6IGFueTtcclxuICAvLyB1c2VySWQ6IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBMYm9wIHtcclxuICBpZDogc3RyaW5nO1xyXG4gIHBhcnRpYWw/OiBzdHJpbmc7XHJcbiAgbmFtZT86IHN0cmluZztcclxuICBsYm9wU3RyaW5nPzogc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUxib3BQYXJhbXMge1xyXG4gIG5hbWU/OiBzdHJpbmc7XHJcbn1cclxuXHJcbmludGVyZmFjZSBDcmVhdGVMYm9wUXVlcnkge1xyXG4gIGNyZWF0ZUxib3A6IHtcclxuICAgIGxib3A6IExib3A7XHJcbiAgfTtcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IENyZWF0ZUxib3BRdWVyeSA9IGdxbGBcclxuICBtdXRhdGlvbiBDcmVhdGVMYm9wKCRpbnB1dDogQ3JlYXRlTGJvcElucHV0ISkge1xyXG4gICAgY3JlYXRlTGJvcChpbnB1dDogJGlucHV0KSB7XHJcbiAgICAgIGxib3Age1xyXG4gICAgICAgIGlkXHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbmA7XHJcblxyXG5pbnRlcmZhY2UgRGVsZXRlTGJvcFF1ZXJ5IHtcclxuICBkZWxldGVMYm9wOiBMYm9wO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgRGVsZXRlTGJvcFF1ZXJ5ID0gZ3FsYFxyXG4gIG11dGF0aW9uIERlbGV0ZUxib3AoJGlucHV0OiBEZWxldGVMYm9wSW5wdXQhKSB7XHJcbiAgICBkZWxldGVMYm9wKGlucHV0OiAkaW5wdXQpIHtcclxuICAgICAgaWRcclxuICAgIH1cclxuICB9XHJcbmA7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFVwZGF0ZUxib3BQYXJhbXMge1xyXG4gIGlkOiBzdHJpbmc7XHJcbiAgbmFtZTogc3RyaW5nO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgVXBkYXRlTGJvcFF1ZXJ5IHtcclxuICB1cGRhdGVMYm9wOiBMYm9wO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgVXBkYXRlTGJvcFF1ZXJ5ID0gZ3FsYFxyXG4gIG11dGF0aW9uIFVwZGF0ZUxib3AoJGlucHV0OiBVcGRhdGVMYm9wSW5wdXQhKSB7XHJcbiAgICB1cGRhdGVMYm9wKGlucHV0OiAkaW5wdXQpIHtcclxuICAgICAgbGJvcCB7XHJcbiAgICAgICAgaWRcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuYDtcclxuXHJcbmV4cG9ydCBjb25zdCBMYm9wUXVlcnkgPSBncWxgXHJcbiAgcXVlcnkgTGJvcCgkaWQ6IExyUmVsYXlJZElucHV0ISkge1xyXG4gICAgbGJvcChpZDogJGlkKSB7XHJcbiAgICAgIGlkXHJcbiAgICAgIGNpcGhlck1ldGFcclxuICAgIH1cclxuICB9XHJcbmA7XHJcblxyXG5pbnRlcmZhY2UgTGJvcHNRdWVyeSB7XHJcbiAgbGJvcHM6IGFueTtcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IExib3BzUXVlcnkgPSBncWxgXHJcbiAgcXVlcnkgTGJvcHMge1xyXG4gICAgbGJvcHMge1xyXG4gICAgICBlZGdlcyB7XHJcbiAgICAgICAgbm9kZSB7XHJcbiAgICAgICAgICBpZFxyXG4gICAgICAgICAgY2lwaGVyTWV0YVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuYDtcclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCcsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBMYm9wU2VydmljZSB7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBDTElFTlRfTk9OQ0VfTEVOR1RIID0gMzI7XHJcbiAgLy8gVGhlcmUgYXJlIDEwMjQgd29yZHMgKDEwIGJpdHMpLCBzbyAyNSB3b3JkcyBzaG91bGQgZ2l2ZSB+MjU2IGJpdHMgb2YgZW50cm9weS5cclxuICBwcml2YXRlIHJlYWRvbmx5IExCT1BfV09SRFMgPSAyNTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBASW5qZWN0KExSX0NPTkZJRykgcHJpdmF0ZSBjb25maWc6IExpZmVSZWFkeUNvbmZpZyxcclxuICAgIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCxcclxuICAgIHByaXZhdGUgbHJBcG9sbG86IExyQXBvbGxvU2VydmljZSxcclxuICAgIHByaXZhdGUgYXV0aDogQXV0aENsYXNzLFxyXG4gICAgcHJpdmF0ZSBhdXRoU2VydmljZTogTGlmZVJlYWR5QXV0aFNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGtleUZhY3Rvcnk6IEtGUyxcclxuICAgIHByaXZhdGUga2V5U2VydmljZTogS2V5U2VydmljZSxcclxuICAgIHByaXZhdGUgZW5jcnlwdGlvblNlcnZpY2U6IEVuY3J5cHRpb25TZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBrZXlHcmFwaDogS2V5R3JhcGhTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBwYXNzd29yZFNlcnZpY2U6IFBhc3N3b3JkU2VydmljZVxyXG4gICkge31cclxuXHJcbiAgcHJpdmF0ZSBnZXRQYXJ0aWFsKGxib3BTdHJpbmc6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gbGJvcFN0cmluZy5zcGxpdCgnICcpWzBdO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIHJlbW92ZShpZDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcclxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMubHJBcG9sbG8ubXV0YXRlPGFueT4oe1xyXG4gICAgICBtdXRhdGlvbjogRGVsZXRlTGJvcFF1ZXJ5LFxyXG4gICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICBpbnB1dDoge1xyXG4gICAgICAgICAgaWQsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiByZXMuZGVsZXRlTGJvcC5pZDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyB1cGRhdGUoeyBpZCwgbmFtZSB9OiBVcGRhdGVMYm9wUGFyYW1zKTogUHJvbWlzZTxMYm9wPiB7XHJcbiAgICBjb25zdCBsYm9wID0gYXdhaXQgdGhpcy5nZXQoaWQpO1xyXG4gICAgbGJvcC5uYW1lID0gbmFtZTtcclxuXHJcbiAgICBjb25zdCBtYXN0ZXJLZXkgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudE1hc3RlcktleSgpO1xyXG4gICAgY29uc3QgY2lwaGVyTWV0YSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgbWFzdGVyS2V5Lmp3ayxcclxuICAgICAgbGJvcFxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmxyQXBvbGxvLm11dGF0ZTxVcGRhdGVMYm9wUXVlcnk+KHtcclxuICAgICAgbXV0YXRpb246IFVwZGF0ZUxib3BRdWVyeSxcclxuICAgICAgdmFyaWFibGVzOiB7XHJcbiAgICAgICAgaW5wdXQ6IHtcclxuICAgICAgICAgIGlkLFxyXG4gICAgICAgICAgY2lwaGVyTWV0YTogSlNPTi5zdHJpbmdpZnkoY2lwaGVyTWV0YSksXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiByZXMudXBkYXRlTGJvcDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyBnZXQoaWQ6IHN0cmluZyk6IFByb21pc2U8TGJvcD4ge1xyXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5sckFwb2xsby5xdWVyeTxhbnk+KHtcclxuICAgICAgcXVlcnk6IExib3BRdWVyeSxcclxuICAgICAgdmFyaWFibGVzOiB7XHJcbiAgICAgICAgaWQsXHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuXHJcbiAgICBjb25zdCBtYXN0ZXJLZXkgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudE1hc3RlcktleSgpO1xyXG5cclxuICAgIGNvbnN0IHBsYWluQ2lwaGVyTWV0YSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZGVjcnlwdChcclxuICAgICAgbWFzdGVyS2V5Lmp3ayxcclxuICAgICAgSlNPTi5wYXJzZShyZXMubGJvcC5jaXBoZXJNZXRhKVxyXG4gICAgKTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBpZDogcmVzLmlkLFxyXG4gICAgICAuLi5wbGFpbkNpcGhlck1ldGEsXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIGxpc3QoKTogUHJvbWlzZTxMYm9wW10+IHtcclxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMubHJBcG9sbG8ucXVlcnk8TGJvcHNRdWVyeT4oe1xyXG4gICAgICBxdWVyeTogTGJvcHNRdWVyeSxcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50TWFzdGVyS2V5KCk7XHJcblxyXG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFxyXG4gICAgICByZXMubGJvcHMuZWRnZXMubWFwKGFzeW5jIChlZGdlKSA9PiB7XHJcbiAgICAgICAgY29uc3QgcGxhaW5DaXBoZXJNZXRhID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxyXG4gICAgICAgICAgbWFzdGVyS2V5Lmp3ayxcclxuICAgICAgICAgIEpTT04ucGFyc2UoZWRnZS5ub2RlLmNpcGhlck1ldGEpXHJcbiAgICAgICAgKTtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgaWQ6IGVkZ2Uubm9kZS5pZCxcclxuICAgICAgICAgIC4uLnBsYWluQ2lwaGVyTWV0YSxcclxuICAgICAgICB9O1xyXG4gICAgICB9KVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyBjcmVhdGUoeyBuYW1lIH06IENyZWF0ZUxib3BQYXJhbXMpOiBQcm9taXNlPExib3A+IHtcclxuICAgIGlmIChTbGlwMzlIZWxwZXIuV09SRF9MSVNULmxlbmd0aCAhPT0gMTAyNCkge1xyXG4gICAgICB0aHJvdyBuZXcgTHJCYWRMb2dpY0V4Y2VwdGlvbignU2xpcDM5SGVscGVyLldPUkRfTElTVC5sZW5ndGggIT0gMTAyNCcpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEdldCBleGlzdGluZyB0byBtYWtlIHN1cmUgdGhlcmUgYXJlIG5vdCBkdXBsaWNhdGUgZmlyc3Qgd29yZHNcclxuICAgIGNvbnN0IGxib3BzID0gYXdhaXQgdGhpcy5saXN0KCk7XHJcblxyXG4gICAgLy8gR2VuZXJhdGUgbmV3IG9uZVxyXG4gICAgbGV0IGxib3BTdHJpbmc7XHJcbiAgICB3aGlsZSAodHJ1ZSkge1xyXG4gICAgICBsYm9wU3RyaW5nID0gdGhpcy5rZXlGYWN0b3J5XHJcbiAgICAgICAgLnJhbmRvbUNob2ljZXMoU2xpcDM5SGVscGVyLldPUkRfTElTVCwgdGhpcy5MQk9QX1dPUkRTKVxyXG4gICAgICAgIC5qb2luKCcgJyk7XHJcbiAgICAgIGNvbnN0IHBhcnRpYWwgPSB0aGlzLmdldFBhcnRpYWwobGJvcFN0cmluZyk7XHJcblxyXG4gICAgICBpZiAoIWxib3BzLnNvbWUoKGxib3ApID0+IGxib3AucGFydGlhbCA9PT0gcGFydGlhbCkpIHtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGxib3BLZXlQYXJhbXMgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlTGJvcEtleVBhcmFtcygpO1xyXG4gICAgY29uc3QgbGJvcEtleSA9IChcclxuICAgICAgYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmRlcml2ZUxib3BLZXkoe1xyXG4gICAgICAgIHBhc3N3b3JkOiBsYm9wU3RyaW5nLFxyXG4gICAgICAgIC4uLmxib3BLZXlQYXJhbXMsXHJcbiAgICAgIH0pXHJcbiAgICApLmp3aztcclxuXHJcbiAgICBjb25zdCBsYm9wS2V5VmVyaWZpZXIgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlU2lnbktleSgpO1xyXG4gICAgY29uc3Qgd3JhcHBlZExib3BLZXlWZXJpZmllciA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgbGJvcEtleSxcclxuICAgICAgbGJvcEtleVZlcmlmaWVyLnRvSlNPTih0cnVlKVxyXG4gICAgKTtcclxuXHJcbiAgICAvLyBSZS1lbmNyeXB0IG1hc3RlciBrZXkgd2l0aCBuZXcga2V5XHJcbiAgICBjb25zdCBjdXJyZW50VXNlciA9IGF3YWl0IHRoaXMuYXV0aFNlcnZpY2UuZ2V0VXNlcigpO1xyXG4gICAgY29uc3QgbWFzdGVyS2V5ID0gYXdhaXQgdGhpcy5rZXlHcmFwaC5nZXRLZXkoXHJcbiAgICAgIGN1cnJlbnRVc2VyLmN1cnJlbnRVc2VyS2V5Lm1hc3RlcktleS5pZFxyXG4gICAgKTtcclxuICAgIGNvbnN0IHdyYXBwZWRNYXN0ZXJLZXkgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgIGxib3BLZXksXHJcbiAgICAgIG1hc3RlcktleS5qd2sudG9KU09OKHRydWUpXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IG1ldGEgPSB7XHJcbiAgICAgIC4uLihuYW1lICYmIHsgbmFtZSB9KSxcclxuICAgICAgcGFydGlhbDogdGhpcy5nZXRQYXJ0aWFsKGxib3BTdHJpbmcpLFxyXG4gICAgfTtcclxuICAgIGNvbnN0IGNpcGhlck1ldGEgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgIG1hc3RlcktleS5qd2ssXHJcbiAgICAgIG1ldGFcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5sckFwb2xsby5tdXRhdGU8Q3JlYXRlTGJvcFF1ZXJ5Pih7XHJcbiAgICAgIG11dGF0aW9uOiBDcmVhdGVMYm9wUXVlcnksXHJcbiAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgIGlucHV0OiB7XHJcbiAgICAgICAgICBjaXBoZXJNZXRhOiBKU09OLnN0cmluZ2lmeShjaXBoZXJNZXRhKSxcclxuICAgICAgICAgIGxib3BLZXlQYXJhbXM6IEpTT04uc3RyaW5naWZ5KGxib3BLZXlQYXJhbXMpLFxyXG4gICAgICAgICAgbGJvcEtleVZlcmlmaWVyOiBKU09OLnN0cmluZ2lmeShsYm9wS2V5VmVyaWZpZXIudG9KU09OKHRydWUpKSxcclxuICAgICAgICAgIHdyYXBwZWRMYm9wS2V5VmVyaWZpZXI6IEpTT04uc3RyaW5naWZ5KHdyYXBwZWRMYm9wS2V5VmVyaWZpZXIpLFxyXG4gICAgICAgICAgbWFzdGVyS2V5SWQ6IGN1cnJlbnRVc2VyLmN1cnJlbnRVc2VyS2V5Lm1hc3RlcktleS5pZCxcclxuICAgICAgICAgIHdyYXBwZWRNYXN0ZXJLZXk6IEpTT04uc3RyaW5naWZ5KHdyYXBwZWRNYXN0ZXJLZXkpLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAuLi5yZXMuY3JlYXRlTGJvcC5sYm9wLFxyXG4gICAgICBsYm9wU3RyaW5nLFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAvLyBGbG93IGJlbG93IGFyZSBmb3IgcGFzc3dvcmQgcmVzZXQgdmlhIExCT1BcclxuICAvL1xyXG4gIC8vIC0tUG90ZW50aWFsIEZhaWx1cmUgUG9pbnQgeHh4LS1cclxuICAvL1xyXG4gIC8vIExvb2sgZm9yIHRoZSBhYm92ZSBhbmQgeW91IGNhbiB0ZXN0IGJ5IGludGVycnVwdGluZyBhdCB0aGVzZSBwb2ludHMuXHJcbiAgLy9cclxuICAvLyBUaGUgTEJPUCByZXNldCBwcm9jZXNzIGNhbiBiZSByZXN0YXJ0ZWQgYXQgYW55IHBvaW50IGJlZm9yZSB0aGUgY2FsbCB0byBcInNldC1wYXNzd29yZC9cIi4gT25jZSBcInNldC1wYXNzd29yZC9cIiBoYXMgYmVlblxyXG4gIC8vIGNhbGxlZCwgd2UgYXNzdW1lIHRoZSBjbGllbnQgaGFzIGEgc2hvcnQgcGVyaW9kIG9mIHRpbWUgdG8gY2hhbmdlIHRoZSBJZHAgcGFzc3dvcmQgdG8gdGhlIG9uZSB0aGV5J3ZlIGNob3Nlbi4gVGhlIFwic2V0LXBhc3N3b3JkL1wiXHJcbiAgLy8gd2lsbCBzZXQgdGhlIElkcCBwYXNzd29yZCB0byBhIHRlbXBvcmFyeSByYW5kb20gcGFzc3dvcmQuIFRoZSB1c2VyIGNhbiBubyBsb25nZXIgbG9naW4gdXNpbmcgdGhlaXIgY3VycmVudCBwYXNzd29yZC4gSWYgdGhlIElkcFxyXG4gIC8vIHBhc3N3b3JkIGNoYW5nZSBwcm9jZXNzIGRvZXMgbm90IGNvbXBsZXRlIG9yIHRha2VzIGxvbmdlciB0aGFuIHRoZSBsb2Nrb3V0IHBlcmlvZCwgdGhlIGFjY291bnQgd2lsbCBub3QgYmUgYWNjZXNzaWJsZSBhbmQgYSBuZXdcclxuICAvLyBMQk9QIHBhc3N3b3JkIHJlc2V0IG11c3QgYmUgY2FycmllZCBvdXQuXHJcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gIHByaXZhdGUgYXN5bmMgdmVyaWZ5TGJvcHMoXHJcbiAgICBjaGFsbGVuZ2VSZXN1bHQ6IENoYWxsZW5nZVJlc3VsdCxcclxuICAgIGxib3BTdHJpbmc6IHN0cmluZ1xyXG4gICk6IFByb21pc2U8eyBsYm9wOiBhbnk7IHNpZ25lZENoYWxsZW5nZTogYW55OyBsYm9wS2V5OiBKV0suS2V5IH0+IHtcclxuICAgIGNvbnN0IGNsaWVudE5vbmNlID0gdGhpcy5rZXlGYWN0b3J5LnJhbmRvbVN0cmluZyh0aGlzLkNMSUVOVF9OT05DRV9MRU5HVEgpO1xyXG5cclxuICAgIGZvciAoY29uc3QgbGJvcCBvZiBjaGFsbGVuZ2VSZXN1bHQubGJvcHMpIHtcclxuICAgICAgY29uc3QgbGJvcEtleSA9IChcclxuICAgICAgICBhd2FpdCB0aGlzLmtleUZhY3RvcnkuZGVyaXZlTGJvcEtleSh7XHJcbiAgICAgICAgICBwYXNzd29yZDogbGJvcFN0cmluZyxcclxuICAgICAgICAgIC4uLmxib3AubGJvcEtleVBhcmFtcyxcclxuICAgICAgICB9KVxyXG4gICAgICApLmp3aztcclxuXHJcbiAgICAgIC8vIElmIGRlY29kaW5nIHN1Y2Nlc3NmdWwgdGhlbiBpdCdzIHRoZSBjb3JyZWN0IGxib3BcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjb25zdCBsYm9wS2V5VmVyaWZpZXIgPSAoYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxyXG4gICAgICAgICAgbGJvcEtleSxcclxuICAgICAgICAgIGxib3Aud3JhcHBlZExib3BLZXlWZXJpZmllclxyXG4gICAgICAgICkpIGFzIGFueTtcclxuXHJcbiAgICAgICAgLy8gRm9yY2UgYSBiYWQgc2lnbmF0dXJlLlxyXG4gICAgICAgIC8vIGNvbnN0IHNlcnZlck5vbmNlID0gY2hhbGxlbmdlUmVzdWx0LmNoYWxsZW5nZS5zZXJ2ZXJOb25jZSArIFwiMVwiLFxyXG5cclxuICAgICAgICBjb25zdCBzZXJ2ZXJOb25jZSA9IGNoYWxsZW5nZVJlc3VsdC5jaGFsbGVuZ2Uuc2VydmVyTm9uY2U7XHJcblxyXG4gICAgICAgIGNvbnN0IHNpZ25lZENoYWxsZW5nZSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihcclxuICAgICAgICAgIGxib3BLZXlWZXJpZmllcixcclxuICAgICAgICAgIHtcclxuICAgICAgICAgICAgc2VydmVyTm9uY2UsXHJcbiAgICAgICAgICAgIGNsaWVudE5vbmNlLFxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICBsYm9wLFxyXG4gICAgICAgICAgc2lnbmVkQ2hhbGxlbmdlLFxyXG4gICAgICAgICAgbGJvcEtleSxcclxuICAgICAgICB9O1xyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aHJvdyBuZXcgTHJFeGNlcHRpb24oe1xyXG4gICAgICBzb3VyY2U6ICdMQk9QJyxcclxuICAgICAgY29kZTogJ0lOVkFMSURfUEFTU1BIUkFTRScsXHJcbiAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIHBhc3NwaHJhc2UuJyxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIHZlcmlmeUNvbnRhY3QoXHJcbiAgICBwYXJhbXM6IFZlcmlmeUNvbnRhY3RQYXJhbXNcclxuICApOiBQcm9taXNlPFZlcmlmeUNvbnRhY3RSZXN1bHQ+IHtcclxuICAgIGNvbnN0IHJldCA9IHRoaXMuaHR0cFxyXG4gICAgICAucG9zdDxWZXJpZnlDb250YWN0UmVzdWx0PihcclxuICAgICAgICBgJHt0aGlzLmNvbmZpZy5hdXRoVXJsfXVzZXJzL2xib3AtcmVzZXQvdmVyaWZ5LWNvbnRhY3QvYCxcclxuICAgICAgICBwYXJhbXNcclxuICAgICAgKVxyXG4gICAgICAudG9Qcm9taXNlKCk7XHJcblxyXG4gICAgLy8gLS1Qb3RlbnRpYWwgRmFpbHVyZSBQb2ludCAxIC0tXHJcbiAgICAvLyBUaGUgY29udGFjdCB2ZXJpZmljYXRpb25zIGFyZSB0aHJvdHRsZWQuIEJ1dCBvdGhlcndpc2UgaGFybWxlc3MuXHJcblxyXG4gICAgcmV0dXJuIHJldDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyBjb25maXJtQ29udGFjdChcclxuICAgIHBhcmFtczogQ29uZmlybUNvbnRhY3RQYXJhbXNcclxuICApOiBQcm9taXNlPENvbmZpcm1Db250YWN0UmVzdWx0PiB7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwXHJcbiAgICAgIC5wb3N0PENvbmZpcm1Db250YWN0UmVzdWx0PihgJHt0aGlzLmNvbmZpZy5hdXRoVXJsfWNvdmUvcmVzcG9uZC9gLCB7XHJcbiAgICAgICAgY2xhaW1faWQ6IHBhcmFtcy5jbGFpbUlkLFxyXG4gICAgICAgIHZfY29kZTogcGFyYW1zLnZDb2RlLFxyXG4gICAgICB9KVxyXG4gICAgICAudG9Qcm9taXNlKCk7XHJcblxyXG4gICAgLy8gLS1Qb3RlbnRpYWwgRmFpbHVyZSBQb2ludCAyIC0tXHJcbiAgICAvLyBBIHZlcmlmaWVkIGNsYWltIGZvciBhIGNvbnRhY3QgZG9lcyBub3QgcHJldmVudCBuZXcgb25lcyBmcm9tIGJlaW5nIGdlbmVyYXRlZC4gU28gaXQgc2hvdWxkIGJlIGZpbmUgdG8ganVzdCBzdGFydCBhZ2Fpbi5cclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyB2ZXJpZnkocGFyYW1zOiBWZXJpZnlQYXJhbXMpOiBQcm9taXNlPFZlcmlmeVJlc3VsdD4ge1xyXG4gICAgY29uc3QgY2hhbGxlbmdlUmVzdWx0ID0gYXdhaXQgdGhpcy5odHRwXHJcbiAgICAgIC5wb3N0PENoYWxsZW5nZVJlc3VsdD4oXHJcbiAgICAgICAgYCR7dGhpcy5jb25maWcuYXV0aFVybH11c2Vycy9sYm9wLXJlc2V0L2dldC1jaGFsbGVuZ2UvYCxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBjbGFpbUlkOiBwYXJhbXMuY2xhaW1JZCxcclxuICAgICAgICAgIGNsYWltVG9rZW46IHBhcmFtcy5jbGFpbVRva2VuLFxyXG4gICAgICAgIH1cclxuICAgICAgKVxyXG4gICAgICAudG9Qcm9taXNlKCk7XHJcblxyXG4gICAgLy8gLS1Qb3RlbnRpYWwgRmFpbHVyZSBQb2ludCAzIC0tXHJcbiAgICAvLyBUaGlzIGRvZXMgbm90IGxvY2sgYW55dGhpbmcuIEEgc2Vjb25kIGNhbGwgdG8gXCJnZXQtY2hhbGxlbmdlL1wiIHdpbGwgY3JlYXRlIGEgbmV3IGNoYWxsZW5nZSBhbWQgaW52YWxpZGF0ZSB0aGUgZmlyc3Qgb25lLlxyXG4gICAgY29uc3QgeyBzaWduZWRDaGFsbGVuZ2UsIGxib3AsIGxib3BLZXkgfSA9IGF3YWl0IHRoaXMudmVyaWZ5TGJvcHMoXHJcbiAgICAgIGNoYWxsZW5nZVJlc3VsdCxcclxuICAgICAgcGFyYW1zLmxib3BcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5odHRwXHJcbiAgICAgIC5wb3N0PGFueT4oYCR7dGhpcy5jb25maWcuYXV0aFVybH11c2Vycy9sYm9wLXJlc2V0L3ZlcmlmeS1jaGFsbGVuZ2UvYCwge1xyXG4gICAgICAgIGxib3BJZDogbGJvcC5sYm9wSWQsXHJcbiAgICAgICAgc2lnbmVkQ2hhbGxlbmdlLFxyXG4gICAgICB9KVxyXG4gICAgICAudG9Qcm9taXNlKCk7XHJcblxyXG4gICAgLy8gLS1Qb3RlbnRpYWwgRmFpbHVyZSBQb2ludCA0IC0tXHJcbiAgICAvLyBUaGlzIGRvZXMgbm90IGxvY2sgYW55dGhpbmcuIFNvIG9rIHRvIHJlc3RhcnQuXHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgbGJvcElkOiBsYm9wLmxib3BJZCxcclxuICAgICAgdmVyaWZpZWRUb2tlbjogcmVzLnZlcmlmaWVkVG9rZW4sXHJcbiAgICAgIG1hc3RlcktleUlkOiByZXMubWFzdGVyS2V5SWQsXHJcbiAgICAgIG1hc3RlcktleTogYXdhaXQgS0ZTLmFzS2V5KFxyXG4gICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZGVjcnlwdChsYm9wS2V5LCByZXMud3JhcHBlZE1hc3RlcktleSlcclxuICAgICAgKSxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYXN5bmMgc2V0UGFzc3dvcmQocGFyYW1zOiBTZXRQYXNzd29yZFBhcmFtcyk6IFByb21pc2U8YW55PiB7XHJcbiAgICAvLyBHZW5lcmF0ZSB0aGUgbmV3IHBhc3N3b3JkIGRlcml2ZWQga2V5c1xyXG4gICAgY29uc3QgcGFzc0tleUJ1bmRsZSA9IGF3YWl0IHRoaXMucGFzc3dvcmRTZXJ2aWNlLmNyZWF0ZVBhc3NLZXlCdW5kbGUoXHJcbiAgICAgIHBhcmFtcy5uZXdQYXNzd29yZFxyXG4gICAgKTtcclxuXHJcbiAgICAvLyBSZS1lbmNyeXB0IG1hc3RlciBrZXkgd2l0aCBuZXcga2V5XHJcbiAgICBjb25zdCBuZXdXcmFwcGVkTWFzdGVyS2V5ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICBwYXNzS2V5QnVuZGxlLnBhc3NLZXksXHJcbiAgICAgIHBhcmFtcy5tYXN0ZXJLZXkudG9KU09OKHRydWUpXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuaHR0cFxyXG4gICAgICAucG9zdDxTZXRQYXNzd29yZEFwaVJlc3VsdD4oXHJcbiAgICAgICAgYCR7dGhpcy5jb25maWcuYXV0aFVybH11c2Vycy9sYm9wLXJlc2V0L3NldC1wYXNzd29yZC9gLFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIGxib3BJZDogcGFyYW1zLmxib3BJZCxcclxuICAgICAgICAgIHZlcmlmaWVkVG9rZW46IHBhcmFtcy52ZXJpZmllZFRva2VuLFxyXG4gICAgICAgICAgbWFzdGVyS2V5SWQ6IHBhcmFtcy5tYXN0ZXJLZXlJZCxcclxuICAgICAgICAgIG5ld1dyYXBwZWRNYXN0ZXJLZXksXHJcbiAgICAgICAgICBuZXdQYXNzS2V5OiB7XHJcbiAgICAgICAgICAgIHBhc3NLZXlQYXJhbXM6IHBhc3NLZXlCdW5kbGUucGFzc0tleVBhcmFtcyxcclxuICAgICAgICAgICAgcGFzc0lkcFBhcmFtczogcGFzc0tleUJ1bmRsZS5wYXNzSWRwUGFyYW1zLFxyXG4gICAgICAgICAgICBwYXNzSWRwVmVyaWZpZXJQYms6IHBhc3NLZXlCdW5kbGUucGFzc0lkcFZlcmlmaWVyLnRvSlNPTigpLFxyXG4gICAgICAgICAgICB3cmFwcGVkUGFzc0lkcFZlcmlmaWVyUHJrOiBwYXNzS2V5QnVuZGxlLndyYXBwZWRQYXNzSWRwVmVyaWZpZXJQcmssXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH1cclxuICAgICAgKVxyXG4gICAgICAudG9Qcm9taXNlKCk7XHJcblxyXG4gICAgLy8gLS1Qb3RlbnRpYWwgRmFpbHVyZSBQb2ludCA1IC0tXHJcbiAgICAvLyBBIHRpbWVkIG11dGV4IGlzIGxvY2tlZC4gVGhlIElkcCBwYXNzd29yZCBjaGFuZ2UgbXVzdCBvY2N1ciB3aXRoaW4gYSBwZXJpb2Qgb2YgdGltZS5cclxuICAgIC8vIElmIGludGVycnVwdGVkIGhlcmUsIHRoZSB1c2VyIGNhbiBub3QgbG9naW4gd2l0aCB0aGVpciBvbGQgcGFzc3dvcmQgYWdhaW4uIFRoZXkgbXVzdFxyXG4gICAgLy8gc3RhcnQgdGhlIHdob2xlIExCT1AgcGFzc3dvcmQgcmVzZXQgcHJvY2VzcyBhZ2Fpbi5cclxuXHJcbiAgICAvLyBUaGlzIGNhbGwgd2lsbCBnbyB0aHJvdWdoIHRoZSBMUiBwcm94eSB3aGljaCBpcyBPSyBzaW5jZSB0aGUgTFIgc2VydmVyIGtub3dzXHJcbiAgICAvLyB0aGUgdGVtcG9yYXJ5IHBhc3N3b3JkIGFueXdheS5cclxuICAgIGxldCB1c2VyID0gYXdhaXQgdGhpcy5hdXRoLnNpZ25JbihyZXN1bHQudXNlcm5hbWUsIHJlc3VsdC5pZHBQYXNzd29yZCwge1xyXG4gICAgICBub1Byb3h5OiAndHJ1ZScsXHJcbiAgICB9KTtcclxuXHJcbiAgICBpZiAodXNlci5jaGFsbGVuZ2VOYW1lICE9PSAnTkVXX1BBU1NXT1JEX1JFUVVJUkVEJykge1xyXG4gICAgICB0aHJvdyBuZXcgTHJFeGNlcHRpb24oe1xyXG4gICAgICAgIG1lc3NhZ2U6XHJcbiAgICAgICAgICAnSW50ZXJuYWwgZXJyb3IuIEV4cGVjdGluZyBDb2duaXRvIHRvIGhhdmUgZG9uZSBhIHBhc3N3b3JkIHJlc2V0LicsXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIC0tUG90ZW50aWFsIEZhaWx1cmUgUG9pbnQgNiAtLVxyXG4gICAgLy8gTXVzdCByZXN0YXJ0IHRoZSBMQk9QIHBhc3N3b3JkIHJlc2V0IHByb2Nlc3MgYWdhaW4uXHJcblxyXG4gICAgLy8gU2V0IG5ldyBwYXNzd29yZCBvbiBJZHBcclxuICAgIHVzZXIgPSBhd2FpdCB0aGlzLmF1dGguY29tcGxldGVOZXdQYXNzd29yZChcclxuICAgICAgdXNlcixcclxuICAgICAgdGhpcy5wYXNzd29yZFNlcnZpY2UuZ2V0UGFzc0lkcFN0cmluZyhwYXNzS2V5QnVuZGxlLnBhc3NJZHApLFxyXG4gICAgICB7fVxyXG4gICAgKTtcclxuXHJcbiAgICAvLyAtLVBvdGVudGlhbCBGYWlsdXJlIFBvaW50IDcgLS1cclxuICAgIC8vIE11c3QgcmVzdGFydCB0aGUgTEJPUCBwYXNzd29yZCByZXNldCBwcm9jZXNzIGFnYWluLlxyXG5cclxuICAgIGF3YWl0IHRoaXMuYXV0aC5zaWduT3V0KCk7XHJcblxyXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuaHR0cFxyXG4gICAgICAucG9zdDxhbnk+KGAke3RoaXMuY29uZmlnLmF1dGhVcmx9dXNlcnMvbGJvcC1yZXNldC9jb21wbGV0ZS9gLCB7XHJcbiAgICAgICAgbGJvcElkOiBwYXJhbXMubGJvcElkLFxyXG4gICAgICAgIHNldFBhc3N3b3JkVG9rZW46IHJlc3VsdC5zZXRQYXNzd29yZFRva2VuLFxyXG4gICAgICB9KVxyXG4gICAgICAudG9Qcm9taXNlKCk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import { LrApolloService } from '../api/lr-apollo.service';
|
|
3
|
+
import { HttpClient } from '@angular/common/http';
|
|
4
|
+
import { Inject, Injectable } from '@angular/core';
|
|
5
|
+
import { AuthClass } from '@aws-amplify/auth/lib-esm/Auth';
|
|
6
|
+
import gql from 'graphql-tag';
|
|
7
|
+
import { EncryptionService } from '../cryptography/encryption.service';
|
|
8
|
+
import { KeyGraphService } from '../cryptography/key-graph.service';
|
|
9
|
+
import { KeyService } from '../cryptography/key.service';
|
|
10
|
+
import { LR_CONFIG } from '../life-ready.config';
|
|
11
|
+
import { LrException, LrBadLogicException, } from '../_common/exceptions';
|
|
12
|
+
import { LifeReadyAuthService } from './life-ready-auth.service';
|
|
13
|
+
import { PasswordService } from './password.service';
|
|
14
|
+
import { Slip39Helper } from 'slip39';
|
|
15
|
+
import { KeyFactoryService as KFS } from '../cryptography/key-factory.service';
|
|
16
|
+
import * as i0 from "@angular/core";
|
|
17
|
+
import * as i1 from "../life-ready.config";
|
|
18
|
+
import * as i2 from "@angular/common/http";
|
|
19
|
+
import * as i3 from "../api/lr-apollo.service";
|
|
20
|
+
import * as i4 from "@aws-amplify/auth/lib-esm/Auth";
|
|
21
|
+
import * as i5 from "./life-ready-auth.service";
|
|
22
|
+
import * as i6 from "../cryptography/key-factory.service";
|
|
23
|
+
import * as i7 from "../cryptography/key.service";
|
|
24
|
+
import * as i8 from "../cryptography/encryption.service";
|
|
25
|
+
import * as i9 from "../cryptography/key-graph.service";
|
|
26
|
+
import * as i10 from "./password.service";
|
|
27
|
+
export const CreateLbopQuery = gql `
|
|
28
|
+
mutation CreateLbop($input: CreateLbopInput!) {
|
|
29
|
+
createLbop(input: $input) {
|
|
30
|
+
lbop {
|
|
31
|
+
id
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
export const DeleteLbopQuery = gql `
|
|
37
|
+
mutation DeleteLbop($input: DeleteLbopInput!) {
|
|
38
|
+
deleteLbop(input: $input) {
|
|
39
|
+
id
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
43
|
+
export const UpdateLbopQuery = gql `
|
|
44
|
+
mutation UpdateLbop($input: UpdateLbopInput!) {
|
|
45
|
+
updateLbop(input: $input) {
|
|
46
|
+
lbop {
|
|
47
|
+
id
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
`;
|
|
52
|
+
export const LbopQuery = gql `
|
|
53
|
+
query Lbop($id: LrRelayIdInput!) {
|
|
54
|
+
lbop(id: $id) {
|
|
55
|
+
id
|
|
56
|
+
cipherMeta
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
`;
|
|
60
|
+
export const LbopsQuery = gql `
|
|
61
|
+
query Lbops {
|
|
62
|
+
lbops {
|
|
63
|
+
edges {
|
|
64
|
+
node {
|
|
65
|
+
id
|
|
66
|
+
cipherMeta
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
`;
|
|
72
|
+
export class LbopService {
|
|
73
|
+
constructor(config, http, lrApollo, auth, authService, keyFactory, keyService, encryptionService, keyGraph, passwordService) {
|
|
74
|
+
this.config = config;
|
|
75
|
+
this.http = http;
|
|
76
|
+
this.lrApollo = lrApollo;
|
|
77
|
+
this.auth = auth;
|
|
78
|
+
this.authService = authService;
|
|
79
|
+
this.keyFactory = keyFactory;
|
|
80
|
+
this.keyService = keyService;
|
|
81
|
+
this.encryptionService = encryptionService;
|
|
82
|
+
this.keyGraph = keyGraph;
|
|
83
|
+
this.passwordService = passwordService;
|
|
84
|
+
this.CLIENT_NONCE_LENGTH = 32;
|
|
85
|
+
// There are 1024 words (10 bits), so 25 words should give ~256 bits of entropy.
|
|
86
|
+
this.LBOP_WORDS = 25;
|
|
87
|
+
}
|
|
88
|
+
getPartial(lbopString) {
|
|
89
|
+
return lbopString.split(' ')[0];
|
|
90
|
+
}
|
|
91
|
+
remove(id) {
|
|
92
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
+
const res = yield this.lrApollo.mutate({
|
|
94
|
+
mutation: DeleteLbopQuery,
|
|
95
|
+
variables: {
|
|
96
|
+
input: {
|
|
97
|
+
id,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
return res.deleteLbop.id;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
update({ id, name }) {
|
|
105
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
106
|
+
const lbop = yield this.get(id);
|
|
107
|
+
lbop.name = name;
|
|
108
|
+
const masterKey = yield this.keyService.getCurrentMasterKey();
|
|
109
|
+
const cipherMeta = yield this.encryptionService.encrypt(masterKey.jwk, lbop);
|
|
110
|
+
const res = yield this.lrApollo.mutate({
|
|
111
|
+
mutation: UpdateLbopQuery,
|
|
112
|
+
variables: {
|
|
113
|
+
input: {
|
|
114
|
+
id,
|
|
115
|
+
cipherMeta: JSON.stringify(cipherMeta),
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
return res.updateLbop;
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
get(id) {
|
|
123
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
124
|
+
const res = yield this.lrApollo.query({
|
|
125
|
+
query: LbopQuery,
|
|
126
|
+
variables: {
|
|
127
|
+
id,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
const masterKey = yield this.keyService.getCurrentMasterKey();
|
|
131
|
+
const plainCipherMeta = yield this.encryptionService.decrypt(masterKey.jwk, JSON.parse(res.lbop.cipherMeta));
|
|
132
|
+
return Object.assign({ id: res.id }, plainCipherMeta);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
list() {
|
|
136
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
137
|
+
const res = yield this.lrApollo.query({
|
|
138
|
+
query: LbopsQuery,
|
|
139
|
+
});
|
|
140
|
+
const masterKey = yield this.keyService.getCurrentMasterKey();
|
|
141
|
+
return Promise.all(res.lbops.edges.map((edge) => __awaiter(this, void 0, void 0, function* () {
|
|
142
|
+
const plainCipherMeta = yield this.encryptionService.decrypt(masterKey.jwk, JSON.parse(edge.node.cipherMeta));
|
|
143
|
+
return Object.assign({ id: edge.node.id }, plainCipherMeta);
|
|
144
|
+
})));
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
create({ name }) {
|
|
148
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
+
if (Slip39Helper.WORD_LIST.length !== 1024) {
|
|
150
|
+
throw new LrBadLogicException('Slip39Helper.WORD_LIST.length != 1024');
|
|
151
|
+
}
|
|
152
|
+
// Get existing to make sure there are not duplicate first words
|
|
153
|
+
const lbops = yield this.list();
|
|
154
|
+
// Generate new one
|
|
155
|
+
let lbopString;
|
|
156
|
+
while (true) {
|
|
157
|
+
lbopString = this.keyFactory
|
|
158
|
+
.randomChoices(Slip39Helper.WORD_LIST, this.LBOP_WORDS)
|
|
159
|
+
.join(' ');
|
|
160
|
+
const partial = this.getPartial(lbopString);
|
|
161
|
+
if (!lbops.some((lbop) => lbop.partial === partial)) {
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const lbopKeyParams = yield this.keyFactory.createLbopKeyParams();
|
|
166
|
+
const lbopKey = (yield this.keyFactory.deriveLbopKey(Object.assign({ password: lbopString }, lbopKeyParams))).jwk;
|
|
167
|
+
const lbopKeyVerifier = yield this.keyFactory.createSignKey();
|
|
168
|
+
const wrappedLbopKeyVerifier = yield this.encryptionService.encrypt(lbopKey, lbopKeyVerifier.toJSON(true));
|
|
169
|
+
// Re-encrypt master key with new key
|
|
170
|
+
const currentUser = yield this.authService.getUser();
|
|
171
|
+
const masterKey = yield this.keyGraph.getKey(currentUser.currentUserKey.masterKey.id);
|
|
172
|
+
const wrappedMasterKey = yield this.encryptionService.encrypt(lbopKey, masterKey.jwk.toJSON(true));
|
|
173
|
+
const meta = Object.assign(Object.assign({}, (name && { name })), { partial: this.getPartial(lbopString) });
|
|
174
|
+
const cipherMeta = yield this.encryptionService.encrypt(masterKey.jwk, meta);
|
|
175
|
+
const res = yield this.lrApollo.mutate({
|
|
176
|
+
mutation: CreateLbopQuery,
|
|
177
|
+
variables: {
|
|
178
|
+
input: {
|
|
179
|
+
cipherMeta: JSON.stringify(cipherMeta),
|
|
180
|
+
lbopKeyParams: JSON.stringify(lbopKeyParams),
|
|
181
|
+
lbopKeyVerifier: JSON.stringify(lbopKeyVerifier.toJSON(true)),
|
|
182
|
+
wrappedLbopKeyVerifier: JSON.stringify(wrappedLbopKeyVerifier),
|
|
183
|
+
masterKeyId: currentUser.currentUserKey.masterKey.id,
|
|
184
|
+
wrappedMasterKey: JSON.stringify(wrappedMasterKey),
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
return Object.assign(Object.assign({}, res.createLbop.lbop), { lbopString });
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
// --------------------------------------------------------------------------------------------------------------------
|
|
192
|
+
// --------------------------------------------------------------------------------------------------------------------
|
|
193
|
+
// Flow below are for password reset via LBOP
|
|
194
|
+
//
|
|
195
|
+
// --Potential Failure Point xxx--
|
|
196
|
+
//
|
|
197
|
+
// Look for the above and you can test by interrupting at these points.
|
|
198
|
+
//
|
|
199
|
+
// The LBOP reset process can be restarted at any point before the call to "set-password/". Once "set-password/" has been
|
|
200
|
+
// called, we assume the client has a short period of time to change the Idp password to the one they've chosen. The "set-password/"
|
|
201
|
+
// will set the Idp password to a temporary random password. The user can no longer login using their current password. If the Idp
|
|
202
|
+
// password change process does not complete or takes longer than the lockout period, the account will not be accessible and a new
|
|
203
|
+
// LBOP password reset must be carried out.
|
|
204
|
+
// --------------------------------------------------------------------------------------------------------------------
|
|
205
|
+
// --------------------------------------------------------------------------------------------------------------------
|
|
206
|
+
verifyLbops(challengeResult, lbopString) {
|
|
207
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
208
|
+
const clientNonce = this.keyFactory.randomString(this.CLIENT_NONCE_LENGTH);
|
|
209
|
+
for (const lbop of challengeResult.lbops) {
|
|
210
|
+
const lbopKey = (yield this.keyFactory.deriveLbopKey(Object.assign({ password: lbopString }, lbop.lbopKeyParams))).jwk;
|
|
211
|
+
// If decoding successful then it's the correct lbop
|
|
212
|
+
try {
|
|
213
|
+
const lbopKeyVerifier = (yield this.encryptionService.decrypt(lbopKey, lbop.wrappedLbopKeyVerifier));
|
|
214
|
+
// Force a bad signature.
|
|
215
|
+
// const serverNonce = challengeResult.challenge.serverNonce + "1",
|
|
216
|
+
const serverNonce = challengeResult.challenge.serverNonce;
|
|
217
|
+
const signedChallenge = yield this.encryptionService.sign(lbopKeyVerifier, {
|
|
218
|
+
serverNonce,
|
|
219
|
+
clientNonce,
|
|
220
|
+
});
|
|
221
|
+
return {
|
|
222
|
+
lbop,
|
|
223
|
+
signedChallenge,
|
|
224
|
+
lbopKey,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
throw new LrException({
|
|
232
|
+
source: 'LBOP',
|
|
233
|
+
code: 'INVALID_PASSPHRASE',
|
|
234
|
+
message: 'Invalid passphrase.',
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
verifyContact(params) {
|
|
239
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
240
|
+
const ret = this.http
|
|
241
|
+
.post(`${this.config.authUrl}users/lbop-reset/verify-contact/`, params)
|
|
242
|
+
.toPromise();
|
|
243
|
+
// --Potential Failure Point 1 --
|
|
244
|
+
// The contact verifications are throttled. But otherwise harmless.
|
|
245
|
+
return ret;
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
confirmContact(params) {
|
|
249
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
250
|
+
return this.http
|
|
251
|
+
.post(`${this.config.authUrl}cove/respond/`, {
|
|
252
|
+
claim_id: params.claimId,
|
|
253
|
+
v_code: params.vCode,
|
|
254
|
+
})
|
|
255
|
+
.toPromise();
|
|
256
|
+
// --Potential Failure Point 2 --
|
|
257
|
+
// A verified claim for a contact does not prevent new ones from being generated. So it should be fine to just start again.
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
verify(params) {
|
|
261
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
262
|
+
const challengeResult = yield this.http
|
|
263
|
+
.post(`${this.config.authUrl}users/lbop-reset/get-challenge/`, {
|
|
264
|
+
claimId: params.claimId,
|
|
265
|
+
claimToken: params.claimToken,
|
|
266
|
+
})
|
|
267
|
+
.toPromise();
|
|
268
|
+
// --Potential Failure Point 3 --
|
|
269
|
+
// This does not lock anything. A second call to "get-challenge/" will create a new challenge amd invalidate the first one.
|
|
270
|
+
const { signedChallenge, lbop, lbopKey } = yield this.verifyLbops(challengeResult, params.lbop);
|
|
271
|
+
const res = yield this.http
|
|
272
|
+
.post(`${this.config.authUrl}users/lbop-reset/verify-challenge/`, {
|
|
273
|
+
lbopId: lbop.lbopId,
|
|
274
|
+
signedChallenge,
|
|
275
|
+
})
|
|
276
|
+
.toPromise();
|
|
277
|
+
// --Potential Failure Point 4 --
|
|
278
|
+
// This does not lock anything. So ok to restart.
|
|
279
|
+
return {
|
|
280
|
+
lbopId: lbop.lbopId,
|
|
281
|
+
verifiedToken: res.verifiedToken,
|
|
282
|
+
masterKeyId: res.masterKeyId,
|
|
283
|
+
masterKey: yield KFS.asKey(yield this.encryptionService.decrypt(lbopKey, res.wrappedMasterKey)),
|
|
284
|
+
};
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
setPassword(params) {
|
|
288
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
289
|
+
// Generate the new password derived keys
|
|
290
|
+
const passKeyBundle = yield this.passwordService.createPassKeyBundle(params.newPassword);
|
|
291
|
+
// Re-encrypt master key with new key
|
|
292
|
+
const newWrappedMasterKey = yield this.encryptionService.encrypt(passKeyBundle.passKey, params.masterKey.toJSON(true));
|
|
293
|
+
const result = yield this.http
|
|
294
|
+
.post(`${this.config.authUrl}users/lbop-reset/set-password/`, {
|
|
295
|
+
lbopId: params.lbopId,
|
|
296
|
+
verifiedToken: params.verifiedToken,
|
|
297
|
+
masterKeyId: params.masterKeyId,
|
|
298
|
+
newWrappedMasterKey,
|
|
299
|
+
newPassKey: {
|
|
300
|
+
passKeyParams: passKeyBundle.passKeyParams,
|
|
301
|
+
passIdpParams: passKeyBundle.passIdpParams,
|
|
302
|
+
passIdpVerifierPbk: passKeyBundle.passIdpVerifier.toJSON(),
|
|
303
|
+
wrappedPassIdpVerifierPrk: passKeyBundle.wrappedPassIdpVerifierPrk,
|
|
304
|
+
},
|
|
305
|
+
})
|
|
306
|
+
.toPromise();
|
|
307
|
+
// --Potential Failure Point 5 --
|
|
308
|
+
// A timed mutex is locked. The Idp password change must occur within a period of time.
|
|
309
|
+
// If interrupted here, the user can not login with their old password again. They must
|
|
310
|
+
// start the whole LBOP password reset process again.
|
|
311
|
+
// This call will go through the LR proxy which is OK since the LR server knows
|
|
312
|
+
// the temporary password anyway.
|
|
313
|
+
let user = yield this.auth.signIn(result.username, result.idpPassword, {
|
|
314
|
+
noProxy: 'true',
|
|
315
|
+
});
|
|
316
|
+
if (user.challengeName !== 'NEW_PASSWORD_REQUIRED') {
|
|
317
|
+
throw new LrException({
|
|
318
|
+
message: 'Internal error. Expecting Cognito to have done a password reset.',
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
// --Potential Failure Point 6 --
|
|
322
|
+
// Must restart the LBOP password reset process again.
|
|
323
|
+
// Set new password on Idp
|
|
324
|
+
user = yield this.auth.completeNewPassword(user, this.passwordService.getPassIdpString(passKeyBundle.passIdp), {});
|
|
325
|
+
// --Potential Failure Point 7 --
|
|
326
|
+
// Must restart the LBOP password reset process again.
|
|
327
|
+
yield this.auth.signOut();
|
|
328
|
+
return yield this.http
|
|
329
|
+
.post(`${this.config.authUrl}users/lbop-reset/complete/`, {
|
|
330
|
+
lbopId: params.lbopId,
|
|
331
|
+
setPasswordToken: result.setPasswordToken,
|
|
332
|
+
})
|
|
333
|
+
.toPromise();
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
LbopService.ɵprov = i0.ɵɵdefineInjectable({ factory: function LbopService_Factory() { return new LbopService(i0.ɵɵinject(i1.LR_CONFIG), i0.ɵɵinject(i2.HttpClient), i0.ɵɵinject(i3.LrApolloService), i0.ɵɵinject(i4.AuthClass), i0.ɵɵinject(i5.LifeReadyAuthService), i0.ɵɵinject(i6.KeyFactoryService), i0.ɵɵinject(i7.KeyService), i0.ɵɵinject(i8.EncryptionService), i0.ɵɵinject(i9.KeyGraphService), i0.ɵɵinject(i10.PasswordService)); }, token: LbopService, providedIn: "root" });
|
|
338
|
+
LbopService.decorators = [
|
|
339
|
+
{ type: Injectable, args: [{
|
|
340
|
+
providedIn: 'root',
|
|
341
|
+
},] }
|
|
342
|
+
];
|
|
343
|
+
LbopService.ctorParameters = () => [
|
|
344
|
+
{ type: undefined, decorators: [{ type: Inject, args: [LR_CONFIG,] }] },
|
|
345
|
+
{ type: HttpClient },
|
|
346
|
+
{ type: LrApolloService },
|
|
347
|
+
{ type: AuthClass },
|
|
348
|
+
{ type: LifeReadyAuthService },
|
|
349
|
+
{ type: KFS },
|
|
350
|
+
{ type: KeyService },
|
|
351
|
+
{ type: EncryptionService },
|
|
352
|
+
{ type: KeyGraphService },
|
|
353
|
+
{ type: PasswordService }
|
|
354
|
+
];
|
|
355
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGJvcC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9vcHQvYXRsYXNzaWFuL3BpcGVsaW5lcy9hZ2VudC9idWlsZC9wcm9qZWN0cy9jb3JlL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9hdXRoL2xib3Auc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDM0QsT0FBTyxHQUFHLE1BQU0sYUFBYSxDQUFDO0FBRTlCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDekQsT0FBTyxFQUFtQixTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRSxPQUFPLEVBQ0wsV0FBVyxFQUVYLG1CQUFtQixHQUNwQixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxpQkFBaUIsSUFBSSxHQUFHLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7Ozs7Ozs7Ozs7O0FBeUUvRSxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsR0FBRyxDQUFBOzs7Ozs7OztDQVFqQyxDQUFDO0FBTUYsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLEdB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QVMsRUFBRSxDQUFDO1FBQ2pCLENBQUM7S0FBQTs7OztZQTNYRixVQUFVLFNBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7Ozs0Q0FPSSxNQUFNLFNBQUMsU0FBUztZQXRLWixVQUFVO1lBRFYsZUFBZTtZQUdmLFNBQVM7WUFZVCxvQkFBb0I7WUFHQyxHQUFHO1lBVnhCLFVBQVU7WUFGVixpQkFBaUI7WUFDakIsZUFBZTtZQVNmLGVBQWUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMckFwb2xsb1NlcnZpY2UgfSBmcm9tICcuLi9hcGkvbHItYXBvbGxvLnNlcnZpY2UnO1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQXV0aENsYXNzIH0gZnJvbSAnQGF3cy1hbXBsaWZ5L2F1dGgvbGliLWVzbS9BdXRoJztcbmltcG9ydCBncWwgZnJvbSAnZ3JhcGhxbC10YWcnO1xuaW1wb3J0IHsgSldLIH0gZnJvbSAnbm9kZS1qb3NlJztcbmltcG9ydCB7IEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vY3J5cHRvZ3JhcGh5L2VuY3J5cHRpb24uc2VydmljZSc7XG5pbXBvcnQgeyBLZXlHcmFwaFNlcnZpY2UgfSBmcm9tICcuLi9jcnlwdG9ncmFwaHkva2V5LWdyYXBoLnNlcnZpY2UnO1xuaW1wb3J0IHsgS2V5U2VydmljZSB9IGZyb20gJy4uL2NyeXB0b2dyYXBoeS9rZXkuc2VydmljZSc7XG5pbXBvcnQgeyBMaWZlUmVhZHlDb25maWcsIExSX0NPTkZJRyB9IGZyb20gJy4uL2xpZmUtcmVhZHkuY29uZmlnJztcbmltcG9ydCB7XG4gIExyRXhjZXB0aW9uLFxuICBMckVycm9yQ29kZSxcbiAgTHJCYWRMb2dpY0V4Y2VwdGlvbixcbn0gZnJvbSAnLi4vX2NvbW1vbi9leGNlcHRpb25zJztcbmltcG9ydCB7IExpZmVSZWFkeUF1dGhTZXJ2aWNlIH0gZnJvbSAnLi9saWZlLXJlYWR5LWF1dGguc2VydmljZSc7XG5pbXBvcnQgeyBQYXNzd29yZFNlcnZpY2UgfSBmcm9tICcuL3Bhc3N3b3JkLnNlcnZpY2UnO1xuaW1wb3J0IHsgU2xpcDM5SGVscGVyIH0gZnJvbSAnc2xpcDM5JztcbmltcG9ydCB7IEtleUZhY3RvcnlTZXJ2aWNlIGFzIEtGUyB9IGZyb20gJy4uL2NyeXB0b2dyYXBoeS9rZXktZmFjdG9yeS5zZXJ2aWNlJztcblxuaW50ZXJmYWNlIFNldFBhc3N3b3JkQXBpUmVzdWx0IHtcbiAgdXNlcm5hbWU6IHN0cmluZztcbiAgaWRwUGFzc3dvcmQ6IHN0cmluZztcbiAgc2V0UGFzc3dvcmRUb2tlbjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNldFBhc3N3b3JkUGFyYW1zIHtcbiAgbGJvcElkOiBzdHJpbmc7XG4gIG5ld1Bhc3N3b3JkOiBzdHJpbmc7XG4gIHZlcmlmaWVkVG9rZW46IHN0cmluZztcbiAgbWFzdGVyS2V5SWQ6IHN0cmluZztcbiAgbWFzdGVyS2V5OiBKV0suS2V5O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZlcmlmeUNvbnRhY3RQYXJhbXMge1xuICBlbWFpbD86IHN0cmluZztcbiAgcGhvbmU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmVyaWZ5Q29udGFjdFJlc3VsdCB7XG4gIC8vIFRoZSBjbGFpbV9pZCBpZGVudGlmaWVzIHRoZSBFbWFpbC9TTVMgY29uZmlybWF0aW9uXG4gIGNsYWltSWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb25maXJtQ29udGFjdFBhcmFtcyB7XG4gIGNsYWltSWQ6IHN0cmluZztcbiAgdkNvZGU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb25maXJtQ29udGFjdFJlc3VsdCB7XG4gIC8vIFRoZSB0b2tlbiB0byBwcm92ZSB0aGUgY2xpZW50IGhhZCB0aGUgY29ycmVjdCBjb25maXJtYXRpb24gY29kZS5cbiAgdG9rZW46IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZXJpZnlQYXJhbXMge1xuICBjbGFpbUlkOiBzdHJpbmc7XG4gIGNsYWltVG9rZW46IHN0cmluZztcbiAgbGJvcDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZlcmlmeVJlc3VsdCB7XG4gIC8vIHVzZXJJZDogc3RyaW5nO1xuICBsYm9wSWQ6IHN0cmluZztcbiAgdmVyaWZpZWRUb2tlbjogc3RyaW5nO1xuICBtYXN0ZXJLZXlJZDogc3RyaW5nO1xuICBtYXN0ZXJLZXk6IEpXSy5LZXk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhbGxlbmdlUmVzdWx0IHtcbiAgY2hhbGxlbmdlOiBhbnk7XG4gIGxib3BzOiBhbnk7XG4gIC8vIHVzZXJJZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExib3Age1xuICBpZDogc3RyaW5nO1xuICBwYXJ0aWFsPzogc3RyaW5nO1xuICBuYW1lPzogc3RyaW5nO1xuICBsYm9wU3RyaW5nPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUxib3BQYXJhbXMge1xuICBuYW1lPzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgQ3JlYXRlTGJvcFF1ZXJ5IHtcbiAgY3JlYXRlTGJvcDoge1xuICAgIGxib3A6IExib3A7XG4gIH07XG59XG5cbmV4cG9ydCBjb25zdCBDcmVhdGVMYm9wUXVlcnkgPSBncWxgXG4gIG11dGF0aW9uIENyZWF0ZUxib3AoJGlucHV0OiBDcmVhdGVMYm9wSW5wdXQhKSB7XG4gICAgY3JlYXRlTGJvcChpbnB1dDogJGlucHV0KSB7XG4gICAgICBsYm9wIHtcbiAgICAgICAgaWRcbiAgICAgIH1cbiAgICB9XG4gIH1cbmA7XG5cbmludGVyZmFjZSBEZWxldGVMYm9wUXVlcnkge1xuICBkZWxldGVMYm9wOiBMYm9wO1xufVxuXG5leHBvcnQgY29uc3QgRGVsZXRlTGJvcFF1ZXJ5ID0gZ3FsYFxuICBtdXRhdGlvbiBEZWxldGVMYm9wKCRpbnB1dDogRGVsZXRlTGJvcElucHV0ISkge1xuICAgIGRlbGV0ZUxib3AoaW5wdXQ6ICRpbnB1dCkge1xuICAgICAgaWRcbiAgICB9XG4gIH1cbmA7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXBkYXRlTGJvcFBhcmFtcyB7XG4gIGlkOiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFVwZGF0ZUxib3BRdWVyeSB7XG4gIHVwZGF0ZUxib3A6IExib3A7XG59XG5cbmV4cG9ydCBjb25zdCBVcGRhdGVMYm9wUXVlcnkgPSBncWxgXG4gIG11dGF0aW9uIFVwZGF0ZUxib3AoJGlucHV0OiBVcGRhdGVMYm9wSW5wdXQhKSB7XG4gICAgdXBkYXRlTGJvcChpbnB1dDogJGlucHV0KSB7XG4gICAgICBsYm9wIHtcbiAgICAgICAgaWRcbiAgICAgIH1cbiAgICB9XG4gIH1cbmA7XG5cbmV4cG9ydCBjb25zdCBMYm9wUXVlcnkgPSBncWxgXG4gIHF1ZXJ5IExib3AoJGlkOiBMclJlbGF5SWRJbnB1dCEpIHtcbiAgICBsYm9wKGlkOiAkaWQpIHtcbiAgICAgIGlkXG4gICAgICBjaXBoZXJNZXRhXG4gICAgfVxuICB9XG5gO1xuXG5pbnRlcmZhY2UgTGJvcHNRdWVyeSB7XG4gIGxib3BzOiBhbnk7XG59XG5cbmV4cG9ydCBjb25zdCBMYm9wc1F1ZXJ5ID0gZ3FsYFxuICBxdWVyeSBMYm9wcyB7XG4gICAgbGJvcHMge1xuICAgICAgZWRnZXMge1xuICAgICAgICBub2RlIHtcbiAgICAgICAgICBpZFxuICAgICAgICAgIGNpcGhlck1ldGFcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuYDtcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIExib3BTZXJ2aWNlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBDTElFTlRfTk9OQ0VfTEVOR1RIID0gMzI7XG4gIC8vIFRoZXJlIGFyZSAxMDI0IHdvcmRzICgxMCBiaXRzKSwgc28gMjUgd29yZHMgc2hvdWxkIGdpdmUgfjI1NiBiaXRzIG9mIGVudHJvcHkuXG4gIHByaXZhdGUgcmVhZG9ubHkgTEJPUF9XT1JEUyA9IDI1O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoTFJfQ09ORklHKSBwcml2YXRlIGNvbmZpZzogTGlmZVJlYWR5Q29uZmlnLFxuICAgIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCxcbiAgICBwcml2YXRlIGxyQXBvbGxvOiBMckFwb2xsb1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBhdXRoOiBBdXRoQ2xhc3MsXG4gICAgcHJpdmF0ZSBhdXRoU2VydmljZTogTGlmZVJlYWR5QXV0aFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBrZXlGYWN0b3J5OiBLRlMsXG4gICAgcHJpdmF0ZSBrZXlTZXJ2aWNlOiBLZXlTZXJ2aWNlLFxuICAgIHByaXZhdGUgZW5jcnlwdGlvblNlcnZpY2U6IEVuY3J5cHRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUga2V5R3JhcGg6IEtleUdyYXBoU2VydmljZSxcbiAgICBwcml2YXRlIHBhc3N3b3JkU2VydmljZTogUGFzc3dvcmRTZXJ2aWNlXG4gICkge31cblxuICBwcml2YXRlIGdldFBhcnRpYWwobGJvcFN0cmluZzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gbGJvcFN0cmluZy5zcGxpdCgnICcpWzBdO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHJlbW92ZShpZDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmxyQXBvbGxvLm11dGF0ZTxhbnk+KHtcbiAgICAgIG11dGF0aW9uOiBEZWxldGVMYm9wUXVlcnksXG4gICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgaW5wdXQ6IHtcbiAgICAgICAgICBpZCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzLmRlbGV0ZUxib3AuaWQ7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgdXBkYXRlKHsgaWQsIG5hbWUgfTogVXBkYXRlTGJvcFBhcmFtcyk6IFByb21pc2U8TGJvcD4ge1xuICAgIGNvbnN0IGxib3AgPSBhd2FpdCB0aGlzLmdldChpZCk7XG4gICAgbGJvcC5uYW1lID0gbmFtZTtcblxuICAgIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50TWFzdGVyS2V5KCk7XG4gICAgY29uc3QgY2lwaGVyTWV0YSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgIG1hc3RlcktleS5qd2ssXG4gICAgICBsYm9wXG4gICAgKTtcblxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMubHJBcG9sbG8ubXV0YXRlPFVwZGF0ZUxib3BRdWVyeT4oe1xuICAgICAgbXV0YXRpb246IFVwZGF0ZUxib3BRdWVyeSxcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBpbnB1dDoge1xuICAgICAgICAgIGlkLFxuICAgICAgICAgIGNpcGhlck1ldGE6IEpTT04uc3RyaW5naWZ5KGNpcGhlck1ldGEpLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHJldHVybiByZXMudXBkYXRlTGJvcDtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBnZXQoaWQ6IHN0cmluZyk6IFByb21pc2U8TGJvcD4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMubHJBcG9sbG8ucXVlcnk8YW55Pih7XG4gICAgICBxdWVyeTogTGJvcFF1ZXJ5LFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIGlkLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50TWFzdGVyS2V5KCk7XG5cbiAgICBjb25zdCBwbGFpbkNpcGhlck1ldGEgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQoXG4gICAgICBtYXN0ZXJLZXkuandrLFxuICAgICAgSlNPTi5wYXJzZShyZXMubGJvcC5jaXBoZXJNZXRhKVxuICAgICk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHJlcy5pZCxcbiAgICAgIC4uLnBsYWluQ2lwaGVyTWV0YSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3QoKTogUHJvbWlzZTxMYm9wW10+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmxyQXBvbGxvLnF1ZXJ5PExib3BzUXVlcnk+KHtcbiAgICAgIHF1ZXJ5OiBMYm9wc1F1ZXJ5LFxuICAgIH0pO1xuXG4gICAgY29uc3QgbWFzdGVyS2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRNYXN0ZXJLZXkoKTtcblxuICAgIHJldHVybiBQcm9taXNlLmFsbChcbiAgICAgIHJlcy5sYm9wcy5lZGdlcy5tYXAoYXN5bmMgKGVkZ2UpID0+IHtcbiAgICAgICAgY29uc3QgcGxhaW5DaXBoZXJNZXRhID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxuICAgICAgICAgIG1hc3RlcktleS5qd2ssXG4gICAgICAgICAgSlNPTi5wYXJzZShlZGdlLm5vZGUuY2lwaGVyTWV0YSlcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBpZDogZWRnZS5ub2RlLmlkLFxuICAgICAgICAgIC4uLnBsYWluQ2lwaGVyTWV0YSxcbiAgICAgICAgfTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBjcmVhdGUoeyBuYW1lIH06IENyZWF0ZUxib3BQYXJhbXMpOiBQcm9taXNlPExib3A+IHtcbiAgICBpZiAoU2xpcDM5SGVscGVyLldPUkRfTElTVC5sZW5ndGggIT09IDEwMjQpIHtcbiAgICAgIHRocm93IG5ldyBMckJhZExvZ2ljRXhjZXB0aW9uKCdTbGlwMzlIZWxwZXIuV09SRF9MSVNULmxlbmd0aCAhPSAxMDI0Jyk7XG4gICAgfVxuXG4gICAgLy8gR2V0IGV4aXN0aW5nIHRvIG1ha2Ugc3VyZSB0aGVyZSBhcmUgbm90IGR1cGxpY2F0ZSBmaXJzdCB3b3Jkc1xuICAgIGNvbnN0IGxib3BzID0gYXdhaXQgdGhpcy5saXN0KCk7XG5cbiAgICAvLyBHZW5lcmF0ZSBuZXcgb25lXG4gICAgbGV0IGxib3BTdHJpbmc7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGxib3BTdHJpbmcgPSB0aGlzLmtleUZhY3RvcnlcbiAgICAgICAgLnJhbmRvbUNob2ljZXMoU2xpcDM5SGVscGVyLldPUkRfTElTVCwgdGhpcy5MQk9QX1dPUkRTKVxuICAgICAgICAuam9pbignICcpO1xuICAgICAgY29uc3QgcGFydGlhbCA9IHRoaXMuZ2V0UGFydGlhbChsYm9wU3RyaW5nKTtcblxuICAgICAgaWYgKCFsYm9wcy5zb21lKChsYm9wKSA9PiBsYm9wLnBhcnRpYWwgPT09IHBhcnRpYWwpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGxib3BLZXlQYXJhbXMgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlTGJvcEtleVBhcmFtcygpO1xuICAgIGNvbnN0IGxib3BLZXkgPSAoXG4gICAgICBhd2FpdCB0aGlzLmtleUZhY3RvcnkuZGVyaXZlTGJvcEtleSh7XG4gICAgICAgIHBhc3N3b3JkOiBsYm9wU3RyaW5nLFxuICAgICAgICAuLi5sYm9wS2V5UGFyYW1zLFxuICAgICAgfSlcbiAgICApLmp3aztcblxuICAgIGNvbnN0IGxib3BLZXlWZXJpZmllciA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVTaWduS2V5KCk7XG4gICAgY29uc3Qgd3JhcHBlZExib3BLZXlWZXJpZmllciA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgIGxib3BLZXksXG4gICAgICBsYm9wS2V5VmVyaWZpZXIudG9KU09OKHRydWUpXG4gICAgKTtcblxuICAgIC8vIFJlLWVuY3J5cHQgbWFzdGVyIGtleSB3aXRoIG5ldyBrZXlcbiAgICBjb25zdCBjdXJyZW50VXNlciA9IGF3YWl0IHRoaXMuYXV0aFNlcnZpY2UuZ2V0VXNlcigpO1xuICAgIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHRoaXMua2V5R3JhcGguZ2V0S2V5KFxuICAgICAgY3VycmVudFVzZXIuY3VycmVudFVzZXJLZXkubWFzdGVyS2V5LmlkXG4gICAgKTtcbiAgICBjb25zdCB3cmFwcGVkTWFzdGVyS2V5ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgbGJvcEtleSxcbiAgICAgIG1hc3RlcktleS5qd2sudG9KU09OKHRydWUpXG4gICAgKTtcblxuICAgIGNvbnN0IG1ldGEgPSB7XG4gICAgICAuLi4obmFtZSAmJiB7IG5hbWUgfSksXG4gICAgICBwYXJ0aWFsOiB0aGlzLmdldFBhcnRpYWwobGJvcFN0cmluZyksXG4gICAgfTtcbiAgICBjb25zdCBjaXBoZXJNZXRhID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgbWFzdGVyS2V5Lmp3ayxcbiAgICAgIG1ldGFcbiAgICApO1xuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5sckFwb2xsby5tdXRhdGU8Q3JlYXRlTGJvcFF1ZXJ5Pih7XG4gICAgICBtdXRhdGlvbjogQ3JlYXRlTGJvcFF1ZXJ5LFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIGlucHV0OiB7XG4gICAgICAgICAgY2lwaGVyTWV0YTogSlNPTi5zdHJpbmdpZnkoY2lwaGVyTWV0YSksXG4gICAgICAgICAgbGJvcEtleVBhcmFtczogSlNPTi5zdHJpbmdpZnkobGJvcEtleVBhcmFtcyksXG4gICAgICAgICAgbGJvcEtleVZlcmlmaWVyOiBKU09OLnN0cmluZ2lmeShsYm9wS2V5VmVyaWZpZXIudG9KU09OKHRydWUpKSxcbiAgICAgICAgICB3cmFwcGVkTGJvcEtleVZlcmlmaWVyOiBKU09OLnN0cmluZ2lmeSh3cmFwcGVkTGJvcEtleVZlcmlmaWVyKSxcbiAgICAgICAgICBtYXN0ZXJLZXlJZDogY3VycmVudFVzZXIuY3VycmVudFVzZXJLZXkubWFzdGVyS2V5LmlkLFxuICAgICAgICAgIHdyYXBwZWRNYXN0ZXJLZXk6IEpTT04uc3RyaW5naWZ5KHdyYXBwZWRNYXN0ZXJLZXkpLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5yZXMuY3JlYXRlTGJvcC5sYm9wLFxuICAgICAgbGJvcFN0cmluZyxcbiAgICB9O1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gRmxvdyBiZWxvdyBhcmUgZm9yIHBhc3N3b3JkIHJlc2V0IHZpYSBMQk9QXG4gIC8vXG4gIC8vIC0tUG90ZW50aWFsIEZhaWx1cmUgUG9pbnQgeHh4LS1cbiAgLy9cbiAgLy8gTG9vayBmb3IgdGhlIGFib3ZlIGFuZCB5b3UgY2FuIHRlc3QgYnkgaW50ZXJydXB0aW5nIGF0IHRoZXNlIHBvaW50cy5cbiAgLy9cbiAgLy8gVGhlIExCT1AgcmVzZXQgcHJvY2VzcyBjYW4gYmUgcmVzdGFydGVkIGF0IGFueSBwb2ludCBiZWZvcmUgdGhlIGNhbGwgdG8gXCJzZXQtcGFzc3dvcmQvXCIuIE9uY2UgXCJzZXQtcGFzc3dvcmQvXCIgaGFzIGJlZW5cbiAgLy8gY2FsbGVkLCB3ZSBhc3N1bWUgdGhlIGNsaWVudCBoYXMgYSBzaG9ydCBwZXJpb2Qgb2YgdGltZSB0byBjaGFuZ2UgdGhlIElkcCBwYXNzd29yZCB0byB0aGUgb25lIHRoZXkndmUgY2hvc2VuLiBUaGUgXCJzZXQtcGFzc3dvcmQvXCJcbiAgLy8gd2lsbCBzZXQgdGhlIElkcCBwYXNzd29yZCB0byBhIHRlbXBvcmFyeSByYW5kb20gcGFzc3dvcmQuIFRoZSB1c2VyIGNhbiBubyBsb25nZXIgbG9naW4gdXNpbmcgdGhlaXIgY3VycmVudCBwYXNzd29yZC4gSWYgdGhlIElkcFxuICAvLyBwYXNzd29yZCBjaGFuZ2UgcHJvY2VzcyBkb2VzIG5vdCBjb21wbGV0ZSBvciB0YWtlcyBsb25nZXIgdGhhbiB0aGUgbG9ja291dCBwZXJpb2QsIHRoZSBhY2NvdW50IHdpbGwgbm90IGJlIGFjY2Vzc2libGUgYW5kIGEgbmV3XG4gIC8vIExCT1AgcGFzc3dvcmQgcmVzZXQgbXVzdCBiZSBjYXJyaWVkIG91dC5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgcHJpdmF0ZSBhc3luYyB2ZXJpZnlMYm9wcyhcbiAgICBjaGFsbGVuZ2VSZXN1bHQ6IENoYWxsZW5nZVJlc3VsdCxcbiAgICBsYm9wU3RyaW5nOiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGxib3A6IGFueTsgc2lnbmVkQ2hhbGxlbmdlOiBhbnk7IGxib3BLZXk6IEpXSy5LZXkgfT4ge1xuICAgIGNvbnN0IGNsaWVudE5vbmNlID0gdGhpcy5rZXlGYWN0b3J5LnJhbmRvbVN0cmluZyh0aGlzLkNMSUVOVF9OT05DRV9MRU5HVEgpO1xuXG4gICAgZm9yIChjb25zdCBsYm9wIG9mIGNoYWxsZW5nZVJlc3VsdC5sYm9wcykge1xuICAgICAgY29uc3QgbGJvcEtleSA9IChcbiAgICAgICAgYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmRlcml2ZUxib3BLZXkoe1xuICAgICAgICAgIHBhc3N3b3JkOiBsYm9wU3RyaW5nLFxuICAgICAgICAgIC4uLmxib3AubGJvcEtleVBhcmFtcyxcbiAgICAgICAgfSlcbiAgICAgICkuandrO1xuXG4gICAgICAvLyBJZiBkZWNvZGluZyBzdWNjZXNzZnVsIHRoZW4gaXQncyB0aGUgY29ycmVjdCBsYm9wXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBsYm9wS2V5VmVyaWZpZXIgPSAoYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxuICAgICAgICAgIGxib3BLZXksXG4gICAgICAgICAgbGJvcC53cmFwcGVkTGJvcEtleVZlcmlmaWVyXG4gICAgICAgICkpIGFzIGFueTtcblxuICAgICAgICAvLyBGb3JjZSBhIGJhZCBzaWduYXR1cmUuXG4gICAgICAgIC8vIGNvbnN0IHNlcnZlck5vbmNlID0gY2hhbGxlbmdlUmVzdWx0LmNoYWxsZW5nZS5zZXJ2ZXJOb25jZSArIFwiMVwiLFxuXG4gICAgICAgIGNvbnN0IHNlcnZlck5vbmNlID0gY2hhbGxlbmdlUmVzdWx0LmNoYWxsZW5nZS5zZXJ2ZXJOb25jZTtcblxuICAgICAgICBjb25zdCBzaWduZWRDaGFsbGVuZ2UgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXG4gICAgICAgICAgbGJvcEtleVZlcmlmaWVyLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNlcnZlck5vbmNlLFxuICAgICAgICAgICAgY2xpZW50Tm9uY2UsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbGJvcCxcbiAgICAgICAgICBzaWduZWRDaGFsbGVuZ2UsXG4gICAgICAgICAgbGJvcEtleSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH1cbiAgICB0aHJvdyBuZXcgTHJFeGNlcHRpb24oe1xuICAgICAgc291cmNlOiAnTEJPUCcsXG4gICAgICBjb2RlOiAnSU5WQUxJRF9QQVNTUEhSQVNFJyxcbiAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIHBhc3NwaHJhc2UuJyxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyB2ZXJpZnlDb250YWN0KFxuICAgIHBhcmFtczogVmVyaWZ5Q29udGFjdFBhcmFtc1xuICApOiBQcm9taXNlPFZlcmlmeUNvbnRhY3RSZXN1bHQ+IHtcbiAgICBjb25zdCByZXQgPSB0aGlzLmh0dHBcbiAgICAgIC5wb3N0PFZlcmlmeUNvbnRhY3RSZXN1bHQ+KFxuICAgICAgICBgJHt0aGlzLmNvbmZpZy5hdXRoVXJsfXVzZXJzL2xib3AtcmVzZXQvdmVyaWZ5LWNvbnRhY3QvYCxcbiAgICAgICAgcGFyYW1zXG4gICAgICApXG4gICAgICAudG9Qcm9taXNlKCk7XG5cbiAgICAvLyAtLVBvdGVudGlhbCBGYWlsdXJlIFBvaW50IDEgLS1cbiAgICAvLyBUaGUgY29udGFjdCB2ZXJpZmljYXRpb25zIGFyZSB0aHJvdHRsZWQuIEJ1dCBvdGhlcndpc2UgaGFybWxlc3MuXG5cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGNvbmZpcm1Db250YWN0KFxuICAgIHBhcmFtczogQ29uZmlybUNvbnRhY3RQYXJhbXNcbiAgKTogUHJvbWlzZTxDb25maXJtQ29udGFjdFJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLmh0dHBcbiAgICAgIC5wb3N0PENvbmZpcm1Db250YWN0UmVzdWx0PihgJHt0aGlzLmNvbmZpZy5hdXRoVXJsfWNvdmUvcmVzcG9uZC9gLCB7XG4gICAgICAgIGNsYWltX2lkOiBwYXJhbXMuY2xhaW1JZCxcbiAgICAgICAgdl9jb2RlOiBwYXJhbXMudkNvZGUsXG4gICAgICB9KVxuICAgICAgLnRvUHJvbWlzZSgpO1xuXG4gICAgLy8gLS1Qb3RlbnRpYWwgRmFpbHVyZSBQb2ludCAyIC0tXG4gICAgLy8gQSB2ZXJpZmllZCBjbGFpbSBmb3IgYSBjb250YWN0IGRvZXMgbm90IHByZXZlbnQgbmV3IG9uZXMgZnJvbSBiZWluZyBnZW5lcmF0ZWQuIFNvIGl0IHNob3VsZCBiZSBmaW5lIHRvIGp1c3Qgc3RhcnQgYWdhaW4uXG4gIH1cblxuICBwdWJsaWMgYXN5bmMgdmVyaWZ5KHBhcmFtczogVmVyaWZ5UGFyYW1zKTogUHJvbWlzZTxWZXJpZnlSZXN1bHQ+IHtcbiAgICBjb25zdCBjaGFsbGVuZ2VSZXN1bHQgPSBhd2FpdCB0aGlzLmh0dHBcbiAgICAgIC5wb3N0PENoYWxsZW5nZVJlc3VsdD4oXG4gICAgICAgIGAke3RoaXMuY29uZmlnLmF1dGhVcmx9dXNlcnMvbGJvcC1yZXNldC9nZXQtY2hhbGxlbmdlL2AsXG4gICAgICAgIHtcbiAgICAgICAgICBjbGFpbUlkOiBwYXJhbXMuY2xhaW1JZCxcbiAgICAgICAgICBjbGFpbVRva2VuOiBwYXJhbXMuY2xhaW1Ub2tlbixcbiAgICAgICAgfVxuICAgICAgKVxuICAgICAgLnRvUHJvbWlzZSgpO1xuXG4gICAgLy8gLS1Qb3RlbnRpYWwgRmFpbHVyZSBQb2ludCAzIC0tXG4gICAgLy8gVGhpcyBkb2VzIG5vdCBsb2NrIGFueXRoaW5nLiBBIHNlY29uZCBjYWxsIHRvIFwiZ2V0LWNoYWxsZW5nZS9cIiB3aWxsIGNyZWF0ZSBhIG5ldyBjaGFsbGVuZ2UgYW1kIGludmFsaWRhdGUgdGhlIGZpcnN0IG9uZS5cbiAgICBjb25zdCB7IHNpZ25lZENoYWxsZW5nZSwgbGJvcCwgbGJvcEtleSB9ID0gYXdhaXQgdGhpcy52ZXJpZnlMYm9wcyhcbiAgICAgIGNoYWxsZW5nZVJlc3VsdCxcbiAgICAgIHBhcmFtcy5sYm9wXG4gICAgKTtcblxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMuaHR0cFxuICAgICAgLnBvc3Q8YW55PihgJHt0aGlzLmNvbmZpZy5hdXRoVXJsfXVzZXJzL2xib3AtcmVzZXQvdmVyaWZ5LWNoYWxsZW5nZS9gLCB7XG4gICAgICAgIGxib3BJZDogbGJvcC5sYm9wSWQsXG4gICAgICAgIHNpZ25lZENoYWxsZW5nZSxcbiAgICAgIH0pXG4gICAgICAudG9Qcm9taXNlKCk7XG5cbiAgICAvLyAtLVBvdGVudGlhbCBGYWlsdXJlIFBvaW50IDQgLS1cbiAgICAvLyBUaGlzIGRvZXMgbm90IGxvY2sgYW55dGhpbmcuIFNvIG9rIHRvIHJlc3RhcnQuXG5cbiAgICByZXR1cm4ge1xuICAgICAgbGJvcElkOiBsYm9wLmxib3BJZCxcbiAgICAgIHZlcmlmaWVkVG9rZW46IHJlcy52ZXJpZmllZFRva2VuLFxuICAgICAgbWFzdGVyS2V5SWQ6IHJlcy5tYXN0ZXJLZXlJZCxcbiAgICAgIG1hc3RlcktleTogYXdhaXQgS0ZTLmFzS2V5KFxuICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQobGJvcEtleSwgcmVzLndyYXBwZWRNYXN0ZXJLZXkpXG4gICAgICApLFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc2V0UGFzc3dvcmQocGFyYW1zOiBTZXRQYXNzd29yZFBhcmFtcyk6IFByb21pc2U8YW55PiB7XG4gICAgLy8gR2VuZXJhdGUgdGhlIG5ldyBwYXNzd29yZCBkZXJpdmVkIGtleXNcbiAgICBjb25zdCBwYXNzS2V5QnVuZGxlID0gYXdhaXQgdGhpcy5wYXNzd29yZFNlcnZpY2UuY3JlYXRlUGFzc0tleUJ1bmRsZShcbiAgICAgIHBhcmFtcy5uZXdQYXNzd29yZFxuICAgICk7XG5cbiAgICAvLyBSZS1lbmNyeXB0IG1hc3RlciBrZXkgd2l0aCBuZXcga2V5XG4gICAgY29uc3QgbmV3V3JhcHBlZE1hc3RlcktleSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgIHBhc3NLZXlCdW5kbGUucGFzc0tleSxcbiAgICAgIHBhcmFtcy5tYXN0ZXJLZXkudG9KU09OKHRydWUpXG4gICAgKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuaHR0cFxuICAgICAgLnBvc3Q8U2V0UGFzc3dvcmRBcGlSZXN1bHQ+KFxuICAgICAgICBgJHt0aGlzLmNvbmZpZy5hdXRoVXJsfXVzZXJzL2xib3AtcmVzZXQvc2V0LXBhc3N3b3JkL2AsXG4gICAgICAgIHtcbiAgICAgICAgICBsYm9wSWQ6IHBhcmFtcy5sYm9wSWQsXG4gICAgICAgICAgdmVyaWZpZWRUb2tlbjogcGFyYW1zLnZlcmlmaWVkVG9rZW4sXG4gICAgICAgICAgbWFzdGVyS2V5SWQ6IHBhcmFtcy5tYXN0ZXJLZXlJZCxcbiAgICAgICAgICBuZXdXcmFwcGVkTWFzdGVyS2V5LFxuICAgICAgICAgIG5ld1Bhc3NLZXk6IHtcbiAgICAgICAgICAgIHBhc3NLZXlQYXJhbXM6IHBhc3NLZXlCdW5kbGUucGFzc0tleVBhcmFtcyxcbiAgICAgICAgICAgIHBhc3NJZHBQYXJhbXM6IHBhc3NLZXlCdW5kbGUucGFzc0lkcFBhcmFtcyxcbiAgICAgICAgICAgIHBhc3NJZHBWZXJpZmllclBiazogcGFzc0tleUJ1bmRsZS5wYXNzSWRwVmVyaWZpZXIudG9KU09OKCksXG4gICAgICAgICAgICB3cmFwcGVkUGFzc0lkcFZlcmlmaWVyUHJrOiBwYXNzS2V5QnVuZGxlLndyYXBwZWRQYXNzSWRwVmVyaWZpZXJQcmssXG4gICAgICAgICAgfSxcbiAgICAgICAgfVxuICAgICAgKVxuICAgICAgLnRvUHJvbWlzZSgpO1xuXG4gICAgLy8gLS1Qb3RlbnRpYWwgRmFpbHVyZSBQb2ludCA1IC0tXG4gICAgLy8gQSB0aW1lZCBtdXRleCBpcyBsb2NrZWQuIFRoZSBJZHAgcGFzc3dvcmQgY2hhbmdlIG11c3Qgb2NjdXIgd2l0aGluIGEgcGVyaW9kIG9mIHRpbWUuXG4gICAgLy8gSWYgaW50ZXJydXB0ZWQgaGVyZSwgdGhlIHVzZXIgY2FuIG5vdCBsb2dpbiB3aXRoIHRoZWlyIG9sZCBwYXNzd29yZCBhZ2Fpbi4gVGhleSBtdXN0XG4gICAgLy8gc3RhcnQgdGhlIHdob2xlIExCT1AgcGFzc3dvcmQgcmVzZXQgcHJvY2VzcyBhZ2Fpbi5cblxuICAgIC8vIFRoaXMgY2FsbCB3aWxsIGdvIHRocm91Z2ggdGhlIExSIHByb3h5IHdoaWNoIGlzIE9LIHNpbmNlIHRoZSBMUiBzZXJ2ZXIga25vd3NcbiAgICAvLyB0aGUgdGVtcG9yYXJ5IHBhc3N3b3JkIGFueXdheS5cbiAgICBsZXQgdXNlciA9IGF3YWl0IHRoaXMuYXV0aC5zaWduSW4ocmVzdWx0LnVzZXJuYW1lLCByZXN1bHQuaWRwUGFzc3dvcmQsIHtcbiAgICAgIG5vUHJveHk6ICd0cnVlJyxcbiAgICB9KTtcblxuICAgIGlmICh1c2VyLmNoYWxsZW5nZU5hbWUgIT09ICdORVdfUEFTU1dPUkRfUkVRVUlSRUQnKSB7XG4gICAgICB0aHJvdyBuZXcgTHJFeGNlcHRpb24oe1xuICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgICdJbnRlcm5hbCBlcnJvci4gRXhwZWN0aW5nIENvZ25pdG8gdG8gaGF2ZSBkb25lIGEgcGFzc3dvcmQgcmVzZXQuJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIC0tUG90ZW50aWFsIEZhaWx1cmUgUG9pbnQgNiAtLVxuICAgIC8vIE11c3QgcmVzdGFydCB0aGUgTEJPUCBwYXNzd29yZCByZXNldCBwcm9jZXNzIGFnYWluLlxuXG4gICAgLy8gU2V0IG5ldyBwYXNzd29yZCBvbiBJZHBcbiAgICB1c2VyID0gYXdhaXQgdGhpcy5hdXRoLmNvbXBsZXRlTmV3UGFzc3dvcmQoXG4gICAgICB1c2VyLFxuICAgICAgdGhpcy5wYXNzd29yZFNlcnZpY2UuZ2V0UGFzc0lkcFN0cmluZyhwYXNzS2V5QnVuZGxlLnBhc3NJZHApLFxuICAgICAge31cbiAgICApO1xuXG4gICAgLy8gLS1Qb3RlbnRpYWwgRmFpbHVyZSBQb2ludCA3IC0tXG4gICAgLy8gTXVzdCByZXN0YXJ0IHRoZSBMQk9QIHBhc3N3b3JkIHJlc2V0IHByb2Nlc3MgYWdhaW4uXG5cbiAgICBhd2FpdCB0aGlzLmF1dGguc2lnbk91dCgpO1xuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuaHR0cFxuICAgICAgLnBvc3Q8YW55PihgJHt0aGlzLmNvbmZpZy5hdXRoVXJsfXVzZXJzL2xib3AtcmVzZXQvY29tcGxldGUvYCwge1xuICAgICAgICBsYm9wSWQ6IHBhcmFtcy5sYm9wSWQsXG4gICAgICAgIHNldFBhc3N3b3JkVG9rZW46IHJlc3VsdC5zZXRQYXNzd29yZFRva2VuLFxuICAgICAgfSlcbiAgICAgIC50b1Byb21pc2UoKTtcbiAgfVxufVxuIl19
|