@annalib/anna-cognito-lib 2.3.12 → 2.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{esm2020 → esm2022}/annalib-anna-cognito-lib.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/anna-login/anna-login.component.mjs +67 -67
- package/{esm2020 → esm2022}/lib/components/cognito-and-sso-login-container/cognito-and-sso-login-container.component.mjs +22 -22
- package/{esm2020 → esm2022}/lib/components/forgot-password/forgot-password.component.mjs +133 -133
- package/{esm2020 → esm2022}/lib/components/password-matching/password-matching.component.mjs +92 -92
- package/{esm2020 → esm2022}/lib/components/powered-by-logo-template/powered-by-logo-template.component.mjs +14 -14
- package/{esm2020 → esm2022}/lib/components/set-new-password/set-new-password.component.mjs +71 -71
- package/{esm2020 → esm2022}/lib/components/sso-login/sso-login.component.mjs +38 -38
- package/{esm2020 → esm2022}/lib/components/surewaves-year-logo/surewaves-year-logo.component.mjs +15 -15
- package/{esm2020 → esm2022}/lib/components/verify-and-set-new-password/verify-and-set-new-password.component.mjs +90 -90
- package/{esm2020 → esm2022}/lib/components/version-and-term-policy/version-and-term-policy.component.mjs +19 -19
- package/{esm2020 → esm2022}/lib/config/acl-service.token.mjs +4 -4
- package/{esm2020 → esm2022}/lib/config/auth-service.token.mjs +3 -3
- package/{esm2020 → esm2022}/lib/config/config-service.token.mjs +3 -3
- package/{esm2020 → esm2022}/lib/config/sso-login-service.token.mjs +3 -3
- package/esm2022/lib/constants/loginConstant.mjs +55 -0
- package/{esm2020 → esm2022}/lib/directives/spinner-button/index.mjs +1 -1
- package/{esm2020 → esm2022}/lib/directives/spinner-button/spinner-button.directive.mjs +43 -43
- package/{esm2020 → esm2022}/lib/models/auth.model.mjs +23 -23
- package/{esm2020 → esm2022}/lib/services/acl.service.mjs +27 -27
- package/{esm2020 → esm2022}/lib/services/auth.service.mjs +312 -312
- package/{esm2020 → esm2022}/lib/services/config.service.mjs +20 -20
- package/{esm2020 → esm2022}/lib/services/sso-login.service.mjs +20 -20
- package/{esm2020 → esm2022}/public-api.mjs +27 -27
- package/{fesm2020 → fesm2022}/annalib-anna-cognito-lib.mjs +905 -905
- package/fesm2022/annalib-anna-cognito-lib.mjs.map +1 -0
- package/index.d.ts +5 -5
- package/lib/components/anna-login/anna-login.component.d.ts +20 -20
- package/lib/components/cognito-and-sso-login-container/cognito-and-sso-login-container.component.d.ts +10 -10
- package/lib/components/forgot-password/forgot-password.component.d.ts +42 -42
- package/lib/components/password-matching/password-matching.component.d.ts +22 -22
- package/lib/components/powered-by-logo-template/powered-by-logo-template.component.d.ts +8 -8
- package/lib/components/set-new-password/set-new-password.component.d.ts +28 -28
- package/lib/components/sso-login/sso-login.component.d.ts +14 -14
- package/lib/components/surewaves-year-logo/surewaves-year-logo.component.d.ts +9 -9
- package/lib/components/verify-and-set-new-password/verify-and-set-new-password.component.d.ts +32 -32
- package/lib/components/version-and-term-policy/version-and-term-policy.component.d.ts +10 -10
- package/lib/config/acl-service.token.d.ts +38 -38
- package/lib/config/auth-service.token.d.ts +23 -23
- package/lib/config/config-service.token.d.ts +13 -13
- package/lib/config/sso-login-service.token.d.ts +10 -10
- package/lib/constants/loginConstant.d.ts +49 -49
- package/lib/directives/spinner-button/index.d.ts +1 -1
- package/lib/directives/spinner-button/spinner-button.directive.d.ts +15 -15
- package/lib/models/auth.model.d.ts +21 -21
- package/lib/services/acl.service.d.ts +11 -11
- package/lib/services/auth.service.d.ts +47 -47
- package/lib/services/config.service.d.ts +8 -8
- package/lib/services/sso-login.service.d.ts +8 -8
- package/package.json +5 -11
- package/public-api.d.ts +20 -20
- package/esm2020/lib/constants/loginConstant.mjs +0 -55
- package/fesm2015/annalib-anna-cognito-lib.mjs +0 -1011
- package/fesm2015/annalib-anna-cognito-lib.mjs.map +0 -1
- package/fesm2020/annalib-anna-cognito-lib.mjs.map +0 -1
|
@@ -1,312 +1,312 @@
|
|
|
1
|
-
// Angular import statements
|
|
2
|
-
import { HttpClient } from '@angular/common/http';
|
|
3
|
-
import { Inject, Injectable } from '@angular/core';
|
|
4
|
-
import { Router } from '@angular/router';
|
|
5
|
-
// Third party import statements
|
|
6
|
-
import { confirmResetPassword, confirmSignIn, fetchAuthSession, getCurrentUser, resetPassword, signIn, signOut, } from 'aws-amplify/auth';
|
|
7
|
-
import { ToastrService } from 'ngx-toastr';
|
|
8
|
-
// User defined import statements
|
|
9
|
-
import { AUTH_SERVICE_TOKEN } from '../config/auth-service.token';
|
|
10
|
-
import { LoginConstant } from '../constants/loginConstant';
|
|
11
|
-
import { AnnaLibAclService } from './acl.service';
|
|
12
|
-
import { SSO_LOGIN_SERVICE_TOKEN } from '../config/sso-login-service.token';
|
|
13
|
-
import * as i0 from "@angular/core";
|
|
14
|
-
import * as i1 from "@angular/router";
|
|
15
|
-
import * as i2 from "./acl.service";
|
|
16
|
-
import * as i3 from "@angular/common/http";
|
|
17
|
-
import * as i4 from "ngx-toastr";
|
|
18
|
-
export class AnnaLibAuthService {
|
|
19
|
-
constructor(router, aclService, httpClient, toastr, consumingProjectSSOLoginService, consumingProjectAuthService) {
|
|
20
|
-
this.router = router;
|
|
21
|
-
this.aclService = aclService;
|
|
22
|
-
this.httpClient = httpClient;
|
|
23
|
-
this.toastr = toastr;
|
|
24
|
-
this.consumingProjectSSOLoginService = consumingProjectSSOLoginService;
|
|
25
|
-
this.consumingProjectAuthService = consumingProjectAuthService;
|
|
26
|
-
this.noOfAttempts = 0;
|
|
27
|
-
this.sessionLocked = false;
|
|
28
|
-
if (!consumingProjectAuthService) {
|
|
29
|
-
throw new Error('You must provide a authService');
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
ngOnInit() { }
|
|
33
|
-
async isUserLoggedIn() {
|
|
34
|
-
try {
|
|
35
|
-
// await getCurrentUser();
|
|
36
|
-
return new Promise(async (resolve, reject) => {
|
|
37
|
-
const session = await fetchAuthSession();
|
|
38
|
-
if (session?.tokens) {
|
|
39
|
-
this.consumingProjectAuthService.IdToken = session?.tokens.idToken.toString();
|
|
40
|
-
this.consumingProjectAuthService.getAllCognitoTokenAndGroups(session.tokens);
|
|
41
|
-
resolve(true);
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
this.toastr.error(LoginConstant.sessionExpiredError);
|
|
45
|
-
this.handleSignOut();
|
|
46
|
-
resolve(false);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
return new Promise((resolve) => {
|
|
52
|
-
clearInterval(this.accessTokenTimerId);
|
|
53
|
-
resolve(false);
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
sessionTimeout() {
|
|
58
|
-
localStorage.clear();
|
|
59
|
-
clearInterval(this.accessTokenTimerId);
|
|
60
|
-
let afterLogoutRedirectTo;
|
|
61
|
-
if (this.consumingProjectSSOLoginService.isSsoIntegrated &&
|
|
62
|
-
!this.consumingProjectSSOLoginService.loggedInViaSso) {
|
|
63
|
-
afterLogoutRedirectTo = LoginConstant.coPilotloginPageUrl;
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
afterLogoutRedirectTo = LoginConstant.loginPageUrl;
|
|
67
|
-
}
|
|
68
|
-
this.router.navigate([afterLogoutRedirectTo]);
|
|
69
|
-
}
|
|
70
|
-
computeTokenExpiration(idToken) {
|
|
71
|
-
let currentTime = Math.floor(Date.now() / 1000);
|
|
72
|
-
let tokenTime = idToken.payload.exp;
|
|
73
|
-
let expTime = (tokenTime - currentTime) * 1000;
|
|
74
|
-
return expTime;
|
|
75
|
-
}
|
|
76
|
-
async handleSignIn({ username, password }) {
|
|
77
|
-
try {
|
|
78
|
-
let session = await fetchAuthSession();
|
|
79
|
-
if (session?.tokens) {
|
|
80
|
-
await this.handleSignOut();
|
|
81
|
-
}
|
|
82
|
-
const { isSignedIn, nextStep } = await signIn({ username, password });
|
|
83
|
-
switch (nextStep?.signInStep) {
|
|
84
|
-
case 'DONE':
|
|
85
|
-
let session = await fetchAuthSession();
|
|
86
|
-
this.onLoginOrSetNewPassword(session);
|
|
87
|
-
await this.consumingProjectAuthService.onSuccessfulAuthenticatingUser(false);
|
|
88
|
-
this.consumingProjectAuthService.getAllCognitoTokenAndGroups(session.tokens);
|
|
89
|
-
this.refreshAccessToken();
|
|
90
|
-
break;
|
|
91
|
-
case 'CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED':
|
|
92
|
-
this.consumingProjectAuthService.isLoggingIn = false;
|
|
93
|
-
this.consumingProjectAuthService.userName = username;
|
|
94
|
-
this.router.navigate([LoginConstant.setNewPasswordUrl]);
|
|
95
|
-
this.setNewPasswordErrorMessage = null;
|
|
96
|
-
break;
|
|
97
|
-
case 'RESET_PASSWORD':
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
console.log(error);
|
|
103
|
-
this.consumingProjectAuthService.isLoggingIn = false;
|
|
104
|
-
if (error?.message == LoginConstant.tempPasswordExpiryError) {
|
|
105
|
-
this.loginErrorMessage = LoginConstant.tempPasswordOnExpiryErrorMsg;
|
|
106
|
-
this.consumingProjectAuthService.sendRegenerationEmail(username);
|
|
107
|
-
}
|
|
108
|
-
else if (error?.message === 'Password attempts exceeded') {
|
|
109
|
-
this.loginErrorMessage = LoginConstant.attemptLimitExceeded;
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
this.loginErrorMessage = this.consumingProjectSSOLoginService.isSsoIntegrated
|
|
113
|
-
? LoginConstant.userCodePasswordIncorrect
|
|
114
|
-
: LoginConstant.userNamePasswordIncorrect;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
onLoginOrSetNewPassword(session) {
|
|
119
|
-
let newExpTime = this.computeTokenExpiration(session.tokens.idToken);
|
|
120
|
-
this.consumingProjectAuthService.accessToken = session.tokens.accessToken.toString();
|
|
121
|
-
this.consumingProjectAuthService.IdToken = session.tokens.idToken.toString();
|
|
122
|
-
localStorage.setItem('accessTokenExpiration', newExpTime.toString());
|
|
123
|
-
this.refreshAccessToken();
|
|
124
|
-
this.loginErrorMessage = null;
|
|
125
|
-
}
|
|
126
|
-
setAccessAndIDTokens(token) {
|
|
127
|
-
this.consumingProjectAuthService.accessToken = token?.accessToken?.toString();
|
|
128
|
-
this.consumingProjectAuthService.IdToken = token?.idToken;
|
|
129
|
-
}
|
|
130
|
-
async getAllCognitoTokenAndGroups(token) {
|
|
131
|
-
this.setAccessAndIDTokens(token);
|
|
132
|
-
if ('cognito:groups' in token.accessToken.payload) {
|
|
133
|
-
let userGroupsInCognitoJWT = token.accessToken.payload['cognito:groups'];
|
|
134
|
-
this.aclService.userGroupsInCognitoJWT = userGroupsInCognitoJWT;
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
this.aclService.userGroupsInCognitoJWT = [];
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
refreshAccessToken() {
|
|
141
|
-
let accessTokenExpiration = localStorage.getItem('accessTokenExpiration');
|
|
142
|
-
let expTime = accessTokenExpiration ? parseInt(accessTokenExpiration) : 0;
|
|
143
|
-
this.accessTokenTimerId = setInterval(() => {
|
|
144
|
-
let counter = 1000;
|
|
145
|
-
let delayFunction = setTimeout(async () => {
|
|
146
|
-
try {
|
|
147
|
-
let session = await fetchAuthSession();
|
|
148
|
-
let token = session.tokens;
|
|
149
|
-
if (token) {
|
|
150
|
-
this.consumingProjectAuthService.getAllCognitoTokenAndGroups(token);
|
|
151
|
-
let newExpTime = this.computeTokenExpiration(this.consumingProjectAuthService.IdToken);
|
|
152
|
-
if (newExpTime <= 0) {
|
|
153
|
-
newExpTime = 1000;
|
|
154
|
-
counter = 0;
|
|
155
|
-
if (delayFunction) {
|
|
156
|
-
clearInterval(delayFunction);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
expTime = newExpTime;
|
|
160
|
-
localStorage.setItem('accessTokenExpiration', newExpTime.toString());
|
|
161
|
-
clearInterval(this.accessTokenTimerId);
|
|
162
|
-
this.refreshAccessToken();
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
this.toastr.error(LoginConstant.sessionExpiredError);
|
|
166
|
-
this.handleSignOut();
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
catch (error) {
|
|
170
|
-
this.toastr.error(LoginConstant.sessionExpiredError);
|
|
171
|
-
this.handleSignOut();
|
|
172
|
-
}
|
|
173
|
-
}, counter);
|
|
174
|
-
}, expTime);
|
|
175
|
-
}
|
|
176
|
-
async changePassword(newPassword) {
|
|
177
|
-
try {
|
|
178
|
-
let inputParam = {
|
|
179
|
-
challengeResponse: newPassword,
|
|
180
|
-
};
|
|
181
|
-
const data = await confirmSignIn(inputParam);
|
|
182
|
-
const { username } = await getCurrentUser();
|
|
183
|
-
console.log(data);
|
|
184
|
-
let session = await fetchAuthSession();
|
|
185
|
-
this.onLoginOrSetNewPassword(session);
|
|
186
|
-
this.consumingProjectAuthService.onPasswordUpdate(username);
|
|
187
|
-
this.router.navigate([LoginConstant.loginPageUrl]);
|
|
188
|
-
this.consumingProjectAuthService.newPasswordSetThenUpdateToBackend(username);
|
|
189
|
-
}
|
|
190
|
-
catch (err) {
|
|
191
|
-
console.log(err);
|
|
192
|
-
this.setNewPasswordErrorMessage = LoginConstant.sessionExpired;
|
|
193
|
-
this.setNewPasswordButtonMessage = LoginConstant.loginAgain;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
async onForgotPasswordGenerateOTP(email) {
|
|
197
|
-
let username = email;
|
|
198
|
-
this.consumingProjectAuthService.userName = email;
|
|
199
|
-
try {
|
|
200
|
-
let result = await resetPassword({ username });
|
|
201
|
-
this.verifyAndSetNewPasswordMessage =
|
|
202
|
-
LoginConstant.verifyAndSetNewPasswordMessage +
|
|
203
|
-
result?.nextStep?.codeDeliveryDetails?.destination +
|
|
204
|
-
LoginConstant.pleaseEnterItBelow;
|
|
205
|
-
this.router.navigate([LoginConstant.verifyAndSetNewPasswordUrl]);
|
|
206
|
-
}
|
|
207
|
-
catch (err) { }
|
|
208
|
-
}
|
|
209
|
-
async verifyCode(confirmationCode, newPassword) {
|
|
210
|
-
try {
|
|
211
|
-
confirmResetPassword({
|
|
212
|
-
username: this.consumingProjectAuthService.userName,
|
|
213
|
-
newPassword: newPassword,
|
|
214
|
-
confirmationCode: confirmationCode,
|
|
215
|
-
}).then((response) => {
|
|
216
|
-
this.expiryAllExistingCurrentSession(this.consumingProjectAuthService.userName, newPassword);
|
|
217
|
-
}, (err) => {
|
|
218
|
-
this.noOfAttempts = this.noOfAttempts + 1;
|
|
219
|
-
this.verifyAndSetNewPasswordErrorMessage = this.forgotPasswordError(err, this.noOfAttempts);
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
catch (err) {
|
|
223
|
-
this.noOfAttempts = this.noOfAttempts + 1;
|
|
224
|
-
this.verifyAndSetNewPasswordErrorMessage = this.forgotPasswordError(err, this.noOfAttempts);
|
|
225
|
-
}
|
|
226
|
-
finally {
|
|
227
|
-
this.forgotPasswordAndGlobalSignoutLoader = false;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
forgotPasswordError(err, noOfAttempts) {
|
|
231
|
-
let errorMessage = '';
|
|
232
|
-
console.log(err);
|
|
233
|
-
let errorThrown = JSON.stringify(err);
|
|
234
|
-
if (errorThrown.includes('LimitExceededException')) {
|
|
235
|
-
this.sessionLocked = true;
|
|
236
|
-
errorMessage = LoginConstant.attemptLimitExceeded;
|
|
237
|
-
}
|
|
238
|
-
else if (errorThrown.includes('ExpiredCodeException')) {
|
|
239
|
-
errorMessage = LoginConstant.sessionExpired;
|
|
240
|
-
this.verifyAndSetNewPasswordButton = LoginConstant.regenerateOtp;
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
errorMessage = LoginConstant.attempt + ' ' + noOfAttempts + LoginConstant.attemptMessage;
|
|
244
|
-
}
|
|
245
|
-
return errorMessage;
|
|
246
|
-
}
|
|
247
|
-
async signInWithSSO() {
|
|
248
|
-
let session = await fetchAuthSession();
|
|
249
|
-
if (session?.tokens) {
|
|
250
|
-
await this.handleSignOut().then((response) => {
|
|
251
|
-
this.consumingProjectAuthService.signInWithSSO();
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
this.consumingProjectAuthService.signInWithSSO();
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
async handleSignOut() {
|
|
259
|
-
try {
|
|
260
|
-
await signOut({ global: false });
|
|
261
|
-
this.sessionTimeout();
|
|
262
|
-
}
|
|
263
|
-
catch (error) {
|
|
264
|
-
console.log('error signing out: ', error);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
expiryAllExistingCurrentSession(username, newPassword) {
|
|
268
|
-
this.loginErrorMessage = null;
|
|
269
|
-
this.onLoginInCogntioToGetAccessToken(username, newPassword);
|
|
270
|
-
}
|
|
271
|
-
async onLoginInCogntioToGetAccessToken(username, password) {
|
|
272
|
-
try {
|
|
273
|
-
const { nextStep } = await signIn({ username, password });
|
|
274
|
-
switch (nextStep?.signInStep) {
|
|
275
|
-
case 'DONE':
|
|
276
|
-
this.setAccessAndIDTokens(await (await fetchAuthSession()).tokens);
|
|
277
|
-
this.consumingProjectAuthService.onPasswordUpdate(this.consumingProjectAuthService.userName);
|
|
278
|
-
this.onCallGlobalSignout();
|
|
279
|
-
break;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
catch (error) {
|
|
283
|
-
this.noOfAttempts = this.noOfAttempts + 1;
|
|
284
|
-
this.verifyAndSetNewPasswordErrorMessage = this.forgotPasswordError(error, this.noOfAttempts);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
async onCallGlobalSignout() {
|
|
288
|
-
try {
|
|
289
|
-
await signOut({ global: true });
|
|
290
|
-
this.forgotPasswordAndGlobalSignoutLoader = false;
|
|
291
|
-
this.router.navigate([LoginConstant.loginPageUrl]);
|
|
292
|
-
}
|
|
293
|
-
catch (error) {
|
|
294
|
-
console.log('error signing out: ', error);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
301
|
-
type: Injectable,
|
|
302
|
-
args: [{
|
|
303
|
-
providedIn: 'root',
|
|
304
|
-
}]
|
|
305
|
-
}], ctorParameters: function () { return [{ type: i1.Router }, { type: i2.AnnaLibAclService }, { type: i3.HttpClient }, { type: i4.ToastrService }, { type: undefined, decorators: [{
|
|
306
|
-
type: Inject,
|
|
307
|
-
args: [SSO_LOGIN_SERVICE_TOKEN]
|
|
308
|
-
}] }, { type: undefined, decorators: [{
|
|
309
|
-
type: Inject,
|
|
310
|
-
args: [AUTH_SERVICE_TOKEN]
|
|
311
|
-
}] }]; } });
|
|
312
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5uYS1jb2duaXRvLWxpYi9zcmMvbGliL3NlcnZpY2VzL2F1dGguc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw0QkFBNEI7QUFDNUIsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUV6QyxnQ0FBZ0M7QUFDaEMsT0FBTyxFQUdILG9CQUFvQixFQUNwQixhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGNBQWMsRUFDZCxhQUFhLEVBQ2IsTUFBTSxFQUNOLE9BQU8sR0FDVixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFM0MsaUNBQWlDO0FBQ2pDLE9BQU8sRUFBRSxrQkFBa0IsRUFBZ0IsTUFBTSw4QkFBOEIsQ0FBQztBQUNoRixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2xELE9BQU8sRUFBb0IsdUJBQXVCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQzs7Ozs7O0FBSzlGLE1BQU0sT0FBTyxrQkFBa0I7SUFZM0IsWUFDWSxNQUFjLEVBQ2YsVUFBNkIsRUFDN0IsVUFBc0IsRUFDckIsTUFBcUIsRUFDVywrQkFBaUQsRUFDdEQsMkJBQXlDO1FBTHBFLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZixlQUFVLEdBQVYsVUFBVSxDQUFtQjtRQUM3QixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3JCLFdBQU0sR0FBTixNQUFNLENBQWU7UUFDVyxvQ0FBK0IsR0FBL0IsK0JBQStC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LE1BQU07MkJBQUMsa0JBQWtCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQW5ndWxhciBpbXBvcnQgc3RhdGVtZW50c1xyXG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuXHJcbi8vIFRoaXJkIHBhcnR5IGltcG9ydCBzdGF0ZW1lbnRzXHJcbmltcG9ydCB7XHJcbiAgICBBdXRoVG9rZW5zLFxyXG4gICAgU2lnbkluSW5wdXQsXHJcbiAgICBjb25maXJtUmVzZXRQYXNzd29yZCxcclxuICAgIGNvbmZpcm1TaWduSW4sXHJcbiAgICBmZXRjaEF1dGhTZXNzaW9uLFxyXG4gICAgZ2V0Q3VycmVudFVzZXIsXHJcbiAgICByZXNldFBhc3N3b3JkLFxyXG4gICAgc2lnbkluLFxyXG4gICAgc2lnbk91dCxcclxufSBmcm9tICdhd3MtYW1wbGlmeS9hdXRoJztcclxuaW1wb3J0IHsgVG9hc3RyU2VydmljZSB9IGZyb20gJ25neC10b2FzdHInO1xyXG5cclxuLy8gVXNlciBkZWZpbmVkIGltcG9ydCBzdGF0ZW1lbnRzXHJcbmltcG9ydCB7IEFVVEhfU0VSVklDRV9UT0tFTiwgSUF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vY29uZmlnL2F1dGgtc2VydmljZS50b2tlbic7XHJcbmltcG9ydCB7IExvZ2luQ29uc3RhbnQgfSBmcm9tICcuLi9jb25zdGFudHMvbG9naW5Db25zdGFudCc7XHJcbmltcG9ydCB7IEFubmFMaWJBY2xTZXJ2aWNlIH0gZnJvbSAnLi9hY2wuc2VydmljZSc7XHJcbmltcG9ydCB7IElTU09Mb2dpblNlcnZpY2UsIFNTT19MT0dJTl9TRVJWSUNFX1RPS0VOIH0gZnJvbSAnLi4vY29uZmlnL3Nzby1sb2dpbi1zZXJ2aWNlLnRva2VuJztcclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICAgIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIEFubmFMaWJBdXRoU2VydmljZSB7XHJcbiAgICBsb2dpbkVycm9yTWVzc2FnZTogc3RyaW5nIHwgbnVsbDtcclxuICAgIHNldE5ld1Bhc3N3b3JkRXJyb3JNZXNzYWdlOiBzdHJpbmc7XHJcbiAgICBzZXROZXdQYXNzd29yZEJ1dHRvbk1lc3NhZ2U6IHN0cmluZztcclxuICAgIHZlcmlmeUFuZFNldE5ld1Bhc3N3b3JkRXJyb3JNZXNzYWdlOiBzdHJpbmc7XHJcbiAgICB2ZXJpZnlBbmRTZXROZXdQYXNzd29yZE1lc3NhZ2U6IHN0cmluZztcclxuICAgIHZlcmlmeUFuZFNldE5ld1Bhc3N3b3JkQnV0dG9uOiBzdHJpbmc7XHJcbiAgICBub09mQXR0ZW1wdHMgPSAwO1xyXG4gICAgc2Vzc2lvbkxvY2tlZCA9IGZhbHNlO1xyXG4gICAgYWNjZXNzVG9rZW5UaW1lcklkOiBhbnk7XHJcbiAgICBmb3Jnb3RQYXNzd29yZEFuZEdsb2JhbFNpZ25vdXRMb2FkZXI6IGJvb2xlYW47XHJcblxyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcclxuICAgICAgICBwdWJsaWMgYWNsU2VydmljZTogQW5uYUxpYkFjbFNlcnZpY2UsXHJcbiAgICAgICAgcHVibGljIGh0dHBDbGllbnQ6IEh0dHBDbGllbnQsXHJcbiAgICAgICAgcHJpdmF0ZSB0b2FzdHI6IFRvYXN0clNlcnZpY2UsXHJcbiAgICAgICAgQEluamVjdChTU09fTE9HSU5fU0VSVklDRV9UT0tFTikgcHVibGljIGNvbnN1bWluZ1Byb2plY3RTU09Mb2dpblNlcnZpY2U6IElTU09Mb2dpblNlcnZpY2UsXHJcbiAgICAgICAgQEluamVjdChBVVRIX1NFUlZJQ0VfVE9LRU4pIHB1YmxpYyBjb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2U6IElBdXRoU2VydmljZSxcclxuICAgICkge1xyXG4gICAgICAgIGlmICghY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IG11c3QgcHJvdmlkZSBhIGF1dGhTZXJ2aWNlJyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG5nT25Jbml0KCkge31cclxuXHJcbiAgICBhc3luYyBpc1VzZXJMb2dnZWRJbigpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAvLyBhd2FpdCBnZXRDdXJyZW50VXNlcigpO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbjogYW55ID0gYXdhaXQgZmV0Y2hBdXRoU2Vzc2lvbigpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlc3Npb24/LnRva2Vucykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLklkVG9rZW4gPSBzZXNzaW9uPy50b2tlbnMuaWRUb2tlbi50b1N0cmluZygpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLmdldEFsbENvZ25pdG9Ub2tlbkFuZEdyb3VwcyhzZXNzaW9uLnRva2Vucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IoTG9naW5Db25zdGFudC5zZXNzaW9uRXhwaXJlZEVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZVNpZ25PdXQoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHRoaXMuYWNjZXNzVG9rZW5UaW1lcklkKTtcclxuICAgICAgICAgICAgICAgIHJlc29sdmUoZmFsc2UpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc2Vzc2lvblRpbWVvdXQoKSB7XHJcbiAgICAgICAgbG9jYWxTdG9yYWdlLmNsZWFyKCk7XHJcbiAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmFjY2Vzc1Rva2VuVGltZXJJZCk7XHJcbiAgICAgICAgbGV0IGFmdGVyTG9nb3V0UmVkaXJlY3RUbzogc3RyaW5nO1xyXG4gICAgICAgIGlmIChcclxuICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0U1NPTG9naW5TZXJ2aWNlLmlzU3NvSW50ZWdyYXRlZCAmJlxyXG4gICAgICAgICAgICAhdGhpcy5jb25zdW1pbmdQcm9qZWN0U1NPTG9naW5TZXJ2aWNlLmxvZ2dlZEluVmlhU3NvXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIGFmdGVyTG9nb3V0UmVkaXJlY3RUbyA9IExvZ2luQ29uc3RhbnQuY29QaWxvdGxvZ2luUGFnZVVybDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBhZnRlckxvZ291dFJlZGlyZWN0VG8gPSBMb2dpbkNvbnN0YW50LmxvZ2luUGFnZVVybDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW2FmdGVyTG9nb3V0UmVkaXJlY3RUb10pO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbXB1dGVUb2tlbkV4cGlyYXRpb24oaWRUb2tlbjogYW55KSB7XHJcbiAgICAgICAgbGV0IGN1cnJlbnRUaW1lID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCk7XHJcbiAgICAgICAgbGV0IHRva2VuVGltZSA9IGlkVG9rZW4ucGF5bG9hZC5leHA7XHJcbiAgICAgICAgbGV0IGV4cFRpbWUgPSAodG9rZW5UaW1lIC0gY3VycmVudFRpbWUpICogMTAwMDtcclxuICAgICAgICByZXR1cm4gZXhwVGltZTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBoYW5kbGVTaWduSW4oeyB1c2VybmFtZSwgcGFzc3dvcmQgfTogU2lnbkluSW5wdXQpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBsZXQgc2Vzc2lvbiA9IGF3YWl0IGZldGNoQXV0aFNlc3Npb24oKTtcclxuICAgICAgICAgICAgaWYgKHNlc3Npb24/LnRva2Vucykge1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVTaWduT3V0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgeyBpc1NpZ25lZEluLCBuZXh0U3RlcCB9ID0gYXdhaXQgc2lnbkluKHsgdXNlcm5hbWUsIHBhc3N3b3JkIH0pO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG5leHRTdGVwPy5zaWduSW5TdGVwKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdET05FJzpcclxuICAgICAgICAgICAgICAgICAgICBsZXQgc2Vzc2lvbiA9IGF3YWl0IGZldGNoQXV0aFNlc3Npb24oKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uTG9naW5PclNldE5ld1Bhc3N3b3JkKHNlc3Npb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLm9uU3VjY2Vzc2Z1bEF1dGhlbnRpY2F0aW5nVXNlcihmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UuZ2V0QWxsQ29nbml0b1Rva2VuQW5kR3JvdXBzKHNlc3Npb24udG9rZW5zKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZnJlc2hBY2Nlc3NUb2tlbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgICAgIGNhc2UgJ0NPTkZJUk1fU0lHTl9JTl9XSVRIX05FV19QQVNTV09SRF9SRVFVSVJFRCc6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UuaXNMb2dnaW5nSW4gPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnN1bWluZ1Byb2plY3RBdXRoU2VydmljZS51c2VyTmFtZSA9IHVzZXJuYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFtMb2dpbkNvbnN0YW50LnNldE5ld1Bhc3N3b3JkVXJsXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXROZXdQYXNzd29yZEVycm9yTWVzc2FnZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAgICAgY2FzZSAnUkVTRVRfUEFTU1dPUkQnOlxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XHJcbiAgICAgICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLmlzTG9nZ2luZ0luID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGlmIChlcnJvcj8ubWVzc2FnZSA9PSBMb2dpbkNvbnN0YW50LnRlbXBQYXNzd29yZEV4cGlyeUVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2luRXJyb3JNZXNzYWdlID0gTG9naW5Db25zdGFudC50ZW1wUGFzc3dvcmRPbkV4cGlyeUVycm9yTXNnO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2Uuc2VuZFJlZ2VuZXJhdGlvbkVtYWlsKHVzZXJuYW1lKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChlcnJvcj8ubWVzc2FnZSA9PT0gJ1Bhc3N3b3JkIGF0dGVtcHRzIGV4Y2VlZGVkJykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2dpbkVycm9yTWVzc2FnZSA9IExvZ2luQ29uc3RhbnQuYXR0ZW1wdExpbWl0RXhjZWVkZWQ7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2luRXJyb3JNZXNzYWdlID0gdGhpcy5jb25zdW1pbmdQcm9qZWN0U1NPTG9naW5TZXJ2aWNlLmlzU3NvSW50ZWdyYXRlZFxyXG4gICAgICAgICAgICAgICAgICAgID8gTG9naW5Db25zdGFudC51c2VyQ29kZVBhc3N3b3JkSW5jb3JyZWN0XHJcbiAgICAgICAgICAgICAgICAgICAgOiBMb2dpbkNvbnN0YW50LnVzZXJOYW1lUGFzc3dvcmRJbmNvcnJlY3Q7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgb25Mb2dpbk9yU2V0TmV3UGFzc3dvcmQoc2Vzc2lvbjogYW55KSB7XHJcbiAgICAgICAgbGV0IG5ld0V4cFRpbWUgPSB0aGlzLmNvbXB1dGVUb2tlbkV4cGlyYXRpb24oc2Vzc2lvbi50b2tlbnMuaWRUb2tlbik7XHJcbiAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UuYWNjZXNzVG9rZW4gPSBzZXNzaW9uLnRva2Vucy5hY2Nlc3NUb2tlbi50b1N0cmluZygpO1xyXG4gICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLklkVG9rZW4gPSBzZXNzaW9uLnRva2Vucy5pZFRva2VuLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2FjY2Vzc1Rva2VuRXhwaXJhdGlvbicsIG5ld0V4cFRpbWUudG9TdHJpbmcoKSk7XHJcbiAgICAgICAgdGhpcy5yZWZyZXNoQWNjZXNzVG9rZW4oKTtcclxuICAgICAgICB0aGlzLmxvZ2luRXJyb3JNZXNzYWdlID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBzZXRBY2Nlc3NBbmRJRFRva2Vucyh0b2tlbjogQXV0aFRva2Vucykge1xyXG4gICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLmFjY2Vzc1Rva2VuID0gdG9rZW4/LmFjY2Vzc1Rva2VuPy50b1N0cmluZygpO1xyXG4gICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLklkVG9rZW4gPSB0b2tlbj8uaWRUb2tlbjtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBnZXRBbGxDb2duaXRvVG9rZW5BbmRHcm91cHModG9rZW46IEF1dGhUb2tlbnMpIHtcclxuICAgICAgICB0aGlzLnNldEFjY2Vzc0FuZElEVG9rZW5zKHRva2VuKTtcclxuICAgICAgICBpZiAoJ2NvZ25pdG86Z3JvdXBzJyBpbiB0b2tlbi5hY2Nlc3NUb2tlbi5wYXlsb2FkKSB7XHJcbiAgICAgICAgICAgIGxldCB1c2VyR3JvdXBzSW5Db2duaXRvSldUOiBhbnkgPSB0b2tlbi5hY2Nlc3NUb2tlbi5wYXlsb2FkWydjb2duaXRvOmdyb3VwcyddO1xyXG4gICAgICAgICAgICB0aGlzLmFjbFNlcnZpY2UudXNlckdyb3Vwc0luQ29nbml0b0pXVCA9IHVzZXJHcm91cHNJbkNvZ25pdG9KV1Q7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5hY2xTZXJ2aWNlLnVzZXJHcm91cHNJbkNvZ25pdG9KV1QgPSBbXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmVmcmVzaEFjY2Vzc1Rva2VuKCkge1xyXG4gICAgICAgIGxldCBhY2Nlc3NUb2tlbkV4cGlyYXRpb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYWNjZXNzVG9rZW5FeHBpcmF0aW9uJyk7XHJcbiAgICAgICAgbGV0IGV4cFRpbWUgPSBhY2Nlc3NUb2tlbkV4cGlyYXRpb24gPyBwYXJzZUludChhY2Nlc3NUb2tlbkV4cGlyYXRpb24pIDogMDtcclxuICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuVGltZXJJZCA9IHNldEludGVydmFsKCgpID0+IHtcclxuICAgICAgICAgICAgbGV0IGNvdW50ZXIgPSAxMDAwO1xyXG4gICAgICAgICAgICBsZXQgZGVsYXlGdW5jdGlvbiA9IHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgc2Vzc2lvbiA9IGF3YWl0IGZldGNoQXV0aFNlc3Npb24oKTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgdG9rZW4gPSBzZXNzaW9uLnRva2VucztcclxuICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UuZ2V0QWxsQ29nbml0b1Rva2VuQW5kR3JvdXBzKHRva2VuKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG5ld0V4cFRpbWUgPSB0aGlzLmNvbXB1dGVUb2tlbkV4cGlyYXRpb24odGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UuSWRUb2tlbik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3RXhwVGltZSA8PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdFeHBUaW1lID0gMTAwMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGF5RnVuY3Rpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKGRlbGF5RnVuY3Rpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cFRpbWUgPSBuZXdFeHBUaW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnYWNjZXNzVG9rZW5FeHBpcmF0aW9uJywgbmV3RXhwVGltZS50b1N0cmluZygpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmFjY2Vzc1Rva2VuVGltZXJJZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVmcmVzaEFjY2Vzc1Rva2VuKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IoTG9naW5Db25zdGFudC5zZXNzaW9uRXhwaXJlZEVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVTaWduT3V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvYXN0ci5lcnJvcihMb2dpbkNvbnN0YW50LnNlc3Npb25FeHBpcmVkRXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlU2lnbk91dCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBjb3VudGVyKTtcclxuICAgICAgICB9LCBleHBUaW1lKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBjaGFuZ2VQYXNzd29yZChuZXdQYXNzd29yZDogc3RyaW5nKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgbGV0IGlucHV0UGFyYW0gPSB7XHJcbiAgICAgICAgICAgICAgICBjaGFsbGVuZ2VSZXNwb25zZTogbmV3UGFzc3dvcmQsXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBjb25maXJtU2lnbkluKGlucHV0UGFyYW0pO1xyXG4gICAgICAgICAgICBjb25zdCB7IHVzZXJuYW1lIH0gPSBhd2FpdCBnZXRDdXJyZW50VXNlcigpO1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhkYXRhKTtcclxuICAgICAgICAgICAgbGV0IHNlc3Npb24gPSBhd2FpdCBmZXRjaEF1dGhTZXNzaW9uKCk7XHJcbiAgICAgICAgICAgIHRoaXMub25Mb2dpbk9yU2V0TmV3UGFzc3dvcmQoc2Vzc2lvbik7XHJcbiAgICAgICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLm9uUGFzc3dvcmRVcGRhdGUodXNlcm5hbWUpO1xyXG4gICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbTG9naW5Db25zdGFudC5sb2dpblBhZ2VVcmxdKTtcclxuICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UubmV3UGFzc3dvcmRTZXRUaGVuVXBkYXRlVG9CYWNrZW5kKHVzZXJuYW1lKTtcclxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcclxuICAgICAgICAgICAgdGhpcy5zZXROZXdQYXNzd29yZEVycm9yTWVzc2FnZSA9IExvZ2luQ29uc3RhbnQuc2Vzc2lvbkV4cGlyZWQ7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0TmV3UGFzc3dvcmRCdXR0b25NZXNzYWdlID0gTG9naW5Db25zdGFudC5sb2dpbkFnYWluO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBvbkZvcmdvdFBhc3N3b3JkR2VuZXJhdGVPVFAoZW1haWw6IHN0cmluZykge1xyXG4gICAgICAgIGxldCB1c2VybmFtZSA9IGVtYWlsO1xyXG4gICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLnVzZXJOYW1lID0gZW1haWw7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgbGV0IHJlc3VsdDogYW55ID0gYXdhaXQgcmVzZXRQYXNzd29yZCh7IHVzZXJuYW1lIH0pO1xyXG4gICAgICAgICAgICB0aGlzLnZlcmlmeUFuZFNldE5ld1Bhc3N3b3JkTWVzc2FnZSA9XHJcbiAgICAgICAgICAgICAgICBMb2dpbkNvbnN0YW50LnZlcmlmeUFuZFNldE5ld1Bhc3N3b3JkTWVzc2FnZSArXHJcbiAgICAgICAgICAgICAgICByZXN1bHQ/Lm5leHRTdGVwPy5jb2RlRGVsaXZlcnlEZXRhaWxzPy5kZXN0aW5hdGlvbiArXHJcbiAgICAgICAgICAgICAgICBMb2dpbkNvbnN0YW50LnBsZWFzZUVudGVySXRCZWxvdztcclxuICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW0xvZ2luQ29uc3RhbnQudmVyaWZ5QW5kU2V0TmV3UGFzc3dvcmRVcmxdKTtcclxuICAgICAgICB9IGNhdGNoIChlcnIpIHt9XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgdmVyaWZ5Q29kZShjb25maXJtYXRpb25Db2RlOiBzdHJpbmcsIG5ld1Bhc3N3b3JkOiBzdHJpbmcpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25maXJtUmVzZXRQYXNzd29yZCh7XHJcbiAgICAgICAgICAgICAgICB1c2VybmFtZTogdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UudXNlck5hbWUsXHJcbiAgICAgICAgICAgICAgICBuZXdQYXNzd29yZDogbmV3UGFzc3dvcmQsXHJcbiAgICAgICAgICAgICAgICBjb25maXJtYXRpb25Db2RlOiBjb25maXJtYXRpb25Db2RlLFxyXG4gICAgICAgICAgICB9KS50aGVuKFxyXG4gICAgICAgICAgICAgICAgKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leHBpcnlBbGxFeGlzdGluZ0N1cnJlbnRTZXNzaW9uKHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLnVzZXJOYW1lLCBuZXdQYXNzd29yZCk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgKGVycikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubm9PZkF0dGVtcHRzID0gdGhpcy5ub09mQXR0ZW1wdHMgKyAxO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmVyaWZ5QW5kU2V0TmV3UGFzc3dvcmRFcnJvck1lc3NhZ2UgPSB0aGlzLmZvcmdvdFBhc3N3b3JkRXJyb3IoZXJyLCB0aGlzLm5vT2ZBdHRlbXB0cyk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICB0aGlzLm5vT2ZBdHRlbXB0cyA9IHRoaXMubm9PZkF0dGVtcHRzICsgMTtcclxuICAgICAgICAgICAgdGhpcy52ZXJpZnlBbmRTZXROZXdQYXNzd29yZEVycm9yTWVzc2FnZSA9IHRoaXMuZm9yZ290UGFzc3dvcmRFcnJvcihlcnIsIHRoaXMubm9PZkF0dGVtcHRzKTtcclxuICAgICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgICAgICB0aGlzLmZvcmdvdFBhc3N3b3JkQW5kR2xvYmFsU2lnbm91dExvYWRlciA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmb3Jnb3RQYXNzd29yZEVycm9yKGVycjogYW55LCBub09mQXR0ZW1wdHM6IG51bWJlcikge1xyXG4gICAgICAgIGxldCBlcnJvck1lc3NhZ2UgPSAnJztcclxuICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xyXG4gICAgICAgIGxldCBlcnJvclRocm93biA9IEpTT04uc3RyaW5naWZ5KGVycik7XHJcbiAgICAgICAgaWYgKGVycm9yVGhyb3duLmluY2x1ZGVzKCdMaW1pdEV4Y2VlZGVkRXhjZXB0aW9uJykpIHtcclxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uTG9ja2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gTG9naW5Db25zdGFudC5hdHRlbXB0TGltaXRFeGNlZWRlZDtcclxuICAgICAgICB9IGVsc2UgaWYgKGVycm9yVGhyb3duLmluY2x1ZGVzKCdFeHBpcmVkQ29kZUV4Y2VwdGlvbicpKSB7XHJcbiAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IExvZ2luQ29uc3RhbnQuc2Vzc2lvbkV4cGlyZWQ7XHJcbiAgICAgICAgICAgIHRoaXMudmVyaWZ5QW5kU2V0TmV3UGFzc3dvcmRCdXR0b24gPSBMb2dpbkNvbnN0YW50LnJlZ2VuZXJhdGVPdHA7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gTG9naW5Db25zdGFudC5hdHRlbXB0ICsgJyAnICsgbm9PZkF0dGVtcHRzICsgTG9naW5Db25zdGFudC5hdHRlbXB0TWVzc2FnZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGVycm9yTWVzc2FnZTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBzaWduSW5XaXRoU1NPKCkge1xyXG4gICAgICAgIGxldCBzZXNzaW9uID0gYXdhaXQgZmV0Y2hBdXRoU2Vzc2lvbigpO1xyXG4gICAgICAgIGlmIChzZXNzaW9uPy50b2tlbnMpIHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVTaWduT3V0KCkudGhlbigocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLnNpZ25JbldpdGhTU08oKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2Uuc2lnbkluV2l0aFNTTygpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBoYW5kbGVTaWduT3V0KCkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHNpZ25PdXQoeyBnbG9iYWw6IGZhbHNlIH0pO1xyXG4gICAgICAgICAgICB0aGlzLnNlc3Npb25UaW1lb3V0KCk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ2Vycm9yIHNpZ25pbmcgb3V0OiAnLCBlcnJvcik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGV4cGlyeUFsbEV4aXN0aW5nQ3VycmVudFNlc3Npb24odXNlcm5hbWU6IHN0cmluZywgbmV3UGFzc3dvcmQ6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMubG9naW5FcnJvck1lc3NhZ2UgPSBudWxsO1xyXG4gICAgICAgIHRoaXMub25Mb2dpbkluQ29nbnRpb1RvR2V0QWNjZXNzVG9rZW4odXNlcm5hbWUsIG5ld1Bhc3N3b3JkKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBvbkxvZ2luSW5Db2dudGlvVG9HZXRBY2Nlc3NUb2tlbih1c2VybmFtZTogc3RyaW5nLCBwYXNzd29yZDogc3RyaW5nKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgY29uc3QgeyBuZXh0U3RlcCB9ID0gYXdhaXQgc2lnbkluKHsgdXNlcm5hbWUsIHBhc3N3b3JkIH0pO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG5leHRTdGVwPy5zaWduSW5TdGVwKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdET05FJzpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFjY2Vzc0FuZElEVG9rZW5zKGF3YWl0IChhd2FpdCBmZXRjaEF1dGhTZXNzaW9uKCkpLnRva2Vucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2Uub25QYXNzd29yZFVwZGF0ZSh0aGlzLmNvbnN1bWluZ1Byb2plY3RBdXRoU2VydmljZS51c2VyTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkNhbGxHbG9iYWxTaWdub3V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XHJcbiAgICAgICAgICAgIHRoaXMubm9PZkF0dGVtcHRzID0gdGhpcy5ub09mQXR0ZW1wdHMgKyAxO1xyXG4gICAgICAgICAgICB0aGlzLnZlcmlmeUFuZFNldE5ld1Bhc3N3b3JkRXJyb3JNZXNzYWdlID0gdGhpcy5mb3Jnb3RQYXNzd29yZEVycm9yKGVycm9yLCB0aGlzLm5vT2ZBdHRlbXB0cyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIG9uQ2FsbEdsb2JhbFNpZ25vdXQoKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgc2lnbk91dCh7IGdsb2JhbDogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgdGhpcy5mb3Jnb3RQYXNzd29yZEFuZEdsb2JhbFNpZ25vdXRMb2FkZXIgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW0xvZ2luQ29uc3RhbnQubG9naW5QYWdlVXJsXSk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ2Vycm9yIHNpZ25pbmcgb3V0OiAnLCBlcnJvcik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiJdfQ==
|
|
1
|
+
// Angular import statements
|
|
2
|
+
import { HttpClient } from '@angular/common/http';
|
|
3
|
+
import { Inject, Injectable } from '@angular/core';
|
|
4
|
+
import { Router } from '@angular/router';
|
|
5
|
+
// Third party import statements
|
|
6
|
+
import { confirmResetPassword, confirmSignIn, fetchAuthSession, getCurrentUser, resetPassword, signIn, signOut, } from 'aws-amplify/auth';
|
|
7
|
+
import { ToastrService } from 'ngx-toastr';
|
|
8
|
+
// User defined import statements
|
|
9
|
+
import { AUTH_SERVICE_TOKEN } from '../config/auth-service.token';
|
|
10
|
+
import { LoginConstant } from '../constants/loginConstant';
|
|
11
|
+
import { AnnaLibAclService } from './acl.service';
|
|
12
|
+
import { SSO_LOGIN_SERVICE_TOKEN } from '../config/sso-login-service.token';
|
|
13
|
+
import * as i0 from "@angular/core";
|
|
14
|
+
import * as i1 from "@angular/router";
|
|
15
|
+
import * as i2 from "./acl.service";
|
|
16
|
+
import * as i3 from "@angular/common/http";
|
|
17
|
+
import * as i4 from "ngx-toastr";
|
|
18
|
+
export class AnnaLibAuthService {
|
|
19
|
+
constructor(router, aclService, httpClient, toastr, consumingProjectSSOLoginService, consumingProjectAuthService) {
|
|
20
|
+
this.router = router;
|
|
21
|
+
this.aclService = aclService;
|
|
22
|
+
this.httpClient = httpClient;
|
|
23
|
+
this.toastr = toastr;
|
|
24
|
+
this.consumingProjectSSOLoginService = consumingProjectSSOLoginService;
|
|
25
|
+
this.consumingProjectAuthService = consumingProjectAuthService;
|
|
26
|
+
this.noOfAttempts = 0;
|
|
27
|
+
this.sessionLocked = false;
|
|
28
|
+
if (!consumingProjectAuthService) {
|
|
29
|
+
throw new Error('You must provide a authService');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
ngOnInit() { }
|
|
33
|
+
async isUserLoggedIn() {
|
|
34
|
+
try {
|
|
35
|
+
// await getCurrentUser();
|
|
36
|
+
return new Promise(async (resolve, reject) => {
|
|
37
|
+
const session = await fetchAuthSession();
|
|
38
|
+
if (session?.tokens) {
|
|
39
|
+
this.consumingProjectAuthService.IdToken = session?.tokens.idToken.toString();
|
|
40
|
+
this.consumingProjectAuthService.getAllCognitoTokenAndGroups(session.tokens);
|
|
41
|
+
resolve(true);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.toastr.error(LoginConstant.sessionExpiredError);
|
|
45
|
+
this.handleSignOut();
|
|
46
|
+
resolve(false);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
return new Promise((resolve) => {
|
|
52
|
+
clearInterval(this.accessTokenTimerId);
|
|
53
|
+
resolve(false);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
sessionTimeout() {
|
|
58
|
+
localStorage.clear();
|
|
59
|
+
clearInterval(this.accessTokenTimerId);
|
|
60
|
+
let afterLogoutRedirectTo;
|
|
61
|
+
if (this.consumingProjectSSOLoginService.isSsoIntegrated &&
|
|
62
|
+
!this.consumingProjectSSOLoginService.loggedInViaSso) {
|
|
63
|
+
afterLogoutRedirectTo = LoginConstant.coPilotloginPageUrl;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
afterLogoutRedirectTo = LoginConstant.loginPageUrl;
|
|
67
|
+
}
|
|
68
|
+
this.router.navigate([afterLogoutRedirectTo]);
|
|
69
|
+
}
|
|
70
|
+
computeTokenExpiration(idToken) {
|
|
71
|
+
let currentTime = Math.floor(Date.now() / 1000);
|
|
72
|
+
let tokenTime = idToken.payload.exp;
|
|
73
|
+
let expTime = (tokenTime - currentTime) * 1000;
|
|
74
|
+
return expTime;
|
|
75
|
+
}
|
|
76
|
+
async handleSignIn({ username, password }) {
|
|
77
|
+
try {
|
|
78
|
+
let session = await fetchAuthSession();
|
|
79
|
+
if (session?.tokens) {
|
|
80
|
+
await this.handleSignOut();
|
|
81
|
+
}
|
|
82
|
+
const { isSignedIn, nextStep } = await signIn({ username, password });
|
|
83
|
+
switch (nextStep?.signInStep) {
|
|
84
|
+
case 'DONE':
|
|
85
|
+
let session = await fetchAuthSession();
|
|
86
|
+
this.onLoginOrSetNewPassword(session);
|
|
87
|
+
await this.consumingProjectAuthService.onSuccessfulAuthenticatingUser(false);
|
|
88
|
+
this.consumingProjectAuthService.getAllCognitoTokenAndGroups(session.tokens);
|
|
89
|
+
this.refreshAccessToken();
|
|
90
|
+
break;
|
|
91
|
+
case 'CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED':
|
|
92
|
+
this.consumingProjectAuthService.isLoggingIn = false;
|
|
93
|
+
this.consumingProjectAuthService.userName = username;
|
|
94
|
+
this.router.navigate([LoginConstant.setNewPasswordUrl]);
|
|
95
|
+
this.setNewPasswordErrorMessage = null;
|
|
96
|
+
break;
|
|
97
|
+
case 'RESET_PASSWORD':
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.log(error);
|
|
103
|
+
this.consumingProjectAuthService.isLoggingIn = false;
|
|
104
|
+
if (error?.message == LoginConstant.tempPasswordExpiryError) {
|
|
105
|
+
this.loginErrorMessage = LoginConstant.tempPasswordOnExpiryErrorMsg;
|
|
106
|
+
this.consumingProjectAuthService.sendRegenerationEmail(username);
|
|
107
|
+
}
|
|
108
|
+
else if (error?.message === 'Password attempts exceeded') {
|
|
109
|
+
this.loginErrorMessage = LoginConstant.attemptLimitExceeded;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
this.loginErrorMessage = this.consumingProjectSSOLoginService.isSsoIntegrated
|
|
113
|
+
? LoginConstant.userCodePasswordIncorrect
|
|
114
|
+
: LoginConstant.userNamePasswordIncorrect;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
onLoginOrSetNewPassword(session) {
|
|
119
|
+
let newExpTime = this.computeTokenExpiration(session.tokens.idToken);
|
|
120
|
+
this.consumingProjectAuthService.accessToken = session.tokens.accessToken.toString();
|
|
121
|
+
this.consumingProjectAuthService.IdToken = session.tokens.idToken.toString();
|
|
122
|
+
localStorage.setItem('accessTokenExpiration', newExpTime.toString());
|
|
123
|
+
this.refreshAccessToken();
|
|
124
|
+
this.loginErrorMessage = null;
|
|
125
|
+
}
|
|
126
|
+
setAccessAndIDTokens(token) {
|
|
127
|
+
this.consumingProjectAuthService.accessToken = token?.accessToken?.toString();
|
|
128
|
+
this.consumingProjectAuthService.IdToken = token?.idToken;
|
|
129
|
+
}
|
|
130
|
+
async getAllCognitoTokenAndGroups(token) {
|
|
131
|
+
this.setAccessAndIDTokens(token);
|
|
132
|
+
if ('cognito:groups' in token.accessToken.payload) {
|
|
133
|
+
let userGroupsInCognitoJWT = token.accessToken.payload['cognito:groups'];
|
|
134
|
+
this.aclService.userGroupsInCognitoJWT = userGroupsInCognitoJWT;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
this.aclService.userGroupsInCognitoJWT = [];
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
refreshAccessToken() {
|
|
141
|
+
let accessTokenExpiration = localStorage.getItem('accessTokenExpiration');
|
|
142
|
+
let expTime = accessTokenExpiration ? parseInt(accessTokenExpiration) : 0;
|
|
143
|
+
this.accessTokenTimerId = setInterval(() => {
|
|
144
|
+
let counter = 1000;
|
|
145
|
+
let delayFunction = setTimeout(async () => {
|
|
146
|
+
try {
|
|
147
|
+
let session = await fetchAuthSession();
|
|
148
|
+
let token = session.tokens;
|
|
149
|
+
if (token) {
|
|
150
|
+
this.consumingProjectAuthService.getAllCognitoTokenAndGroups(token);
|
|
151
|
+
let newExpTime = this.computeTokenExpiration(this.consumingProjectAuthService.IdToken);
|
|
152
|
+
if (newExpTime <= 0) {
|
|
153
|
+
newExpTime = 1000;
|
|
154
|
+
counter = 0;
|
|
155
|
+
if (delayFunction) {
|
|
156
|
+
clearInterval(delayFunction);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
expTime = newExpTime;
|
|
160
|
+
localStorage.setItem('accessTokenExpiration', newExpTime.toString());
|
|
161
|
+
clearInterval(this.accessTokenTimerId);
|
|
162
|
+
this.refreshAccessToken();
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
this.toastr.error(LoginConstant.sessionExpiredError);
|
|
166
|
+
this.handleSignOut();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
this.toastr.error(LoginConstant.sessionExpiredError);
|
|
171
|
+
this.handleSignOut();
|
|
172
|
+
}
|
|
173
|
+
}, counter);
|
|
174
|
+
}, expTime);
|
|
175
|
+
}
|
|
176
|
+
async changePassword(newPassword) {
|
|
177
|
+
try {
|
|
178
|
+
let inputParam = {
|
|
179
|
+
challengeResponse: newPassword,
|
|
180
|
+
};
|
|
181
|
+
const data = await confirmSignIn(inputParam);
|
|
182
|
+
const { username } = await getCurrentUser();
|
|
183
|
+
console.log(data);
|
|
184
|
+
let session = await fetchAuthSession();
|
|
185
|
+
this.onLoginOrSetNewPassword(session);
|
|
186
|
+
this.consumingProjectAuthService.onPasswordUpdate(username);
|
|
187
|
+
this.router.navigate([LoginConstant.loginPageUrl]);
|
|
188
|
+
this.consumingProjectAuthService.newPasswordSetThenUpdateToBackend(username);
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
console.log(err);
|
|
192
|
+
this.setNewPasswordErrorMessage = LoginConstant.sessionExpired;
|
|
193
|
+
this.setNewPasswordButtonMessage = LoginConstant.loginAgain;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async onForgotPasswordGenerateOTP(email) {
|
|
197
|
+
let username = email;
|
|
198
|
+
this.consumingProjectAuthService.userName = email;
|
|
199
|
+
try {
|
|
200
|
+
let result = await resetPassword({ username });
|
|
201
|
+
this.verifyAndSetNewPasswordMessage =
|
|
202
|
+
LoginConstant.verifyAndSetNewPasswordMessage +
|
|
203
|
+
result?.nextStep?.codeDeliveryDetails?.destination +
|
|
204
|
+
LoginConstant.pleaseEnterItBelow;
|
|
205
|
+
this.router.navigate([LoginConstant.verifyAndSetNewPasswordUrl]);
|
|
206
|
+
}
|
|
207
|
+
catch (err) { }
|
|
208
|
+
}
|
|
209
|
+
async verifyCode(confirmationCode, newPassword) {
|
|
210
|
+
try {
|
|
211
|
+
confirmResetPassword({
|
|
212
|
+
username: this.consumingProjectAuthService.userName,
|
|
213
|
+
newPassword: newPassword,
|
|
214
|
+
confirmationCode: confirmationCode,
|
|
215
|
+
}).then((response) => {
|
|
216
|
+
this.expiryAllExistingCurrentSession(this.consumingProjectAuthService.userName, newPassword);
|
|
217
|
+
}, (err) => {
|
|
218
|
+
this.noOfAttempts = this.noOfAttempts + 1;
|
|
219
|
+
this.verifyAndSetNewPasswordErrorMessage = this.forgotPasswordError(err, this.noOfAttempts);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
this.noOfAttempts = this.noOfAttempts + 1;
|
|
224
|
+
this.verifyAndSetNewPasswordErrorMessage = this.forgotPasswordError(err, this.noOfAttempts);
|
|
225
|
+
}
|
|
226
|
+
finally {
|
|
227
|
+
this.forgotPasswordAndGlobalSignoutLoader = false;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
forgotPasswordError(err, noOfAttempts) {
|
|
231
|
+
let errorMessage = '';
|
|
232
|
+
console.log(err);
|
|
233
|
+
let errorThrown = JSON.stringify(err);
|
|
234
|
+
if (errorThrown.includes('LimitExceededException')) {
|
|
235
|
+
this.sessionLocked = true;
|
|
236
|
+
errorMessage = LoginConstant.attemptLimitExceeded;
|
|
237
|
+
}
|
|
238
|
+
else if (errorThrown.includes('ExpiredCodeException')) {
|
|
239
|
+
errorMessage = LoginConstant.sessionExpired;
|
|
240
|
+
this.verifyAndSetNewPasswordButton = LoginConstant.regenerateOtp;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
errorMessage = LoginConstant.attempt + ' ' + noOfAttempts + LoginConstant.attemptMessage;
|
|
244
|
+
}
|
|
245
|
+
return errorMessage;
|
|
246
|
+
}
|
|
247
|
+
async signInWithSSO() {
|
|
248
|
+
let session = await fetchAuthSession();
|
|
249
|
+
if (session?.tokens) {
|
|
250
|
+
await this.handleSignOut().then((response) => {
|
|
251
|
+
this.consumingProjectAuthService.signInWithSSO();
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
this.consumingProjectAuthService.signInWithSSO();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
async handleSignOut() {
|
|
259
|
+
try {
|
|
260
|
+
await signOut({ global: false });
|
|
261
|
+
this.sessionTimeout();
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
console.log('error signing out: ', error);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
expiryAllExistingCurrentSession(username, newPassword) {
|
|
268
|
+
this.loginErrorMessage = null;
|
|
269
|
+
this.onLoginInCogntioToGetAccessToken(username, newPassword);
|
|
270
|
+
}
|
|
271
|
+
async onLoginInCogntioToGetAccessToken(username, password) {
|
|
272
|
+
try {
|
|
273
|
+
const { nextStep } = await signIn({ username, password });
|
|
274
|
+
switch (nextStep?.signInStep) {
|
|
275
|
+
case 'DONE':
|
|
276
|
+
this.setAccessAndIDTokens(await (await fetchAuthSession()).tokens);
|
|
277
|
+
this.consumingProjectAuthService.onPasswordUpdate(this.consumingProjectAuthService.userName);
|
|
278
|
+
this.onCallGlobalSignout();
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
this.noOfAttempts = this.noOfAttempts + 1;
|
|
284
|
+
this.verifyAndSetNewPasswordErrorMessage = this.forgotPasswordError(error, this.noOfAttempts);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
async onCallGlobalSignout() {
|
|
288
|
+
try {
|
|
289
|
+
await signOut({ global: true });
|
|
290
|
+
this.forgotPasswordAndGlobalSignoutLoader = false;
|
|
291
|
+
this.router.navigate([LoginConstant.loginPageUrl]);
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
console.log('error signing out: ', error);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AnnaLibAuthService, deps: [{ token: i1.Router }, { token: i2.AnnaLibAclService }, { token: i3.HttpClient }, { token: i4.ToastrService }, { token: SSO_LOGIN_SERVICE_TOKEN }, { token: AUTH_SERVICE_TOKEN }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
298
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AnnaLibAuthService, providedIn: 'root' }); }
|
|
299
|
+
}
|
|
300
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AnnaLibAuthService, decorators: [{
|
|
301
|
+
type: Injectable,
|
|
302
|
+
args: [{
|
|
303
|
+
providedIn: 'root',
|
|
304
|
+
}]
|
|
305
|
+
}], ctorParameters: function () { return [{ type: i1.Router }, { type: i2.AnnaLibAclService }, { type: i3.HttpClient }, { type: i4.ToastrService }, { type: undefined, decorators: [{
|
|
306
|
+
type: Inject,
|
|
307
|
+
args: [SSO_LOGIN_SERVICE_TOKEN]
|
|
308
|
+
}] }, { type: undefined, decorators: [{
|
|
309
|
+
type: Inject,
|
|
310
|
+
args: [AUTH_SERVICE_TOKEN]
|
|
311
|
+
}] }]; } });
|
|
312
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5uYS1jb2duaXRvLWxpYi9zcmMvbGliL3NlcnZpY2VzL2F1dGguc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw0QkFBNEI7QUFDNUIsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUV6QyxnQ0FBZ0M7QUFDaEMsT0FBTyxFQUdILG9CQUFvQixFQUNwQixhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGNBQWMsRUFDZCxhQUFhLEVBQ2IsTUFBTSxFQUNOLE9BQU8sR0FDVixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFM0MsaUNBQWlDO0FBQ2pDLE9BQU8sRUFBRSxrQkFBa0IsRUFBZ0IsTUFBTSw4QkFBOEIsQ0FBQztBQUNoRixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2xELE9BQU8sRUFBb0IsdUJBQXVCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQzs7Ozs7O0FBSzlGLE1BQU0sT0FBTyxrQkFBa0I7SUFZM0IsWUFDWSxNQUFjLEVBQ2YsVUFBNkIsRUFDN0IsVUFBc0IsRUFDckIsTUFBcUIsRUFDVywrQkFBaUQsRUFDdEQsMkJBQXlDO1FBTHBFLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZixlQUFVLEdBQVYsVUFBVSxDQUFtQjtRQUM3QixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3JCLFdBQU0sR0FBTixNQUFNLENBQWU7UUFDVyxvQ0FBK0IsR0FBL0IsK0JBQStC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LE1BQU07MkJBQUMsa0JBQWtCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQW5ndWxhciBpbXBvcnQgc3RhdGVtZW50c1xyXG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuXHJcbi8vIFRoaXJkIHBhcnR5IGltcG9ydCBzdGF0ZW1lbnRzXHJcbmltcG9ydCB7XHJcbiAgICBBdXRoVG9rZW5zLFxyXG4gICAgU2lnbkluSW5wdXQsXHJcbiAgICBjb25maXJtUmVzZXRQYXNzd29yZCxcclxuICAgIGNvbmZpcm1TaWduSW4sXHJcbiAgICBmZXRjaEF1dGhTZXNzaW9uLFxyXG4gICAgZ2V0Q3VycmVudFVzZXIsXHJcbiAgICByZXNldFBhc3N3b3JkLFxyXG4gICAgc2lnbkluLFxyXG4gICAgc2lnbk91dCxcclxufSBmcm9tICdhd3MtYW1wbGlmeS9hdXRoJztcclxuaW1wb3J0IHsgVG9hc3RyU2VydmljZSB9IGZyb20gJ25neC10b2FzdHInO1xyXG5cclxuLy8gVXNlciBkZWZpbmVkIGltcG9ydCBzdGF0ZW1lbnRzXHJcbmltcG9ydCB7IEFVVEhfU0VSVklDRV9UT0tFTiwgSUF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vY29uZmlnL2F1dGgtc2VydmljZS50b2tlbic7XHJcbmltcG9ydCB7IExvZ2luQ29uc3RhbnQgfSBmcm9tICcuLi9jb25zdGFudHMvbG9naW5Db25zdGFudCc7XHJcbmltcG9ydCB7IEFubmFMaWJBY2xTZXJ2aWNlIH0gZnJvbSAnLi9hY2wuc2VydmljZSc7XHJcbmltcG9ydCB7IElTU09Mb2dpblNlcnZpY2UsIFNTT19MT0dJTl9TRVJWSUNFX1RPS0VOIH0gZnJvbSAnLi4vY29uZmlnL3Nzby1sb2dpbi1zZXJ2aWNlLnRva2VuJztcclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICAgIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIEFubmFMaWJBdXRoU2VydmljZSB7XHJcbiAgICBsb2dpbkVycm9yTWVzc2FnZTogc3RyaW5nIHwgbnVsbDtcclxuICAgIHNldE5ld1Bhc3N3b3JkRXJyb3JNZXNzYWdlOiBzdHJpbmc7XHJcbiAgICBzZXROZXdQYXNzd29yZEJ1dHRvbk1lc3NhZ2U6IHN0cmluZztcclxuICAgIHZlcmlmeUFuZFNldE5ld1Bhc3N3b3JkRXJyb3JNZXNzYWdlOiBzdHJpbmc7XHJcbiAgICB2ZXJpZnlBbmRTZXROZXdQYXNzd29yZE1lc3NhZ2U6IHN0cmluZztcclxuICAgIHZlcmlmeUFuZFNldE5ld1Bhc3N3b3JkQnV0dG9uOiBzdHJpbmc7XHJcbiAgICBub09mQXR0ZW1wdHMgPSAwO1xyXG4gICAgc2Vzc2lvbkxvY2tlZCA9IGZhbHNlO1xyXG4gICAgYWNjZXNzVG9rZW5UaW1lcklkOiBhbnk7XHJcbiAgICBmb3Jnb3RQYXNzd29yZEFuZEdsb2JhbFNpZ25vdXRMb2FkZXI6IGJvb2xlYW47XHJcblxyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcclxuICAgICAgICBwdWJsaWMgYWNsU2VydmljZTogQW5uYUxpYkFjbFNlcnZpY2UsXHJcbiAgICAgICAgcHVibGljIGh0dHBDbGllbnQ6IEh0dHBDbGllbnQsXHJcbiAgICAgICAgcHJpdmF0ZSB0b2FzdHI6IFRvYXN0clNlcnZpY2UsXHJcbiAgICAgICAgQEluamVjdChTU09fTE9HSU5fU0VSVklDRV9UT0tFTikgcHVibGljIGNvbnN1bWluZ1Byb2plY3RTU09Mb2dpblNlcnZpY2U6IElTU09Mb2dpblNlcnZpY2UsXHJcbiAgICAgICAgQEluamVjdChBVVRIX1NFUlZJQ0VfVE9LRU4pIHB1YmxpYyBjb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2U6IElBdXRoU2VydmljZSxcclxuICAgICkge1xyXG4gICAgICAgIGlmICghY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IG11c3QgcHJvdmlkZSBhIGF1dGhTZXJ2aWNlJyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG5nT25Jbml0KCkge31cclxuXHJcbiAgICBhc3luYyBpc1VzZXJMb2dnZWRJbigpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAvLyBhd2FpdCBnZXRDdXJyZW50VXNlcigpO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbjogYW55ID0gYXdhaXQgZmV0Y2hBdXRoU2Vzc2lvbigpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlc3Npb24/LnRva2Vucykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLklkVG9rZW4gPSBzZXNzaW9uPy50b2tlbnMuaWRUb2tlbi50b1N0cmluZygpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLmdldEFsbENvZ25pdG9Ub2tlbkFuZEdyb3VwcyhzZXNzaW9uLnRva2Vucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IoTG9naW5Db25zdGFudC5zZXNzaW9uRXhwaXJlZEVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZVNpZ25PdXQoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHRoaXMuYWNjZXNzVG9rZW5UaW1lcklkKTtcclxuICAgICAgICAgICAgICAgIHJlc29sdmUoZmFsc2UpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc2Vzc2lvblRpbWVvdXQoKSB7XHJcbiAgICAgICAgbG9jYWxTdG9yYWdlLmNsZWFyKCk7XHJcbiAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmFjY2Vzc1Rva2VuVGltZXJJZCk7XHJcbiAgICAgICAgbGV0IGFmdGVyTG9nb3V0UmVkaXJlY3RUbzogc3RyaW5nO1xyXG4gICAgICAgIGlmIChcclxuICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0U1NPTG9naW5TZXJ2aWNlLmlzU3NvSW50ZWdyYXRlZCAmJlxyXG4gICAgICAgICAgICAhdGhpcy5jb25zdW1pbmdQcm9qZWN0U1NPTG9naW5TZXJ2aWNlLmxvZ2dlZEluVmlhU3NvXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIGFmdGVyTG9nb3V0UmVkaXJlY3RUbyA9IExvZ2luQ29uc3RhbnQuY29QaWxvdGxvZ2luUGFnZVVybDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBhZnRlckxvZ291dFJlZGlyZWN0VG8gPSBMb2dpbkNvbnN0YW50LmxvZ2luUGFnZVVybDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW2FmdGVyTG9nb3V0UmVkaXJlY3RUb10pO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbXB1dGVUb2tlbkV4cGlyYXRpb24oaWRUb2tlbjogYW55KSB7XHJcbiAgICAgICAgbGV0IGN1cnJlbnRUaW1lID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCk7XHJcbiAgICAgICAgbGV0IHRva2VuVGltZSA9IGlkVG9rZW4ucGF5bG9hZC5leHA7XHJcbiAgICAgICAgbGV0IGV4cFRpbWUgPSAodG9rZW5UaW1lIC0gY3VycmVudFRpbWUpICogMTAwMDtcclxuICAgICAgICByZXR1cm4gZXhwVGltZTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBoYW5kbGVTaWduSW4oeyB1c2VybmFtZSwgcGFzc3dvcmQgfTogU2lnbkluSW5wdXQpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBsZXQgc2Vzc2lvbiA9IGF3YWl0IGZldGNoQXV0aFNlc3Npb24oKTtcclxuICAgICAgICAgICAgaWYgKHNlc3Npb24/LnRva2Vucykge1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVTaWduT3V0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgeyBpc1NpZ25lZEluLCBuZXh0U3RlcCB9ID0gYXdhaXQgc2lnbkluKHsgdXNlcm5hbWUsIHBhc3N3b3JkIH0pO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG5leHRTdGVwPy5zaWduSW5TdGVwKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdET05FJzpcclxuICAgICAgICAgICAgICAgICAgICBsZXQgc2Vzc2lvbiA9IGF3YWl0IGZldGNoQXV0aFNlc3Npb24oKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uTG9naW5PclNldE5ld1Bhc3N3b3JkKHNlc3Npb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLm9uU3VjY2Vzc2Z1bEF1dGhlbnRpY2F0aW5nVXNlcihmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UuZ2V0QWxsQ29nbml0b1Rva2VuQW5kR3JvdXBzKHNlc3Npb24udG9rZW5zKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZnJlc2hBY2Nlc3NUb2tlbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgICAgIGNhc2UgJ0NPTkZJUk1fU0lHTl9JTl9XSVRIX05FV19QQVNTV09SRF9SRVFVSVJFRCc6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UuaXNMb2dnaW5nSW4gPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnN1bWluZ1Byb2plY3RBdXRoU2VydmljZS51c2VyTmFtZSA9IHVzZXJuYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFtMb2dpbkNvbnN0YW50LnNldE5ld1Bhc3N3b3JkVXJsXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXROZXdQYXNzd29yZEVycm9yTWVzc2FnZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAgICAgY2FzZSAnUkVTRVRfUEFTU1dPUkQnOlxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XHJcbiAgICAgICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLmlzTG9nZ2luZ0luID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGlmIChlcnJvcj8ubWVzc2FnZSA9PSBMb2dpbkNvbnN0YW50LnRlbXBQYXNzd29yZEV4cGlyeUVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2luRXJyb3JNZXNzYWdlID0gTG9naW5Db25zdGFudC50ZW1wUGFzc3dvcmRPbkV4cGlyeUVycm9yTXNnO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2Uuc2VuZFJlZ2VuZXJhdGlvbkVtYWlsKHVzZXJuYW1lKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChlcnJvcj8ubWVzc2FnZSA9PT0gJ1Bhc3N3b3JkIGF0dGVtcHRzIGV4Y2VlZGVkJykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2dpbkVycm9yTWVzc2FnZSA9IExvZ2luQ29uc3RhbnQuYXR0ZW1wdExpbWl0RXhjZWVkZWQ7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2luRXJyb3JNZXNzYWdlID0gdGhpcy5jb25zdW1pbmdQcm9qZWN0U1NPTG9naW5TZXJ2aWNlLmlzU3NvSW50ZWdyYXRlZFxyXG4gICAgICAgICAgICAgICAgICAgID8gTG9naW5Db25zdGFudC51c2VyQ29kZVBhc3N3b3JkSW5jb3JyZWN0XHJcbiAgICAgICAgICAgICAgICAgICAgOiBMb2dpbkNvbnN0YW50LnVzZXJOYW1lUGFzc3dvcmRJbmNvcnJlY3Q7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgb25Mb2dpbk9yU2V0TmV3UGFzc3dvcmQoc2Vzc2lvbjogYW55KSB7XHJcbiAgICAgICAgbGV0IG5ld0V4cFRpbWUgPSB0aGlzLmNvbXB1dGVUb2tlbkV4cGlyYXRpb24oc2Vzc2lvbi50b2tlbnMuaWRUb2tlbik7XHJcbiAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UuYWNjZXNzVG9rZW4gPSBzZXNzaW9uLnRva2Vucy5hY2Nlc3NUb2tlbi50b1N0cmluZygpO1xyXG4gICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLklkVG9rZW4gPSBzZXNzaW9uLnRva2Vucy5pZFRva2VuLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2FjY2Vzc1Rva2VuRXhwaXJhdGlvbicsIG5ld0V4cFRpbWUudG9TdHJpbmcoKSk7XHJcbiAgICAgICAgdGhpcy5yZWZyZXNoQWNjZXNzVG9rZW4oKTtcclxuICAgICAgICB0aGlzLmxvZ2luRXJyb3JNZXNzYWdlID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBzZXRBY2Nlc3NBbmRJRFRva2Vucyh0b2tlbjogQXV0aFRva2Vucykge1xyXG4gICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLmFjY2Vzc1Rva2VuID0gdG9rZW4/LmFjY2Vzc1Rva2VuPy50b1N0cmluZygpO1xyXG4gICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLklkVG9rZW4gPSB0b2tlbj8uaWRUb2tlbjtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBnZXRBbGxDb2duaXRvVG9rZW5BbmRHcm91cHModG9rZW46IEF1dGhUb2tlbnMpIHtcclxuICAgICAgICB0aGlzLnNldEFjY2Vzc0FuZElEVG9rZW5zKHRva2VuKTtcclxuICAgICAgICBpZiAoJ2NvZ25pdG86Z3JvdXBzJyBpbiB0b2tlbi5hY2Nlc3NUb2tlbi5wYXlsb2FkKSB7XHJcbiAgICAgICAgICAgIGxldCB1c2VyR3JvdXBzSW5Db2duaXRvSldUOiBhbnkgPSB0b2tlbi5hY2Nlc3NUb2tlbi5wYXlsb2FkWydjb2duaXRvOmdyb3VwcyddO1xyXG4gICAgICAgICAgICB0aGlzLmFjbFNlcnZpY2UudXNlckdyb3Vwc0luQ29nbml0b0pXVCA9IHVzZXJHcm91cHNJbkNvZ25pdG9KV1Q7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5hY2xTZXJ2aWNlLnVzZXJHcm91cHNJbkNvZ25pdG9KV1QgPSBbXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmVmcmVzaEFjY2Vzc1Rva2VuKCkge1xyXG4gICAgICAgIGxldCBhY2Nlc3NUb2tlbkV4cGlyYXRpb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYWNjZXNzVG9rZW5FeHBpcmF0aW9uJyk7XHJcbiAgICAgICAgbGV0IGV4cFRpbWUgPSBhY2Nlc3NUb2tlbkV4cGlyYXRpb24gPyBwYXJzZUludChhY2Nlc3NUb2tlbkV4cGlyYXRpb24pIDogMDtcclxuICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuVGltZXJJZCA9IHNldEludGVydmFsKCgpID0+IHtcclxuICAgICAgICAgICAgbGV0IGNvdW50ZXIgPSAxMDAwO1xyXG4gICAgICAgICAgICBsZXQgZGVsYXlGdW5jdGlvbiA9IHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgc2Vzc2lvbiA9IGF3YWl0IGZldGNoQXV0aFNlc3Npb24oKTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgdG9rZW4gPSBzZXNzaW9uLnRva2VucztcclxuICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UuZ2V0QWxsQ29nbml0b1Rva2VuQW5kR3JvdXBzKHRva2VuKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG5ld0V4cFRpbWUgPSB0aGlzLmNvbXB1dGVUb2tlbkV4cGlyYXRpb24odGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UuSWRUb2tlbik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3RXhwVGltZSA8PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdFeHBUaW1lID0gMTAwMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGF5RnVuY3Rpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKGRlbGF5RnVuY3Rpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cFRpbWUgPSBuZXdFeHBUaW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnYWNjZXNzVG9rZW5FeHBpcmF0aW9uJywgbmV3RXhwVGltZS50b1N0cmluZygpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmFjY2Vzc1Rva2VuVGltZXJJZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVmcmVzaEFjY2Vzc1Rva2VuKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IoTG9naW5Db25zdGFudC5zZXNzaW9uRXhwaXJlZEVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVTaWduT3V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvYXN0ci5lcnJvcihMb2dpbkNvbnN0YW50LnNlc3Npb25FeHBpcmVkRXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlU2lnbk91dCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBjb3VudGVyKTtcclxuICAgICAgICB9LCBleHBUaW1lKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBjaGFuZ2VQYXNzd29yZChuZXdQYXNzd29yZDogc3RyaW5nKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgbGV0IGlucHV0UGFyYW0gPSB7XHJcbiAgICAgICAgICAgICAgICBjaGFsbGVuZ2VSZXNwb25zZTogbmV3UGFzc3dvcmQsXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBjb25maXJtU2lnbkluKGlucHV0UGFyYW0pO1xyXG4gICAgICAgICAgICBjb25zdCB7IHVzZXJuYW1lIH0gPSBhd2FpdCBnZXRDdXJyZW50VXNlcigpO1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhkYXRhKTtcclxuICAgICAgICAgICAgbGV0IHNlc3Npb24gPSBhd2FpdCBmZXRjaEF1dGhTZXNzaW9uKCk7XHJcbiAgICAgICAgICAgIHRoaXMub25Mb2dpbk9yU2V0TmV3UGFzc3dvcmQoc2Vzc2lvbik7XHJcbiAgICAgICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLm9uUGFzc3dvcmRVcGRhdGUodXNlcm5hbWUpO1xyXG4gICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbTG9naW5Db25zdGFudC5sb2dpblBhZ2VVcmxdKTtcclxuICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UubmV3UGFzc3dvcmRTZXRUaGVuVXBkYXRlVG9CYWNrZW5kKHVzZXJuYW1lKTtcclxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcclxuICAgICAgICAgICAgdGhpcy5zZXROZXdQYXNzd29yZEVycm9yTWVzc2FnZSA9IExvZ2luQ29uc3RhbnQuc2Vzc2lvbkV4cGlyZWQ7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0TmV3UGFzc3dvcmRCdXR0b25NZXNzYWdlID0gTG9naW5Db25zdGFudC5sb2dpbkFnYWluO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBvbkZvcmdvdFBhc3N3b3JkR2VuZXJhdGVPVFAoZW1haWw6IHN0cmluZykge1xyXG4gICAgICAgIGxldCB1c2VybmFtZSA9IGVtYWlsO1xyXG4gICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLnVzZXJOYW1lID0gZW1haWw7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgbGV0IHJlc3VsdDogYW55ID0gYXdhaXQgcmVzZXRQYXNzd29yZCh7IHVzZXJuYW1lIH0pO1xyXG4gICAgICAgICAgICB0aGlzLnZlcmlmeUFuZFNldE5ld1Bhc3N3b3JkTWVzc2FnZSA9XHJcbiAgICAgICAgICAgICAgICBMb2dpbkNvbnN0YW50LnZlcmlmeUFuZFNldE5ld1Bhc3N3b3JkTWVzc2FnZSArXHJcbiAgICAgICAgICAgICAgICByZXN1bHQ/Lm5leHRTdGVwPy5jb2RlRGVsaXZlcnlEZXRhaWxzPy5kZXN0aW5hdGlvbiArXHJcbiAgICAgICAgICAgICAgICBMb2dpbkNvbnN0YW50LnBsZWFzZUVudGVySXRCZWxvdztcclxuICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW0xvZ2luQ29uc3RhbnQudmVyaWZ5QW5kU2V0TmV3UGFzc3dvcmRVcmxdKTtcclxuICAgICAgICB9IGNhdGNoIChlcnIpIHt9XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgdmVyaWZ5Q29kZShjb25maXJtYXRpb25Db2RlOiBzdHJpbmcsIG5ld1Bhc3N3b3JkOiBzdHJpbmcpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25maXJtUmVzZXRQYXNzd29yZCh7XHJcbiAgICAgICAgICAgICAgICB1c2VybmFtZTogdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2UudXNlck5hbWUsXHJcbiAgICAgICAgICAgICAgICBuZXdQYXNzd29yZDogbmV3UGFzc3dvcmQsXHJcbiAgICAgICAgICAgICAgICBjb25maXJtYXRpb25Db2RlOiBjb25maXJtYXRpb25Db2RlLFxyXG4gICAgICAgICAgICB9KS50aGVuKFxyXG4gICAgICAgICAgICAgICAgKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leHBpcnlBbGxFeGlzdGluZ0N1cnJlbnRTZXNzaW9uKHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLnVzZXJOYW1lLCBuZXdQYXNzd29yZCk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgKGVycikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubm9PZkF0dGVtcHRzID0gdGhpcy5ub09mQXR0ZW1wdHMgKyAxO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmVyaWZ5QW5kU2V0TmV3UGFzc3dvcmRFcnJvck1lc3NhZ2UgPSB0aGlzLmZvcmdvdFBhc3N3b3JkRXJyb3IoZXJyLCB0aGlzLm5vT2ZBdHRlbXB0cyk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICB0aGlzLm5vT2ZBdHRlbXB0cyA9IHRoaXMubm9PZkF0dGVtcHRzICsgMTtcclxuICAgICAgICAgICAgdGhpcy52ZXJpZnlBbmRTZXROZXdQYXNzd29yZEVycm9yTWVzc2FnZSA9IHRoaXMuZm9yZ290UGFzc3dvcmRFcnJvcihlcnIsIHRoaXMubm9PZkF0dGVtcHRzKTtcclxuICAgICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgICAgICB0aGlzLmZvcmdvdFBhc3N3b3JkQW5kR2xvYmFsU2lnbm91dExvYWRlciA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmb3Jnb3RQYXNzd29yZEVycm9yKGVycjogYW55LCBub09mQXR0ZW1wdHM6IG51bWJlcikge1xyXG4gICAgICAgIGxldCBlcnJvck1lc3NhZ2UgPSAnJztcclxuICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xyXG4gICAgICAgIGxldCBlcnJvclRocm93biA9IEpTT04uc3RyaW5naWZ5KGVycik7XHJcbiAgICAgICAgaWYgKGVycm9yVGhyb3duLmluY2x1ZGVzKCdMaW1pdEV4Y2VlZGVkRXhjZXB0aW9uJykpIHtcclxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uTG9ja2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gTG9naW5Db25zdGFudC5hdHRlbXB0TGltaXRFeGNlZWRlZDtcclxuICAgICAgICB9IGVsc2UgaWYgKGVycm9yVGhyb3duLmluY2x1ZGVzKCdFeHBpcmVkQ29kZUV4Y2VwdGlvbicpKSB7XHJcbiAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IExvZ2luQ29uc3RhbnQuc2Vzc2lvbkV4cGlyZWQ7XHJcbiAgICAgICAgICAgIHRoaXMudmVyaWZ5QW5kU2V0TmV3UGFzc3dvcmRCdXR0b24gPSBMb2dpbkNvbnN0YW50LnJlZ2VuZXJhdGVPdHA7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gTG9naW5Db25zdGFudC5hdHRlbXB0ICsgJyAnICsgbm9PZkF0dGVtcHRzICsgTG9naW5Db25zdGFudC5hdHRlbXB0TWVzc2FnZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGVycm9yTWVzc2FnZTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBzaWduSW5XaXRoU1NPKCkge1xyXG4gICAgICAgIGxldCBzZXNzaW9uID0gYXdhaXQgZmV0Y2hBdXRoU2Vzc2lvbigpO1xyXG4gICAgICAgIGlmIChzZXNzaW9uPy50b2tlbnMpIHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVTaWduT3V0KCkudGhlbigocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29uc3VtaW5nUHJvamVjdEF1dGhTZXJ2aWNlLnNpZ25JbldpdGhTU08oKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2Uuc2lnbkluV2l0aFNTTygpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBoYW5kbGVTaWduT3V0KCkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHNpZ25PdXQoeyBnbG9iYWw6IGZhbHNlIH0pO1xyXG4gICAgICAgICAgICB0aGlzLnNlc3Npb25UaW1lb3V0KCk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ2Vycm9yIHNpZ25pbmcgb3V0OiAnLCBlcnJvcik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGV4cGlyeUFsbEV4aXN0aW5nQ3VycmVudFNlc3Npb24odXNlcm5hbWU6IHN0cmluZywgbmV3UGFzc3dvcmQ6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMubG9naW5FcnJvck1lc3NhZ2UgPSBudWxsO1xyXG4gICAgICAgIHRoaXMub25Mb2dpbkluQ29nbnRpb1RvR2V0QWNjZXNzVG9rZW4odXNlcm5hbWUsIG5ld1Bhc3N3b3JkKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBvbkxvZ2luSW5Db2dudGlvVG9HZXRBY2Nlc3NUb2tlbih1c2VybmFtZTogc3RyaW5nLCBwYXNzd29yZDogc3RyaW5nKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgY29uc3QgeyBuZXh0U3RlcCB9ID0gYXdhaXQgc2lnbkluKHsgdXNlcm5hbWUsIHBhc3N3b3JkIH0pO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG5leHRTdGVwPy5zaWduSW5TdGVwKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdET05FJzpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFjY2Vzc0FuZElEVG9rZW5zKGF3YWl0IChhd2FpdCBmZXRjaEF1dGhTZXNzaW9uKCkpLnRva2Vucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25zdW1pbmdQcm9qZWN0QXV0aFNlcnZpY2Uub25QYXNzd29yZFVwZGF0ZSh0aGlzLmNvbnN1bWluZ1Byb2plY3RBdXRoU2VydmljZS51c2VyTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkNhbGxHbG9iYWxTaWdub3V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XHJcbiAgICAgICAgICAgIHRoaXMubm9PZkF0dGVtcHRzID0gdGhpcy5ub09mQXR0ZW1wdHMgKyAxO1xyXG4gICAgICAgICAgICB0aGlzLnZlcmlmeUFuZFNldE5ld1Bhc3N3b3JkRXJyb3JNZXNzYWdlID0gdGhpcy5mb3Jnb3RQYXNzd29yZEVycm9yKGVycm9yLCB0aGlzLm5vT2ZBdHRlbXB0cyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIG9uQ2FsbEdsb2JhbFNpZ25vdXQoKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgc2lnbk91dCh7IGdsb2JhbDogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgdGhpcy5mb3Jnb3RQYXNzd29yZEFuZEdsb2JhbFNpZ25vdXRMb2FkZXIgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW0xvZ2luQ29uc3RhbnQubG9naW5QYWdlVXJsXSk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ2Vycm9yIHNpZ25pbmcgb3V0OiAnLCBlcnJvcik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiJdfQ==
|