@lifeready/core 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/README.md +62 -62
  2. package/bundles/lifeready-core.umd.js +15445 -15445
  3. package/bundles/lifeready-core.umd.js.map +1 -1
  4. package/bundles/lifeready-core.umd.min.js.map +1 -1
  5. package/esm2015/lib/_common/ast.js +40 -40
  6. package/esm2015/lib/_common/deferred-promise.js +24 -24
  7. package/esm2015/lib/_common/exceptions.js +157 -157
  8. package/esm2015/lib/_common/queries.gql.js +190 -190
  9. package/esm2015/lib/_common/run-outside-angular.js +79 -79
  10. package/esm2015/lib/_common/types.js +1 -1
  11. package/esm2015/lib/_common/utils.js +44 -44
  12. package/esm2015/lib/api/contact-card.gql.js +79 -79
  13. package/esm2015/lib/api/contact-card.service.js +154 -154
  14. package/esm2015/lib/api/contact-card2.gql.js +60 -60
  15. package/esm2015/lib/api/contact-card2.service.js +103 -103
  16. package/esm2015/lib/api/file.service.js +74 -74
  17. package/esm2015/lib/api/item2.gql.js +110 -110
  18. package/esm2015/lib/api/item2.service.js +311 -311
  19. package/esm2015/lib/api/key-exchange.gql.js +188 -188
  20. package/esm2015/lib/api/key-exchange.service.js +442 -442
  21. package/esm2015/lib/api/key-exchange.types.js +18 -18
  22. package/esm2015/lib/api/key-exchange2.gql.js +171 -171
  23. package/esm2015/lib/api/key-exchange2.service.js +479 -479
  24. package/esm2015/lib/api/lock.gql.js +40 -40
  25. package/esm2015/lib/api/lock.service.js +64 -64
  26. package/esm2015/lib/api/lr-apollo.service.js +46 -46
  27. package/esm2015/lib/api/lr-graphql/index.js +6 -6
  28. package/esm2015/lib/api/lr-graphql/lr-graphql.service.js +155 -155
  29. package/esm2015/lib/api/lr-graphql/lr-merged-mutation.js +213 -213
  30. package/esm2015/lib/api/lr-graphql/lr-mutation-base.js +51 -51
  31. package/esm2015/lib/api/lr-graphql/lr-mutation.js +48 -48
  32. package/esm2015/lib/api/lr-graphql/lr.service.js +18 -18
  33. package/esm2015/lib/api/message.service.js +138 -138
  34. package/esm2015/lib/api/persist.service.js +181 -181
  35. package/esm2015/lib/api/query-processor/common-processors.service.js +93 -93
  36. package/esm2015/lib/api/query-processor/index.js +3 -3
  37. package/esm2015/lib/api/query-processor/query-processor.service.js +192 -192
  38. package/esm2015/lib/api/query-processor/tp-password-reset-processor.service.js +109 -109
  39. package/esm2015/lib/api/shared-contact-card.service.js +119 -119
  40. package/esm2015/lib/api/shared-contact-card2.gql.js +41 -41
  41. package/esm2015/lib/api/shared-contact-card2.service.js +117 -117
  42. package/esm2015/lib/api/time.service.js +146 -146
  43. package/esm2015/lib/api/types/graphql.types.js +7 -7
  44. package/esm2015/lib/api/types/index.js +3 -3
  45. package/esm2015/lib/api/types/lr-graphql.types.js +71 -71
  46. package/esm2015/lib/auth/auth.config.js +57 -57
  47. package/esm2015/lib/auth/auth.gql.js +48 -48
  48. package/esm2015/lib/auth/auth.types.js +27 -27
  49. package/esm2015/lib/auth/idle.service.js +168 -168
  50. package/esm2015/lib/auth/idle.types.js +7 -7
  51. package/esm2015/lib/auth/lbop.service.js +355 -355
  52. package/esm2015/lib/auth/life-ready-auth.service.js +500 -500
  53. package/esm2015/lib/auth/password.service.js +320 -320
  54. package/esm2015/lib/auth/register.service.js +172 -172
  55. package/esm2015/lib/auth/two-factor.service.js +74 -74
  56. package/esm2015/lib/category/category-meta.service.js +99 -99
  57. package/esm2015/lib/category/category.gql.js +406 -406
  58. package/esm2015/lib/category/category.service.js +390 -390
  59. package/esm2015/lib/category/category.types.js +29 -29
  60. package/esm2015/lib/cryptography/cryptography.types.js +11 -11
  61. package/esm2015/lib/cryptography/encryption.service.js +189 -189
  62. package/esm2015/lib/cryptography/key-factory.service.js +237 -237
  63. package/esm2015/lib/cryptography/key-graph.service.js +280 -280
  64. package/esm2015/lib/cryptography/key-meta.service.js +200 -200
  65. package/esm2015/lib/cryptography/key.service.js +124 -124
  66. package/esm2015/lib/cryptography/slip39.service.js +169 -169
  67. package/esm2015/lib/cryptography/web-crypto.service.js +29 -29
  68. package/esm2015/lib/life-ready.config.js +84 -84
  69. package/esm2015/lib/life-ready.module.js +74 -74
  70. package/esm2015/lib/plan/plan.gql.js +123 -123
  71. package/esm2015/lib/plan/plan.service.js +149 -149
  72. package/esm2015/lib/plan/plan.types.js +11 -11
  73. package/esm2015/lib/record/record-attachment.service.js +101 -101
  74. package/esm2015/lib/record/record.gql.js +179 -179
  75. package/esm2015/lib/record/record.service.js +206 -206
  76. package/esm2015/lib/record/record.types.js +15 -15
  77. package/esm2015/lib/record-type/record-type.service.js +75 -75
  78. package/esm2015/lib/record-type/record-type.types.js +28 -28
  79. package/esm2015/lib/scenario/approvals/scenario-approval.gql.js +105 -105
  80. package/esm2015/lib/scenario/approvals/scenario-approval.types.js +1 -1
  81. package/esm2015/lib/scenario/approvals/scenario-approver.service.js +300 -300
  82. package/esm2015/lib/scenario/claimants/scenario-claimant.gql.js +52 -52
  83. package/esm2015/lib/scenario/claimants/scenario-claimant.service.js +97 -97
  84. package/esm2015/lib/scenario/claimants/scenario-claimant.types.js +1 -1
  85. package/esm2015/lib/scenario/receivers/scenario-receiver.gql.js +150 -150
  86. package/esm2015/lib/scenario/receivers/scenario-receiver.service.js +229 -229
  87. package/esm2015/lib/scenario/receivers/scenario-receiver.types.js +1 -1
  88. package/esm2015/lib/scenario/scenario-setup.service.js +269 -269
  89. package/esm2015/lib/scenario/scenario.gql.js +368 -368
  90. package/esm2015/lib/scenario/scenario.service.js +611 -611
  91. package/esm2015/lib/scenario/scenario.types.js +64 -64
  92. package/esm2015/lib/search/search.gql.js +62 -62
  93. package/esm2015/lib/search/search.service.js +156 -156
  94. package/esm2015/lib/search/search.types.js +6 -6
  95. package/esm2015/lib/trusted-parties/tp-password-reset-request.service.js +112 -112
  96. package/esm2015/lib/trusted-parties/tp-password-reset-user.service.js +129 -129
  97. package/esm2015/lib/trusted-parties/tp-password-reset.constants.js +4 -4
  98. package/esm2015/lib/trusted-parties/tp-password-reset.gql.js +232 -232
  99. package/esm2015/lib/trusted-parties/tp-password-reset.service.js +299 -299
  100. package/esm2015/lib/trusted-parties/trusted-party.gql.js +148 -148
  101. package/esm2015/lib/trusted-parties/trusted-party.service.js +326 -326
  102. package/esm2015/lib/trusted-parties/trusted-party.types.js +41 -41
  103. package/esm2015/lib/trusted-parties/trusted-party2.gql.js +87 -87
  104. package/esm2015/lib/trusted-parties/trusted-party2.service.js +215 -215
  105. package/esm2015/lib/users/profile-details.service.js +214 -214
  106. package/esm2015/lib/users/profile.gql.js +97 -97
  107. package/esm2015/lib/users/profile.service.js +169 -169
  108. package/esm2015/lib/users/profile.types.js +34 -34
  109. package/esm2015/lib/users/user.gql.js +60 -60
  110. package/esm2015/lib/users/user.service.js +79 -79
  111. package/esm2015/lib/users/user.types.js +5 -5
  112. package/esm2015/lifeready-core.js +10 -10
  113. package/esm2015/public-api.js +81 -81
  114. package/fesm2015/lifeready-core.js +13088 -13088
  115. package/fesm2015/lifeready-core.js.map +1 -1
  116. package/lib/_common/ast.d.ts +11 -11
  117. package/lib/_common/deferred-promise.d.ts +12 -12
  118. package/lib/_common/exceptions.d.ts +109 -109
  119. package/lib/_common/queries.gql.d.ts +10 -10
  120. package/lib/_common/run-outside-angular.d.ts +14 -14
  121. package/lib/_common/types.d.ts +10 -10
  122. package/lib/_common/utils.d.ts +3 -3
  123. package/lib/api/contact-card.gql.d.ts +7 -7
  124. package/lib/api/contact-card.service.d.ts +52 -52
  125. package/lib/api/contact-card2.gql.d.ts +34 -34
  126. package/lib/api/contact-card2.service.d.ts +49 -49
  127. package/lib/api/file.service.d.ts +18 -18
  128. package/lib/api/item2.gql.d.ts +96 -96
  129. package/lib/api/item2.service.d.ts +177 -177
  130. package/lib/api/key-exchange.gql.d.ts +9 -9
  131. package/lib/api/key-exchange.service.d.ts +39 -39
  132. package/lib/api/key-exchange.types.d.ts +196 -196
  133. package/lib/api/key-exchange2.gql.d.ts +125 -125
  134. package/lib/api/key-exchange2.service.d.ts +187 -187
  135. package/lib/api/lock.gql.d.ts +27 -27
  136. package/lib/api/lock.service.d.ts +25 -25
  137. package/lib/api/lr-apollo.service.d.ts +15 -15
  138. package/lib/api/lr-graphql/index.d.ts +5 -5
  139. package/lib/api/lr-graphql/lr-graphql.service.d.ts +60 -60
  140. package/lib/api/lr-graphql/lr-merged-mutation.d.ts +27 -27
  141. package/lib/api/lr-graphql/lr-mutation-base.d.ts +28 -28
  142. package/lib/api/lr-graphql/lr-mutation.d.ts +8 -8
  143. package/lib/api/lr-graphql/lr.service.d.ts +9 -9
  144. package/lib/api/message.service.d.ts +58 -58
  145. package/lib/api/persist.service.d.ts +31 -31
  146. package/lib/api/query-processor/common-processors.service.d.ts +36 -36
  147. package/lib/api/query-processor/index.d.ts +2 -2
  148. package/lib/api/query-processor/query-processor.service.d.ts +18 -18
  149. package/lib/api/query-processor/tp-password-reset-processor.service.d.ts +15 -15
  150. package/lib/api/shared-contact-card.service.d.ts +33 -33
  151. package/lib/api/shared-contact-card2.gql.d.ts +36 -36
  152. package/lib/api/shared-contact-card2.service.d.ts +45 -45
  153. package/lib/api/time.service.d.ts +16 -16
  154. package/lib/api/types/graphql.types.d.ts +29 -29
  155. package/lib/api/types/index.d.ts +2 -2
  156. package/lib/api/types/lr-graphql.types.d.ts +385 -385
  157. package/lib/auth/auth.config.d.ts +5 -5
  158. package/lib/auth/auth.gql.d.ts +15 -15
  159. package/lib/auth/auth.types.d.ts +66 -66
  160. package/lib/auth/idle.service.d.ts +40 -40
  161. package/lib/auth/idle.types.d.ts +10 -10
  162. package/lib/auth/lbop.service.d.ts +91 -91
  163. package/lib/auth/life-ready-auth.service.d.ts +59 -59
  164. package/lib/auth/password.service.d.ts +78 -78
  165. package/lib/auth/register.service.d.ts +25 -25
  166. package/lib/auth/two-factor.service.d.ts +15 -15
  167. package/lib/category/category-meta.service.d.ts +23 -23
  168. package/lib/category/category.gql.d.ts +45 -45
  169. package/lib/category/category.service.d.ts +67 -67
  170. package/lib/category/category.types.d.ts +79 -79
  171. package/lib/cryptography/cryptography.types.d.ts +83 -83
  172. package/lib/cryptography/encryption.service.d.ts +41 -41
  173. package/lib/cryptography/key-factory.service.d.ts +38 -38
  174. package/lib/cryptography/key-graph.service.d.ts +33 -33
  175. package/lib/cryptography/key-meta.service.d.ts +44 -44
  176. package/lib/cryptography/key.service.d.ts +36 -36
  177. package/lib/cryptography/slip39.service.d.ts +43 -43
  178. package/lib/cryptography/web-crypto.service.d.ts +5 -5
  179. package/lib/life-ready.config.d.ts +14 -14
  180. package/lib/life-ready.module.d.ts +5 -5
  181. package/lib/plan/plan.gql.d.ts +11 -11
  182. package/lib/plan/plan.service.d.ts +33 -33
  183. package/lib/plan/plan.types.d.ts +31 -31
  184. package/lib/record/record-attachment.service.d.ts +16 -16
  185. package/lib/record/record.gql.d.ts +14 -14
  186. package/lib/record/record.service.d.ts +25 -25
  187. package/lib/record/record.types.d.ts +57 -57
  188. package/lib/record-type/record-type.service.d.ts +11 -11
  189. package/lib/record-type/record-type.types.d.ts +50 -50
  190. package/lib/scenario/approvals/scenario-approval.gql.d.ts +7 -7
  191. package/lib/scenario/approvals/scenario-approval.types.d.ts +63 -63
  192. package/lib/scenario/approvals/scenario-approver.service.d.ts +32 -32
  193. package/lib/scenario/claimants/scenario-claimant.gql.d.ts +5 -5
  194. package/lib/scenario/claimants/scenario-claimant.service.d.ts +17 -17
  195. package/lib/scenario/claimants/scenario-claimant.types.d.ts +18 -18
  196. package/lib/scenario/receivers/scenario-receiver.gql.d.ts +8 -8
  197. package/lib/scenario/receivers/scenario-receiver.service.d.ts +30 -30
  198. package/lib/scenario/receivers/scenario-receiver.types.d.ts +54 -54
  199. package/lib/scenario/scenario-setup.service.d.ts +22 -22
  200. package/lib/scenario/scenario.gql.d.ts +34 -34
  201. package/lib/scenario/scenario.service.d.ts +58 -58
  202. package/lib/scenario/scenario.types.d.ts +217 -217
  203. package/lib/search/search.gql.d.ts +1 -1
  204. package/lib/search/search.service.d.ts +25 -25
  205. package/lib/search/search.types.d.ts +20 -20
  206. package/lib/trusted-parties/tp-password-reset-request.service.d.ts +20 -20
  207. package/lib/trusted-parties/tp-password-reset-user.service.d.ts +35 -35
  208. package/lib/trusted-parties/tp-password-reset.constants.d.ts +3 -3
  209. package/lib/trusted-parties/tp-password-reset.gql.d.ts +218 -218
  210. package/lib/trusted-parties/tp-password-reset.service.d.ts +130 -130
  211. package/lib/trusted-parties/trusted-party.gql.d.ts +9 -9
  212. package/lib/trusted-parties/trusted-party.service.d.ts +44 -44
  213. package/lib/trusted-parties/trusted-party.types.d.ts +102 -102
  214. package/lib/trusted-parties/trusted-party2.gql.d.ts +79 -79
  215. package/lib/trusted-parties/trusted-party2.service.d.ts +114 -114
  216. package/lib/users/profile-details.service.d.ts +21 -21
  217. package/lib/users/profile.gql.d.ts +11 -11
  218. package/lib/users/profile.service.d.ts +35 -35
  219. package/lib/users/profile.types.d.ts +96 -96
  220. package/lib/users/user.gql.d.ts +9 -9
  221. package/lib/users/user.service.d.ts +12 -12
  222. package/lib/users/user.types.d.ts +23 -23
  223. package/lifeready-core.d.ts +9 -9
  224. package/package.json +1 -1
  225. package/public-api.d.ts +77 -77
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGJvcC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IkM6L1Byb2plY3RzL25ld3JlcG8va2MtY2xpZW50L3Byb2plY3RzL2NvcmUvc3JjLyIsInNvdXJjZXMiOlsibGliL2F1dGgvbGJvcC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRCxPQUFPLEdBQUcsTUFBTSxhQUFhLENBQUM7QUFFOUIsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDdkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN6RCxPQUFPLEVBQW1CLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xFLE9BQU8sRUFDTCxXQUFXLEVBRVgsbUJBQW1CLEdBQ3BCLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDakUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDdEMsT0FBTyxFQUFFLGlCQUFpQixJQUFJLEdBQUcsRUFBRSxNQUFNLHFDQUFxQyxDQUFDOzs7Ozs7Ozs7Ozs7QUF5RS9FLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxHQUFHLENBQUE7Ozs7Ozs7O0NBUWpDLENBQUM7QUFNRixNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsR0FBRyxDQUFB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LENBQUM7UUFDakIsQ0FBQztLQUFBOzs7O1lBM1hGLFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQjs7OzRDQU9JLE1BQU0sU0FBQyxTQUFTO1lBdEtaLFVBQVU7WUFEVixlQUFlO1lBR2YsU0FBUztZQVlULG9CQUFvQjtZQUdDLEdBQUc7WUFWeEIsVUFBVTtZQUZWLGlCQUFpQjtZQUNqQixlQUFlO1lBU2YsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExyQXBvbGxvU2VydmljZSB9IGZyb20gJy4uL2FwaS9sci1hcG9sbG8uc2VydmljZSc7XHJcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBBdXRoQ2xhc3MgfSBmcm9tICdAYXdzLWFtcGxpZnkvYXV0aC9saWItZXNtL0F1dGgnO1xyXG5pbXBvcnQgZ3FsIGZyb20gJ2dyYXBocWwtdGFnJztcclxuaW1wb3J0IHsgSldLIH0gZnJvbSAnbm9kZS1qb3NlJztcclxuaW1wb3J0IHsgRW5jcnlwdGlvblNlcnZpY2UgfSBmcm9tICcuLi9jcnlwdG9ncmFwaHkvZW5jcnlwdGlvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgS2V5R3JhcGhTZXJ2aWNlIH0gZnJvbSAnLi4vY3J5cHRvZ3JhcGh5L2tleS1ncmFwaC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgS2V5U2VydmljZSB9IGZyb20gJy4uL2NyeXB0b2dyYXBoeS9rZXkuc2VydmljZSc7XHJcbmltcG9ydCB7IExpZmVSZWFkeUNvbmZpZywgTFJfQ09ORklHIH0gZnJvbSAnLi4vbGlmZS1yZWFkeS5jb25maWcnO1xyXG5pbXBvcnQge1xyXG4gIExyRXhjZXB0aW9uLFxyXG4gIExyRXJyb3JDb2RlLFxyXG4gIExyQmFkTG9naWNFeGNlcHRpb24sXHJcbn0gZnJvbSAnLi4vX2NvbW1vbi9leGNlcHRpb25zJztcclxuaW1wb3J0IHsgTGlmZVJlYWR5QXV0aFNlcnZpY2UgfSBmcm9tICcuL2xpZmUtcmVhZHktYXV0aC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgUGFzc3dvcmRTZXJ2aWNlIH0gZnJvbSAnLi9wYXNzd29yZC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgU2xpcDM5SGVscGVyIH0gZnJvbSAnc2xpcDM5JztcclxuaW1wb3J0IHsgS2V5RmFjdG9yeVNlcnZpY2UgYXMgS0ZTIH0gZnJvbSAnLi4vY3J5cHRvZ3JhcGh5L2tleS1mYWN0b3J5LnNlcnZpY2UnO1xyXG5cclxuaW50ZXJmYWNlIFNldFBhc3N3b3JkQXBpUmVzdWx0IHtcclxuICB1c2VybmFtZTogc3RyaW5nO1xyXG4gIGlkcFBhc3N3b3JkOiBzdHJpbmc7XHJcbiAgc2V0UGFzc3dvcmRUb2tlbjogc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFNldFBhc3N3b3JkUGFyYW1zIHtcclxuICBsYm9wSWQ6IHN0cmluZztcclxuICBuZXdQYXNzd29yZDogc3RyaW5nO1xyXG4gIHZlcmlmaWVkVG9rZW46IHN0cmluZztcclxuICBtYXN0ZXJLZXlJZDogc3RyaW5nO1xyXG4gIG1hc3RlcktleTogSldLLktleTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBWZXJpZnlDb250YWN0UGFyYW1zIHtcclxuICBlbWFpbD86IHN0cmluZztcclxuICBwaG9uZT86IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBWZXJpZnlDb250YWN0UmVzdWx0IHtcclxuICAvLyBUaGUgY2xhaW1faWQgaWRlbnRpZmllcyB0aGUgRW1haWwvU01TIGNvbmZpcm1hdGlvblxyXG4gIGNsYWltSWQ6IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBDb25maXJtQ29udGFjdFBhcmFtcyB7XHJcbiAgY2xhaW1JZDogc3RyaW5nO1xyXG4gIHZDb2RlOiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQ29uZmlybUNvbnRhY3RSZXN1bHQge1xyXG4gIC8vIFRoZSB0b2tlbiB0byBwcm92ZSB0aGUgY2xpZW50IGhhZCB0aGUgY29ycmVjdCBjb25maXJtYXRpb24gY29kZS5cclxuICB0b2tlbjogc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFZlcmlmeVBhcmFtcyB7XHJcbiAgY2xhaW1JZDogc3RyaW5nO1xyXG4gIGNsYWltVG9rZW46IHN0cmluZztcclxuICBsYm9wOiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVmVyaWZ5UmVzdWx0IHtcclxuICAvLyB1c2VySWQ6IHN0cmluZztcclxuICBsYm9wSWQ6IHN0cmluZztcclxuICB2ZXJpZmllZFRva2VuOiBzdHJpbmc7XHJcbiAgbWFzdGVyS2V5SWQ6IHN0cmluZztcclxuICBtYXN0ZXJLZXk6IEpXSy5LZXk7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQ2hhbGxlbmdlUmVzdWx0IHtcclxuICBjaGFsbGVuZ2U6IGFueTtcclxuICBsYm9wczogYW55O1xyXG4gIC8vIHVzZXJJZDogc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIExib3Age1xyXG4gIGlkOiBzdHJpbmc7XHJcbiAgcGFydGlhbD86IHN0cmluZztcclxuICBuYW1lPzogc3RyaW5nO1xyXG4gIGxib3BTdHJpbmc/OiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlTGJvcFBhcmFtcyB7XHJcbiAgbmFtZT86IHN0cmluZztcclxufVxyXG5cclxuaW50ZXJmYWNlIENyZWF0ZUxib3BRdWVyeSB7XHJcbiAgY3JlYXRlTGJvcDoge1xyXG4gICAgbGJvcDogTGJvcDtcclxuICB9O1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgQ3JlYXRlTGJvcFF1ZXJ5ID0gZ3FsYFxyXG4gIG11dGF0aW9uIENyZWF0ZUxib3AoJGlucHV0OiBDcmVhdGVMYm9wSW5wdXQhKSB7XHJcbiAgICBjcmVhdGVMYm9wKGlucHV0OiAkaW5wdXQpIHtcclxuICAgICAgbGJvcCB7XHJcbiAgICAgICAgaWRcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuYDtcclxuXHJcbmludGVyZmFjZSBEZWxldGVMYm9wUXVlcnkge1xyXG4gIGRlbGV0ZUxib3A6IExib3A7XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBEZWxldGVMYm9wUXVlcnkgPSBncWxgXHJcbiAgbXV0YXRpb24gRGVsZXRlTGJvcCgkaW5wdXQ6IERlbGV0ZUxib3BJbnB1dCEpIHtcclxuICAgIGRlbGV0ZUxib3AoaW5wdXQ6ICRpbnB1dCkge1xyXG4gICAgICBpZFxyXG4gICAgfVxyXG4gIH1cclxuYDtcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVXBkYXRlTGJvcFBhcmFtcyB7XHJcbiAgaWQ6IHN0cmluZztcclxuICBuYW1lOiBzdHJpbmc7XHJcbn1cclxuXHJcbmludGVyZmFjZSBVcGRhdGVMYm9wUXVlcnkge1xyXG4gIHVwZGF0ZUxib3A6IExib3A7XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBVcGRhdGVMYm9wUXVlcnkgPSBncWxgXHJcbiAgbXV0YXRpb24gVXBkYXRlTGJvcCgkaW5wdXQ6IFVwZGF0ZUxib3BJbnB1dCEpIHtcclxuICAgIHVwZGF0ZUxib3AoaW5wdXQ6ICRpbnB1dCkge1xyXG4gICAgICBsYm9wIHtcclxuICAgICAgICBpZFxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5gO1xyXG5cclxuZXhwb3J0IGNvbnN0IExib3BRdWVyeSA9IGdxbGBcclxuICBxdWVyeSBMYm9wKCRpZDogTHJSZWxheUlkSW5wdXQhKSB7XHJcbiAgICBsYm9wKGlkOiAkaWQpIHtcclxuICAgICAgaWRcclxuICAgICAgY2lwaGVyTWV0YVxyXG4gICAgfVxyXG4gIH1cclxuYDtcclxuXHJcbmludGVyZmFjZSBMYm9wc1F1ZXJ5IHtcclxuICBsYm9wczogYW55O1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgTGJvcHNRdWVyeSA9IGdxbGBcclxuICBxdWVyeSBMYm9wcyB7XHJcbiAgICBsYm9wcyB7XHJcbiAgICAgIGVkZ2VzIHtcclxuICAgICAgICBub2RlIHtcclxuICAgICAgICAgIGlkXHJcbiAgICAgICAgICBjaXBoZXJNZXRhXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5gO1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIExib3BTZXJ2aWNlIHtcclxuICBwcml2YXRlIHJlYWRvbmx5IENMSUVOVF9OT05DRV9MRU5HVEggPSAzMjtcclxuICAvLyBUaGVyZSBhcmUgMTAyNCB3b3JkcyAoMTAgYml0cyksIHNvIDI1IHdvcmRzIHNob3VsZCBnaXZlIH4yNTYgYml0cyBvZiBlbnRyb3B5LlxyXG4gIHByaXZhdGUgcmVhZG9ubHkgTEJPUF9XT1JEUyA9IDI1O1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIEBJbmplY3QoTFJfQ09ORklHKSBwcml2YXRlIGNvbmZpZzogTGlmZVJlYWR5Q29uZmlnLFxyXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxyXG4gICAgcHJpdmF0ZSBsckFwb2xsbzogTHJBcG9sbG9TZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBhdXRoOiBBdXRoQ2xhc3MsXHJcbiAgICBwcml2YXRlIGF1dGhTZXJ2aWNlOiBMaWZlUmVhZHlBdXRoU2VydmljZSxcclxuICAgIHByaXZhdGUga2V5RmFjdG9yeTogS0ZTLFxyXG4gICAgcHJpdmF0ZSBrZXlTZXJ2aWNlOiBLZXlTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBlbmNyeXB0aW9uU2VydmljZTogRW5jcnlwdGlvblNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGtleUdyYXBoOiBLZXlHcmFwaFNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHBhc3N3b3JkU2VydmljZTogUGFzc3dvcmRTZXJ2aWNlXHJcbiAgKSB7fVxyXG5cclxuICBwcml2YXRlIGdldFBhcnRpYWwobGJvcFN0cmluZzogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBsYm9wU3RyaW5nLnNwbGl0KCcgJylbMF07XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYXN5bmMgcmVtb3ZlKGlkOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5sckFwb2xsby5tdXRhdGU8YW55Pih7XHJcbiAgICAgIG11dGF0aW9uOiBEZWxldGVMYm9wUXVlcnksXHJcbiAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgIGlucHV0OiB7XHJcbiAgICAgICAgICBpZCxcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHJlcy5kZWxldGVMYm9wLmlkO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIHVwZGF0ZSh7IGlkLCBuYW1lIH06IFVwZGF0ZUxib3BQYXJhbXMpOiBQcm9taXNlPExib3A+IHtcclxuICAgIGNvbnN0IGxib3AgPSBhd2FpdCB0aGlzLmdldChpZCk7XHJcbiAgICBsYm9wLm5hbWUgPSBuYW1lO1xyXG5cclxuICAgIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50TWFzdGVyS2V5KCk7XHJcbiAgICBjb25zdCBjaXBoZXJNZXRhID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICBtYXN0ZXJLZXkuandrLFxyXG4gICAgICBsYm9wXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMubHJBcG9sbG8ubXV0YXRlPFVwZGF0ZUxib3BRdWVyeT4oe1xyXG4gICAgICBtdXRhdGlvbjogVXBkYXRlTGJvcFF1ZXJ5LFxyXG4gICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICBpbnB1dDoge1xyXG4gICAgICAgICAgaWQsXHJcbiAgICAgICAgICBjaXBoZXJNZXRhOiBKU09OLnN0cmluZ2lmeShjaXBoZXJNZXRhKSxcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHJlcy51cGRhdGVMYm9wO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIGdldChpZDogc3RyaW5nKTogUHJvbWlzZTxMYm9wPiB7XHJcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmxyQXBvbGxvLnF1ZXJ5PGFueT4oe1xyXG4gICAgICBxdWVyeTogTGJvcFF1ZXJ5LFxyXG4gICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICBpZCxcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50TWFzdGVyS2V5KCk7XHJcblxyXG4gICAgY29uc3QgcGxhaW5DaXBoZXJNZXRhID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxyXG4gICAgICBtYXN0ZXJLZXkuandrLFxyXG4gICAgICBKU09OLnBhcnNlKHJlcy5sYm9wLmNpcGhlck1ldGEpXHJcbiAgICApO1xyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIGlkOiByZXMuaWQsXHJcbiAgICAgIC4uLnBsYWluQ2lwaGVyTWV0YSxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYXN5bmMgbGlzdCgpOiBQcm9taXNlPExib3BbXT4ge1xyXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5sckFwb2xsby5xdWVyeTxMYm9wc1F1ZXJ5Pih7XHJcbiAgICAgIHF1ZXJ5OiBMYm9wc1F1ZXJ5LFxyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3QgbWFzdGVyS2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRNYXN0ZXJLZXkoKTtcclxuXHJcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoXHJcbiAgICAgIHJlcy5sYm9wcy5lZGdlcy5tYXAoYXN5bmMgKGVkZ2UpID0+IHtcclxuICAgICAgICBjb25zdCBwbGFpbkNpcGhlck1ldGEgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQoXHJcbiAgICAgICAgICBtYXN0ZXJLZXkuandrLFxyXG4gICAgICAgICAgSlNPTi5wYXJzZShlZGdlLm5vZGUuY2lwaGVyTWV0YSlcclxuICAgICAgICApO1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICBpZDogZWRnZS5ub2RlLmlkLFxyXG4gICAgICAgICAgLi4ucGxhaW5DaXBoZXJNZXRhLFxyXG4gICAgICAgIH07XHJcbiAgICAgIH0pXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIGNyZWF0ZSh7IG5hbWUgfTogQ3JlYXRlTGJvcFBhcmFtcyk6IFByb21pc2U8TGJvcD4ge1xyXG4gICAgaWYgKFNsaXAzOUhlbHBlci5XT1JEX0xJU1QubGVuZ3RoICE9PSAxMDI0KSB7XHJcbiAgICAgIHRocm93IG5ldyBMckJhZExvZ2ljRXhjZXB0aW9uKCdTbGlwMzlIZWxwZXIuV09SRF9MSVNULmxlbmd0aCAhPSAxMDI0Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IGV4aXN0aW5nIHRvIG1ha2Ugc3VyZSB0aGVyZSBhcmUgbm90IGR1cGxpY2F0ZSBmaXJzdCB3b3Jkc1xyXG4gICAgY29uc3QgbGJvcHMgPSBhd2FpdCB0aGlzLmxpc3QoKTtcclxuXHJcbiAgICAvLyBHZW5lcmF0ZSBuZXcgb25lXHJcbiAgICBsZXQgbGJvcFN0cmluZztcclxuICAgIHdoaWxlICh0cnVlKSB7XHJcbiAgICAgIGxib3BTdHJpbmcgPSB0aGlzLmtleUZhY3RvcnlcclxuICAgICAgICAucmFuZG9tQ2hvaWNlcyhTbGlwMzlIZWxwZXIuV09SRF9MSVNULCB0aGlzLkxCT1BfV09SRFMpXHJcbiAgICAgICAgLmpvaW4oJyAnKTtcclxuICAgICAgY29uc3QgcGFydGlhbCA9IHRoaXMuZ2V0UGFydGlhbChsYm9wU3RyaW5nKTtcclxuXHJcbiAgICAgIGlmICghbGJvcHMuc29tZSgobGJvcCkgPT4gbGJvcC5wYXJ0aWFsID09PSBwYXJ0aWFsKSkge1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgbGJvcEtleVBhcmFtcyA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVMYm9wS2V5UGFyYW1zKCk7XHJcbiAgICBjb25zdCBsYm9wS2V5ID0gKFxyXG4gICAgICBhd2FpdCB0aGlzLmtleUZhY3RvcnkuZGVyaXZlTGJvcEtleSh7XHJcbiAgICAgICAgcGFzc3dvcmQ6IGxib3BTdHJpbmcsXHJcbiAgICAgICAgLi4ubGJvcEtleVBhcmFtcyxcclxuICAgICAgfSlcclxuICAgICkuandrO1xyXG5cclxuICAgIGNvbnN0IGxib3BLZXlWZXJpZmllciA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVTaWduS2V5KCk7XHJcbiAgICBjb25zdCB3cmFwcGVkTGJvcEtleVZlcmlmaWVyID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICBsYm9wS2V5LFxyXG4gICAgICBsYm9wS2V5VmVyaWZpZXIudG9KU09OKHRydWUpXHJcbiAgICApO1xyXG5cclxuICAgIC8vIFJlLWVuY3J5cHQgbWFzdGVyIGtleSB3aXRoIG5ldyBrZXlcclxuICAgIGNvbnN0IGN1cnJlbnRVc2VyID0gYXdhaXQgdGhpcy5hdXRoU2VydmljZS5nZXRVc2VyKCk7XHJcbiAgICBjb25zdCBtYXN0ZXJLZXkgPSBhd2FpdCB0aGlzLmtleUdyYXBoLmdldEtleShcclxuICAgICAgY3VycmVudFVzZXIuY3VycmVudFVzZXJLZXkubWFzdGVyS2V5LmlkXHJcbiAgICApO1xyXG4gICAgY29uc3Qgd3JhcHBlZE1hc3RlcktleSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgbGJvcEtleSxcclxuICAgICAgbWFzdGVyS2V5Lmp3ay50b0pTT04odHJ1ZSlcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgbWV0YSA9IHtcclxuICAgICAgLi4uKG5hbWUgJiYgeyBuYW1lIH0pLFxyXG4gICAgICBwYXJ0aWFsOiB0aGlzLmdldFBhcnRpYWwobGJvcFN0cmluZyksXHJcbiAgICB9O1xyXG4gICAgY29uc3QgY2lwaGVyTWV0YSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgbWFzdGVyS2V5Lmp3ayxcclxuICAgICAgbWV0YVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmxyQXBvbGxvLm11dGF0ZTxDcmVhdGVMYm9wUXVlcnk+KHtcclxuICAgICAgbXV0YXRpb246IENyZWF0ZUxib3BRdWVyeSxcclxuICAgICAgdmFyaWFibGVzOiB7XHJcbiAgICAgICAgaW5wdXQ6IHtcclxuICAgICAgICAgIGNpcGhlck1ldGE6IEpTT04uc3RyaW5naWZ5KGNpcGhlck1ldGEpLFxyXG4gICAgICAgICAgbGJvcEtleVBhcmFtczogSlNPTi5zdHJpbmdpZnkobGJvcEtleVBhcmFtcyksXHJcbiAgICAgICAgICBsYm9wS2V5VmVyaWZpZXI6IEpTT04uc3RyaW5naWZ5KGxib3BLZXlWZXJpZmllci50b0pTT04odHJ1ZSkpLFxyXG4gICAgICAgICAgd3JhcHBlZExib3BLZXlWZXJpZmllcjogSlNPTi5zdHJpbmdpZnkod3JhcHBlZExib3BLZXlWZXJpZmllciksXHJcbiAgICAgICAgICBtYXN0ZXJLZXlJZDogY3VycmVudFVzZXIuY3VycmVudFVzZXJLZXkubWFzdGVyS2V5LmlkLFxyXG4gICAgICAgICAgd3JhcHBlZE1hc3RlcktleTogSlNPTi5zdHJpbmdpZnkod3JhcHBlZE1hc3RlcktleSksXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIC4uLnJlcy5jcmVhdGVMYm9wLmxib3AsXHJcbiAgICAgIGxib3BTdHJpbmcsXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gIC8vIEZsb3cgYmVsb3cgYXJlIGZvciBwYXNzd29yZCByZXNldCB2aWEgTEJPUFxyXG4gIC8vXHJcbiAgLy8gLS1Qb3RlbnRpYWwgRmFpbHVyZSBQb2ludCB4eHgtLVxyXG4gIC8vXHJcbiAgLy8gTG9vayBmb3IgdGhlIGFib3ZlIGFuZCB5b3UgY2FuIHRlc3QgYnkgaW50ZXJydXB0aW5nIGF0IHRoZXNlIHBvaW50cy5cclxuICAvL1xyXG4gIC8vIFRoZSBMQk9QIHJlc2V0IHByb2Nlc3MgY2FuIGJlIHJlc3RhcnRlZCBhdCBhbnkgcG9pbnQgYmVmb3JlIHRoZSBjYWxsIHRvIFwic2V0LXBhc3N3b3JkL1wiLiBPbmNlIFwic2V0LXBhc3N3b3JkL1wiIGhhcyBiZWVuXHJcbiAgLy8gY2FsbGVkLCB3ZSBhc3N1bWUgdGhlIGNsaWVudCBoYXMgYSBzaG9ydCBwZXJpb2Qgb2YgdGltZSB0byBjaGFuZ2UgdGhlIElkcCBwYXNzd29yZCB0byB0aGUgb25lIHRoZXkndmUgY2hvc2VuLiBUaGUgXCJzZXQtcGFzc3dvcmQvXCJcclxuICAvLyB3aWxsIHNldCB0aGUgSWRwIHBhc3N3b3JkIHRvIGEgdGVtcG9yYXJ5IHJhbmRvbSBwYXNzd29yZC4gVGhlIHVzZXIgY2FuIG5vIGxvbmdlciBsb2dpbiB1c2luZyB0aGVpciBjdXJyZW50IHBhc3N3b3JkLiBJZiB0aGUgSWRwXHJcbiAgLy8gcGFzc3dvcmQgY2hhbmdlIHByb2Nlc3MgZG9lcyBub3QgY29tcGxldGUgb3IgdGFrZXMgbG9uZ2VyIHRoYW4gdGhlIGxvY2tvdXQgcGVyaW9kLCB0aGUgYWNjb3VudCB3aWxsIG5vdCBiZSBhY2Nlc3NpYmxlIGFuZCBhIG5ld1xyXG4gIC8vIExCT1AgcGFzc3dvcmQgcmVzZXQgbXVzdCBiZSBjYXJyaWVkIG91dC5cclxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgcHJpdmF0ZSBhc3luYyB2ZXJpZnlMYm9wcyhcclxuICAgIGNoYWxsZW5nZVJlc3VsdDogQ2hhbGxlbmdlUmVzdWx0LFxyXG4gICAgbGJvcFN0cmluZzogc3RyaW5nXHJcbiAgKTogUHJvbWlzZTx7IGxib3A6IGFueTsgc2lnbmVkQ2hhbGxlbmdlOiBhbnk7IGxib3BLZXk6IEpXSy5LZXkgfT4ge1xyXG4gICAgY29uc3QgY2xpZW50Tm9uY2UgPSB0aGlzLmtleUZhY3RvcnkucmFuZG9tU3RyaW5nKHRoaXMuQ0xJRU5UX05PTkNFX0xFTkdUSCk7XHJcblxyXG4gICAgZm9yIChjb25zdCBsYm9wIG9mIGNoYWxsZW5nZVJlc3VsdC5sYm9wcykge1xyXG4gICAgICBjb25zdCBsYm9wS2V5ID0gKFxyXG4gICAgICAgIGF3YWl0IHRoaXMua2V5RmFjdG9yeS5kZXJpdmVMYm9wS2V5KHtcclxuICAgICAgICAgIHBhc3N3b3JkOiBsYm9wU3RyaW5nLFxyXG4gICAgICAgICAgLi4ubGJvcC5sYm9wS2V5UGFyYW1zLFxyXG4gICAgICAgIH0pXHJcbiAgICAgICkuandrO1xyXG5cclxuICAgICAgLy8gSWYgZGVjb2Rpbmcgc3VjY2Vzc2Z1bCB0aGVuIGl0J3MgdGhlIGNvcnJlY3QgbGJvcFxyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGNvbnN0IGxib3BLZXlWZXJpZmllciA9IChhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQoXHJcbiAgICAgICAgICBsYm9wS2V5LFxyXG4gICAgICAgICAgbGJvcC53cmFwcGVkTGJvcEtleVZlcmlmaWVyXHJcbiAgICAgICAgKSkgYXMgYW55O1xyXG5cclxuICAgICAgICAvLyBGb3JjZSBhIGJhZCBzaWduYXR1cmUuXHJcbiAgICAgICAgLy8gY29uc3Qgc2VydmVyTm9uY2UgPSBjaGFsbGVuZ2VSZXN1bHQuY2hhbGxlbmdlLnNlcnZlck5vbmNlICsgXCIxXCIsXHJcblxyXG4gICAgICAgIGNvbnN0IHNlcnZlck5vbmNlID0gY2hhbGxlbmdlUmVzdWx0LmNoYWxsZW5nZS5zZXJ2ZXJOb25jZTtcclxuXHJcbiAgICAgICAgY29uc3Qgc2lnbmVkQ2hhbGxlbmdlID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKFxyXG4gICAgICAgICAgbGJvcEtleVZlcmlmaWVyLFxyXG4gICAgICAgICAge1xyXG4gICAgICAgICAgICBzZXJ2ZXJOb25jZSxcclxuICAgICAgICAgICAgY2xpZW50Tm9uY2UsXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgIGxib3AsXHJcbiAgICAgICAgICBzaWduZWRDaGFsbGVuZ2UsXHJcbiAgICAgICAgICBsYm9wS2V5LFxyXG4gICAgICAgIH07XHJcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHRocm93IG5ldyBMckV4Y2VwdGlvbih7XHJcbiAgICAgIHNvdXJjZTogJ0xCT1AnLFxyXG4gICAgICBjb2RlOiAnSU5WQUxJRF9QQVNTUEhSQVNFJyxcclxuICAgICAgbWVzc2FnZTogJ0ludmFsaWQgcGFzc3BocmFzZS4nLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYXN5bmMgdmVyaWZ5Q29udGFjdChcclxuICAgIHBhcmFtczogVmVyaWZ5Q29udGFjdFBhcmFtc1xyXG4gICk6IFByb21pc2U8VmVyaWZ5Q29udGFjdFJlc3VsdD4ge1xyXG4gICAgY29uc3QgcmV0ID0gdGhpcy5odHRwXHJcbiAgICAgIC5wb3N0PFZlcmlmeUNvbnRhY3RSZXN1bHQ+KFxyXG4gICAgICAgIGAke3RoaXMuY29uZmlnLmF1dGhVcmx9dXNlcnMvbGJvcC1yZXNldC92ZXJpZnktY29udGFjdC9gLFxyXG4gICAgICAgIHBhcmFtc1xyXG4gICAgICApXHJcbiAgICAgIC50b1Byb21pc2UoKTtcclxuXHJcbiAgICAvLyAtLVBvdGVudGlhbCBGYWlsdXJlIFBvaW50IDEgLS1cclxuICAgIC8vIFRoZSBjb250YWN0IHZlcmlmaWNhdGlvbnMgYXJlIHRocm90dGxlZC4gQnV0IG90aGVyd2lzZSBoYXJtbGVzcy5cclxuXHJcbiAgICByZXR1cm4gcmV0O1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIGNvbmZpcm1Db250YWN0KFxyXG4gICAgcGFyYW1zOiBDb25maXJtQ29udGFjdFBhcmFtc1xyXG4gICk6IFByb21pc2U8Q29uZmlybUNvbnRhY3RSZXN1bHQ+IHtcclxuICAgIHJldHVybiB0aGlzLmh0dHBcclxuICAgICAgLnBvc3Q8Q29uZmlybUNvbnRhY3RSZXN1bHQ+KGAke3RoaXMuY29uZmlnLmF1dGhVcmx9Y292ZS9yZXNwb25kL2AsIHtcclxuICAgICAgICBjbGFpbV9pZDogcGFyYW1zLmNsYWltSWQsXHJcbiAgICAgICAgdl9jb2RlOiBwYXJhbXMudkNvZGUsXHJcbiAgICAgIH0pXHJcbiAgICAgIC50b1Byb21pc2UoKTtcclxuXHJcbiAgICAvLyAtLVBvdGVudGlhbCBGYWlsdXJlIFBvaW50IDIgLS1cclxuICAgIC8vIEEgdmVyaWZpZWQgY2xhaW0gZm9yIGEgY29udGFjdCBkb2VzIG5vdCBwcmV2ZW50IG5ldyBvbmVzIGZyb20gYmVpbmcgZ2VuZXJhdGVkLiBTbyBpdCBzaG91bGQgYmUgZmluZSB0byBqdXN0IHN0YXJ0IGFnYWluLlxyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIHZlcmlmeShwYXJhbXM6IFZlcmlmeVBhcmFtcyk6IFByb21pc2U8VmVyaWZ5UmVzdWx0PiB7XHJcbiAgICBjb25zdCBjaGFsbGVuZ2VSZXN1bHQgPSBhd2FpdCB0aGlzLmh0dHBcclxuICAgICAgLnBvc3Q8Q2hhbGxlbmdlUmVzdWx0PihcclxuICAgICAgICBgJHt0aGlzLmNvbmZpZy5hdXRoVXJsfXVzZXJzL2xib3AtcmVzZXQvZ2V0LWNoYWxsZW5nZS9gLFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIGNsYWltSWQ6IHBhcmFtcy5jbGFpbUlkLFxyXG4gICAgICAgICAgY2xhaW1Ub2tlbjogcGFyYW1zLmNsYWltVG9rZW4sXHJcbiAgICAgICAgfVxyXG4gICAgICApXHJcbiAgICAgIC50b1Byb21pc2UoKTtcclxuXHJcbiAgICAvLyAtLVBvdGVudGlhbCBGYWlsdXJlIFBvaW50IDMgLS1cclxuICAgIC8vIFRoaXMgZG9lcyBub3QgbG9jayBhbnl0aGluZy4gQSBzZWNvbmQgY2FsbCB0byBcImdldC1jaGFsbGVuZ2UvXCIgd2lsbCBjcmVhdGUgYSBuZXcgY2hhbGxlbmdlIGFtZCBpbnZhbGlkYXRlIHRoZSBmaXJzdCBvbmUuXHJcbiAgICBjb25zdCB7IHNpZ25lZENoYWxsZW5nZSwgbGJvcCwgbGJvcEtleSB9ID0gYXdhaXQgdGhpcy52ZXJpZnlMYm9wcyhcclxuICAgICAgY2hhbGxlbmdlUmVzdWx0LFxyXG4gICAgICBwYXJhbXMubGJvcFxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmh0dHBcclxuICAgICAgLnBvc3Q8YW55PihgJHt0aGlzLmNvbmZpZy5hdXRoVXJsfXVzZXJzL2xib3AtcmVzZXQvdmVyaWZ5LWNoYWxsZW5nZS9gLCB7XHJcbiAgICAgICAgbGJvcElkOiBsYm9wLmxib3BJZCxcclxuICAgICAgICBzaWduZWRDaGFsbGVuZ2UsXHJcbiAgICAgIH0pXHJcbiAgICAgIC50b1Byb21pc2UoKTtcclxuXHJcbiAgICAvLyAtLVBvdGVudGlhbCBGYWlsdXJlIFBvaW50IDQgLS1cclxuICAgIC8vIFRoaXMgZG9lcyBub3QgbG9jayBhbnl0aGluZy4gU28gb2sgdG8gcmVzdGFydC5cclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBsYm9wSWQ6IGxib3AubGJvcElkLFxyXG4gICAgICB2ZXJpZmllZFRva2VuOiByZXMudmVyaWZpZWRUb2tlbixcclxuICAgICAgbWFzdGVyS2V5SWQ6IHJlcy5tYXN0ZXJLZXlJZCxcclxuICAgICAgbWFzdGVyS2V5OiBhd2FpdCBLRlMuYXNLZXkoXHJcbiAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KGxib3BLZXksIHJlcy53cmFwcGVkTWFzdGVyS2V5KVxyXG4gICAgICApLFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyBzZXRQYXNzd29yZChwYXJhbXM6IFNldFBhc3N3b3JkUGFyYW1zKTogUHJvbWlzZTxhbnk+IHtcclxuICAgIC8vIEdlbmVyYXRlIHRoZSBuZXcgcGFzc3dvcmQgZGVyaXZlZCBrZXlzXHJcbiAgICBjb25zdCBwYXNzS2V5QnVuZGxlID0gYXdhaXQgdGhpcy5wYXNzd29yZFNlcnZpY2UuY3JlYXRlUGFzc0tleUJ1bmRsZShcclxuICAgICAgcGFyYW1zLm5ld1Bhc3N3b3JkXHJcbiAgICApO1xyXG5cclxuICAgIC8vIFJlLWVuY3J5cHQgbWFzdGVyIGtleSB3aXRoIG5ldyBrZXlcclxuICAgIGNvbnN0IG5ld1dyYXBwZWRNYXN0ZXJLZXkgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgIHBhc3NLZXlCdW5kbGUucGFzc0tleSxcclxuICAgICAgcGFyYW1zLm1hc3RlcktleS50b0pTT04odHJ1ZSlcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5odHRwXHJcbiAgICAgIC5wb3N0PFNldFBhc3N3b3JkQXBpUmVzdWx0PihcclxuICAgICAgICBgJHt0aGlzLmNvbmZpZy5hdXRoVXJsfXVzZXJzL2xib3AtcmVzZXQvc2V0LXBhc3N3b3JkL2AsXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbGJvcElkOiBwYXJhbXMubGJvcElkLFxyXG4gICAgICAgICAgdmVyaWZpZWRUb2tlbjogcGFyYW1zLnZlcmlmaWVkVG9rZW4sXHJcbiAgICAgICAgICBtYXN0ZXJLZXlJZDogcGFyYW1zLm1hc3RlcktleUlkLFxyXG4gICAgICAgICAgbmV3V3JhcHBlZE1hc3RlcktleSxcclxuICAgICAgICAgIG5ld1Bhc3NLZXk6IHtcclxuICAgICAgICAgICAgcGFzc0tleVBhcmFtczogcGFzc0tleUJ1bmRsZS5wYXNzS2V5UGFyYW1zLFxyXG4gICAgICAgICAgICBwYXNzSWRwUGFyYW1zOiBwYXNzS2V5QnVuZGxlLnBhc3NJZHBQYXJhbXMsXHJcbiAgICAgICAgICAgIHBhc3NJZHBWZXJpZmllclBiazogcGFzc0tleUJ1bmRsZS5wYXNzSWRwVmVyaWZpZXIudG9KU09OKCksXHJcbiAgICAgICAgICAgIHdyYXBwZWRQYXNzSWRwVmVyaWZpZXJQcms6IHBhc3NLZXlCdW5kbGUud3JhcHBlZFBhc3NJZHBWZXJpZmllclByayxcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgfVxyXG4gICAgICApXHJcbiAgICAgIC50b1Byb21pc2UoKTtcclxuXHJcbiAgICAvLyAtLVBvdGVudGlhbCBGYWlsdXJlIFBvaW50IDUgLS1cclxuICAgIC8vIEEgdGltZWQgbXV0ZXggaXMgbG9ja2VkLiBUaGUgSWRwIHBhc3N3b3JkIGNoYW5nZSBtdXN0IG9jY3VyIHdpdGhpbiBhIHBlcmlvZCBvZiB0aW1lLlxyXG4gICAgLy8gSWYgaW50ZXJydXB0ZWQgaGVyZSwgdGhlIHVzZXIgY2FuIG5vdCBsb2dpbiB3aXRoIHRoZWlyIG9sZCBwYXNzd29yZCBhZ2Fpbi4gVGhleSBtdXN0XHJcbiAgICAvLyBzdGFydCB0aGUgd2hvbGUgTEJPUCBwYXNzd29yZCByZXNldCBwcm9jZXNzIGFnYWluLlxyXG5cclxuICAgIC8vIFRoaXMgY2FsbCB3aWxsIGdvIHRocm91Z2ggdGhlIExSIHByb3h5IHdoaWNoIGlzIE9LIHNpbmNlIHRoZSBMUiBzZXJ2ZXIga25vd3NcclxuICAgIC8vIHRoZSB0ZW1wb3JhcnkgcGFzc3dvcmQgYW55d2F5LlxyXG4gICAgbGV0IHVzZXIgPSBhd2FpdCB0aGlzLmF1dGguc2lnbkluKHJlc3VsdC51c2VybmFtZSwgcmVzdWx0LmlkcFBhc3N3b3JkLCB7XHJcbiAgICAgIG5vUHJveHk6ICd0cnVlJyxcclxuICAgIH0pO1xyXG5cclxuICAgIGlmICh1c2VyLmNoYWxsZW5nZU5hbWUgIT09ICdORVdfUEFTU1dPUkRfUkVRVUlSRUQnKSB7XHJcbiAgICAgIHRocm93IG5ldyBMckV4Y2VwdGlvbih7XHJcbiAgICAgICAgbWVzc2FnZTpcclxuICAgICAgICAgICdJbnRlcm5hbCBlcnJvci4gRXhwZWN0aW5nIENvZ25pdG8gdG8gaGF2ZSBkb25lIGEgcGFzc3dvcmQgcmVzZXQuJyxcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gLS1Qb3RlbnRpYWwgRmFpbHVyZSBQb2ludCA2IC0tXHJcbiAgICAvLyBNdXN0IHJlc3RhcnQgdGhlIExCT1AgcGFzc3dvcmQgcmVzZXQgcHJvY2VzcyBhZ2Fpbi5cclxuXHJcbiAgICAvLyBTZXQgbmV3IHBhc3N3b3JkIG9uIElkcFxyXG4gICAgdXNlciA9IGF3YWl0IHRoaXMuYXV0aC5jb21wbGV0ZU5ld1Bhc3N3b3JkKFxyXG4gICAgICB1c2VyLFxyXG4gICAgICB0aGlzLnBhc3N3b3JkU2VydmljZS5nZXRQYXNzSWRwU3RyaW5nKHBhc3NLZXlCdW5kbGUucGFzc0lkcCksXHJcbiAgICAgIHt9XHJcbiAgICApO1xyXG5cclxuICAgIC8vIC0tUG90ZW50aWFsIEZhaWx1cmUgUG9pbnQgNyAtLVxyXG4gICAgLy8gTXVzdCByZXN0YXJ0IHRoZSBMQk9QIHBhc3N3b3JkIHJlc2V0IHByb2Nlc3MgYWdhaW4uXHJcblxyXG4gICAgYXdhaXQgdGhpcy5hdXRoLnNpZ25PdXQoKTtcclxuXHJcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5odHRwXHJcbiAgICAgIC5wb3N0PGFueT4oYCR7dGhpcy5jb25maWcuYXV0aFVybH11c2Vycy9sYm9wLXJlc2V0L2NvbXBsZXRlL2AsIHtcclxuICAgICAgICBsYm9wSWQ6IHBhcmFtcy5sYm9wSWQsXHJcbiAgICAgICAgc2V0UGFzc3dvcmRUb2tlbjogcmVzdWx0LnNldFBhc3N3b3JkVG9rZW4sXHJcbiAgICAgIH0pXHJcbiAgICAgIC50b1Byb21pc2UoKTtcclxuICB9XHJcbn1cclxuIl19
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