@lifeready/core 9.0.7 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/fesm2022/lifeready-core.mjs +10522 -0
  2. package/fesm2022/lifeready-core.mjs.map +1 -0
  3. package/package.json +21 -16
  4. package/types/lifeready-core.d.ts +5329 -0
  5. package/bundles/lifeready-core.umd.js +0 -13231
  6. package/bundles/lifeready-core.umd.js.map +0 -1
  7. package/bundles/lifeready-core.umd.min.js +0 -2
  8. package/bundles/lifeready-core.umd.min.js.map +0 -1
  9. package/esm2015/lib/_common/ast.js +0 -41
  10. package/esm2015/lib/_common/deferred-promise.js +0 -24
  11. package/esm2015/lib/_common/exceptions.js +0 -186
  12. package/esm2015/lib/_common/index.js +0 -3
  13. package/esm2015/lib/_common/kc-lodash.js +0 -11
  14. package/esm2015/lib/_common/key.js +0 -28
  15. package/esm2015/lib/_common/queries.gql.js +0 -43
  16. package/esm2015/lib/_common/run-outside-angular.js +0 -80
  17. package/esm2015/lib/_common/storage.js +0 -28
  18. package/esm2015/lib/_common/types.js +0 -2
  19. package/esm2015/lib/_common/utils.js +0 -73
  20. package/esm2015/lib/api/lr-apollo.service.js +0 -47
  21. package/esm2015/lib/api/lr-graphql/index.js +0 -6
  22. package/esm2015/lib/api/lr-graphql/lr-graphql.service.js +0 -170
  23. package/esm2015/lib/api/lr-graphql/lr-merged-mutation.js +0 -216
  24. package/esm2015/lib/api/lr-graphql/lr-mutation-base.js +0 -51
  25. package/esm2015/lib/api/lr-graphql/lr-mutation.js +0 -91
  26. package/esm2015/lib/api/lr-graphql/lr.service.js +0 -18
  27. package/esm2015/lib/api/query-processor/common-processors.service.js +0 -94
  28. package/esm2015/lib/api/query-processor/index.js +0 -3
  29. package/esm2015/lib/api/query-processor/query-processor.service.js +0 -307
  30. package/esm2015/lib/api/query-processor/tp-password-reset-processor.service.js +0 -110
  31. package/esm2015/lib/api/types/graphql.types.js +0 -8
  32. package/esm2015/lib/api/types/index.js +0 -3
  33. package/esm2015/lib/api/types/lr-graphql.types.js +0 -182
  34. package/esm2015/lib/auth/auth.config.js +0 -57
  35. package/esm2015/lib/auth/auth.gql.private.js +0 -85
  36. package/esm2015/lib/auth/auth.service.js +0 -616
  37. package/esm2015/lib/auth/auth.types.js +0 -19
  38. package/esm2015/lib/contact-card/contact-card.gql.js +0 -79
  39. package/esm2015/lib/contact-card/contact-card.service.js +0 -156
  40. package/esm2015/lib/contact-card/contact-card2.gql.js +0 -29
  41. package/esm2015/lib/contact-card/contact-card2.service.js +0 -103
  42. package/esm2015/lib/encryption/encryption.service.js +0 -188
  43. package/esm2015/lib/file-upload/file-upload.service.js +0 -70
  44. package/esm2015/lib/file-upload/file-upload.types.js +0 -2
  45. package/esm2015/lib/idle/idle.service.js +0 -159
  46. package/esm2015/lib/idle/idle.types.js +0 -7
  47. package/esm2015/lib/item/item.gql.js +0 -166
  48. package/esm2015/lib/item/item.gql.private.js +0 -41
  49. package/esm2015/lib/item/item.service.js +0 -662
  50. package/esm2015/lib/item/item.types.js +0 -2
  51. package/esm2015/lib/key/key-factory.service.js +0 -226
  52. package/esm2015/lib/key/key-graph.service.js +0 -314
  53. package/esm2015/lib/key/key-meta.service.js +0 -153
  54. package/esm2015/lib/key/key.service.js +0 -124
  55. package/esm2015/lib/key/key.types.js +0 -16
  56. package/esm2015/lib/key-exchange/key-exchange.gql.js +0 -174
  57. package/esm2015/lib/key-exchange/key-exchange.service.js +0 -496
  58. package/esm2015/lib/lbop/lbop.service.js +0 -351
  59. package/esm2015/lib/life-ready.config.js +0 -96
  60. package/esm2015/lib/life-ready.module.js +0 -42
  61. package/esm2015/lib/lock/lock.gql.js +0 -40
  62. package/esm2015/lib/lock/lock.service.js +0 -64
  63. package/esm2015/lib/notification/notification.gql.js +0 -43
  64. package/esm2015/lib/notification/notification.service.js +0 -118
  65. package/esm2015/lib/password/password.gql.js +0 -28
  66. package/esm2015/lib/password/password.service.js +0 -309
  67. package/esm2015/lib/persist/persist.service.js +0 -181
  68. package/esm2015/lib/plan/plan.gql.js +0 -91
  69. package/esm2015/lib/plan/plan.service.js +0 -191
  70. package/esm2015/lib/plan/plan.types.js +0 -2
  71. package/esm2015/lib/profile/profile-details.service.js +0 -261
  72. package/esm2015/lib/profile/profile.gql.js +0 -170
  73. package/esm2015/lib/profile/profile.service.js +0 -166
  74. package/esm2015/lib/profile/profile.types.js +0 -45
  75. package/esm2015/lib/register/register.service.js +0 -173
  76. package/esm2015/lib/register/register.types.js +0 -3
  77. package/esm2015/lib/reminder/reminder.gql.js +0 -27
  78. package/esm2015/lib/reminder/reminder.service.js +0 -85
  79. package/esm2015/lib/reminder/reminder.types.js +0 -2
  80. package/esm2015/lib/scenario/scenario.constants.js +0 -2
  81. package/esm2015/lib/scenario/scenario.controller.js +0 -34
  82. package/esm2015/lib/scenario/scenario.gql.js +0 -90
  83. package/esm2015/lib/scenario/scenario.private.gql.js +0 -200
  84. package/esm2015/lib/scenario/scenario.service.js +0 -679
  85. package/esm2015/lib/scenario/scenario.types.js +0 -2
  86. package/esm2015/lib/server-config/server-config.gql.js +0 -9
  87. package/esm2015/lib/server-config/server-config.service.js +0 -41
  88. package/esm2015/lib/shared-contact-card/shared-contact-card.service.js +0 -119
  89. package/esm2015/lib/shared-contact-card/shared-contact-card2.gql.js +0 -41
  90. package/esm2015/lib/shared-contact-card/shared-contact-card2.service.js +0 -117
  91. package/esm2015/lib/slip39/slip39.service.js +0 -167
  92. package/esm2015/lib/time/time.service.js +0 -152
  93. package/esm2015/lib/tp-assembly/tp-assembly.js +0 -363
  94. package/esm2015/lib/tp-assembly/tp-assembly.private.gql.js +0 -22
  95. package/esm2015/lib/tp-assembly/tp-assembly.types.js +0 -2
  96. package/esm2015/lib/tp-password-reset/tp-password-reset-request.service.js +0 -98
  97. package/esm2015/lib/tp-password-reset/tp-password-reset-user.service.js +0 -121
  98. package/esm2015/lib/tp-password-reset/tp-password-reset.constants.js +0 -4
  99. package/esm2015/lib/tp-password-reset/tp-password-reset.controller.js +0 -34
  100. package/esm2015/lib/tp-password-reset/tp-password-reset.gql.js +0 -74
  101. package/esm2015/lib/tp-password-reset/tp-password-reset.private.gql.js +0 -166
  102. package/esm2015/lib/tp-password-reset/tp-password-reset.private.service.js +0 -54
  103. package/esm2015/lib/tp-password-reset/tp-password-reset.service.js +0 -110
  104. package/esm2015/lib/tp-password-reset/tp-password-reset.types.js +0 -2
  105. package/esm2015/lib/trusted-party/trusted-party.gql.js +0 -96
  106. package/esm2015/lib/trusted-party/trusted-party.gql.private.js +0 -51
  107. package/esm2015/lib/trusted-party/trusted-party.service.js +0 -461
  108. package/esm2015/lib/trusted-party/trusted-party.types.js +0 -2
  109. package/esm2015/lib/two-factor/two-factor.service.js +0 -74
  110. package/esm2015/lib/user/user.gql.js +0 -32
  111. package/esm2015/lib/user/user.service.js +0 -58
  112. package/esm2015/lib/user/user.types.js +0 -2
  113. package/esm2015/lib/web-crypto/web-crypto.service.js +0 -29
  114. package/esm2015/lifeready-core.js +0 -17
  115. package/esm2015/public-api.js +0 -60
  116. package/fesm2015/lifeready-core.js +0 -10970
  117. package/fesm2015/lifeready-core.js.map +0 -1
  118. package/lib/_common/ast.d.ts +0 -11
  119. package/lib/_common/deferred-promise.d.ts +0 -12
  120. package/lib/_common/exceptions.d.ts +0 -126
  121. package/lib/_common/index.d.ts +0 -2
  122. package/lib/_common/kc-lodash.d.ts +0 -5
  123. package/lib/_common/key.d.ts +0 -14
  124. package/lib/_common/queries.gql.d.ts +0 -4
  125. package/lib/_common/run-outside-angular.d.ts +0 -14
  126. package/lib/_common/storage.d.ts +0 -13
  127. package/lib/_common/types.d.ts +0 -15
  128. package/lib/_common/utils.d.ts +0 -12
  129. package/lib/api/lr-apollo.service.d.ts +0 -15
  130. package/lib/api/lr-graphql/index.d.ts +0 -5
  131. package/lib/api/lr-graphql/lr-graphql.service.d.ts +0 -81
  132. package/lib/api/lr-graphql/lr-merged-mutation.d.ts +0 -46
  133. package/lib/api/lr-graphql/lr-mutation-base.d.ts +0 -28
  134. package/lib/api/lr-graphql/lr-mutation.d.ts +0 -48
  135. package/lib/api/lr-graphql/lr.service.d.ts +0 -9
  136. package/lib/api/query-processor/common-processors.service.d.ts +0 -36
  137. package/lib/api/query-processor/index.d.ts +0 -2
  138. package/lib/api/query-processor/query-processor.service.d.ts +0 -18
  139. package/lib/api/query-processor/tp-password-reset-processor.service.d.ts +0 -15
  140. package/lib/api/types/graphql.types.d.ts +0 -30
  141. package/lib/api/types/index.d.ts +0 -2
  142. package/lib/api/types/lr-graphql.types.d.ts +0 -807
  143. package/lib/auth/auth.config.d.ts +0 -5
  144. package/lib/auth/auth.gql.private.d.ts +0 -25
  145. package/lib/auth/auth.service.d.ts +0 -72
  146. package/lib/auth/auth.types.d.ts +0 -70
  147. package/lib/contact-card/contact-card.gql.d.ts +0 -7
  148. package/lib/contact-card/contact-card.service.d.ts +0 -53
  149. package/lib/contact-card/contact-card2.gql.d.ts +0 -25
  150. package/lib/contact-card/contact-card2.service.d.ts +0 -64
  151. package/lib/encryption/encryption.service.d.ts +0 -42
  152. package/lib/file-upload/file-upload.service.d.ts +0 -15
  153. package/lib/file-upload/file-upload.types.d.ts +0 -5
  154. package/lib/idle/idle.service.d.ts +0 -47
  155. package/lib/idle/idle.types.d.ts +0 -10
  156. package/lib/item/item.gql.d.ts +0 -134
  157. package/lib/item/item.gql.private.d.ts +0 -35
  158. package/lib/item/item.service.d.ts +0 -201
  159. package/lib/item/item.types.d.ts +0 -95
  160. package/lib/key/key-factory.service.d.ts +0 -40
  161. package/lib/key/key-graph.service.d.ts +0 -41
  162. package/lib/key/key-meta.service.d.ts +0 -51
  163. package/lib/key/key.service.d.ts +0 -36
  164. package/lib/key/key.types.d.ts +0 -86
  165. package/lib/key-exchange/key-exchange.gql.d.ts +0 -141
  166. package/lib/key-exchange/key-exchange.service.d.ts +0 -179
  167. package/lib/lbop/lbop.service.d.ts +0 -99
  168. package/lib/life-ready.config.d.ts +0 -26
  169. package/lib/life-ready.module.d.ts +0 -5
  170. package/lib/lock/lock.gql.d.ts +0 -27
  171. package/lib/lock/lock.service.d.ts +0 -34
  172. package/lib/notification/notification.gql.d.ts +0 -37
  173. package/lib/notification/notification.service.d.ts +0 -64
  174. package/lib/password/password.gql.d.ts +0 -3
  175. package/lib/password/password.service.d.ts +0 -79
  176. package/lib/persist/persist.service.d.ts +0 -31
  177. package/lib/plan/plan.gql.d.ts +0 -69
  178. package/lib/plan/plan.service.d.ts +0 -111
  179. package/lib/plan/plan.types.d.ts +0 -16
  180. package/lib/profile/profile-details.service.d.ts +0 -20
  181. package/lib/profile/profile.gql.d.ts +0 -21
  182. package/lib/profile/profile.service.d.ts +0 -32
  183. package/lib/profile/profile.types.d.ts +0 -121
  184. package/lib/register/register.service.d.ts +0 -25
  185. package/lib/register/register.types.d.ts +0 -6
  186. package/lib/reminder/reminder.gql.d.ts +0 -23
  187. package/lib/reminder/reminder.service.d.ts +0 -33
  188. package/lib/reminder/reminder.types.d.ts +0 -17
  189. package/lib/scenario/scenario.constants.d.ts +0 -1
  190. package/lib/scenario/scenario.controller.d.ts +0 -10
  191. package/lib/scenario/scenario.gql.d.ts +0 -78
  192. package/lib/scenario/scenario.private.gql.d.ts +0 -16
  193. package/lib/scenario/scenario.service.d.ts +0 -655
  194. package/lib/scenario/scenario.types.d.ts +0 -64
  195. package/lib/server-config/server-config.gql.d.ts +0 -5
  196. package/lib/server-config/server-config.service.d.ts +0 -9
  197. package/lib/shared-contact-card/shared-contact-card.service.d.ts +0 -33
  198. package/lib/shared-contact-card/shared-contact-card2.gql.d.ts +0 -36
  199. package/lib/shared-contact-card/shared-contact-card2.service.d.ts +0 -45
  200. package/lib/slip39/slip39.service.d.ts +0 -42
  201. package/lib/time/time.service.d.ts +0 -26
  202. package/lib/tp-assembly/tp-assembly.d.ts +0 -177
  203. package/lib/tp-assembly/tp-assembly.private.gql.d.ts +0 -5
  204. package/lib/tp-assembly/tp-assembly.types.d.ts +0 -40
  205. package/lib/tp-password-reset/tp-password-reset-request.service.d.ts +0 -16
  206. package/lib/tp-password-reset/tp-password-reset-user.service.d.ts +0 -29
  207. package/lib/tp-password-reset/tp-password-reset.constants.d.ts +0 -3
  208. package/lib/tp-password-reset/tp-password-reset.controller.d.ts +0 -10
  209. package/lib/tp-password-reset/tp-password-reset.gql.d.ts +0 -63
  210. package/lib/tp-password-reset/tp-password-reset.private.gql.d.ts +0 -163
  211. package/lib/tp-password-reset/tp-password-reset.private.service.d.ts +0 -59
  212. package/lib/tp-password-reset/tp-password-reset.service.d.ts +0 -112
  213. package/lib/tp-password-reset/tp-password-reset.types.d.ts +0 -40
  214. package/lib/trusted-party/trusted-party.gql.d.ts +0 -85
  215. package/lib/trusted-party/trusted-party.gql.private.d.ts +0 -40
  216. package/lib/trusted-party/trusted-party.service.d.ts +0 -192
  217. package/lib/trusted-party/trusted-party.types.d.ts +0 -31
  218. package/lib/two-factor/two-factor.service.d.ts +0 -15
  219. package/lib/user/user.gql.d.ts +0 -8
  220. package/lib/user/user.service.d.ts +0 -9
  221. package/lib/user/user.types.d.ts +0 -16
  222. package/lib/web-crypto/web-crypto.service.d.ts +0 -5
  223. package/lifeready-core.d.ts +0 -16
  224. package/lifeready-core.metadata.json +0 -1
  225. package/public-api.d.ts +0 -56
@@ -1,616 +0,0 @@
1
- var AuthService_1;
2
- import { __awaiter, __decorate } from "tslib";
3
- import { HttpClient } from '@angular/common/http';
4
- import { Inject, Injectable, Injector, isDevMode, NgZone } from '@angular/core';
5
- import { AuthClass } from '@aws-amplify/auth/lib-esm/Auth';
6
- import { Hub } from '@aws-amplify/core';
7
- import { JWK } from 'node-jose';
8
- import { LrGraphQLService, LrMutation, LrService } from '../api/lr-graphql';
9
- import { TpClaimState } from '../api/types';
10
- import { EncryptionService } from '../encryption/encryption.service';
11
- import { IdleService } from '../idle/idle.service';
12
- import { KeyFactoryService } from '../key/key-factory.service';
13
- import { KeyGraphService } from '../key/key-graph.service';
14
- import { KeyService } from '../key/key.service';
15
- import { KC_CONFIG } from '../life-ready.config';
16
- import { PasswordService } from '../password/password.service';
17
- import { PersistService } from '../persist/persist.service';
18
- import { TP_PASSWORD_RESET_CLIENT_NONCE_LENGTH, TP_PASSWORD_RESET_USERNAME_SUFFIX, } from '../tp-password-reset/tp-password-reset.constants';
19
- import { TpPasswordResetAssemblyController } from '../tp-password-reset/tp-password-reset.controller';
20
- import { CompleteTpPasswordResetRequestMutation, CreateTpAssemblyKeyChallengeMutation, PreCompleteTpPasswordResetRequestMutation, } from '../tp-password-reset/tp-password-reset.gql';
21
- import { KcBadRequestException, KcBadStateException, KcConcurrentAccessException, KcInternalErrorException, } from '../_common/exceptions';
22
- import { KeyContainer } from '../_common/key';
23
- import { RunOutsideAngular } from '../_common/run-outside-angular';
24
- import { CurrentUserQuery, ResetUserQuery, SetSessionEncryptionKeyMutation, } from './auth.gql.private';
25
- import { CognitoChallengeName, PasswordChangeStatus, RecoveryStatus, } from './auth.types';
26
- import * as i0 from "@angular/core";
27
- import * as i1 from "@angular/common/http";
28
- import * as i2 from "@aws-amplify/auth/lib-esm/Auth";
29
- import * as i3 from "../api/lr-graphql/lr-graphql.service";
30
- import * as i4 from "../key/key.service";
31
- import * as i5 from "../key/key-graph.service";
32
- import * as i6 from "../key/key-factory.service";
33
- import * as i7 from "../password/password.service";
34
- import * as i8 from "../idle/idle.service";
35
- import * as i9 from "../persist/persist.service";
36
- import * as i10 from "../encryption/encryption.service";
37
- import * as i11 from "../tp-password-reset/tp-password-reset.controller";
38
- import * as i12 from "../life-ready.config";
39
- let AuthService = AuthService_1 = class AuthService extends LrService {
40
- constructor(ngZone, injector, http, cognito, api, keyService, keyGraphService, keyFactoryService, passwordService, idleService, persistService, encryptionService, assemblyController, kcConfig) {
41
- super(injector);
42
- this.ngZone = ngZone;
43
- this.injector = injector;
44
- this.http = http;
45
- this.cognito = cognito;
46
- this.api = api;
47
- this.keyService = keyService;
48
- this.keyGraphService = keyGraphService;
49
- this.keyFactoryService = keyFactoryService;
50
- this.passwordService = passwordService;
51
- this.idleService = idleService;
52
- this.persistService = persistService;
53
- this.encryptionService = encryptionService;
54
- this.assemblyController = assemblyController;
55
- this.kcConfig = kcConfig;
56
- // Could use rxjs observables here. But trying to have kc-client use as little angular
57
- // features as possible. Rxjs is not used anywhere else in kc-client.
58
- this.logoutListeners = new Set();
59
- // Stores the password for use after mfa verification to decrypt masterKey.
60
- this.password = null;
61
- if (!isDevMode()) {
62
- if (this.kcConfig.debug != null) {
63
- throw new KcBadRequestException('In production mode, "KcConfig.debug" must be set to null');
64
- }
65
- }
66
- }
67
- importPassword(plainPassword) {
68
- return this.keyFactoryService.importPassword(plainPassword);
69
- }
70
- logout() {
71
- var _a;
72
- return __awaiter(this, void 0, void 0, function* () {
73
- // Notify all listeners to clean up.
74
- yield Promise.all([...this.logoutListeners].map((callback) => callback()));
75
- this.user = null;
76
- this.keyService.purgeKeys();
77
- this.keyGraphService.purgeKeys();
78
- // Sign out on both cognito and kc-server
79
- yield Promise.all([this.cognito.signOut(), this.kcLogout()]);
80
- if ((_a = this.kcConfig.debug) === null || _a === void 0 ? void 0 : _a.username) {
81
- this.kcConfig.debug.username = null;
82
- }
83
- });
84
- }
85
- addLogoutListener(callback) {
86
- this.logoutListeners.add(callback);
87
- }
88
- removeLogoutListener(callback) {
89
- this.logoutListeners.delete(callback);
90
- }
91
- login(emailOrPhone, password, { tpPasswordResetAutoComplete = true } = {}) {
92
- var _a;
93
- return __awaiter(this, void 0, void 0, function* () {
94
- let loginResult = yield this.loginImpl(emailOrPhone, password);
95
- // Save the password for use after meeting challenge.
96
- if (loginResult.challenge) {
97
- this.password = new KeyContainer(password, AuthService_1.CHALLENGE_TIMEOUT);
98
- return loginResult;
99
- }
100
- if (tpPasswordResetAutoComplete &&
101
- ((_a = loginResult.user.resetUser) === null || _a === void 0 ? void 0 : _a.state) === TpClaimState.APPROVED) {
102
- yield this.completeResetRequest(password);
103
- loginResult = yield this.loginImpl(emailOrPhone, password);
104
- }
105
- return loginResult;
106
- });
107
- }
108
- verifyLogin(options) {
109
- return __awaiter(this, void 0, void 0, function* () {
110
- const { challenge, code, rememberMe } = options;
111
- const VALID_CHALLENGE_NAMES = [
112
- CognitoChallengeName.SMS_MFA,
113
- CognitoChallengeName.SOFTWARE_TOKEN_MFA,
114
- ];
115
- if (!VALID_CHALLENGE_NAMES.includes(challenge.cognitoUser.challengeName)) {
116
- throw new KcBadRequestException(`challengeName must be one of ${VALID_CHALLENGE_NAMES}`);
117
- }
118
- // TODO: this.auth.confirmSignIn() could return another challenge.
119
- const cognitoUser = yield this.cognito.confirmSignIn(challenge.cognitoUser, code, challenge.cognitoUser.challengeName);
120
- yield this.handlePostAuth(challenge.recoveryStatus);
121
- const user = yield this.loadUser(cognitoUser, this.password.pop());
122
- // This is not strictly necessary since the this.password.pop() already clears the
123
- // password inside the container. But doesn't hurt either.
124
- this.password = null;
125
- if (rememberMe) {
126
- cognitoUser.setDeviceStatusRemembered({
127
- onSuccess: () => {
128
- return;
129
- },
130
- onFailure: (e) => console.error(e),
131
- });
132
- }
133
- return {
134
- user,
135
- };
136
- });
137
- }
138
- getUser() {
139
- return __awaiter(this, void 0, void 0, function* () {
140
- if (this.user) {
141
- return this.user;
142
- }
143
- const cognitoUser = yield this.cognito.currentAuthenticatedUser();
144
- return this.loadUser(cognitoUser);
145
- });
146
- }
147
- refreshAccessToken() {
148
- return __awaiter(this, void 0, void 0, function* () {
149
- const cognitoUser = yield this.cognito.currentAuthenticatedUser();
150
- const refreshToken = cognitoUser.getSignInUserSession().getRefreshToken();
151
- console.log('Token refresh...');
152
- return new Promise((resolve, reject) => {
153
- cognitoUser.refreshSession(refreshToken, (err) => {
154
- if (err) {
155
- console.error('Error refreshing token: ', err);
156
- reject(err);
157
- }
158
- else {
159
- console.log('Token refresh complete');
160
- resolve(0);
161
- }
162
- });
163
- });
164
- });
165
- }
166
- // ----------------------------------------------------------------------------------------------------
167
- // Helpers
168
- // ----------------------------------------------------------------------------------------------------
169
- fetchCurrentUser() {
170
- return __awaiter(this, void 0, void 0, function* () {
171
- return (yield this.api.query({
172
- query: CurrentUserQuery,
173
- processorOptions: {
174
- hasKeys: false,
175
- },
176
- })).currentUser;
177
- });
178
- }
179
- fetchResetUser() {
180
- return __awaiter(this, void 0, void 0, function* () {
181
- return (yield this.api.query({
182
- query: ResetUserQuery,
183
- processorOptions: {
184
- hasKeys: false,
185
- },
186
- })).tpPasswordResetUser;
187
- });
188
- }
189
- kcLogout() {
190
- return __awaiter(this, void 0, void 0, function* () {
191
- yield this.http
192
- .post(`${this.kcConfig.authUrl}auth/sign-out/`, null, {
193
- withCredentials: true,
194
- responseType: 'text',
195
- })
196
- .toPromise();
197
- });
198
- }
199
- fetchPassIdpParams(emailOrPhone) {
200
- return __awaiter(this, void 0, void 0, function* () {
201
- return yield this.http
202
- .get(`${this.kcConfig.authUrl}users/pass-idp-params/?login_name=${encodeURIComponent(emailOrPhone)}`)
203
- .toPromise();
204
- });
205
- }
206
- loginImpl(emailOrPhone, password) {
207
- return __awaiter(this, void 0, void 0, function* () {
208
- yield this.logout();
209
- const loginIdpResult = yield this.loginIdp(emailOrPhone, password);
210
- // Can't get the user yet because we still ned to meet MFA challenges
211
- if ([
212
- CognitoChallengeName.SMS_MFA,
213
- CognitoChallengeName.SOFTWARE_TOKEN_MFA,
214
- ].includes(loginIdpResult.cognitoUser.challengeName)) {
215
- return {
216
- challenge: {
217
- cognitoUser: loginIdpResult.cognitoUser,
218
- recoveryStatus: loginIdpResult.recoveryStatus,
219
- },
220
- };
221
- }
222
- yield this.handlePostAuth(loginIdpResult.recoveryStatus);
223
- // There should be no MFA on the TP reset user.
224
- const user = yield this.loadUser(loginIdpResult.cognitoUser, password);
225
- return {
226
- user,
227
- };
228
- });
229
- }
230
- loginIdp(emailOrPhone, password) {
231
- return __awaiter(this, void 0, void 0, function* () {
232
- // Download the salt needed to derive the PassIdp
233
- const passIdpApiResult = yield this.fetchPassIdpParams(emailOrPhone);
234
- if (passIdpApiResult.passwordChangeStatus === PasswordChangeStatus.IN_PROGRESS) {
235
- throw new KcConcurrentAccessException('A password change is in progress');
236
- }
237
- if (passIdpApiResult.passwordChangeStatus === PasswordChangeStatus.RECOVERY) {
238
- console.log('In recovery mode.');
239
- // Let's say we don't know if the password is the new one or the old one. We just have to try both.
240
- try {
241
- const user = {
242
- cognitoUser: yield this.loginIdpImpl(emailOrPhone, password, passIdpApiResult.newPassIdpParams),
243
- recoveryStatus: RecoveryStatus.NEW_PASSWORD,
244
- };
245
- // New password worked. Let's set to the current password
246
- // --Potential Failure Point 1--
247
- // if changePasswordComplete() doesn't get called, then it should remain
248
- console.log('New password works!');
249
- return user;
250
- }
251
- catch (error) {
252
- // Just bubble up any other type of error.
253
- if (error.code !== 'NotAuthorizedException') {
254
- throw error;
255
- }
256
- // pass, try again assuming it's the old password
257
- }
258
- // Now assume it's the previous password. Any exception is allowed to bubble up.
259
- try {
260
- const user = {
261
- cognitoUser: yield this.loginIdpImpl(emailOrPhone, password, passIdpApiResult.currentPassIdpParams),
262
- recoveryStatus: RecoveryStatus.OLD_PASSWORD,
263
- };
264
- // Old password worked.
265
- console.log('Old password works!');
266
- return user;
267
- }
268
- catch (error) {
269
- // Just bubble up any other type of error.
270
- throw error.code === 'NotAuthorizedException'
271
- ? new KcBadRequestException('The password change request was interrupted, please try to login with both your new and old password')
272
- : error;
273
- }
274
- }
275
- // Try again as the TP password reset account
276
- if (passIdpApiResult.tpPasswordReset) {
277
- try {
278
- // TP password reset is in process. We need to try the password against both
279
- // original account and the new reset account.
280
- const reset = passIdpApiResult.tpPasswordReset;
281
- const user = {
282
- cognitoUser: yield this.loginIdpImpl(reset.resetUsername, password, reset.passIdpParams),
283
- recoveryStatus: RecoveryStatus.NONE,
284
- };
285
- return user;
286
- }
287
- catch (err) {
288
- // continue, try again as regular user.
289
- }
290
- }
291
- // Login as regular user
292
- const user = {
293
- cognitoUser: yield this.loginIdpImpl(emailOrPhone, password, passIdpApiResult.currentPassIdpParams),
294
- recoveryStatus: RecoveryStatus.NONE,
295
- };
296
- return user;
297
- });
298
- }
299
- loginIdpImpl(emailOrPhone, password, passIdpParams) {
300
- return __awaiter(this, void 0, void 0, function* () {
301
- const passIdpResult = yield this.keyFactoryService.derivePassIdp(Object.assign({ password }, passIdpParams));
302
- // Use the derived password to signin with cognito
303
- return this.cognito.signIn(emailOrPhone, this.passwordService.getPassIdpString(passIdpResult.jwk));
304
- });
305
- }
306
- handlePostAuth(recoveryStatus) {
307
- return __awaiter(this, void 0, void 0, function* () {
308
- yield this.handlePasswordRecovery(recoveryStatus);
309
- yield this.handleSessionEncryptionKey();
310
- });
311
- }
312
- handlePasswordRecovery(recoveryStatus) {
313
- return __awaiter(this, void 0, void 0, function* () {
314
- if (recoveryStatus !== RecoveryStatus.NONE) {
315
- yield this.passwordService.changePasswordComplete({
316
- useNewPassword: recoveryStatus === RecoveryStatus.NEW_PASSWORD,
317
- });
318
- }
319
- });
320
- }
321
- handleSessionEncryptionKey() {
322
- return __awaiter(this, void 0, void 0, function* () {
323
- if (this.kcConfig.disableSessionEncryptionKey) {
324
- if (!isDevMode()) {
325
- const msg = 'You should not set disableSessionEncryptionKey=True in mode prod. It defaults to false.';
326
- console.error(msg);
327
- throw new KcInternalErrorException(msg);
328
- }
329
- else {
330
- console.warn('You have set disableSessionEncryptionKey=True. Make sure not to do this in prod mode.');
331
- }
332
- }
333
- else {
334
- // Set the session key to a new encryption key for this session
335
- const sessionEncryptionKey = yield this.keyFactoryService.createKey();
336
- yield this.lrGraphQL.lrMutate(new LrMutation({
337
- mutation: SetSessionEncryptionKeyMutation,
338
- variables: {
339
- input: {
340
- sessionEncryptionKey: JSON.stringify(sessionEncryptionKey.toJSON(true)),
341
- },
342
- },
343
- }), {
344
- includeKeyGraph: false,
345
- });
346
- this.persistService.setServerSessionEncryptionKey(sessionEncryptionKey);
347
- }
348
- });
349
- }
350
- getCognitoUserAttribute(attributeName, userAttributes) {
351
- const userAttribute = userAttributes.find((x) => x.getName() === attributeName);
352
- return userAttribute ? userAttribute.getValue() : null;
353
- }
354
- loadUserKeys(options) {
355
- return __awaiter(this, void 0, void 0, function* () {
356
- const { userKeys, password, sessionEncryptionKey } = options;
357
- if (sessionEncryptionKey) {
358
- this.persistService.setServerSessionEncryptionKey(yield JWK.asKey(sessionEncryptionKey));
359
- }
360
- // password is not needed if the master key is already persisted.
361
- if (password) {
362
- const passKey = (yield this.keyFactoryService.derivePassKey(Object.assign({ password }, userKeys.passKey.passKeyParams))).jwk;
363
- yield this.idleService.persistMasterKey(yield this.keyGraphService.unwrapWithPassKey(userKeys.passKey.id, passKey, userKeys.masterKey.id));
364
- }
365
- });
366
- }
367
- loadUser(cognitoUser, password) {
368
- return __awaiter(this, void 0, void 0, function* () {
369
- if (cognitoUser.getUsername().endsWith(TP_PASSWORD_RESET_USERNAME_SUFFIX)) {
370
- this.user = yield this.loadResetUser(cognitoUser, password);
371
- }
372
- else {
373
- this.user = yield this.loadRegularUser(cognitoUser, password);
374
- }
375
- yield this.idleService.start(); // Run idleService whenever user is logged in.
376
- return this.user;
377
- });
378
- }
379
- loadRegularUser(cognitoUser, password) {
380
- return __awaiter(this, void 0, void 0, function* () {
381
- const currentUser = yield this.fetchCurrentUser();
382
- yield this.loadUserKeys({
383
- userKeys: currentUser.currentUserKey,
384
- password,
385
- sessionEncryptionKey: currentUser.sessionEncryptionKey,
386
- });
387
- // Regular user populates all keys
388
- yield this.keyGraphService.populateKeys(currentUser.currentUserKey);
389
- const { id, username } = currentUser;
390
- const userAttributes = yield this.cognito.userAttributes(cognitoUser);
391
- return {
392
- id,
393
- username,
394
- sub: this.getCognitoUserAttribute('sub', userAttributes),
395
- loginEmail: this.getCognitoUserAttribute('email', userAttributes),
396
- resetUser: null,
397
- };
398
- });
399
- }
400
- loadResetUser(cognitoUser, password) {
401
- return __awaiter(this, void 0, void 0, function* () {
402
- const resetUser = yield this.fetchResetUser();
403
- const userKeys = {
404
- passKey: {
405
- id: resetUser.passKey.id,
406
- passKeyParams: resetUser.passKey.passKeyParams,
407
- },
408
- masterKey: {
409
- id: resetUser.masterKey.id,
410
- },
411
- };
412
- yield this.loadUserKeys({
413
- userKeys,
414
- password,
415
- sessionEncryptionKey: resetUser.sessionEncryptionKey,
416
- });
417
- // Reset user only sets a subset of keys
418
- yield this.keyService.setKeys(userKeys);
419
- const { username } = resetUser;
420
- const userAttributes = yield this.cognito.userAttributes(cognitoUser);
421
- return {
422
- username,
423
- sub: this.getCognitoUserAttribute('sub', userAttributes),
424
- loginEmail: this.getCognitoUserAttribute('email', userAttributes),
425
- resetUser: {
426
- state: resetUser.state,
427
- },
428
- };
429
- });
430
- }
431
- recoverAssemblyKey(resetUser) {
432
- return __awaiter(this, void 0, void 0, function* () {
433
- const prk = yield this.keyGraphService.getKey(resetUser.pxk.id);
434
- const partials = yield Promise.all(resetUser.approvals
435
- .filter((approval) => !!approval.receiverCipherPartialAssemblyKey)
436
- .map((approval) => this.encryptionService.decrypt(prk, approval.receiverCipherPartialAssemblyKey)));
437
- return this.assemblyController.recoverAssemblyKey(partials);
438
- });
439
- }
440
- completeResetRequest(newPassword) {
441
- return __awaiter(this, void 0, void 0, function* () {
442
- const resetUser = yield this.fetchResetUser();
443
- if (resetUser.state !== TpClaimState.APPROVED) {
444
- throw new KcBadStateException('Password reset request has not been approved.');
445
- }
446
- // --------------------------------------------------------------
447
- // Prepare all materials to ensure there are no errors.
448
- // --------------------------------------------------------------
449
- const assemblyKey = yield this.recoverAssemblyKey(resetUser);
450
- const { rootKey } = yield this.encryptionService.decrypt(assemblyKey, resetUser.assemblyCipherData);
451
- // Making sure it's a valid key.
452
- const rootKeyJwk = yield JWK.asKey(rootKey);
453
- const masterKey = yield this.keyGraphService.getKey(resetUser.masterKey.id);
454
- const masterKeyWrappedRootKey = yield this.encryptionService.encryptToString(masterKey.jwk, rootKeyJwk.toJSON(true));
455
- // The new password
456
- const newPassIdpResult = yield this.keyFactoryService.derivePassIdp(Object.assign({ password: newPassword }, resetUser.passKey.passIdpParams));
457
- const newIdpPassword = this.passwordService.getPassIdpString(newPassIdpResult.jwk);
458
- // --------------------------------------------------------------
459
- // Get assembly key challenge
460
- // --------------------------------------------------------------
461
- const challenge = (yield this.lrGraphQL.lrMutate(new LrMutation({
462
- mutation: CreateTpAssemblyKeyChallengeMutation,
463
- variables: {
464
- input: {},
465
- },
466
- }), {
467
- includeKeyGraph: false,
468
- })).createTpAssemblyKeyChallenge.challenge;
469
- // Sign the challenge
470
- // Generate a client side nonce that's no in the server's control.
471
- challenge.clientNonce = this.keyFactoryService.randomString(TP_PASSWORD_RESET_CLIENT_NONCE_LENGTH);
472
- const assemblyKeyVerifierPrk = yield this.encryptionService.decrypt(assemblyKey, resetUser.wrappedAssemblyKeyVerifierPrk);
473
- const signedChallenge = yield this.encryptionService.sign(assemblyKeyVerifierPrk, challenge);
474
- // --------------------------------------------------------------
475
- // Change password for the original user
476
- // --------------------------------------------------------------
477
- const tempIdpPassword = (yield this.lrGraphQL.lrMutate(new LrMutation({
478
- mutation: PreCompleteTpPasswordResetRequestMutation,
479
- variables: {
480
- input: {
481
- signedChallenge: JSON.stringify(signedChallenge),
482
- },
483
- },
484
- }), {
485
- includeKeyGraph: false,
486
- })).preCompleteTpPasswordResetRequest.idpPassword;
487
- // --------------------------------------------------------------
488
- // Login as the original user using new temporary password
489
- // --------------------------------------------------------------
490
- // At this point, the original account's password has been changed
491
- // to a temporary password. It is no longer possible for the user
492
- // to use the original password to login. Any successful login
493
- // can only be using the temporary password. So it's safe to assume
494
- // that we want to "complete" the password reset.
495
- // There maybe 2FA so we listen for the auth event from Amplify.
496
- const retPromise = new Promise((resolve) => {
497
- const listener = (data) => __awaiter(this, void 0, void 0, function* () {
498
- if (data.payload.event !== 'signIn') {
499
- return;
500
- }
501
- Hub.remove('auth', listener);
502
- yield this.cognito.signIn(resetUser.username, newIdpPassword);
503
- // Switch over to the new set of keys
504
- yield this.lrGraphQL.lrMutate(new LrMutation({
505
- mutation: CompleteTpPasswordResetRequestMutation,
506
- variables: {
507
- input: {
508
- masterKeyWrappedRootKey,
509
- masterKeyId: masterKey.id,
510
- },
511
- },
512
- }));
513
- resolve();
514
- });
515
- Hub.listen('auth', listener);
516
- });
517
- // Signin as the original user. Password has been reset to temporary one. It should return
518
- // with NEW_PASSWORD_REQUIRED
519
- let user = yield this.cognito.signIn(resetUser.username, tempIdpPassword, {
520
- noProxy: 'true',
521
- });
522
- if (user.challengeName !== 'NEW_PASSWORD_REQUIRED') {
523
- throw new KcInternalErrorException('Expecting Cognito to have done a password reset after call to PreCompleteTpPasswordResetRequestMutation.');
524
- }
525
- // Set new password on Idp
526
- // the awsFetch() function passes NEW_PASSWORD_REQUIRED directly to AWS without
527
- // going through the proxy.
528
- user = yield this.cognito.completeNewPassword(user, newIdpPassword, {});
529
- return retPromise;
530
- });
531
- }
532
- // ------------------------------------------------------
533
- // Debug utilities
534
- // ------------------------------------------------------
535
- debugLogin(username, password) {
536
- return __awaiter(this, void 0, void 0, function* () {
537
- // This will fail if debug is null. But when debug is null, this function
538
- // should not be called.
539
- this.kcConfig.debug.username = username;
540
- // Reset it so we don't get surprises.
541
- this.kcConfig.debug.rbacCacheMode = null;
542
- // This mechanism only works in a browser session because it needs to set cookies etc.
543
- // But it sets the last_login field for the users which we need in some tests.
544
- yield this.http
545
- .get(`${this.kcConfig.authUrl}debug_only/users/login/?username=${encodeURIComponent(username)}`)
546
- .toPromise();
547
- return this.debugLoadUser(password);
548
- });
549
- }
550
- debugLoadUser(password) {
551
- return __awaiter(this, void 0, void 0, function* () {
552
- const currentUser = yield this.fetchCurrentUser();
553
- const { id, username, currentUserKey } = currentUser;
554
- // Debug mode can not deal with session encryption key yet.
555
- // NO SESSION ENCRYPTION KEY.
556
- const passKey = (yield this.keyFactoryService.derivePassKey(Object.assign({ password }, currentUserKey.passKey.passKeyParams))).jwk;
557
- const masterKey = yield this.keyGraphService.unwrapWithPassKey(currentUserKey.passKey.id, passKey, currentUserKey.masterKey.id);
558
- yield this.idleService.persistMasterKey(masterKey);
559
- yield this.keyGraphService.populateKeys(currentUserKey);
560
- this.user = {
561
- id,
562
- username,
563
- resetUser: null,
564
- sub: 'DEBUG_MODE',
565
- loginEmail: 'DEBUG_MODE',
566
- };
567
- return this.user;
568
- });
569
- }
570
- /**
571
- * Clears the caches user. So we can simulate a page refresh and test getUser().
572
- */
573
- debugClearUser() {
574
- this.user = null;
575
- }
576
- getCurrentUserAttributes() {
577
- return __awaiter(this, void 0, void 0, function* () {
578
- const cognitoUser = yield this.cognito.currentAuthenticatedUser();
579
- const userAttributes = yield this.cognito.userAttributes(cognitoUser);
580
- return userAttributes;
581
- });
582
- }
583
- debugRetainRbacCache(b) {
584
- this.kcConfig.debug.rbacCacheMode = b ? 'retain' : null;
585
- }
586
- };
587
- AuthService.CHALLENGE_TIMEOUT = 1000 * 60 * 5;
588
- AuthService.ɵprov = i0.ɵɵdefineInjectable({ factory: function AuthService_Factory() { return new AuthService(i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i0.INJECTOR), i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(i2.AuthClass), i0.ɵɵinject(i3.LrGraphQLService), i0.ɵɵinject(i4.KeyService), i0.ɵɵinject(i5.KeyGraphService), i0.ɵɵinject(i6.KeyFactoryService), i0.ɵɵinject(i7.PasswordService), i0.ɵɵinject(i8.IdleService), i0.ɵɵinject(i9.PersistService), i0.ɵɵinject(i10.EncryptionService), i0.ɵɵinject(i11.TpPasswordResetAssemblyController), i0.ɵɵinject(i12.KC_CONFIG)); }, token: AuthService, providedIn: "root" });
589
- AuthService.decorators = [
590
- { type: Injectable, args: [{
591
- providedIn: 'root',
592
- },] }
593
- ];
594
- AuthService.ctorParameters = () => [
595
- { type: NgZone },
596
- { type: Injector },
597
- { type: HttpClient },
598
- { type: AuthClass },
599
- { type: LrGraphQLService },
600
- { type: KeyService },
601
- { type: KeyGraphService },
602
- { type: KeyFactoryService },
603
- { type: PasswordService },
604
- { type: IdleService },
605
- { type: PersistService },
606
- { type: EncryptionService },
607
- { type: TpPasswordResetAssemblyController },
608
- { type: undefined, decorators: [{ type: Inject, args: [KC_CONFIG,] }] }
609
- ];
610
- AuthService = AuthService_1 = __decorate([
611
- RunOutsideAngular({
612
- ngZoneName: 'ngZone',
613
- })
614
- ], AuthService);
615
- export { AuthService };
616
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29yZS9zcmMvbGliL2F1dGgvYXV0aC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRWhGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFeEMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNoQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDNUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsVUFBVSxFQUFZLE1BQU0sb0JBQW9CLENBQUM7QUFFMUQsT0FBTyxFQUFZLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzNELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDNUQsT0FBTyxFQUNMLHFDQUFxQyxFQUNyQyxpQ0FBaUMsR0FDbEMs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VixTQUFTO1lBSVQsZ0JBQWdCO1lBTWhCLFVBQVU7WUFEVixlQUFlO1lBRGYsaUJBQWlCO1lBS2pCLGVBQWU7WUFOZixXQUFXO1lBT1gsY0FBYztZQVJkLGlCQUFpQjtZQWFqQixpQ0FBaUM7NENBaUVyQyxNQUFNLFNBQUMsU0FBUzs7QUF4QlIsV0FBVztJQU52QixpQkFBaUIsQ0FBQztRQUNqQixVQUFVLEVBQUUsUUFBUTtLQUNyQixDQUFDO0dBSVcsV0FBVyxDQTR3QnZCO1NBNXdCWSxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSwgSW5qZWN0b3IsIGlzRGV2TW9kZSwgTmdab25lIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb2duaXRvVXNlciB9IGZyb20gJ0Bhd3MtYW1wbGlmeS9hdXRoJztcbmltcG9ydCB7IEF1dGhDbGFzcyB9IGZyb20gJ0Bhd3MtYW1wbGlmeS9hdXRoL2xpYi1lc20vQXV0aCc7XG5pbXBvcnQgeyBIdWIgfSBmcm9tICdAYXdzLWFtcGxpZnkvY29yZSc7XG5pbXBvcnQgeyBDb2duaXRvVXNlckF0dHJpYnV0ZSB9IGZyb20gJ2FtYXpvbi1jb2duaXRvLWlkZW50aXR5LWpzJztcbmltcG9ydCB7IEpXSyB9IGZyb20gJ25vZGUtam9zZSc7XG5pbXBvcnQgeyBMckdyYXBoUUxTZXJ2aWNlLCBMck11dGF0aW9uLCBMclNlcnZpY2UgfSBmcm9tICcuLi9hcGkvbHItZ3JhcGhxbCc7XG5pbXBvcnQgeyBUcENsYWltU3RhdGUgfSBmcm9tICcuLi9hcGkvdHlwZXMnO1xuaW1wb3J0IHsgRW5jcnlwdGlvblNlcnZpY2UgfSBmcm9tICcuLi9lbmNyeXB0aW9uL2VuY3J5cHRpb24uc2VydmljZSc7XG5pbXBvcnQgeyBJZGxlU2VydmljZSB9IGZyb20gJy4uL2lkbGUvaWRsZS5zZXJ2aWNlJztcbmltcG9ydCB7IEtleUZhY3RvcnlTZXJ2aWNlIH0gZnJvbSAnLi4va2V5L2tleS1mYWN0b3J5LnNlcnZpY2UnO1xuaW1wb3J0IHsgS2V5R3JhcGhTZXJ2aWNlIH0gZnJvbSAnLi4va2V5L2tleS1ncmFwaC5zZXJ2aWNlJztcbmltcG9ydCB7IEtleVNlcnZpY2UsIFVzZXJLZXlzIH0gZnJvbSAnLi4va2V5L2tleS5zZXJ2aWNlJztcbmltcG9ydCB7IFBhc3NJZHBQYXJhbXMgfSBmcm9tICcuLi9rZXkva2V5LnR5cGVzJztcbmltcG9ydCB7IEtjQ29uZmlnLCBLQ19DT05GSUcgfSBmcm9tICcuLi9saWZlLXJlYWR5LmNvbmZpZyc7XG5pbXBvcnQgeyBQYXNzd29yZFNlcnZpY2UgfSBmcm9tICcuLi9wYXNzd29yZC9wYXNzd29yZC5zZXJ2aWNlJztcbmltcG9ydCB7IFBlcnNpc3RTZXJ2aWNlIH0gZnJvbSAnLi4vcGVyc2lzdC9wZXJzaXN0LnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgVFBfUEFTU1dPUkRfUkVTRVRfQ0xJRU5UX05PTkNFX0xFTkdUSCxcbiAgVFBfUEFTU1dPUkRfUkVTRVRfVVNFUk5BTUVfU1VGRklYLFxufSBmcm9tICcuLi90cC1wYXNzd29yZC1yZXNldC90cC1wYXNzd29yZC1yZXNldC5jb25zdGFudHMnO1xuaW1wb3J0IHsgVHBQYXNzd29yZFJlc2V0QXNzZW1ibHlDb250cm9sbGVyIH0gZnJvbSAnLi4vdHAtcGFzc3dvcmQtcmVzZXQvdHAtcGFzc3dvcmQtcmVzZXQuY29udHJvbGxlcic7XG5pbXBvcnQge1xuICBDb21wbGV0ZVRwUGFzc3dvcmRSZXNldFJlcXVlc3RNdXRhdGlvbixcbiAgQ3JlYXRlVHBBc3NlbWJseUtleUNoYWxsZW5nZU11dGF0aW9uLFxuICBQcmVDb21wbGV0ZVRwUGFzc3dvcmRSZXNldFJlcXVlc3RNdXRhdGlvbixcbn0gZnJvbSAnLi4vdHAtcGFzc3dvcmQtcmVzZXQvdHAtcGFzc3dvcmQtcmVzZXQuZ3FsJztcbmltcG9ydCB7XG4gIEtjQmFkUmVxdWVzdEV4Y2VwdGlvbixcbiAgS2NCYWRTdGF0ZUV4Y2VwdGlvbixcbiAgS2NDb25jdXJyZW50QWNjZXNzRXhjZXB0aW9uLFxuICBLY0ludGVybmFsRXJyb3JFeGNlcHRpb24sXG59IGZyb20gJy4uL19jb21tb24vZXhjZXB0aW9ucyc7XG5pbXBvcnQgeyBLZXlDb250YWluZXIgfSBmcm9tICcuLi9fY29tbW9uL2tleSc7XG5pbXBvcnQgeyBSdW5PdXRzaWRlQW5ndWxhciB9IGZyb20gJy4uL19jb21tb24vcnVuLW91dHNpZGUtYW5ndWxhcic7XG5pbXBvcnQge1xuICBDdXJyZW50VXNlclF1ZXJ5LFxuICBDdXJyZW50VXNlclF1ZXJ5UmVzdWx0LFxuICBSZXNldFVzZXJRdWVyeSxcbiAgUmVzZXRVc2VyUXVlcnlSZXN1bHQsXG4gIFNldFNlc3Npb25FbmNyeXB0aW9uS2V5TXV0YXRpb24sXG59IGZyb20gJy4vYXV0aC5ncWwucHJpdmF0ZSc7XG5pbXBvcnQge1xuICBBdXRoVXNlcixcbiAgQ29nbml0b0NoYWxsZW5nZU5hbWUsXG4gIExvZ2luQ2hhbGxlbmdlLFxuICBMb2dpbk9wdGlvbnMsXG4gIExvZ2luUmVzdWx0LFxuICBMb2dvdXRMaXN0ZW5lcixcbiAgTHJDb2duaXRvVXNlcixcbiAgTHJDb2duaXRvVXNlckF0dHJpYnV0ZSxcbiAgUGFzc0lkcFJlc3VsdCxcbiAgUGFzc3dvcmRDaGFuZ2VTdGF0dXMsXG4gIFJlY292ZXJ5U3RhdHVzLFxufSBmcm9tICcuL2F1dGgudHlwZXMnO1xuXG5AUnVuT3V0c2lkZUFuZ3VsYXIoe1xuICBuZ1pvbmVOYW1lOiAnbmdab25lJyxcbn0pXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgQXV0aFNlcnZpY2UgZXh0ZW5kcyBMclNlcnZpY2Uge1xuICBzdGF0aWMgQ0hBTExFTkdFX1RJTUVPVVQgPSAxMDAwICogNjAgKiA1O1xuXG4gIC8vIENvdWxkIHVzZSByeGpzIG9ic2VydmFibGVzIGhlcmUuIEJ1dCB0cnlpbmcgdG8gaGF2ZSBrYy1jbGllbnQgdXNlIGFzIGxpdHRsZSBhbmd1bGFyXG4gIC8vIGZlYXR1cmVzIGFzIHBvc3NpYmxlLiBSeGpzIGlzIG5vdCB1c2VkIGFueXdoZXJlIGVsc2UgaW4ga2MtY2xpZW50LlxuICBwcml2YXRlIGxvZ291dExpc3RlbmVycyA9IG5ldyBTZXQ8TG9nb3V0TGlzdGVuZXI+KCk7XG4gIHByaXZhdGUgdXNlcjogQXV0aFVzZXI7XG4gIC8vIFN0b3JlcyB0aGUgcGFzc3dvcmQgZm9yIHVzZSBhZnRlciBtZmEgdmVyaWZpY2F0aW9uIHRvIGRlY3J5cHQgbWFzdGVyS2V5LlxuICBwcml2YXRlIHBhc3N3b3JkOiBLZXlDb250YWluZXIgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxuICAgIHByaXZhdGUgY29nbml0bzogQXV0aENsYXNzLFxuICAgIHByaXZhdGUgYXBpOiBMckdyYXBoUUxTZXJ2aWNlLFxuICAgIHByaXZhdGUga2V5U2VydmljZTogS2V5U2VydmljZSxcbiAgICBwcml2YXRlIGtleUdyYXBoU2VydmljZTogS2V5R3JhcGhTZXJ2aWNlLFxuICAgIHByaXZhdGUga2V5RmFjdG9yeVNlcnZpY2U6IEtleUZhY3RvcnlTZXJ2aWNlLFxuICAgIHByaXZhdGUgcGFzc3dvcmRTZXJ2aWNlOiBQYXNzd29yZFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBpZGxlU2VydmljZTogSWRsZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBwZXJzaXN0U2VydmljZTogUGVyc2lzdFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBlbmNyeXB0aW9uU2VydmljZTogRW5jcnlwdGlvblNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhc3NlbWJseUNvbnRyb2xsZXI6IFRwUGFzc3dvcmRSZXNldEFzc2VtYmx5Q29udHJvbGxlcixcbiAgICBASW5qZWN0KEtDX0NPTkZJRykgcHJpdmF0ZSBrY0NvbmZpZzogS2NDb25maWdcbiAgKSB7XG4gICAgc3VwZXIoaW5qZWN0b3IpO1xuICAgIGlmICghaXNEZXZNb2RlKCkpIHtcbiAgICAgIGlmICh0aGlzLmtjQ29uZmlnLmRlYnVnICE9IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEtjQmFkUmVxdWVzdEV4Y2VwdGlvbihcbiAgICAgICAgICAnSW4gcHJvZHVjdGlvbiBtb2RlLCBcIktjQ29uZmlnLmRlYnVnXCIgbXVzdCBiZSBzZXQgdG8gbnVsbCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpbXBvcnRQYXNzd29yZChwbGFpblBhc3N3b3JkOiBzdHJpbmcpOiBQcm9taXNlPENyeXB0b0tleT4ge1xuICAgIHJldHVybiB0aGlzLmtleUZhY3RvcnlTZXJ2aWNlLmltcG9ydFBhc3N3b3JkKHBsYWluUGFzc3dvcmQpO1xuICB9XG5cbiAgYXN5bmMgbG9nb3V0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIE5vdGlmeSBhbGwgbGlzdGVuZXJzIHRvIGNsZWFuIHVwLlxuICAgIGF3YWl0IFByb21pc2UuYWxsKFsuLi50aGlzLmxvZ291dExpc3RlbmVyc10ubWFwKChjYWxsYmFjaykgPT4gY2FsbGJhY2soKSkpO1xuXG4gICAgdGhpcy51c2VyID0gbnVsbDtcbiAgICB0aGlzLmtleVNlcnZpY2UucHVyZ2VLZXlzKCk7XG4gICAgdGhpcy5rZXlHcmFwaFNlcnZpY2UucHVyZ2VLZXlzKCk7XG5cbiAgICAvLyBTaWduIG91dCBvbiBib3RoIGNvZ25pdG8gYW5kIGtjLXNlcnZlclxuICAgIGF3YWl0IFByb21pc2UuYWxsKFt0aGlzLmNvZ25pdG8uc2lnbk91dCgpLCB0aGlzLmtjTG9nb3V0KCldKTtcblxuICAgIGlmICh0aGlzLmtjQ29uZmlnLmRlYnVnPy51c2VybmFtZSkge1xuICAgICAgdGhpcy5rY0NvbmZpZy5kZWJ1Zy51c2VybmFtZSA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgYWRkTG9nb3V0TGlzdGVuZXIoY2FsbGJhY2s6IExvZ291dExpc3RlbmVyKSB7XG4gICAgdGhpcy5sb2dvdXRMaXN0ZW5lcnMuYWRkKGNhbGxiYWNrKTtcbiAgfVxuXG4gIHJlbW92ZUxvZ291dExpc3RlbmVyKGNhbGxiYWNrOiBMb2dvdXRMaXN0ZW5lcikge1xuICAgIHRoaXMubG9nb3V0TGlzdGVuZXJzLmRlbGV0ZShjYWxsYmFjayk7XG4gIH1cblxuICBhc3luYyBsb2dpbihcbiAgICBlbWFpbE9yUGhvbmU6IHN0cmluZyxcbiAgICBwYXNzd29yZDogQ3J5cHRvS2V5LFxuICAgIHsgdHBQYXNzd29yZFJlc2V0QXV0b0NvbXBsZXRlID0gdHJ1ZSB9OiBMb2dpbk9wdGlvbnMgPSB7fVxuICApOiBQcm9taXNlPExvZ2luUmVzdWx0PiB7XG4gICAgbGV0IGxvZ2luUmVzdWx0OiBMb2dpblJlc3VsdCA9IGF3YWl0IHRoaXMubG9naW5JbXBsKGVtYWlsT3JQaG9uZSwgcGFzc3dvcmQpO1xuXG4gICAgLy8gU2F2ZSB0aGUgcGFzc3dvcmQgZm9yIHVzZSBhZnRlciBtZWV0aW5nIGNoYWxsZW5nZS5cbiAgICBpZiAobG9naW5SZXN1bHQuY2hhbGxlbmdlKSB7XG4gICAgICB0aGlzLnBhc3N3b3JkID0gbmV3IEtleUNvbnRhaW5lcihwYXNzd29yZCwgQXV0aFNlcnZpY2UuQ0hBTExFTkdFX1RJTUVPVVQpO1xuXG4gICAgICByZXR1cm4gbG9naW5SZXN1bHQ7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHBQYXNzd29yZFJlc2V0QXV0b0NvbXBsZXRlICYmXG4gICAgICBsb2dpblJlc3VsdC51c2VyLnJlc2V0VXNlcj8uc3RhdGUgPT09IFRwQ2xhaW1TdGF0ZS5BUFBST1ZFRFxuICAgICkge1xuICAgICAgYXdhaXQgdGhpcy5jb21wbGV0ZVJlc2V0UmVxdWVzdChwYXNzd29yZCk7XG4gICAgICBsb2dpblJlc3VsdCA9IGF3YWl0IHRoaXMubG9naW5JbXBsKGVtYWlsT3JQaG9uZSwgcGFzc3dvcmQpO1xuICAgIH1cblxuICAgIHJldHVybiBsb2dpblJlc3VsdDtcbiAgfVxuXG4gIGFzeW5jIHZlcmlmeUxvZ2luKG9wdGlvbnM6IHtcbiAgICBjaGFsbGVuZ2U6IExvZ2luQ2hhbGxlbmdlO1xuICAgIGNvZGU6IHN0cmluZztcbiAgICByZW1lbWJlck1lOiBib29sZWFuO1xuICB9KTogUHJvbWlzZTxMb2dpblJlc3VsdD4ge1xuICAgIGNvbnN0IHsgY2hhbGxlbmdlLCBjb2RlLCByZW1lbWJlck1lIH0gPSBvcHRpb25zO1xuXG4gICAgY29uc3QgVkFMSURfQ0hBTExFTkdFX05BTUVTID0gW1xuICAgICAgQ29nbml0b0NoYWxsZW5nZU5hbWUuU01TX01GQSxcbiAgICAgIENvZ25pdG9DaGFsbGVuZ2VOYW1lLlNPRlRXQVJFX1RPS0VOX01GQSxcbiAgICBdO1xuXG4gICAgaWYgKCFWQUxJRF9DSEFMTEVOR0VfTkFNRVMuaW5jbHVkZXMoY2hhbGxlbmdlLmNvZ25pdG9Vc2VyLmNoYWxsZW5nZU5hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgS2NCYWRSZXF1ZXN0RXhjZXB0aW9uKFxuICAgICAgICBgY2hhbGxlbmdlTmFtZSBtdXN0IGJlIG9uZSBvZiAke1ZBTElEX0NIQUxMRU5HRV9OQU1FU31gXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFRPRE86IHRoaXMuYXV0aC5jb25maXJtU2lnbkluKCkgY291bGQgcmV0dXJuIGFub3RoZXIgY2hhbGxlbmdlLlxuICAgIGNvbnN0IGNvZ25pdG9Vc2VyID0gYXdhaXQgdGhpcy5jb2duaXRvLmNvbmZpcm1TaWduSW4oXG4gICAgICBjaGFsbGVuZ2UuY29nbml0b1VzZXIsXG4gICAgICBjb2RlLFxuICAgICAgY2hhbGxlbmdlLmNvZ25pdG9Vc2VyLmNoYWxsZW5nZU5hbWUgYXNcbiAgICAgICAgfCBDb2duaXRvQ2hhbGxlbmdlTmFtZS5TTVNfTUZBXG4gICAgICAgIHwgQ29nbml0b0NoYWxsZW5nZU5hbWUuU09GVFdBUkVfVE9LRU5fTUZBXG4gICAgKTtcblxuICAgIGF3YWl0IHRoaXMuaGFuZGxlUG9zdEF1dGgoY2hhbGxlbmdlLnJlY292ZXJ5U3RhdHVzKTtcblxuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLmxvYWRVc2VyKGNvZ25pdG9Vc2VyLCB0aGlzLnBhc3N3b3JkLnBvcCgpKTtcblxuICAgIC8vIFRoaXMgaXMgbm90IHN0cmljdGx5IG5lY2Vzc2FyeSBzaW5jZSB0aGUgdGhpcy5wYXNzd29yZC5wb3AoKSBhbHJlYWR5IGNsZWFycyB0aGVcbiAgICAvLyBwYXNzd29yZCBpbnNpZGUgdGhlIGNvbnRhaW5lci4gQnV0IGRvZXNuJ3QgaHVydCBlaXRoZXIuXG4gICAgdGhpcy5wYXNzd29yZCA9IG51bGw7XG5cbiAgICBpZiAocmVtZW1iZXJNZSkge1xuICAgICAgY29nbml0b1VzZXIuc2V0RGV2aWNlU3RhdHVzUmVtZW1iZXJlZCh7XG4gICAgICAgIG9uU3VjY2VzczogKCkgPT4ge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSxcbiAgICAgICAgb25GYWlsdXJlOiAoZSkgPT4gY29uc29sZS5lcnJvcihlKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB1c2VyLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBnZXRVc2VyKCk6IFByb21pc2U8QXV0aFVzZXI+IHtcbiAgICBpZiAodGhpcy51c2VyKSB7XG4gICAgICByZXR1cm4gdGhpcy51c2VyO1xuICAgIH1cblxuICAgIGNvbnN0IGNvZ25pdG9Vc2VyID0gYXdhaXQgdGhpcy5jb2duaXRvLmN1cnJlbnRBdXRoZW50aWNhdGVkVXNlcigpO1xuXG4gICAgcmV0dXJuIHRoaXMubG9hZFVzZXIoY29nbml0b1VzZXIpO1xuICB9XG5cbiAgYXN5bmMgcmVmcmVzaEFjY2Vzc1Rva2VuKCkge1xuICAgIGNvbnN0IGNvZ25pdG9Vc2VyOiBDb2duaXRvVXNlciA9XG4gICAgICBhd2FpdCB0aGlzLmNvZ25pdG8uY3VycmVudEF1dGhlbnRpY2F0ZWRVc2VyKCk7XG4gICAgY29uc3QgcmVmcmVzaFRva2VuID0gY29nbml0b1VzZXIuZ2V0U2lnbkluVXNlclNlc3Npb24oKS5nZXRSZWZyZXNoVG9rZW4oKTtcblxuICAgIGNvbnNvbGUubG9nKCdUb2tlbiByZWZyZXNoLi4uJyk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvZ25pdG9Vc2VyLnJlZnJlc2hTZXNzaW9uKHJlZnJlc2hUb2tlbiwgKGVycikgPT4ge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgcmVmcmVzaGluZyB0b2tlbjogJywgZXJyKTtcbiAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnVG9rZW4gcmVmcmVzaCBjb21wbGV0ZScpO1xuICAgICAgICAgIHJlc29sdmUoMCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBIZWxwZXJzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwcml2YXRlIGFzeW5jIGZldGNoQ3VycmVudFVzZXIoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGF3YWl0IHRoaXMuYXBpLnF1ZXJ5PEN1cnJlbnRVc2VyUXVlcnlSZXN1bHQ+KHtcbiAgICAgICAgcXVlcnk6IEN1cnJlbnRVc2VyUXVlcnksXG4gICAgICAgIHByb2Nlc3Nvck9wdGlvbnM6IHtcbiAgICAgICAgICBoYXNLZXlzOiBmYWxzZSwgLy8gRG9uJ3QgdHJ5IHRvIGRlY3J5cHQgYW55dGhpbmcgYmVjYXVzZSBrZXlzIGhhdmUgbm90IGJlZW4gc2V0dXAgeWV0XG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICkuY3VycmVudFVzZXI7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGZldGNoUmVzZXRVc2VyKCkge1xuICAgIHJldHVybiAoXG4gICAgICBhd2FpdCB0aGlzLmFwaS5xdWVyeTxSZXNldFVzZXJRdWVyeVJlc3VsdD4oe1xuICAgICAgICBxdWVyeTogUmVzZXRVc2VyUXVlcnksXG4gICAgICAgIHByb2Nlc3Nvck9wdGlvbnM6IHtcbiAgICAgICAgICBoYXNLZXlzOiBmYWxzZSwgLy8gRG9uJ3QgdHJ5IHRvIGRlY3J5cHQgYW55dGhpbmcgYmVjYXVzZSBrZXlzIGhhdmUgbm90IGJlZW4gc2V0dXAgeWV0XG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICkudHBQYXNzd29yZFJlc2V0VXNlcjtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMga2NMb2dvdXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5odHRwXG4gICAgICAucG9zdChgJHt0aGlzLmtjQ29uZmlnLmF1dGhVcmx9YXV0aC9zaWduLW91dC9gLCBudWxsLCB7XG4gICAgICAgIHdpdGhDcmVkZW50aWFsczogdHJ1ZSxcbiAgICAgICAgcmVzcG9uc2VUeXBlOiAndGV4dCcsXG4gICAgICB9KVxuICAgICAgLnRvUHJvbWlzZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaFBhc3NJZHBQYXJhbXMoXG4gICAgZW1haWxPclBob25lOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxQYXNzSWRwUmVzdWx0PiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuaHR0cFxuICAgICAgLmdldDxQYXNzSWRwUmVzdWx0PihcbiAgICAgICAgYCR7XG4gICAgICAgICAgdGhpcy5rY0NvbmZpZy5hdXRoVXJsXG4gICAgICAgIH11c2Vycy9wYXNzLWlkcC1wYXJhbXMvP2xvZ2luX25hbWU9JHtlbmNvZGVVUklDb21wb25lbnQoZW1haWxPclBob25lKX1gXG4gICAgICApXG4gICAgICAudG9Qcm9taXNlKCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvZ2luSW1wbChcbiAgICBlbWFpbE9yUGhvbmU6IHN0cmluZyxcbiAgICBwYXNzd29yZDogQ3J5cHRvS2V5XG4gICk6IFByb21pc2U8TG9naW5SZXN1bHQ+IHtcbiAgICBhd2FpdCB0aGlzLmxvZ291dCgpO1xuICAgIGNvbnN0IGxvZ2luSWRwUmVzdWx0ID0gYXdhaXQgdGhpcy5sb2dpbklkcChlbWFpbE9yUGhvbmUsIHBhc3N3b3JkKTtcblxuICAgIC8vIENhbid0IGdldCB0aGUgdXNlciB5ZXQgYmVjYXVzZSB3ZSBzdGlsbCBuZWQgdG8gbWVldCBNRkEgY2hhbGxlbmdlc1xuICAgIGlmIChcbiAgICAgIFtcbiAgICAgICAgQ29nbml0b0NoYWxsZW5nZU5hbWUuU01TX01GQSxcbiAgICAgICAgQ29nbml0b0NoYWxsZW5nZU5hbWUuU09GVFdBUkVfVE9LRU5fTUZBLFxuICAgICAgXS5pbmNsdWRlcyhsb2dpbklkcFJlc3VsdC5jb2duaXRvVXNlci5jaGFsbGVuZ2VOYW1lKVxuICAgICkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY2hhbGxlbmdlOiB7XG4gICAgICAgICAgY29nbml0b1VzZXI6IGxvZ2luSWRwUmVzdWx0LmNvZ25pdG9Vc2VyLFxuICAgICAgICAgIHJlY292ZXJ5U3RhdHVzOiBsb2dpbklkcFJlc3VsdC5yZWNvdmVyeVN0YXR1cyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5oYW5kbGVQb3N0QXV0aChsb2dpbklkcFJlc3VsdC5yZWNvdmVyeVN0YXR1cyk7XG4gICAgLy8gVGhlcmUgc2hvdWxkIGJlIG5vIE1GQSBvbiB0aGUgVFAgcmVzZXQgdXNlci5cbiAgICBjb25zdCB1c2VyID0gYXdhaXQgdGhpcy5sb2FkVXNlcihsb2dpbklkcFJlc3VsdC5jb2duaXRvVXNlciwgcGFzc3dvcmQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHVzZXIsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbG9naW5JZHAoXG4gICAgZW1haWxPclBob25lOiBzdHJpbmcsXG4gICAgcGFzc3dvcmQ6IENyeXB0b0tleVxuICApOiBQcm9taXNlPExvZ2luQ2hhbGxlbmdlPiB7XG4gICAgLy8gRG93bmxvYWQgdGhlIHNhbHQgbmVlZGVkIHRvIGRlcml2ZSB0aGUgUGFzc0lkcFxuICAgIGNvbnN0IHBhc3NJZHBBcGlSZXN1bHQgPSBhd2FpdCB0aGlzLmZldGNoUGFzc0lkcFBhcmFtcyhlbWFpbE9yUGhvbmUpO1xuXG4gICAgaWYgKFxuICAgICAgcGFzc0lkcEFwaVJlc3VsdC5wYXNzd29yZENoYW5nZVN0YXR1cyA9PT0gUGFzc3dvcmRDaGFuZ2VTdGF0dXMuSU5fUFJPR1JFU1NcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBLY0NvbmN1cnJlbnRBY2Nlc3NFeGNlcHRpb24oJ0EgcGFzc3dvcmQgY2hhbmdlIGlzIGluIHByb2dyZXNzJyk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgcGFzc0lkcEFwaVJlc3VsdC5wYXNzd29yZENoYW5nZVN0YXR1cyA9PT0gUGFzc3dvcmRDaGFuZ2VTdGF0dXMuUkVDT1ZFUllcbiAgICApIHtcbiAgICAgIGNvbnNvbGUubG9nKCdJbiByZWNvdmVyeSBtb2RlLicpO1xuXG4gICAgICAvLyBMZXQncyBzYXkgd2UgZG9uJ3Qga25vdyBpZiB0aGUgcGFzc3dvcmQgaXMgdGhlIG5ldyBvbmUgb3IgdGhlIG9sZCBvbmUuIFdlIGp1c3QgaGF2ZSB0byB0cnkgYm90aC5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHVzZXI6IExvZ2luQ2hhbGxlbmdlID0ge1xuICAgICAgICAgIGNvZ25pdG9Vc2VyOiBhd2FpdCB0aGlzLmxvZ2luSWRwSW1wbChcbiAgICAgICAgICAgIGVtYWlsT3JQaG9uZSxcbiAgICAgICAgICAgIHBhc3N3b3JkLFxuICAgICAgICAgICAgcGFzc0lkcEFwaVJlc3VsdC5uZXdQYXNzSWRwUGFyYW1zXG4gICAgICAgICAgKSxcbiAgICAgICAgICByZWNvdmVyeVN0YXR1czogUmVjb3ZlcnlTdGF0dXMuTkVXX1BBU1NXT1JELFxuICAgICAgICB9O1xuICAgICAgICAvLyBOZXcgcGFzc3dvcmQgd29ya2VkLiBMZXQncyBzZXQgdG8gdGhlIGN1cnJlbnQgcGFzc3dvcmRcblxuICAgICAgICAvLyAtLVBvdGVudGlhbCBGYWlsdXJlIFBvaW50IDEtLVxuICAgICAgICAvLyBpZiBjaGFuZ2VQYXNzd29yZENvbXBsZXRlKCkgZG9lc24ndCBnZXQgY2FsbGVkLCB0aGVuIGl0IHNob3VsZCByZW1haW5cblxuICAgICAgICBjb25zb2xlLmxvZygnTmV3IHBhc3N3b3JkIHdvcmtzIScpO1xuXG4gICAgICAgIHJldHVybiB1c2VyO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gSnVzdCBidWJibGUgdXAgYW55IG90aGVyIHR5cGUgb2YgZXJyb3IuXG4gICAgICAgIGlmIChlcnJvci5jb2RlICE9PSAnTm90QXV0aG9yaXplZEV4Y2VwdGlvbicpIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICAvLyBwYXNzLCB0cnkgYWdhaW4gYXNzdW1pbmcgaXQncyB0aGUgb2xkIHBhc3N3b3JkXG4gICAgICB9XG5cbiAgICAgIC8vIE5vdyBhc3N1bWUgaXQncyB0aGUgcHJldmlvdXMgcGFzc3dvcmQuIEFueSBleGNlcHRpb24gaXMgYWxsb3dlZCB0byBidWJibGUgdXAuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB1c2VyOiBMb2dpbkNoYWxsZW5nZSA9IHtcbiAgICAgICAgICBjb2duaXRvVXNlcjogYXdhaXQgdGhpcy5sb2dpbklkcEltcGwoXG4gICAgICAgICAgICBlbWFpbE9yUGhvbmUsXG4gICAgICAgICAgICBwYXNzd29yZCxcbiAgICAgICAgICAgIHBhc3NJZHBBcGlSZXN1bHQuY3VycmVudFBhc3NJZHBQYXJhbXNcbiAgICAgICAgICApLFxuICAgICAgICAgIHJlY292ZXJ5U3RhdHVzOiBSZWNvdmVyeVN0YXR1cy5PTERfUEFTU1dPUkQsXG4gICAgICAgIH07XG4gICAgICAgIC8vIE9sZCBwYXNzd29yZCB3b3JrZWQuXG4gICAgICAgIGNvbnNvbGUubG9nKCdPbGQgcGFzc3dvcmQgd29ya3MhJyk7XG5cbiAgICAgICAgcmV0dXJuIHVzZXI7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBKdXN0IGJ1YmJsZSB1cCBhbnkgb3RoZXIgdHlwZSBvZiBlcnJvci5cbiAgICAgICAgdGhyb3cgZXJyb3IuY29kZSA9PT0gJ05vdEF1dGhvcml6ZWRFeGNlcHRpb24nXG4gICAgICAgICAgPyBuZXcgS2NCYWRSZXF1ZXN0RXhjZXB0aW9uKFxuICAgICAgICAgICAgICAnVGhlIHBhc3N3b3JkIGNoYW5nZSByZXF1ZXN0IHdhcyBpbnRlcnJ1cHRlZCwgcGxlYXNlIHRyeSB0byBsb2dpbiB3aXRoIGJvdGggeW91ciBuZXcgYW5kIG9sZCBwYXNzd29yZCdcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6IGVycm9yO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRyeSBhZ2FpbiBhcyB0aGUgVFAgcGFzc3dvcmQgcmVzZXQgYWNjb3VudFxuICAgIGlmIChwYXNzSWRwQXBpUmVzdWx0LnRwUGFzc3dvcmRSZXNldCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gVFAgcGFzc3dvcmQgcmVzZXQgaXMgaW4gcHJvY2Vzcy4gV2UgbmVlZCB0byB0cnkgdGhlIHBhc3N3b3JkIGFnYWluc3QgYm90aFxuICAgICAgICAvLyBvcmlnaW5hbCBhY2NvdW50IGFuZCB0aGUgbmV3IHJlc2V0IGFjY291bnQuXG4gICAgICAgIGNvbnN0IHJlc2V0ID0gcGFzc0lkcEFwaVJlc3VsdC50cFBhc3N3b3JkUmVzZXQ7XG4gICAgICAgIGNvbnN0IHVzZXI6IExvZ2luQ2hhbGxlbmdlID0ge1xuICAgICAgICAgIGNvZ25pdG9Vc2VyOiBhd2FpdCB0aGlzLmxvZ2luSWRwSW1wbChcbiAgICAgICAgICAgIHJlc2V0LnJlc2V0VXNlcm5hbWUsXG4gICAgICAgICAgICBwYXNzd29yZCxcbiAgICAgICAgICAgIHJlc2V0LnBhc3NJZHBQYXJhbXNcbiAgICAgICAgICApLFxuICAgICAgICAgIHJlY292ZXJ5U3RhdHVzOiBSZWNvdmVyeVN0YXR1cy5OT05FLFxuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiB1c2VyO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIC8vIGNvbnRpbnVlLCB0cnkgYWdhaW4gYXMgcmVndWxhciB1c2VyLlxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIExvZ2luIGFzIHJlZ3VsYXIgdXNlclxuICAgIGNvbnN0IHVzZXI6IExvZ2luQ2hhbGxlbmdlID0ge1xuICAgICAgY29nbml0b1VzZXI6IGF3YWl0IHRoaXMubG9naW5JZHBJbXBsKFxuICAgICAgICBlbWFpbE9yUGhvbmUsXG4gICAgICAgIHBhc3N3b3JkLFxuICAgICAgICBwYXNzSWRwQXBpUmVzdWx0LmN1cnJlbnRQYXNzSWRwUGFyYW1zXG4gICAgICApLFxuICAgICAgcmVjb3ZlcnlTdGF0dXM6IFJlY292ZXJ5U3RhdHVzLk5PTkUsXG4gICAgfTtcblxuICAgIHJldHVybiB1c2VyO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBsb2dpbklkcEltcGwoXG4gICAgZW1haWxPclBob25lOiBzdHJpbmcsXG4gICAgcGFzc3dvcmQ6IENyeXB0b0tleSxcbiAgICBwYXNzSWRwUGFyYW1zOiBQYXNzSWRwUGFyYW1zXG4gICk6IFByb21pc2U8THJDb2duaXRvVXNlcj4ge1xuICAgIGNvbnN0IHBhc3NJZHBSZXN1bHQgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnlTZXJ2aWNlLmRlcml2ZVBhc3NJZHAoe1xuICAgICAgcGFzc3dvcmQsXG4gICAgICAuLi5wYXNzSWRwUGFyYW1zLFxuICAgIH0pO1xuXG4gICAgLy8gVXNlIHRoZSBkZXJpdmVkIHBhc3N3b3JkIHRvIHNpZ25pbiB3aXRoIGNvZ25pdG9cbiAgICByZXR1cm4gdGhpcy5jb2duaXRvLnNpZ25JbihcbiAgICAgIGVtYWlsT3JQaG9uZSxcbiAgICAgIHRoaXMucGFzc3dvcmRTZXJ2aWNlLmdldFBhc3NJZHBTdHJpbmcocGFzc0lkcFJlc3VsdC5qd2spXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlUG9zdEF1dGgocmVjb3ZlcnlTdGF0dXM6IFJlY292ZXJ5U3RhdHVzKSB7XG4gICAgYXdhaXQgdGhpcy5oYW5kbGVQYXNzd29yZFJlY292ZXJ5KHJlY292ZXJ5U3RhdHVzKTtcbiAgICBhd2FpdCB0aGlzLmhhbmRsZVNlc3Npb25FbmNyeXB0aW9uS2V5KCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGhhbmRsZVBhc3N3b3JkUmVjb3ZlcnkocmVjb3ZlcnlTdGF0dXM6IFJlY292ZXJ5U3RhdHVzKSB7XG4gICAgaWYgKHJlY292ZXJ5U3RhdHVzICE9PSBSZWNvdmVyeVN0YXR1cy5OT05FKSB7XG4gICAgICBhd2FpdCB0aGlzLnBhc3N3b3JkU2VydmljZS5jaGFuZ2VQYXNzd29yZENvbXBsZXRlKHtcbiAgICAgICAgdXNlTmV3UGFzc3dvcmQ6IHJlY292ZXJ5U3RhdHVzID09PSBSZWNvdmVyeVN0YXR1cy5ORVdfUEFTU1dPUkQsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGhhbmRsZVNlc3Npb25FbmNyeXB0aW9uS2V5KCkge1xuICAgIGlmICh0aGlzLmtjQ29uZmlnLmRpc2FibGVTZXNzaW9uRW5jcnlwdGlvbktleSkge1xuICAgICAgaWYgKCFpc0Rldk1vZGUoKSkge1xuICAgICAgICBjb25zdCBtc2cgPVxuICAgICAgICAgICdZb3Ugc2hvdWxkIG5vdCBzZXQgZGlzYWJsZVNlc3Npb25FbmNyeXB0aW9uS2V5PVRydWUgaW4gbW9kZSBwcm9kLiBJdCBkZWZhdWx0cyB0byBmYWxzZS4nO1xuICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XG4gICAgICAgIHRocm93IG5ldyBLY0ludGVybmFsRXJyb3JFeGNlcHRpb24obXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAnWW91IGhhdmUgc2V0IGRpc2FibGVTZXNzaW9uRW5jcnlwdGlvbktleT1UcnVlLiBNYWtlIHN1cmUgbm90IHRvIGRvIHRoaXMgaW4gcHJvZCBtb2RlLidcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU2V0IHRoZSBzZXNzaW9uIGtleSB0byBhIG5ldyBlbmNyeXB0aW9uIGtleSBmb3IgdGhpcyBzZXNzaW9uXG4gICAgICBjb25zdCBzZXNzaW9uRW5jcnlwdGlvbktleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeVNlcnZpY2UuY3JlYXRlS2V5KCk7XG4gICAgICBhd2FpdCB0aGlzLmxyR3JhcGhRTC5sck11dGF0ZShcbiAgICAgICAgbmV3IExyTXV0YXRpb24oe1xuICAgICAgICAgIG11dGF0aW9uOiBTZXRTZXNzaW9uRW5jcnlwdGlvbktleU11dGF0aW9uLFxuICAgICAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICAgICAgaW5wdXQ6IHtcbiAgICAgICAgICAgICAgc2Vzc2lvbkVuY3J5cHRpb25LZXk6IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgICAgIHNlc3Npb25FbmNyeXB0aW9uS2V5LnRvSlNPTih0cnVlKVxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAge1xuICAgICAgICAgIGluY2x1ZGVLZXlHcmFwaDogZmFsc2UsXG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIHRoaXMucGVyc2lzdFNlcnZpY2Uuc2V0U2VydmVyU2Vzc2lvbkVuY3J5cHRpb25LZXkoc2Vzc2lvbkVuY3J5cHRpb25LZXkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29nbml0b1VzZXJBdHRyaWJ1dGUoXG4gICAgYXR0cmlidXRlTmFtZTogc3RyaW5nLFxuICAgIHVzZXJBdHRyaWJ1dGVzOiBDb2duaXRvVXNlckF0dHJpYnV0ZVtdXG4gICkge1xuICAgIGNvbnN0IHVzZXJBdHRyaWJ1dGUgPSB1c2VyQXR0cmlidXRlcy5maW5kKFxuICAgICAgKHgpID0+IHguZ2V0TmFtZSgpID09PSBhdHRyaWJ1dGVOYW1lXG4gICAgKTtcblxuICAgIHJldHVybiB1c2VyQXR0cmlidXRlID8gdXNlckF0dHJpYnV0ZS5nZXRWYWx1ZSgpIDogbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbG9hZFVzZXJLZXlzKG9wdGlvbnM6IHtcbiAgICB1c2VyS2V5czogVXNlcktleXM7XG4gICAgcGFzc3dvcmQ/OiBDcnlwdG9LZXk7XG4gICAgc2Vzc2lvbkVuY3J5cHRpb25LZXk/OiBzdHJpbmc7XG4gIH0pIHtcbiAgICBjb25zdCB7IHVzZXJLZXlzLCBwYXNzd29yZCwgc2Vzc2lvbkVuY3J5cHRpb25LZXkgfSA9IG9wdGlvbnM7XG5cbiAgICBpZiAoc2Vzc2lvbkVuY3J5cHRpb25LZXkpIHtcbiAgICAgIHRoaXMucGVyc2lzdFNlcnZpY2Uuc2V0U2VydmVyU2Vzc2lvbkVuY3J5cHRpb25LZXkoXG4gICAgICAgIGF3YWl0IEpXSy5hc0tleShzZXNzaW9uRW5jcnlwdGlvbktleSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gcGFzc3dvcmQgaXMgbm90IG5lZWRlZCBpZiB0aGUgbWFzdGVyIGtleSBpcyBhbHJlYWR5IHBlcnNpc3RlZC5cbiAgICBpZiAocGFzc3dvcmQpIHtcbiAgICAgIGNvbnN0IHBhc3NLZXkgPSAoXG4gICAgICAgIGF3YWl0IHRoaXMua2V5RmFjdG9yeVNlcnZpY2UuZGVyaXZlUGFzc0tleSh7XG4gICAgICAgICAgcGFzc3dvcmQsXG4gICAgICAgICAgLi4udXNlcktleXMucGFzc0tleS5wYXNzS2V5UGFyYW1zLFxuICAgICAgICB9KVxuICAgICAgKS5qd2s7XG5cbiAgICAgIGF3YWl0IHRoaXMuaWRsZVNlcnZpY2UucGVyc2lzdE1hc3RlcktleShcbiAgICAgICAgYXdhaXQgdGhpcy5rZXlHcmFwaFNlcnZpY2UudW53cmFwV2l0aFBhc3NLZXkoXG4gICAgICAgICAgdXNlcktleXMucGFzc0tleS5pZCxcbiAgICAgICAgICBwYXNzS2V5LFxuICAgICAgICAgIHVzZXJLZXlzLm1hc3RlcktleS5pZFxuICAgICAgICApXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbG9hZFVzZXIoXG4gICAgY29nbml0b1VzZXI6IENvZ25pdG9Vc2VyLFxuICAgIHBhc3N3b3JkPzogQ3J5cHRvS2V5XG4gICk6IFByb21pc2U8QXV0aFVzZXI+IHtcbiAgICBpZiAoY29nbml0b1VzZXIuZ2V0VXNlcm5hbWUoKS5lbmRzV2l0aChUUF9QQVNTV09SRF9SRVNFVF9VU0VSTkFNRV9TVUZGSVgpKSB7XG4gICAgICB0aGlzLnVzZXIgPSBhd2FpdCB0aGlzLmxvYWRSZXNldFVzZXIoY29nbml0b1VzZXIsIHBhc3N3b3JkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51c2VyID0gYXdhaXQgdGhpcy5sb2FkUmVndWxhclVzZXIoY29nbml0b1VzZXIsIHBhc3N3b3JkKTtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmlkbGVTZXJ2aWNlLnN0YXJ0KCk7IC8vIFJ1biBpZGxlU2VydmljZSB3aGVuZXZlciB1c2VyIGlzIGxvZ2dlZCBpbi5cblxuICAgIHJldHVybiB0aGlzLnVzZXI7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRSZWd1bGFyVXNlcihcbiAgICBjb2duaXRvVXNlcjogQ29nbml0b1VzZXIsXG4gICAgcGFzc3dvcmQ/OiBDcnlwdG9LZXlcbiAgKTogUHJvbWlzZTxBdXRoVXNlcj4ge1xuICAgIGNvbnN0IGN1cnJlbnRVc2VyID0gYXdhaXQgdGhpcy5mZXRjaEN1cnJlbnRVc2VyKCk7XG5cbiAgICBhd2FpdCB0aGlzLmxvYWRVc2VyS2V5cyh7XG4gICAgICB1c2VyS2V5czogY3VycmVudFVzZXIuY3VycmVudFVzZXJLZXksXG4gICAgICBwYXNzd29yZCxcbiAgICAgIHNlc3Npb25FbmNyeXB0aW9uS2V5OiBjdXJyZW50VXNlci5zZXNzaW9uRW5jcnlwdGlvbktleSxcbiAgICB9KTtcblxuICAgIC8vIFJlZ3VsYXIgdXNlciBwb3B1bGF0ZXMgYWxsIGtleXNcbiAgICBhd2FpdCB0aGlzLmtleUdyYXBoU2VydmljZS5wb3B1bGF0ZUtleXMoY3VycmVudFVzZXIuY3VycmVudFVzZXJLZXkpO1xuXG4gICAgY29uc3QgeyBpZCwgdXNlcm5hbWUgfSA9IGN1cnJlbnRVc2VyO1xuICAgIGNvbnN0IHVzZXJBdHRyaWJ1dGVzID0gYXdhaXQgdGhpcy5jb2duaXRvLnVzZXJBdHRyaWJ1dGVzKGNvZ25pdG9Vc2VyKTtcblxuICAgIHJldHVybiB7XG4gICAgICBpZCxcbiAgICAgIHVzZXJuYW1lLFxuICAgICAgc3ViOiB0aGlzLmdldENvZ25pdG9Vc2VyQXR0cmlidXRlKCdzdWInLCB1c2VyQXR0cmlidXRlcyksXG4gICAgICBsb2dpbkVtYWlsOiB0aGlzLmdldENvZ25pdG9Vc2VyQXR0cmlidXRlKCdlbWFpbCcsIHVzZXJBdHRyaWJ1dGVzKSxcbiAgICAgIHJlc2V0VXNlcjogbnVsbCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBsb2FkUmVzZXRVc2VyKFxuICAgIGNvZ25pdG9Vc2VyOiBDb2duaXRvVXNlcixcbiAgICBwYXNzd29yZD86IENyeXB0b0tleVxuICApOiBQcm9taXNlPEF1dGhVc2VyPiB7XG4gICAgY29uc3QgcmVzZXRVc2VyID0gYXdhaXQgdGhpcy5mZXRjaFJlc2V0VXNlcigpO1xuXG4gICAgY29uc3QgdXNlcktleXMgPSB7XG4gICAgICBwYXNzS2V5OiB7XG4gICAgICAgIGlkOiByZXNldFVzZXIucGFzc0tleS5pZCxcbiAgICAgICAgcGFzc0tleVBhcmFtczogcmVzZXRVc2VyLnBhc3NLZXkucGFzc0tleVBhcmFtcyxcbiAgICAgIH0sXG4gICAgICBtYXN0ZXJLZXk6IHtcbiAgICAgICAgaWQ6IHJlc2V0VXNlci5tYXN0ZXJLZXkuaWQsXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBhd2FpdCB0aGlzLmxvYWRVc2VyS2V5cyh7XG4gICAgICB1c2VyS2V5cyxcbiAgICAgIHBhc3N3b3JkLFxuICAgICAgc2Vzc2lvbkVuY3J5cHRpb25LZXk6IHJlc2V0VXNlci5zZXNzaW9uRW5jcnlwdGlvbktleSxcbiAgICB9KTtcblxuICAgIC8vIFJlc2V0IHVzZXIgb25seSBzZXRzIGEgc3Vic2V0IG9mIGtleXNcbiAgICBhd2FpdCB0aGlzLmtleVNlcnZpY2Uuc2V0S2V5cyh1c2VyS2V5cyk7XG5cbiAgICBjb25zdCB7IHVzZXJuYW1lIH0gPSByZXNldFVzZXI7XG4gICAgY29uc3QgdXNlckF0dHJpYnV0ZXMgPSBhd2FpdCB0aGlzLmNvZ25pdG8udXNlckF0dHJpYnV0ZXMoY29nbml0b1VzZXIpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHVzZXJuYW1lLFxuICAgICAgc3ViOiB0aGlzLmdldENvZ25pdG9Vc2VyQXR0cmlidXRlKCdzdWInLCB1c2VyQXR0cmlidXRlcyksXG4gICAgICBsb2dpbkVtYWlsOiB0aGlzLmdldENvZ25pdG9Vc2VyQXR0cmlidXRlKCdlbWFpbCcsIHVzZXJBdHRyaWJ1dGVzKSxcbiAgICAgIHJlc2V0VXNlcjoge1xuICAgICAgICBzdGF0ZTogcmVzZXRVc2VyLnN0YXRlLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZWNvdmVyQXNzZW1ibHlLZXkoXG4gICAgcmVzZXRVc2VyOiBSZXNldFVzZXJRdWVyeVJlc3VsdFsndHBQYXNzd29yZFJlc2V0VXNlciddXG4gICk6IFByb21pc2U8SldLLktleT4ge1xuICAgIGNvbnN0IHByayA9IGF3YWl0IHRoaXMua2V5R3JhcGhTZXJ2aWNlLmdldEtleShyZXNldFVzZXIucHhrLmlkKTtcblxuICAgIGNvbnN0IHBhcnRpYWxzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICByZXNldFVzZXIuYXBwcm92YWxzXG4gICAgICAgIC5maWx0ZXIoKGFwcHJvdmFsKSA9PiAhIWFwcHJvdmFsLnJlY2VpdmVyQ2lwaGVyUGFydGlhbEFzc2VtYmx5S2V5KVxuICAgICAgICAubWFwKChhcHByb3ZhbCkgPT5cbiAgICAgICAgICB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQoXG4gICAgICAgICAgICBwcmssXG4gICAgICAgICAgICBhcHByb3ZhbC5yZWNlaXZlckNpcGhlclBhcnRpYWxBc3NlbWJseUtleVxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICk7XG5cbiAgICByZXR1cm4gdGhpcy5hc3NlbWJseUNvbnRyb2xsZXIucmVjb3ZlckFzc2VtYmx5S2V5KHBhcnRpYWxzKTtcbiAgfVxuXG4gIGFzeW5jIGNvbXBsZXRlUmVzZXRSZXF1ZXN0KG5ld1Bhc3N3b3JkOiBDcnlwdG9LZXkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCByZXNldFVzZXIgPSBhd2FpdCB0aGlzLmZldGNoUmVzZXRVc2VyKCk7XG5cbiAgICBpZiAocmVzZXRVc2VyLnN0YXRlICE9PSBUcENsYWltU3RhdGUuQVBQUk9WRUQpIHtcbiAgICAgIHRocm93IG5ldyBLY0JhZFN0YXRlRXhjZXB0aW9uKFxuICAgICAgICAnUGFzc3dvcmQgcmVzZXQgcmVxdWVzdCBoYXMgbm90IGJlZW4gYXBwcm92ZWQuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFByZXBhcmUgYWxsIG1hdGVyaWFscyB0byBlbnN1cmUgdGhlcmUgYXJlIG5vIGVycm9ycy5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGNvbnN0IGFzc2VtYmx5S2V5ID0gYXdhaXQgdGhpcy5yZWNvdmVyQXNzZW1ibHlLZXkocmVzZXRVc2VyKTtcblxuICAgIGNvbnN0IHsgcm9vdEtleSB9ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxuICAgICAgYXNzZW1ibHlLZXksXG4gICAgICByZXNldFVzZXIuYXNzZW1ibHlDaXBoZXJEYXRhXG4gICAgKTtcblxuICAgIC8vIE1ha2luZyBzdXJlIGl0J3MgYSB2YWxpZCBrZXkuXG4gICAgY29uc3Qgcm9vdEtleUp3ayA9IGF3YWl0IEpXSy5hc0tleShyb290S2V5KTtcblxuICAgIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHRoaXMua2V5R3JhcGhTZXJ2aWNlLmdldEtleShyZXNldFVzZXIubWFzdGVyS2V5LmlkKTtcblxuICAgIGNvbnN0IG1hc3RlcktleVdyYXBwZWRSb290S2V5ID1cbiAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdFRvU3RyaW5nKFxuICAgICAgICBtYXN0ZXJLZXkuandrLFxuICAgICAgICByb290S2V5SndrLnRvSlNPTih0cnVlKVxuICAgICAgKTtcblxuICAgIC8vIFRoZSBuZXcgcGFzc3dvcmRcbiAgICBjb25zdCBuZXdQYXNzSWRwUmVzdWx0ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5U2VydmljZS5kZXJpdmVQYXNzSWRwKHtcbiAgICAgIHBhc3N3b3JkOiBuZXdQYXNzd29yZCxcbiAgICAgIC4uLnJlc2V0VXNlci5wYXNzS2V5LnBhc3NJZHBQYXJhbXMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBuZXdJZHBQYXNzd29yZCA9IHRoaXMucGFzc3dvcmRTZXJ2aWNlLmdldFBhc3NJZHBTdHJpbmcoXG4gICAgICBuZXdQYXNzSWRwUmVzdWx0Lmp3a1xuICAgICk7XG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEdldCBhc3NlbWJseSBrZXkgY2hhbGxlbmdlXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjb25zdCBjaGFsbGVuZ2UgPSAoXG4gICAgICBhd2FpdCB0aGlzLmxyR3JhcGhRTC5sck11dGF0ZShcbiAgICAgICAgbmV3IExyTXV0YXRpb24oe1xuICAgICAgICAgIG11dGF0aW9uOiBDcmVhdGVUcEFzc2VtYmx5S2V5Q2hhbGxlbmdlTXV0YXRpb24sXG4gICAgICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgICAgICBpbnB1dDoge30sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICAgIHtcbiAgICAgICAgICBpbmNsdWRlS2V5R3JhcGg6IGZhbHNlLFxuICAgICAgICB9XG4gICAgICApXG4gICAgKS5jcmVhdGVUcEFzc2VtYmx5S2V5Q2hhbGxlbmdlLmNoYWxsZW5nZTtcblxuICAgIC8vIFNpZ24gdGhlIGNoYWxsZW5nZVxuICAgIC8vIEdlbmVyYXRlIGEgY2xpZW50IHNpZGUgbm9uY2UgdGhhdCdzIG5vIGluIHRoZSBzZXJ2ZXIncyBjb250cm9sLlxuICAgIGNoYWxsZW5nZS5jbGllbnROb25jZSA9IHRoaXMua2V5RmFjdG9yeVNlcnZpY2UucmFuZG9tU3RyaW5nKFxuICAgICAgVFBfUEFTU1dPUkRfUkVTRVRfQ0xJRU5UX05PTkNFX0xFTkdUSFxuICAgICk7XG5cbiAgICBjb25zdCBhc3NlbWJseUtleVZlcmlmaWVyUHJrID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxuICAgICAgYXNzZW1ibHlLZXksXG4gICAgICByZXNldFVzZXIud3JhcHBlZEFzc2VtYmx5S2V5VmVyaWZpZXJQcmtcbiAgICApO1xuICAgIGNvbnN0IHNpZ25lZENoYWxsZW5nZSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihcbiAgICAgIGFzc2VtYmx5S2V5VmVyaWZpZXJQcmssXG4gICAgICBjaGFsbGVuZ2VcbiAgICApO1xuXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBDaGFuZ2UgcGFzc3dvcmQgZm9yIHRoZSBvcmlnaW5hbCB1c2VyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjb25zdCB0ZW1wSWRwUGFzc3dvcmQgPSAoXG4gICAgICBhd2FpdCB0aGlzLmxyR3JhcGhRTC5sck11dGF0ZShcbiAgICAgICAgbmV3IExyTXV0YXRpb24oe1xuICAgICAgICAgIG11dGF0aW9uOiBQcmVDb21wbGV0ZVRwUGFzc3dvcmRSZXNldFJlcXVlc3RNdXRhdGlvbixcbiAgICAgICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgICAgIGlucHV0OiB7XG4gICAgICAgICAgICAgIHNpZ25lZENoYWxsZW5nZTogSlNPTi5zdHJpbmdpZnkoc2lnbmVkQ2hhbGxlbmdlKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICAgIHtcbiAgICAgICAgICBpbmNsdWRlS2V5R3JhcGg6IGZhbHNlLFxuICAgICAgICB9XG4gICAgICApXG4gICAgKS5wcmVDb21wbGV0ZVRwUGFzc3dvcmRSZXNldFJlcXVlc3QuaWRwUGFzc3dvcmQ7XG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIExvZ2luIGFzIHRoZSBvcmlnaW5hbCB1c2VyIHVzaW5nIG5ldyB0ZW1wb3JhcnkgcGFzc3dvcmRcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEF0IHRoaXMgcG9pbnQsIHRoZSBvcmlnaW5hbCBhY2NvdW50J3MgcGFzc3dvcmQgaGFzIGJlZW4gY2hhbmdlZFxuICAgIC8vIHRvIGEgdGVtcG9yYXJ5IHBhc3N3b3JkLiBJdCBpcyBubyBsb25nZXIgcG9zc2libGUgZm9yIHRoZSB1c2VyXG4gICAgLy8gdG8gdXNlIHRoZSBvcmlnaW5hbCBwYXNzd29yZCB0byBsb2dpbi4gQW55IHN1Y2Nlc3NmdWwgbG9naW5cbiAgICAvLyBjYW4gb25seSBiZSB1c2luZyB0aGUgdGVtcG9yYXJ5IHBhc3N3b3JkLiBTbyBpdCdzIHNhZmUgdG8gYXNzdW1lXG4gICAgLy8gdGhhdCB3ZSB3YW50IHRvIFwiY29tcGxldGVcIiB0aGUgcGFzc3dvcmQgcmVzZXQuXG5cbiAgICAvLyBUaGVyZSBtYXliZSAyRkEgc28gd2UgbGlzdGVuIGZvciB0aGUgYXV0aCBldmVudCBmcm9tIEFtcGxpZnkuXG4gICAgY29uc3QgcmV0UHJvbWlzZSA9IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICBjb25zdCBsaXN0ZW5lciA9IGFzeW5jIChkYXRhKSA9PiB7XG4gICAgICAgIGlmIChkYXRhLnBheWxvYWQuZXZlbnQgIT09ICdzaWduSW4nKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgSHViLnJlbW92ZSgnYXV0aCcsIGxpc3RlbmVyKTtcblxuICAgICAgICBhd2FpdCB0aGlzLmNvZ25pdG8uc2lnbkluKHJlc2V0VXNlci51c2VybmFtZSwgbmV3SWRwUGFzc3dvcmQpO1xuXG4gICAgICAgIC8vIFN3aXRjaCBvdmVyIHRvIHRoZSBuZXcgc2V0IG9mIGtleXNcbiAgICAgICAgYXdhaXQgdGhpcy5sckdyYXBoUUwubHJNdXRhdGUoXG4gICAgICAgICAgbmV3IExyTXV0YXRpb24oe1xuICAgICAgICAgICAgbXV0YXRpb246IENvbXBsZXRlVHBQYXNzd29yZFJlc2V0UmVxdWVzdE11dGF0aW9uLFxuICAgICAgICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgICAgICAgIGlucHV0OiB7XG4gICAgICAgICAgICAgICAgbWFzdGVyS2V5V3JhcHBlZFJvb3RLZXksXG4gICAgICAgICAgICAgICAgbWFzdGVyS2V5SWQ6IG1hc3RlcktleS5pZCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9O1xuXG4gICAgICBIdWIubGlzdGVuKCdhdXRoJywgbGlzdGVuZXIpO1xuICAgIH0pO1xuXG4gICAgLy8gU2lnbmluIGFzIHRoZSBvcmlnaW5hbCB1c2VyLiBQYXNzd29yZCBoYXMgYmVlbiByZXNldCB0byB0ZW1wb3Jhcnkgb25lLiBJdCBzaG91bGQgcmV0dXJuXG4gICAgLy8gd2l0aCBORVdfUEFTU1dPUkRfUkVRVUlSRURcbiAgICBsZXQgdXNlciA9IGF3YWl0IHRoaXMuY29nbml0by5zaWduSW4ocmVzZXRVc2VyLnVzZXJuYW1lLCB0ZW1wSWRwUGFzc3dvcmQsIHtcbiAgICAgIG5vUHJveHk6ICd0cnVlJyxcbiAgICB9KTtcblxuICAgIGlmICh1c2VyLmNoYWxsZW5nZU5hbWUgIT09ICdORVdfUEFTU1dPUkRfUkVRVUlSRUQnKSB7XG4gICAgICB0aHJvdyBuZXcgS2NJbnRlcm5hbEVycm9yRXhjZXB0aW9uKFxuICAgICAgICAnRXhwZWN0aW5nIENvZ25pdG8gdG8gaGF2ZSBkb25lIGEgcGFzc3dvcmQgcmVzZXQgYWZ0ZXIgY2FsbCB0byBQcmVDb21wbGV0ZVRwUGFzc3dvcmRSZXNldFJlcXVlc3RNdXRhdGlvbi4nXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFNldCBuZXcgcGFzc3dvcmQgb24gSWRwXG4gICAgLy8gdGhlIGF3c0ZldGNoKCkgZnVuY3Rpb24gcGFzc2VzIE5FV19QQVNTV09SRF9SRVFVSVJFRCBkaXJlY3RseSB0byBBV1Mgd2l0aG91dFxuICAgIC8vIGdvaW5nIHRocm91Z2ggdGhlIHByb3h5LlxuICAgIHVzZXIgPSBhd2FpdCB0aGlzLmNvZ25pdG8uY29tcGxldGVOZXdQYXNzd29yZCh1c2VyLCBuZXdJZHBQYXNzd29yZCwge30pO1xuXG4gICAgcmV0dXJuIHJldFByb21pc2U7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gRGVidWcgdXRpbGl0aWVzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICBhc3luYyBkZWJ1Z0xvZ2luKHVzZXJuYW1lOiBzdHJpbmcsIHBhc3N3b3JkOiBDcnlwdG9LZXkpOiBQcm9taXNlPEF1dGhVc2VyPiB7XG4gICAgLy8gVGhpcyB3aWxsIGZhaWwgaWYgZGVidWcgaXMgbnVsbC4gQnV0IHdoZW4gZGVidWcgaXMgbnVsbCwgdGhpcyBmdW5jdGlvblxuICAgIC8vIHNob3VsZCBub3QgYmUgY2FsbGVkLlxuICAgIHRoaXMua2NDb25maWcuZGVidWcudXNlcm5hbWUgPSB1c2VybmFtZTtcbiAgICAvLyBSZXNldCBpdCBzbyB3ZSBkb24ndCBnZXQgc3VycHJpc2VzLlxuICAgIHRoaXMua2NDb25maWcuZGVidWcucmJhY0NhY2hlTW9kZSA9IG51bGw7XG5cbiAgICAvLyBUaGlzIG1lY2hhbmlzbSBvbmx5IHdvcmtzIGluIGEgYnJvd3NlciBzZXNzaW9uIGJlY2F1c2UgaXQgbmVlZHMgdG8gc2V0IGNvb2tpZXMgZXRjLlxuICAgIC8vIEJ1dCBpdCBzZXRzIHRoZSBsYXN0X2xvZ2luIGZpZWxkIGZvciB0aGUgdXNlcnMgd2hpY2ggd2UgbmVlZCBpbiBzb21lIHRlc3RzLlxuICAgIGF3YWl0IHRoaXMuaHR0cFxuICAgICAgLmdldChcbiAgICAgICAgYCR7XG4gICAgICAgICAgdGhpcy5rY0NvbmZpZy5hdXRoVXJsXG4gICAgICAgIH1kZWJ1Z19vbmx5L3VzZXJzL2xvZ2luLz91c2VybmFtZT0ke2VuY29kZVVSSUNvbXBvbmVudCh1c2VybmFtZSl9YFxuICAgICAgKVxuICAgICAgLnRvUHJvbWlzZSgpO1xuXG4gICAgcmV0dXJuIHRoaXMuZGVidWdMb2FkVXNlcihwYXNzd29yZCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRlYnVnTG9hZFVzZXIocGFzc3dvcmQ6IENyeXB0b0tleSk6IFByb21pc2U8QXV0aFVzZXI+IHtcbiAgICBjb25zdCBjdXJyZW50VXNlciA9IGF3YWl0IHRoaXMuZmV0Y2hDdXJyZW50VXNlcigpO1xuXG4gICAgY29uc3QgeyBpZCwgdXNlcm5hbWUsIGN1cnJlbnRVc2VyS2V5IH0gPSBjdXJyZW50VXNlcjtcblxuICAgIC8vIERlYnVnIG1vZGUgY2FuIG5vdCBkZWFsIHdpdGggc2Vzc2lvbiBlbmNyeXB0aW9uIGtleSB5ZXQuXG4gICAgLy8gTk8gU0VTU0lPTiBFTkNSWVBUSU9OIEtFWS5cblxuICAgIGNvbnN0IHBhc3NLZXkgPSAoXG4gICAgICBhd2FpdCB0aGlzLmtleUZhY3RvcnlTZXJ2aWNlLmRlcml2ZVBhc3NLZXkoe1xuICAgICAgICBwYXNzd29yZCxcbiAgICAgICAgLi4uY3VycmVudFVzZXJLZXkucGFzc0tleS5wYXNzS2V5UGFyYW1zLFxuICAgICAgfSlcbiAgICApLmp3aztcblxuICAgIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHRoaXMua2V5R3JhcGhTZXJ2aWNlLnVud3JhcFdpdGhQYXNzS2V5KFxuICAgICAgY3VycmVudFVzZXJLZXkucGFzc0tleS5pZCxcbiAgICAgIHBhc3NLZXksXG4gICAgICBjdXJyZW50VXNlcktleS5tYXN0ZXJLZXkuaWRcbiAgICApO1xuXG4gICAgYXdhaXQgdGhpcy5pZGxlU2VydmljZS5wZXJzaXN0TWFzdGVyS2V5KG1hc3RlcktleSk7XG5cbiAgICBhd2FpdCB0aGlzLmtleUdyYXBoU2VydmljZS5wb3B1bGF0ZUtleXMoY3VycmVudFVzZXJLZXkpO1xuXG4gICAgdGhpcy51c2VyID0ge1xuICAgICAgaWQsXG4gICAgICB1c2VybmFtZSxcbiAgICAgIHJlc2V0VXNlcjogbnVsbCxcbiAgICAgIHN1YjogJ0RFQlVHX01PREUnLFxuICAgICAgbG9naW5FbWFpbDogJ0RFQlVHX01PREUnLFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy51c2VyO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyB0aGUgY2FjaGVzIHVzZXIuIFNvIHdlIGNhbiBzaW11bGF0ZSBhIHBhZ2UgcmVmcmVzaCBhbmQgdGVzdCBnZXRVc2VyKCkuXG4gICAqL1xuICBkZWJ1Z0NsZWFyVXNlcigpIHtcbiAgICB0aGlzLnVzZXIgPSBudWxsO1xuICB9XG5cbiAgYXN5bmMgZ2V0Q3VycmVudFVzZXJBdHRyaWJ1dGVzKCk6IFByb21pc2U8THJDb2duaXRvVXNlckF0dHJpYnV0ZVtdPiB7XG4gICAgY29uc3QgY29nbml0b1VzZXIgPSBhd2FpdCB0aGlzLmNvZ25pdG8uY3VycmVudEF1dGhlbnRpY2F0ZWRVc2VyKCk7XG4gICAgY29uc3QgdXNlckF0dHJpYnV0ZXMgPSBhd2FpdCB0aGlzLmNvZ25pdG8udXNlckF0dHJpYnV0ZXMoY29nbml0b1VzZXIpO1xuXG4gICAgcmV0dXJuIHVzZXJBdHRyaWJ1dGVzO1xuICB9XG5cbiAgZGVidWdSZXRhaW5SYmFjQ2FjaGUoYjogYm9vbGVhbikge1xuICAgIHRoaXMua2NDb25maWcuZGVidWcucmJhY0NhY2hlTW9kZSA9IGIgPyAncmV0YWluJyA6IG51bGw7XG4gIH1cbn1cbiJdfQ==