@huntsman-cancer-institute/authentication 12.5.0 → 14.1.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.
- package/authentication.component.d.ts +1 -1
- package/directlogin.component.d.ts +4 -4
- package/esm2020/authentication.component.mjs +131 -0
- package/esm2020/authentication.module.mjs +105 -0
- package/esm2020/authentication.provider.mjs +36 -0
- package/esm2020/authentication.service.mjs +393 -0
- package/esm2020/authorization.interceptor.mjs +79 -0
- package/esm2020/directlogin.component.mjs +96 -0
- package/esm2020/huntsman-cancer-institute-authentication.mjs +5 -0
- package/esm2020/index.mjs +13 -0
- package/esm2020/route-guard.service.mjs +52 -0
- package/esm2020/timeout-notification.component.mjs +148 -0
- package/fesm2015/huntsman-cancer-institute-authentication.mjs +1000 -0
- package/fesm2015/huntsman-cancer-institute-authentication.mjs.map +1 -0
- package/{fesm2015/huntsman-cancer-institute-authentication.js → fesm2020/huntsman-cancer-institute-authentication.mjs} +64 -189
- package/fesm2020/huntsman-cancer-institute-authentication.mjs.map +1 -0
- package/package.json +26 -18
- package/timeout-notification.component.d.ts +1 -1
- package/CHANGELOG.md +0 -4
- package/bundles/huntsman-cancer-institute-authentication.umd.js +0 -945
- package/bundles/huntsman-cancer-institute-authentication.umd.js.map +0 -1
- package/bundles/huntsman-cancer-institute-authentication.umd.min.js +0 -2
- package/bundles/huntsman-cancer-institute-authentication.umd.min.js.map +0 -1
- package/esm2015/authentication.component.js +0 -153
- package/esm2015/authentication.module.js +0 -107
- package/esm2015/authentication.provider.js +0 -36
- package/esm2015/authentication.service.js +0 -393
- package/esm2015/authorization.interceptor.js +0 -79
- package/esm2015/directlogin.component.js +0 -146
- package/esm2015/huntsman-cancer-institute-authentication.js +0 -5
- package/esm2015/index.js +0 -13
- package/esm2015/route-guard.service.js +0 -52
- package/esm2015/timeout-notification.component.js +0 -205
- package/esm5/authentication.component.js +0 -120
- package/esm5/authentication.module.js +0 -109
- package/esm5/authentication.provider.js +0 -47
- package/esm5/authentication.service.js +0 -411
- package/esm5/authorization.interceptor.js +0 -81
- package/esm5/directlogin.component.js +0 -53
- package/esm5/huntsman-cancer-institute-authentication.js +0 -5
- package/esm5/index.js +0 -13
- package/esm5/route-guard.service.js +0 -55
- package/esm5/timeout-notification.component.js +0 -125
- package/fesm2015/huntsman-cancer-institute-authentication.js.map +0 -1
- package/fesm5/huntsman-cancer-institute-authentication.js +0 -937
- package/fesm5/huntsman-cancer-institute-authentication.js.map +0 -1
- package/huntsman-cancer-institute-authentication.d.ts +0 -5
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2016 Huntsman Cancer Institute at the University of Utah, Confidential and Proprietary
|
|
3
|
+
*/
|
|
4
|
+
import { Injectable, InjectionToken, Inject, Optional, isDevMode } from "@angular/core";
|
|
5
|
+
import { LocationStrategy } from "@angular/common";
|
|
6
|
+
import { Router } from "@angular/router";
|
|
7
|
+
import { HttpClient, HttpHeaders } from "@angular/common/http";
|
|
8
|
+
import { interval, BehaviorSubject, throwError } from "rxjs";
|
|
9
|
+
import { catchError, map } from "rxjs/operators";
|
|
10
|
+
import { JwtHelperService } from "@auth0/angular-jwt";
|
|
11
|
+
import { AuthenticationProvider } from "./authentication.provider";
|
|
12
|
+
import { CoolLocalStorage } from "@angular-cool/storage";
|
|
13
|
+
import * as i0 from "@angular/core";
|
|
14
|
+
import * as i1 from "@angular/common/http";
|
|
15
|
+
import * as i2 from "@angular/router";
|
|
16
|
+
import * as i3 from "@angular-cool/storage";
|
|
17
|
+
import * as i4 from "@auth0/angular-jwt";
|
|
18
|
+
import * as i5 from "./authentication.provider";
|
|
19
|
+
import * as i6 from "@angular/common";
|
|
20
|
+
/**
|
|
21
|
+
* The token used for injection of the server side endpoint for the currently authenticated subject.
|
|
22
|
+
*
|
|
23
|
+
* @type {InjectionToken}
|
|
24
|
+
*/
|
|
25
|
+
export let AUTHENTICATION_SERVER_URL = new InjectionToken("authentication_server_rest_api");
|
|
26
|
+
export let AUTHENTICATION_LOGOUT_PATH = new InjectionToken("authentication_logout_path");
|
|
27
|
+
export let AUTHENTICATION_DIRECT_ENDPOINT = new InjectionToken("authentication_direct_endpoint");
|
|
28
|
+
export let AUTHENTICATION_TOKEN_ENDPOINT = new InjectionToken("authentication_token_endpoint");
|
|
29
|
+
export let AUTHENTICATION_ROUTE = new InjectionToken("authentication_route");
|
|
30
|
+
export let AUTHENTICATION_MAX_INACTIVITY_MINUTES = new InjectionToken("authentication_max_inactivity");
|
|
31
|
+
export let AUTHENTICATION_USER_COUNTDOWN_SECONDS = new InjectionToken("authentication_user_countdown_seconds");
|
|
32
|
+
export let AUTHENTICATION_IDP_INACTIVITY_MINUTES = new InjectionToken("authentication_idp_inactivity_minutes");
|
|
33
|
+
/**
|
|
34
|
+
* @since 1.0.0
|
|
35
|
+
*/
|
|
36
|
+
export class AuthenticationService {
|
|
37
|
+
constructor(_http, _router, _localStorageService, _jwtHelper, authenticationProvider, _authenticationRoute, _logoutPath, _tokenEndpoint, _serverUrl, _directEndpoint, _maxInactivity, _userCountdownSeconds, _idpInactivityMinutes, locationStrategy) {
|
|
38
|
+
this._http = _http;
|
|
39
|
+
this._router = _router;
|
|
40
|
+
this._localStorageService = _localStorageService;
|
|
41
|
+
this._jwtHelper = _jwtHelper;
|
|
42
|
+
this.authenticationProvider = authenticationProvider;
|
|
43
|
+
this._authenticationRoute = _authenticationRoute;
|
|
44
|
+
this._logoutPath = _logoutPath;
|
|
45
|
+
this._tokenEndpoint = _tokenEndpoint;
|
|
46
|
+
this._serverUrl = _serverUrl;
|
|
47
|
+
this._directEndpoint = _directEndpoint;
|
|
48
|
+
this._maxInactivity = _maxInactivity;
|
|
49
|
+
this._userCountdownSeconds = _userCountdownSeconds;
|
|
50
|
+
this._idpInactivityMinutes = _idpInactivityMinutes;
|
|
51
|
+
this.locationStrategy = locationStrategy;
|
|
52
|
+
this.userCountdownSeconds = 60;
|
|
53
|
+
this.idpInactivityMinutes = 5;
|
|
54
|
+
this.contentType = "application/json";
|
|
55
|
+
this.limitedContext = false;
|
|
56
|
+
this.deidentifiedContext = false;
|
|
57
|
+
this.maxViewPermission = new BehaviorSubject("viewident");
|
|
58
|
+
this._isAuthenticatedSubject = new BehaviorSubject(false);
|
|
59
|
+
this._userIsAboutToTimeOut = new BehaviorSubject(false);
|
|
60
|
+
this._maxInactivityMinutes = 120;
|
|
61
|
+
this.contextRoot = "";
|
|
62
|
+
if (isDevMode()) {
|
|
63
|
+
console.debug("window.location.href: " + window.location.href);
|
|
64
|
+
}
|
|
65
|
+
if (window.location) {
|
|
66
|
+
let parts = window.location.href.split("/");
|
|
67
|
+
this.baseUrl = parts[0] + "//" + parts[2];
|
|
68
|
+
if (parts.length > 3) {
|
|
69
|
+
this.contextRoot = parts[3];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (this._localStorageService.getItem("maxViewPermission")) {
|
|
73
|
+
this.maxViewPermission.next(this._localStorageService.getItem("maxViewPermission"));
|
|
74
|
+
}
|
|
75
|
+
if (_maxInactivity) {
|
|
76
|
+
this._maxInactivityMinutes = _maxInactivity;
|
|
77
|
+
}
|
|
78
|
+
if (_userCountdownSeconds) {
|
|
79
|
+
this.userCountdownSeconds = _userCountdownSeconds;
|
|
80
|
+
}
|
|
81
|
+
if (_idpInactivityMinutes) {
|
|
82
|
+
this.idpInactivityMinutes = _idpInactivityMinutes;
|
|
83
|
+
}
|
|
84
|
+
this.hasValidConfig();
|
|
85
|
+
//There could be a non-expired token in local storage.
|
|
86
|
+
let token = this.authenticationProvider.authToken;
|
|
87
|
+
this.storeToken(token);
|
|
88
|
+
}
|
|
89
|
+
getBaseUrl() {
|
|
90
|
+
return (this.baseUrl) ? this.baseUrl : "";
|
|
91
|
+
}
|
|
92
|
+
getContextRoot() {
|
|
93
|
+
return this.contextRoot;
|
|
94
|
+
}
|
|
95
|
+
getHeaders(req) {
|
|
96
|
+
let headers = req.headers;
|
|
97
|
+
//Don't set content type if already set
|
|
98
|
+
if (!req.headers.get(AuthenticationService.CONTENT_TYPE)) {
|
|
99
|
+
headers = headers.set(AuthenticationService.CONTENT_TYPE, this.contentType.toString());
|
|
100
|
+
}
|
|
101
|
+
if (headers.get(AuthenticationService.SEC_GOV_CLASS_HEADER) === "") {
|
|
102
|
+
headers = headers.delete(AuthenticationService.SEC_GOV_CLASS_HEADER);
|
|
103
|
+
}
|
|
104
|
+
else if (this.securityGovernorClass && !headers.get(AuthenticationService.SEC_GOV_CLASS_HEADER)) {
|
|
105
|
+
headers = headers.set(AuthenticationService.SEC_GOV_CLASS_HEADER, this.securityGovernorClass);
|
|
106
|
+
}
|
|
107
|
+
if (headers.get(AuthenticationService.SEC_GOV_ID_HEADER) === "") {
|
|
108
|
+
headers = headers.delete(AuthenticationService.SEC_GOV_ID_HEADER);
|
|
109
|
+
}
|
|
110
|
+
else if (this.securityGovernorId && !headers.get(AuthenticationService.SEC_GOV_ID_HEADER)) {
|
|
111
|
+
headers = headers.set(AuthenticationService.SEC_GOV_ID_HEADER, this.securityGovernorId.toString());
|
|
112
|
+
}
|
|
113
|
+
headers = headers.set(AuthenticationService.DEIDENT_HEADER, this.deidentifiedContext.toString());
|
|
114
|
+
headers = headers.set(AuthenticationService.LIMITED_HEADER, this.limitedContext.toString());
|
|
115
|
+
return headers;
|
|
116
|
+
}
|
|
117
|
+
get authenticationTokenKey() {
|
|
118
|
+
return this.authenticationProvider.authenticationTokenKey;
|
|
119
|
+
}
|
|
120
|
+
get authToken() {
|
|
121
|
+
return this.authenticationProvider.authToken;
|
|
122
|
+
}
|
|
123
|
+
updateUserActivity() {
|
|
124
|
+
if (this._isAuthenticatedSubject.value) {
|
|
125
|
+
this._lastUserInteraction = new Date();
|
|
126
|
+
this._userIsAboutToTimeOut.next(false);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* A mutator for identifying the clients original request location. Setting this value will influence the end location
|
|
131
|
+
* navigated to by {@link #navigateToPath}.
|
|
132
|
+
*
|
|
133
|
+
* @param redirectUrl location of the users request before authentication
|
|
134
|
+
*/
|
|
135
|
+
set redirectUrl(redirectUrl) {
|
|
136
|
+
this._redirectUrl = redirectUrl;
|
|
137
|
+
}
|
|
138
|
+
get redirectUrl() {
|
|
139
|
+
return this._redirectUrl;
|
|
140
|
+
}
|
|
141
|
+
requestAccessToken(redirectOnSuccess) {
|
|
142
|
+
this._http.get(this.tokenLocation(), { withCredentials: true })
|
|
143
|
+
.subscribe((response) => {
|
|
144
|
+
this.storeToken(response.auth_token);
|
|
145
|
+
if (redirectOnSuccess) {
|
|
146
|
+
this.proceedIfAuthenticated();
|
|
147
|
+
}
|
|
148
|
+
}, (error) => {
|
|
149
|
+
//Token refresh failed.
|
|
150
|
+
this.logout(true);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Verifies whether or not a current user session exists.
|
|
155
|
+
*
|
|
156
|
+
* @returns {Observable<boolean>} evaluates to true if the user is authenticated, false otherwise.
|
|
157
|
+
*/
|
|
158
|
+
isAuthenticated() {
|
|
159
|
+
return this._isAuthenticatedSubject.asObservable();
|
|
160
|
+
}
|
|
161
|
+
isAboutToTimeOut() {
|
|
162
|
+
return this._userIsAboutToTimeOut.asObservable();
|
|
163
|
+
}
|
|
164
|
+
getTimeoutStart() {
|
|
165
|
+
if (this._lastUserInteraction) {
|
|
166
|
+
return this._lastUserInteraction.valueOf() + (((this._maxInactivityMinutes * 60) - this.userCountdownSeconds) * 1000);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
tokenLocation() {
|
|
170
|
+
if (this._serverUrl) {
|
|
171
|
+
return this._serverUrl + this._tokenEndpoint;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
return this._tokenEndpoint;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
directLoginLocation() {
|
|
178
|
+
if (this._serverUrl) {
|
|
179
|
+
return this._serverUrl + this._directEndpoint;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
return this._directEndpoint;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
logoutLocation() {
|
|
186
|
+
if (this._serverUrl) {
|
|
187
|
+
return this._serverUrl + this._logoutPath;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
return this._logoutPath;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* A function to authenticated the user with the provided credentials. Failure results in an error that describes the
|
|
195
|
+
* server response (status and status message) and should be actionable by the client application.
|
|
196
|
+
*
|
|
197
|
+
* @param username of the authenticating user to verify
|
|
198
|
+
* @param password of the authenticating user to verify
|
|
199
|
+
* @returns {Observable<R>} describing the result of the login action, true or an error
|
|
200
|
+
*/
|
|
201
|
+
login(_username, _password) {
|
|
202
|
+
return this._http.post(this.directLoginLocation(), { username: _username, password: _password }, { observe: "response" }).pipe(map((resp) => {
|
|
203
|
+
if (resp.status === 201) {
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
throw new Error("Authentication failed. " + resp.status + ": " + resp.statusText);
|
|
208
|
+
}
|
|
209
|
+
}), catchError(this.handleError));
|
|
210
|
+
}
|
|
211
|
+
clearLogin() {
|
|
212
|
+
//Front-end logout
|
|
213
|
+
try {
|
|
214
|
+
this._localStorageService.removeItem(this.authenticationProvider.authenticationTokenKey);
|
|
215
|
+
this.unsubscribeFromTokenRefresh();
|
|
216
|
+
this._isAuthenticatedSubject.next(false);
|
|
217
|
+
this._userIsAboutToTimeOut.next(false);
|
|
218
|
+
}
|
|
219
|
+
catch (Error) {
|
|
220
|
+
}
|
|
221
|
+
//Back-end logout
|
|
222
|
+
let headers = new HttpHeaders().set(AuthenticationService.CONTENT_TYPE, "text/plain");
|
|
223
|
+
return this._http.get(this.logoutLocation(), { headers: headers });
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* A function to signal the termination of the current session. Invoking this function will clean up any relevant state
|
|
227
|
+
* related to the last active session.
|
|
228
|
+
*/
|
|
229
|
+
logout(keepCurrentRoute = false) {
|
|
230
|
+
//Prevent logout if already on authentication route. Doing otherwise screws up SAML
|
|
231
|
+
if (!this._router.routerState || this._router.routerState.snapshot.url !== this._authenticationRoute) {
|
|
232
|
+
this._redirectUrl = (keepCurrentRoute && this._router.routerState && this._router.routerState.snapshot) ? this._router.routerState.snapshot.url : "";
|
|
233
|
+
if (this._redirectUrl.startsWith("/")) {
|
|
234
|
+
this._redirectUrl = this._redirectUrl.substring(1);
|
|
235
|
+
}
|
|
236
|
+
this.clearLogin().subscribe((response) => {
|
|
237
|
+
window.location.replace(this._redirectUrl);
|
|
238
|
+
}, (error) => {
|
|
239
|
+
window.location.replace(this._redirectUrl);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
storeToken(token) {
|
|
244
|
+
let valid = this.validateToken(token);
|
|
245
|
+
// unsubscribe from refesh before we decide wether to resubscribe
|
|
246
|
+
this.unsubscribeFromTokenRefresh();
|
|
247
|
+
if (valid) {
|
|
248
|
+
this._localStorageService.setItem(this.authenticationProvider.authenticationTokenKey, token);
|
|
249
|
+
this.subscribeToTokenRefresh(token);
|
|
250
|
+
//Change the BehaviorSubject if the user was not previously authenticated.
|
|
251
|
+
//Since other code may be subscribing to this observable, we don't want to cause new events to fire if just refreshing the JWT.
|
|
252
|
+
if (!this._isAuthenticatedSubject.value) {
|
|
253
|
+
this._isAuthenticatedSubject.next(true);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
this._localStorageService.removeItem(this.authenticationProvider.authenticationTokenKey);
|
|
258
|
+
this._isAuthenticatedSubject.next(false);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
proceedIfAuthenticated() {
|
|
262
|
+
if (isDevMode()) {
|
|
263
|
+
console.debug("AuthenticationService.proceedIfAuthenticated: " + this._redirectUrl);
|
|
264
|
+
}
|
|
265
|
+
if (this._isAuthenticatedSubject.value) {
|
|
266
|
+
//Login counts as user activity, too
|
|
267
|
+
this.updateUserActivity();
|
|
268
|
+
if (this._redirectUrl && this._redirectUrl && this._redirectUrl !== "") {
|
|
269
|
+
this._router.navigateByUrl(this._redirectUrl);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
this._router.navigate([""]);
|
|
273
|
+
}
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
validateToken(token) {
|
|
281
|
+
return (token && !this._jwtHelper.isTokenExpired(token));
|
|
282
|
+
}
|
|
283
|
+
subscribeToTokenRefresh(token) {
|
|
284
|
+
let exp = this._jwtHelper.getTokenExpirationDate(token);
|
|
285
|
+
// Use a timer to periodically check timeouts
|
|
286
|
+
this._refreshSubscription = interval(1000)
|
|
287
|
+
.subscribe(() => {
|
|
288
|
+
// If a tab is inactive we can't know if our timer is accurate
|
|
289
|
+
// so when the interval hits check against timestamps
|
|
290
|
+
if (this._isAuthenticatedSubject.value && Date.now() > this.getTimeoutStart()) {
|
|
291
|
+
//Don't update the subject more than once! Doing so initializes more than one countdown timer!
|
|
292
|
+
if (this._userIsAboutToTimeOut.getValue() !== true) {
|
|
293
|
+
this._userIsAboutToTimeOut.next(true);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// check for refresh token
|
|
297
|
+
let msToExpiry = (exp.valueOf() - new Date().valueOf());
|
|
298
|
+
// Refresh 60 seconds before expiry
|
|
299
|
+
if (msToExpiry <= 60000) {
|
|
300
|
+
this.refreshTokenIfUserIsActive();
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
unsubscribeFromTokenRefresh() {
|
|
305
|
+
if (this._refreshSubscription && !this._refreshSubscription.closed) {
|
|
306
|
+
this._refreshSubscription.unsubscribe();
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
getMaxViewPermission() {
|
|
310
|
+
return this.maxViewPermission.getValue();
|
|
311
|
+
}
|
|
312
|
+
getMaxViewPermissionSubject() {
|
|
313
|
+
return this.maxViewPermission;
|
|
314
|
+
}
|
|
315
|
+
setMaxViewPermission(maxViewPermission) {
|
|
316
|
+
this._localStorageService.setItem("maxViewPermission", maxViewPermission);
|
|
317
|
+
this.maxViewPermission.next(maxViewPermission);
|
|
318
|
+
}
|
|
319
|
+
refreshTokenIfUserIsActive() {
|
|
320
|
+
//Only refresh if the user has been active
|
|
321
|
+
if (this._lastUserInteraction && ((new Date().valueOf() - this._lastUserInteraction.valueOf()) <= (this._maxInactivityMinutes * 60 * 1000))) {
|
|
322
|
+
this.requestAccessToken(false);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
hasValidConfig() {
|
|
326
|
+
if (this._tokenEndpoint == null && (this._serverUrl === null || this._logoutPath === null)) {
|
|
327
|
+
throw new Error("BUG ALERT! Invalid AuthenticationService configuration. No valid configuration for authentication endpoint(s).");
|
|
328
|
+
}
|
|
329
|
+
if (this._localStorageService === null || this.authenticationProvider.authenticationTokenKey === null) {
|
|
330
|
+
throw new Error("BUG ALERT! Invalid AuthenticationService configuration. No valid configuration for local storage");
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
handleError(error) {
|
|
334
|
+
let errMsg = (error.message) ? error.message : AuthenticationService.GENERIC_ERR_MSG;
|
|
335
|
+
return throwError(errMsg);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* The generic error message used when a server error is thrown without a status.
|
|
340
|
+
*
|
|
341
|
+
* @type {string}
|
|
342
|
+
*/
|
|
343
|
+
AuthenticationService.GENERIC_ERR_MSG = "Server error";
|
|
344
|
+
AuthenticationService.CONTENT_TYPE = "Content-Type";
|
|
345
|
+
AuthenticationService.SEC_GOV_CLASS_HEADER = "SecurityGovernorClass";
|
|
346
|
+
AuthenticationService.SEC_GOV_ID_HEADER = "SecurityGovernorId";
|
|
347
|
+
AuthenticationService.DEIDENT_HEADER = "DeidentifiedContext";
|
|
348
|
+
AuthenticationService.LIMITED_HEADER = "LimitedContext";
|
|
349
|
+
AuthenticationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AuthenticationService, deps: [{ token: i1.HttpClient }, { token: i2.Router }, { token: i3.CoolLocalStorage }, { token: i4.JwtHelperService }, { token: i5.AuthenticationProvider }, { token: AUTHENTICATION_ROUTE }, { token: AUTHENTICATION_LOGOUT_PATH }, { token: AUTHENTICATION_TOKEN_ENDPOINT }, { token: AUTHENTICATION_SERVER_URL, optional: true }, { token: AUTHENTICATION_DIRECT_ENDPOINT, optional: true }, { token: AUTHENTICATION_MAX_INACTIVITY_MINUTES, optional: true }, { token: AUTHENTICATION_USER_COUNTDOWN_SECONDS, optional: true }, { token: AUTHENTICATION_IDP_INACTIVITY_MINUTES, optional: true }, { token: LocationStrategy, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
350
|
+
AuthenticationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AuthenticationService });
|
|
351
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AuthenticationService, decorators: [{
|
|
352
|
+
type: Injectable
|
|
353
|
+
}], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.Router }, { type: i3.CoolLocalStorage }, { type: i4.JwtHelperService }, { type: i5.AuthenticationProvider }, { type: undefined, decorators: [{
|
|
354
|
+
type: Inject,
|
|
355
|
+
args: [AUTHENTICATION_ROUTE]
|
|
356
|
+
}] }, { type: undefined, decorators: [{
|
|
357
|
+
type: Inject,
|
|
358
|
+
args: [AUTHENTICATION_LOGOUT_PATH]
|
|
359
|
+
}] }, { type: undefined, decorators: [{
|
|
360
|
+
type: Inject,
|
|
361
|
+
args: [AUTHENTICATION_TOKEN_ENDPOINT]
|
|
362
|
+
}] }, { type: undefined, decorators: [{
|
|
363
|
+
type: Optional
|
|
364
|
+
}, {
|
|
365
|
+
type: Inject,
|
|
366
|
+
args: [AUTHENTICATION_SERVER_URL]
|
|
367
|
+
}] }, { type: undefined, decorators: [{
|
|
368
|
+
type: Optional
|
|
369
|
+
}, {
|
|
370
|
+
type: Inject,
|
|
371
|
+
args: [AUTHENTICATION_DIRECT_ENDPOINT]
|
|
372
|
+
}] }, { type: undefined, decorators: [{
|
|
373
|
+
type: Optional
|
|
374
|
+
}, {
|
|
375
|
+
type: Inject,
|
|
376
|
+
args: [AUTHENTICATION_MAX_INACTIVITY_MINUTES]
|
|
377
|
+
}] }, { type: undefined, decorators: [{
|
|
378
|
+
type: Optional
|
|
379
|
+
}, {
|
|
380
|
+
type: Inject,
|
|
381
|
+
args: [AUTHENTICATION_USER_COUNTDOWN_SECONDS]
|
|
382
|
+
}] }, { type: undefined, decorators: [{
|
|
383
|
+
type: Optional
|
|
384
|
+
}, {
|
|
385
|
+
type: Inject,
|
|
386
|
+
args: [AUTHENTICATION_IDP_INACTIVITY_MINUTES]
|
|
387
|
+
}] }, { type: i6.LocationStrategy, decorators: [{
|
|
388
|
+
type: Optional
|
|
389
|
+
}, {
|
|
390
|
+
type: Inject,
|
|
391
|
+
args: [LocationStrategy]
|
|
392
|
+
}] }]; } });
|
|
393
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aGVudGljYXRpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2F1dGhlbnRpY2F0aW9uL3NyYy9hdXRoZW50aWNhdGlvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsT0FBTyxFQUFDLFVBQVUsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDdEYsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sRUFBQyxVQUFVLEVBQUUsV0FBVyxFQUE0QixNQUFNLHNCQUFzQixDQUFDO0FBRXhGLE9BQU8sRUFBQyxRQUFRLEVBQWMsZUFBZSxFQUFnQixVQUFVLEVBQUssTUFBTSxNQUFNLENBQUM7QUFDekYsT0FBTyxFQUFDLFVBQVUsRUFBUyxHQUFHLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUVwRCxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7Ozs7Ozs7QUFFekQ7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxJQUFJLHlCQUF5QixHQUFHLElBQUksY0FBYyxDQUFTLGdDQUFnQyxDQUFDLENBQUM7QUFDcEcsTUFBTSxDQUFDLElBQUksMEJBQTBCLEdBQUcsSUFBSSxjQUFjLENBQVMsNEJBQTRCLENBQUMsQ0FBQztBQUNqRyxNQUFNLENBQUMsSUFBSSw4QkFBOEIsR0FBRyxJQUFJLGNBQWMsQ0FBUyxnQ0FBZ0MsQ0FBQyxDQUFDO0FBQ3pHLE1BQU0sQ0FBQyxJQUFJLDZCQUE2QixHQUFHLElBQUks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LENBQUE7QUFDdkQsdUNBQWlCLEdBQVcsb0JBQXFCLENBQUE7QUFDakQsb0NBQWMsR0FBVyxxQkFBc0IsQ0FBQTtBQUMvQyxvQ0FBYyxHQUFXLGdCQUFpQixDQUFBO2tIQWI5QyxxQkFBcUIsd0tBd0NaLG9CQUFvQixhQUNwQiwwQkFBMEIsYUFDMUIsNkJBQTZCLGFBQ2pCLHlCQUF5Qiw2QkFDekIsOEJBQThCLDZCQUM5QixxQ0FBcUMsNkJBQ3JDLHFDQUFxQyw2QkFDckMscUNBQXFDLDZCQUNyQyxnQkFBZ0I7c0hBaERyQyxxQkFBcUI7MkZBQXJCLHFCQUFxQjtrQkFEakMsVUFBVTs7MEJBeUNJLE1BQU07MkJBQUMsb0JBQW9COzswQkFDM0IsTUFBTTsyQkFBQywwQkFBMEI7OzBCQUNqQyxNQUFNOzJCQUFDLDZCQUE2Qjs7MEJBQ3BDLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMseUJBQXlCOzswQkFDNUMsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyw4QkFBOEI7OzBCQUNqRCxRQUFROzswQkFBSSxNQUFNOzJCQUFDLHFDQUFxQzs7MEJBQ3hELFFBQVE7OzBCQUFJLE1BQU07MkJBQUMscUNBQXFDOzswQkFDeEQsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxxQ0FBcUM7OzBCQUN4RCxRQUFROzswQkFBSSxNQUFNOzJCQUFDLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbIi8qXHJcbiAqIENvcHlyaWdodCAoYykgMjAxNiBIdW50c21hbiBDYW5jZXIgSW5zdGl0dXRlIGF0IHRoZSBVbml2ZXJzaXR5IG9mIFV0YWgsIENvbmZpZGVudGlhbCBhbmQgUHJvcHJpZXRhcnlcclxuICovXHJcbmltcG9ydCB7SW5qZWN0YWJsZSwgSW5qZWN0aW9uVG9rZW4sIEluamVjdCwgT3B0aW9uYWwsIGlzRGV2TW9kZX0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0IHtMb2NhdGlvblN0cmF0ZWd5fSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XHJcbmltcG9ydCB7Um91dGVyfSBmcm9tIFwiQGFuZ3VsYXIvcm91dGVyXCI7XHJcbmltcG9ydCB7SHR0cENsaWVudCwgSHR0cEhlYWRlcnMsIEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2V9IGZyb20gXCJAYW5ndWxhci9jb21tb24vaHR0cFwiO1xyXG5cclxuaW1wb3J0IHtpbnRlcnZhbCwgT2JzZXJ2YWJsZSwgQmVoYXZpb3JTdWJqZWN0LCBTdWJzY3JpcHRpb24sIHRocm93RXJyb3IsIG9mfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQge2NhdGNoRXJyb3IsIGZpcnN0LCBtYXB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xyXG5pbXBvcnQge0p3dEhlbHBlclNlcnZpY2V9IGZyb20gXCJAYXV0aDAvYW5ndWxhci1qd3RcIjtcclxuXHJcbmltcG9ydCB7QXV0aGVudGljYXRpb25Qcm92aWRlcn0gZnJvbSBcIi4vYXV0aGVudGljYXRpb24ucHJvdmlkZXJcIjtcclxuaW1wb3J0IHsgQ29vbExvY2FsU3RvcmFnZSB9IGZyb20gXCJAYW5ndWxhci1jb29sL3N0b3JhZ2VcIjtcclxuXHJcbi8qKlxyXG4gKiBUaGUgdG9rZW4gdXNlZCBmb3IgaW5qZWN0aW9uIG9mIHRoZSBzZXJ2ZXIgc2lkZSBlbmRwb2ludCBmb3IgdGhlIGN1cnJlbnRseSBhdXRoZW50aWNhdGVkIHN1YmplY3QuXHJcbiAqXHJcbiAqIEB0eXBlIHtJbmplY3Rpb25Ub2tlbn1cclxuICovXHJcbmV4cG9ydCBsZXQgQVVUSEVOVElDQVRJT05fU0VSVkVSX1VSTCA9IG5ldyBJbmplY3Rpb25Ub2tlbjxzdHJpbmc+KFwiYXV0aGVudGljYXRpb25fc2VydmVyX3Jlc3RfYXBpXCIpO1xyXG5leHBvcnQgbGV0IEFVVEhFTlRJQ0FUSU9OX0xPR09VVF9QQVRIID0gbmV3IEluamVjdGlvblRva2VuPHN0cmluZz4oXCJhdXRoZW50aWNhdGlvbl9sb2dvdXRfcGF0aFwiKTtcclxuZXhwb3J0IGxldCBBVVRIRU5USUNBVElPTl9ESVJFQ1RfRU5EUE9JTlQgPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPihcImF1dGhlbnRpY2F0aW9uX2RpcmVjdF9lbmRwb2ludFwiKTtcclxuZXhwb3J0IGxldCBBVVRIRU5USUNBVElPTl9UT0tFTl9FTkRQT0lOVCA9IG5ldyBJbmplY3Rpb25Ub2tlbjxzdHJpbmc+KFwiYXV0aGVudGljYXRpb25fdG9rZW5fZW5kcG9pbnRcIik7XHJcbmV4cG9ydCBsZXQgQVVUSEVOVElDQVRJT05fUk9VVEUgPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPihcImF1dGhlbnRpY2F0aW9uX3JvdXRlXCIpO1xyXG5leHBvcnQgbGV0IEFVVEhFTlRJQ0FUSU9OX01BWF9JTkFDVElWSVRZX01JTlVURVMgPSBuZXcgSW5qZWN0aW9uVG9rZW48bnVtYmVyPihcImF1dGhlbnRpY2F0aW9uX21heF9pbmFjdGl2aXR5XCIpO1xyXG5leHBvcnQgbGV0IEFVVEhFTlRJQ0FUSU9OX1VTRVJfQ09VTlRET1dOX1NFQ09ORFMgPSBuZXcgSW5qZWN0aW9uVG9rZW48bnVtYmVyPihcImF1dGhlbnRpY2F0aW9uX3VzZXJfY291bnRkb3duX3NlY29uZHNcIik7XHJcbmV4cG9ydCBsZXQgQVVUSEVOVElDQVRJT05fSURQX0lOQUNUSVZJVFlfTUlOVVRFUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxudW1iZXI+KFwiYXV0aGVudGljYXRpb25faWRwX2luYWN0aXZpdHlfbWludXRlc1wiKTtcclxuXHJcbi8qKlxyXG4gKiBAc2luY2UgMS4wLjBcclxuICovXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIEF1dGhlbnRpY2F0aW9uU2VydmljZSB7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBnZW5lcmljIGVycm9yIG1lc3NhZ2UgdXNlZCB3aGVuIGEgc2VydmVyIGVycm9yIGlzIHRocm93biB3aXRob3V0IGEgc3RhdHVzLlxyXG4gICAqXHJcbiAgICogQHR5cGUge3N0cmluZ31cclxuICAgKi9cclxuICBwdWJsaWMgc3RhdGljIEdFTkVSSUNfRVJSX01TRzogc3RyaW5nID0gXCJTZXJ2ZXIgZXJyb3JcIjtcclxuXHJcbiAgcHJpdmF0ZSBzdGF0aWMgQ09OVEVOVF9UWVBFOiBzdHJpbmcgPSBcIkNvbnRlbnQtVHlwZVwiO1xyXG4gIHByaXZhdGUgc3RhdGljIFNFQ19HT1ZfQ0xBU1NfSEVBREVSOiBzdHJpbmcgPSBcIlNlY3VyaXR5R292ZXJub3JDbGFzc1wiO1xyXG4gIHByaXZhdGUgc3RhdGljIFNFQ19HT1ZfSURfSEVBREVSOiBzdHJpbmcgPSBcIlNlY3VyaXR5R292ZXJub3JJZFwiO1xyXG4gIHByaXZhdGUgc3RhdGljIERFSURFTlRfSEVBREVSOiBzdHJpbmcgPSBcIkRlaWRlbnRpZmllZENvbnRleHRcIjtcclxuICBwcml2YXRlIHN0YXRpYyBMSU1JVEVEX0hFQURFUjogc3RyaW5nID0gXCJMaW1pdGVkQ29udGV4dFwiO1xyXG5cclxuICBwdWJsaWMgdXNlckNvdW50ZG93blNlY29uZHM6IG51bWJlciA9IDYwO1xyXG4gIHB1YmxpYyBpZHBJbmFjdGl2aXR5TWludXRlczogbnVtYmVyID0gNTtcclxuXHJcbiAgcHVibGljIGNvbnRlbnRUeXBlOiBzdHJpbmcgPSBcImFwcGxpY2F0aW9uL2pzb25cIjtcclxuICBwdWJsaWMgc2VjdXJpdHlHb3Zlcm5vckNsYXNzOiBzdHJpbmc7XHJcbiAgcHVibGljIHNlY3VyaXR5R292ZXJub3JJZDogbnVtYmVyO1xyXG4gIHB1YmxpYyBsaW1pdGVkQ29udGV4dDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHB1YmxpYyBkZWlkZW50aWZpZWRDb250ZXh0OiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIHByaXZhdGUgbWF4Vmlld1Blcm1pc3Npb246IEJlaGF2aW9yU3ViamVjdDxcInZpZXdcIiB8IFwidmlld2lkZW50XCIgfCBcInZpZXdsaW1pdGVkXCI+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxcInZpZXdcIiB8IFwidmlld2lkZW50XCIgfCBcInZpZXdsaW1pdGVkXCI+KFwidmlld2lkZW50XCIpO1xyXG4gIHByaXZhdGUgX2lzQXV0aGVudGljYXRlZFN1YmplY3Q6IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIHByaXZhdGUgX3VzZXJJc0Fib3V0VG9UaW1lT3V0OiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcclxuICBwcml2YXRlIF9yZWRpcmVjdFVybDogc3RyaW5nO1xyXG4gIHByaXZhdGUgX3JlZnJlc2hTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcclxuICBwcml2YXRlIF9sYXN0VXNlckludGVyYWN0aW9uOiBEYXRlO1xyXG4gIHByaXZhdGUgX21heEluYWN0aXZpdHlNaW51dGVzOiBudW1iZXIgPSAxMjA7XHJcblxyXG4gIHByaXZhdGUgYmFzZVVybDogc3RyaW5nO1xyXG4gIHByaXZhdGUgY29udGV4dFJvb3Q6IHN0cmluZyA9IFwiXCI7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2h0dHA6IEh0dHBDbGllbnQsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfcm91dGVyOiBSb3V0ZXIsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfbG9jYWxTdG9yYWdlU2VydmljZTogQ29vbExvY2FsU3RvcmFnZSxcclxuICAgICAgICAgICAgICBwcml2YXRlIF9qd3RIZWxwZXI6IEp3dEhlbHBlclNlcnZpY2UsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBhdXRoZW50aWNhdGlvblByb3ZpZGVyOiBBdXRoZW50aWNhdGlvblByb3ZpZGVyLFxyXG4gICAgICAgICAgICAgIEBJbmplY3QoQVVUSEVOVElDQVRJT05fUk9VVEUpIHByaXZhdGUgX2F1dGhlbnRpY2F0aW9uUm91dGU6IHN0cmluZyxcclxuICAgICAgICAgICAgICBASW5qZWN0KEFVVEhFTlRJQ0FUSU9OX0xPR09VVF9QQVRIKSBwcml2YXRlIF9sb2dvdXRQYXRoOiBzdHJpbmcsXHJcbiAgICAgICAgICAgICAgQEluamVjdChBVVRIRU5USUNBVElPTl9UT0tFTl9FTkRQT0lOVCkgcHJpdmF0ZSBfdG9rZW5FbmRwb2ludDogc3RyaW5nLFxyXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQVVUSEVOVElDQVRJT05fU0VSVkVSX1VSTCkgcHJpdmF0ZSBfc2VydmVyVXJsOiBzdHJpbmcsXHJcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChBVVRIRU5USUNBVElPTl9ESVJFQ1RfRU5EUE9JTlQpIHByaXZhdGUgX2RpcmVjdEVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChBVVRIRU5USUNBVElPTl9NQVhfSU5BQ1RJVklUWV9NSU5VVEVTKSBwcml2YXRlIF9tYXhJbmFjdGl2aXR5OiBudW1iZXIsXHJcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChBVVRIRU5USUNBVElPTl9VU0VSX0NPVU5URE9XTl9TRUNPTkRTKSBwcml2YXRlIF91c2VyQ291bnRkb3duU2Vjb25kczogbnVtYmVyLFxyXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQVVUSEVOVElDQVRJT05fSURQX0lOQUNUSVZJVFlfTUlOVVRFUykgcHJpdmF0ZSBfaWRwSW5hY3Rpdml0eU1pbnV0ZXM6IG51bWJlcixcclxuICAgICAgICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KExvY2F0aW9uU3RyYXRlZ3kpIHByaXZhdGUgbG9jYXRpb25TdHJhdGVneTogTG9jYXRpb25TdHJhdGVneSkge1xyXG4gICAgaWYgKGlzRGV2TW9kZSgpKSB7XHJcbiAgICAgIGNvbnNvbGUuZGVidWcoXCJ3aW5kb3cubG9jYXRpb24uaHJlZjogXCIgKyB3aW5kb3cubG9jYXRpb24uaHJlZik7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHdpbmRvdy5sb2NhdGlvbikge1xyXG4gICAgICBsZXQgcGFydHM6IHN0cmluZ1tdID0gd2luZG93LmxvY2F0aW9uLmhyZWYuc3BsaXQoXCIvXCIpO1xyXG4gICAgICB0aGlzLmJhc2VVcmwgPSBwYXJ0c1swXSArIFwiLy9cIiArIHBhcnRzWzJdO1xyXG4gICAgICBpZiAocGFydHMubGVuZ3RoID4gMykge1xyXG4gICAgICAgIHRoaXMuY29udGV4dFJvb3QgPSBwYXJ0c1szXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9sb2NhbFN0b3JhZ2VTZXJ2aWNlLmdldEl0ZW0oXCJtYXhWaWV3UGVybWlzc2lvblwiKSkge1xyXG4gICAgICB0aGlzLm1heFZpZXdQZXJtaXNzaW9uLm5leHQoPFwidmlld1wiIHwgXCJ2aWV3aWRlbnRcIiB8IFwidmlld2xpbWl0ZWRcIj50aGlzLl9sb2NhbFN0b3JhZ2VTZXJ2aWNlLmdldEl0ZW0oXCJtYXhWaWV3UGVybWlzc2lvblwiKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKF9tYXhJbmFjdGl2aXR5KSB7XHJcbiAgICAgIHRoaXMuX21heEluYWN0aXZpdHlNaW51dGVzID0gX21heEluYWN0aXZpdHk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKF91c2VyQ291bnRkb3duU2Vjb25kcykge1xyXG4gICAgICB0aGlzLnVzZXJDb3VudGRvd25TZWNvbmRzID0gX3VzZXJDb3VudGRvd25TZWNvbmRzO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChfaWRwSW5hY3Rpdml0eU1pbnV0ZXMpIHtcclxuICAgICAgdGhpcy5pZHBJbmFjdGl2aXR5TWludXRlcyA9IF9pZHBJbmFjdGl2aXR5TWludXRlcztcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmhhc1ZhbGlkQ29uZmlnKCk7XHJcblxyXG4gICAgLy9UaGVyZSBjb3VsZCBiZSBhIG5vbi1leHBpcmVkIHRva2VuIGluIGxvY2FsIHN0b3JhZ2UuXHJcbiAgICBsZXQgdG9rZW46IHN0cmluZyA9IHRoaXMuYXV0aGVudGljYXRpb25Qcm92aWRlci5hdXRoVG9rZW47XHJcbiAgICB0aGlzLnN0b3JlVG9rZW4odG9rZW4pO1xyXG4gIH1cclxuXHJcbiAgZ2V0QmFzZVVybCgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuICh0aGlzLmJhc2VVcmwpID8gdGhpcy5iYXNlVXJsIDogXCJcIjtcclxuICB9XHJcblxyXG4gIGdldENvbnRleHRSb290KCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5jb250ZXh0Um9vdDtcclxuICB9XHJcblxyXG4gIGdldEhlYWRlcnMocmVxOiBIdHRwUmVxdWVzdDxhbnk+KTogSHR0cEhlYWRlcnMge1xyXG4gICAgbGV0IGhlYWRlcnM6IEh0dHBIZWFkZXJzID0gcmVxLmhlYWRlcnM7XHJcblxyXG4gICAgLy9Eb24ndCBzZXQgY29udGVudCB0eXBlIGlmIGFscmVhZHkgc2V0XHJcbiAgICBpZiAoIXJlcS5oZWFkZXJzLmdldChBdXRoZW50aWNhdGlvblNlcnZpY2UuQ09OVEVOVF9UWVBFKSkge1xyXG4gICAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLkNPTlRFTlRfVFlQRSwgdGhpcy5jb250ZW50VHlwZS50b1N0cmluZygpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaGVhZGVycy5nZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLlNFQ19HT1ZfQ0xBU1NfSEVBREVSKSA9PT0gXCJcIikge1xyXG4gICAgICBoZWFkZXJzID0gaGVhZGVycy5kZWxldGUoQXV0aGVudGljYXRpb25TZXJ2aWNlLlNFQ19HT1ZfQ0xBU1NfSEVBREVSKTtcclxuICAgIH0gZWxzZSBpZiAodGhpcy5zZWN1cml0eUdvdmVybm9yQ2xhc3MgJiYgIWhlYWRlcnMuZ2V0KEF1dGhlbnRpY2F0aW9uU2VydmljZS5TRUNfR09WX0NMQVNTX0hFQURFUikpIHtcclxuICAgICAgaGVhZGVycyA9IGhlYWRlcnMuc2V0KEF1dGhlbnRpY2F0aW9uU2VydmljZS5TRUNfR09WX0NMQVNTX0hFQURFUiwgdGhpcy5zZWN1cml0eUdvdmVybm9yQ2xhc3MpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChoZWFkZXJzLmdldChBdXRoZW50aWNhdGlvblNlcnZpY2UuU0VDX0dPVl9JRF9IRUFERVIpID09PSBcIlwiKSB7XHJcbiAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLmRlbGV0ZShBdXRoZW50aWNhdGlvblNlcnZpY2UuU0VDX0dPVl9JRF9IRUFERVIpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLnNlY3VyaXR5R292ZXJub3JJZCAmJiAhaGVhZGVycy5nZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLlNFQ19HT1ZfSURfSEVBREVSKSkge1xyXG4gICAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLlNFQ19HT1ZfSURfSEVBREVSLCB0aGlzLnNlY3VyaXR5R292ZXJub3JJZC50b1N0cmluZygpKTtcclxuICAgIH1cclxuXHJcbiAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLkRFSURFTlRfSEVBREVSLCB0aGlzLmRlaWRlbnRpZmllZENvbnRleHQudG9TdHJpbmcoKSk7XHJcbiAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLkxJTUlURURfSEVBREVSLCB0aGlzLmxpbWl0ZWRDb250ZXh0LnRvU3RyaW5nKCkpO1xyXG5cclxuICAgIHJldHVybiBoZWFkZXJzO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGF1dGhlbnRpY2F0aW9uVG9rZW5LZXkoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLmF1dGhlbnRpY2F0aW9uUHJvdmlkZXIuYXV0aGVudGljYXRpb25Ub2tlbktleTtcclxuICB9XHJcblxyXG4gIGdldCBhdXRoVG9rZW4oKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLmF1dGhlbnRpY2F0aW9uUHJvdmlkZXIuYXV0aFRva2VuO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHVwZGF0ZVVzZXJBY3Rpdml0eSgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLl9pc0F1dGhlbnRpY2F0ZWRTdWJqZWN0LnZhbHVlKSB7XHJcbiAgICAgIHRoaXMuX2xhc3RVc2VySW50ZXJhY3Rpb24gPSBuZXcgRGF0ZSgpO1xyXG4gICAgICB0aGlzLl91c2VySXNBYm91dFRvVGltZU91dC5uZXh0KGZhbHNlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEEgbXV0YXRvciBmb3IgaWRlbnRpZnlpbmcgdGhlIGNsaWVudHMgb3JpZ2luYWwgcmVxdWVzdCBsb2NhdGlvbi4gU2V0dGluZyB0aGlzIHZhbHVlIHdpbGwgaW5mbHVlbmNlIHRoZSBlbmQgbG9jYXRpb25cclxuICAgKiBuYXZpZ2F0ZWQgdG8gYnkge0BsaW5rICNuYXZpZ2F0ZVRvUGF0aH0uXHJcbiAgICpcclxuICAgKiBAcGFyYW0gcmVkaXJlY3RVcmwgbG9jYXRpb24gb2YgdGhlIHVzZXJzIHJlcXVlc3QgYmVmb3JlIGF1dGhlbnRpY2F0aW9uXHJcbiAgICovXHJcbiAgc2V0IHJlZGlyZWN0VXJsKHJlZGlyZWN0VXJsOiBzdHJpbmcpIHtcclxuICAgIHRoaXMuX3JlZGlyZWN0VXJsID0gcmVkaXJlY3RVcmw7XHJcbiAgfVxyXG5cclxuICBnZXQgcmVkaXJlY3RVcmwoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fcmVkaXJlY3RVcmw7XHJcbiAgfVxyXG5cclxuICByZXF1ZXN0QWNjZXNzVG9rZW4ocmVkaXJlY3RPblN1Y2Nlc3M6IGJvb2xlYW4pOiB2b2lkIHtcclxuXHJcbiAgICB0aGlzLl9odHRwLmdldCh0aGlzLnRva2VuTG9jYXRpb24oKSwge3dpdGhDcmVkZW50aWFsczogdHJ1ZX0pXHJcbiAgICAgIC5zdWJzY3JpYmUoXHJcbiAgICAgICAgKHJlc3BvbnNlOiBhbnkpID0+IHtcclxuICAgICAgICAgIHRoaXMuc3RvcmVUb2tlbihyZXNwb25zZS5hdXRoX3Rva2VuKTtcclxuICAgICAgICAgIGlmIChyZWRpcmVjdE9uU3VjY2Vzcykge1xyXG4gICAgICAgICAgICB0aGlzLnByb2NlZWRJZkF1dGhlbnRpY2F0ZWQoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgLy9Ub2tlbiByZWZyZXNoIGZhaWxlZC5cclxuICAgICAgICAgIHRoaXMubG9nb3V0KHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFZlcmlmaWVzIHdoZXRoZXIgb3Igbm90IGEgY3VycmVudCB1c2VyIHNlc3Npb24gZXhpc3RzLlxyXG4gICAqXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGU8Ym9vbGVhbj59IGV2YWx1YXRlcyB0byB0cnVlIGlmIHRoZSB1c2VyIGlzIGF1dGhlbnRpY2F0ZWQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgKi9cclxuICBpc0F1dGhlbnRpY2F0ZWQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XHJcbiAgICByZXR1cm4gdGhpcy5faXNBdXRoZW50aWNhdGVkU3ViamVjdC5hc09ic2VydmFibGUoKTtcclxuICB9XHJcblxyXG4gIGlzQWJvdXRUb1RpbWVPdXQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XHJcbiAgICByZXR1cm4gdGhpcy5fdXNlcklzQWJvdXRUb1RpbWVPdXQuYXNPYnNlcnZhYmxlKCk7XHJcbiAgfVxyXG5cclxuICBnZXRUaW1lb3V0U3RhcnQoKTogbnVtYmVyIHtcclxuICAgIGlmICh0aGlzLl9sYXN0VXNlckludGVyYWN0aW9uKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9sYXN0VXNlckludGVyYWN0aW9uLnZhbHVlT2YoKSArICgoKHRoaXMuX21heEluYWN0aXZpdHlNaW51dGVzICogNjApIC0gdGhpcy51c2VyQ291bnRkb3duU2Vjb25kcykgKiAxMDAwKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHRva2VuTG9jYXRpb24oKTogc3RyaW5nIHtcclxuICAgIGlmICh0aGlzLl9zZXJ2ZXJVcmwpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX3NlcnZlclVybCArIHRoaXMuX3Rva2VuRW5kcG9pbnQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gdGhpcy5fdG9rZW5FbmRwb2ludDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGRpcmVjdExvZ2luTG9jYXRpb24oKTogc3RyaW5nIHtcclxuICAgIGlmICh0aGlzLl9zZXJ2ZXJVcmwpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX3NlcnZlclVybCArIHRoaXMuX2RpcmVjdEVuZHBvaW50O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX2RpcmVjdEVuZHBvaW50O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbG9nb3V0TG9jYXRpb24oKTogc3RyaW5nIHtcclxuICAgIGlmICh0aGlzLl9zZXJ2ZXJVcmwpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX3NlcnZlclVybCArIHRoaXMuX2xvZ291dFBhdGg7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gdGhpcy5fbG9nb3V0UGF0aDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEEgZnVuY3Rpb24gdG8gYXV0aGVudGljYXRlZCB0aGUgdXNlciB3aXRoIHRoZSBwcm92aWRlZCBjcmVkZW50aWFscy4gRmFpbHVyZSByZXN1bHRzIGluIGFuIGVycm9yIHRoYXQgZGVzY3JpYmVzIHRoZVxyXG4gICAqIHNlcnZlciByZXNwb25zZSAoc3RhdHVzIGFuZCBzdGF0dXMgbWVzc2FnZSkgYW5kIHNob3VsZCBiZSBhY3Rpb25hYmxlIGJ5IHRoZSBjbGllbnQgYXBwbGljYXRpb24uXHJcbiAgICpcclxuICAgKiBAcGFyYW0gdXNlcm5hbWUgb2YgdGhlIGF1dGhlbnRpY2F0aW5nIHVzZXIgdG8gdmVyaWZ5XHJcbiAgICogQHBhcmFtIHBhc3N3b3JkIG9mIHRoZSBhdXRoZW50aWNhdGluZyB1c2VyIHRvIHZlcmlmeVxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlPFI+fSBkZXNjcmliaW5nIHRoZSByZXN1bHQgb2YgdGhlIGxvZ2luIGFjdGlvbiwgdHJ1ZSBvciBhbiBlcnJvclxyXG4gICAqL1xyXG4gIGxvZ2luKF91c2VybmFtZTogc3RyaW5nLCBfcGFzc3dvcmQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2h0dHAucG9zdChcclxuICAgICAgdGhpcy5kaXJlY3RMb2dpbkxvY2F0aW9uKCksXHJcbiAgICAgIHt1c2VybmFtZTogX3VzZXJuYW1lLCBwYXNzd29yZDogX3Bhc3N3b3JkfSxcclxuICAgICAge29ic2VydmU6IFwicmVzcG9uc2VcIn1cclxuICAgICkucGlwZShtYXAoKHJlc3A6IEh0dHBSZXNwb25zZTxhbnk+KSA9PiB7XHJcbiAgICAgIGlmIChyZXNwLnN0YXR1cyA9PT0gMjAxKSB7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQXV0aGVudGljYXRpb24gZmFpbGVkLiBcIiArIHJlc3Auc3RhdHVzICsgXCI6IFwiICsgcmVzcC5zdGF0dXNUZXh0KTtcclxuICAgICAgfVxyXG4gICAgfSksXHJcbiAgICAgIGNhdGNoRXJyb3IodGhpcy5oYW5kbGVFcnJvcikpO1xyXG4gIH1cclxuXHJcblxyXG4gIGNsZWFyTG9naW4oKTogT2JzZXJ2YWJsZTxSZXNwb25zZT4ge1xyXG4gICAgLy9Gcm9udC1lbmQgbG9nb3V0XHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLl9sb2NhbFN0b3JhZ2VTZXJ2aWNlLnJlbW92ZUl0ZW0odGhpcy5hdXRoZW50aWNhdGlvblByb3ZpZGVyLmF1dGhlbnRpY2F0aW9uVG9rZW5LZXkpO1xyXG4gICAgICB0aGlzLnVuc3Vic2NyaWJlRnJvbVRva2VuUmVmcmVzaCgpO1xyXG4gICAgICB0aGlzLl9pc0F1dGhlbnRpY2F0ZWRTdWJqZWN0Lm5leHQoZmFsc2UpO1xyXG4gICAgICB0aGlzLl91c2VySXNBYm91dFRvVGltZU91dC5uZXh0KGZhbHNlKTtcclxuICAgIH0gY2F0Y2ggKEVycm9yKSB7XHJcbiAgICB9XHJcblxyXG4gICAgLy9CYWNrLWVuZCBsb2dvdXRcclxuICAgIGxldCBoZWFkZXJzID0gbmV3IEh0dHBIZWFkZXJzKCkuc2V0KEF1dGhlbnRpY2F0aW9uU2VydmljZS5DT05URU5UX1RZUEUsIFwidGV4dC9wbGFpblwiKTtcclxuICAgIHJldHVybiA8T2JzZXJ2YWJsZTxSZXNwb25zZT4+dGhpcy5faHR0cC5nZXQodGhpcy5sb2dvdXRMb2NhdGlvbigpLCB7aGVhZGVyczogaGVhZGVyc30pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQSBmdW5jdGlvbiB0byBzaWduYWwgdGhlIHRlcm1pbmF0aW9uIG9mIHRoZSBjdXJyZW50IHNlc3Npb24uIEludm9raW5nIHRoaXMgZnVuY3Rpb24gd2lsbCBjbGVhbiB1cCBhbnkgcmVsZXZhbnQgc3RhdGVcclxuICAgKiByZWxhdGVkIHRvIHRoZSBsYXN0IGFjdGl2ZSBzZXNzaW9uLlxyXG4gICAqL1xyXG4gIGxvZ291dChrZWVwQ3VycmVudFJvdXRlOiBib29sZWFuID0gZmFsc2UpOiB2b2lkIHtcclxuICAgIC8vUHJldmVudCBsb2dvdXQgaWYgYWxyZWFkeSBvbiBhdXRoZW50aWNhdGlvbiByb3V0ZS4gRG9pbmcgb3RoZXJ3aXNlIHNjcmV3cyB1cCBTQU1MXHJcbiAgICBpZiAoISB0aGlzLl9yb3V0ZXIucm91dGVyU3RhdGUgfHwgdGhpcy5fcm91dGVyLnJvdXRlclN0YXRlLnNuYXBzaG90LnVybCAhPT0gdGhpcy5fYXV0aGVudGljYXRpb25Sb3V0ZSkge1xyXG4gICAgICB0aGlzLl9yZWRpcmVjdFVybCA9IChrZWVwQ3VycmVudFJvdXRlICYmIHRoaXMuX3JvdXRlci5yb3V0ZXJTdGF0ZSAmJiB0aGlzLl9yb3V0ZXIucm91dGVyU3RhdGUuc25hcHNob3QpID8gdGhpcy5fcm91dGVyLnJvdXRlclN0YXRlLnNuYXBzaG90LnVybCA6IFwiXCI7XHJcblxyXG4gICAgICBpZiAodGhpcy5fcmVkaXJlY3RVcmwuc3RhcnRzV2l0aChcIi9cIikpIHtcclxuICAgICAgICB0aGlzLl9yZWRpcmVjdFVybCA9IHRoaXMuX3JlZGlyZWN0VXJsLnN1YnN0cmluZygxKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5jbGVhckxvZ2luKCkuc3Vic2NyaWJlKFxyXG4gICAgICAgIChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgd2luZG93LmxvY2F0aW9uLnJlcGxhY2UodGhpcy5fcmVkaXJlY3RVcmwpO1xyXG4gICAgICAgICAgfSxcclxuICAgICAgICAoZXJyb3IpID0+IHtcclxuICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKHRoaXMuX3JlZGlyZWN0VXJsKTtcclxuICAgICAgICB9XHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzdG9yZVRva2VuKHRva2VuOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGxldCB2YWxpZCA9IHRoaXMudmFsaWRhdGVUb2tlbih0b2tlbik7XHJcblxyXG4gICAgLy8gdW5zdWJzY3JpYmUgZnJvbSByZWZlc2ggYmVmb3JlIHdlIGRlY2lkZSB3ZXRoZXIgdG8gcmVzdWJzY3JpYmVcclxuICAgIHRoaXMudW5zdWJzY3JpYmVGcm9tVG9rZW5SZWZyZXNoKCk7XHJcblxyXG4gICAgaWYgKHZhbGlkKSB7XHJcbiAgICAgIHRoaXMuX2xvY2FsU3RvcmFnZVNlcnZpY2Uuc2V0SXRlbSh0aGlzLmF1dGhlbnRpY2F0aW9uUHJvdmlkZXIuYXV0aGVudGljYXRpb25Ub2tlbktleSwgdG9rZW4pO1xyXG4gICAgICB0aGlzLnN1YnNjcmliZVRvVG9rZW5SZWZyZXNoKHRva2VuKTtcclxuXHJcbiAgICAgIC8vQ2hhbmdlIHRoZSBCZWhhdmlvclN1YmplY3QgaWYgdGhlIHVzZXIgd2FzIG5vdCBwcmV2aW91c2x5IGF1dGhlbnRpY2F0ZWQuXHJcbiAgICAgIC8vU2luY2Ugb3RoZXIgY29kZSBtYXkgYmUgc3Vic2NyaWJpbmcgdG8gdGhpcyBvYnNlcnZhYmxlLCB3ZSBkb24ndCB3YW50IHRvIGNhdXNlIG5ldyBldmVudHMgdG8gZmlyZSBpZiBqdXN0IHJlZnJlc2hpbmcgdGhlIEpXVC5cclxuICAgICAgaWYgKCEgdGhpcy5faXNBdXRoZW50aWNhdGVkU3ViamVjdC52YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX2lzQXV0aGVudGljYXRlZFN1YmplY3QubmV4dCh0cnVlKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5fbG9jYWxTdG9yYWdlU2VydmljZS5yZW1vdmVJdGVtKHRoaXMuYXV0aGVudGljYXRpb25Qcm92aWRlci5hdXRoZW50aWNhdGlvblRva2VuS2V5KTtcclxuICAgICAgdGhpcy5faXNBdXRoZW50aWNhdGVkU3ViamVjdC5uZXh0KGZhbHNlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByb2NlZWRJZkF1dGhlbnRpY2F0ZWQoKTogYm9vbGVhbiB7XHJcbiAgICBpZiAoaXNEZXZNb2RlKCkpIHtcclxuICAgICAgY29uc29sZS5kZWJ1ZyhcIkF1dGhlbnRpY2F0aW9uU2VydmljZS5wcm9jZWVkSWZBdXRoZW50aWNhdGVkOiBcIiArIHRoaXMuX3JlZGlyZWN0VXJsKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5faXNBdXRoZW50aWNhdGVkU3ViamVjdC52YWx1ZSkge1xyXG4gICAgICAvL0xvZ2luIGNvdW50cyBhcyB1c2VyIGFjdGl2aXR5LCB0b29cclxuICAgICAgdGhpcy51cGRhdGVVc2VyQWN0aXZpdHkoKTtcclxuXHJcbiAgICAgIGlmICh0aGlzLl9yZWRpcmVjdFVybCAmJiB0aGlzLl9yZWRpcmVjdFVybCAmJiB0aGlzLl9yZWRpcmVjdFVybCAhPT0gXCJcIikge1xyXG4gICAgICAgIHRoaXMuX3JvdXRlci5uYXZpZ2F0ZUJ5VXJsKHRoaXMuX3JlZGlyZWN0VXJsKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLl9yb3V0ZXIubmF2aWdhdGUoW1wiXCJdKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB2YWxpZGF0ZVRva2VuKHRva2VuOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIHJldHVybiAodG9rZW4gJiYgIXRoaXMuX2p3dEhlbHBlci5pc1Rva2VuRXhwaXJlZCh0b2tlbikpO1xyXG4gIH1cclxuXHJcbiAgc3Vic2NyaWJlVG9Ub2tlblJlZnJlc2godG9rZW46IGFueSk6IHZvaWQge1xyXG4gICAgbGV0IGV4cCA9IHRoaXMuX2p3dEhlbHBlci5nZXRUb2tlbkV4cGlyYXRpb25EYXRlKHRva2VuKTtcclxuXHJcbiAgICAvLyBVc2UgYSB0aW1lciB0byBwZXJpb2RpY2FsbHkgY2hlY2sgdGltZW91dHNcclxuICAgIHRoaXMuX3JlZnJlc2hTdWJzY3JpcHRpb24gPSBpbnRlcnZhbCgxMDAwKVxyXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuXHJcbiAgICAgICAgLy8gSWYgYSB0YWIgaXMgaW5hY3RpdmUgd2UgY2FuJ3Qga25vdyBpZiBvdXIgdGltZXIgaXMgYWNjdXJhdGVcclxuICAgICAgICAvLyBzbyB3aGVuIHRoZSBpbnRlcnZhbCBoaXRzIGNoZWNrIGFnYWluc3QgdGltZXN0YW1wc1xyXG4gICAgICAgIGlmICh0aGlzLl9pc0F1dGhlbnRpY2F0ZWRTdWJqZWN0LnZhbHVlICYmIERhdGUubm93KCkgPiB0aGlzLmdldFRpbWVvdXRTdGFydCgpKSB7XHJcbiAgICAgICAgICAvL0Rvbid0IHVwZGF0ZSB0aGUgc3ViamVjdCBtb3JlIHRoYW4gb25jZSEgRG9pbmcgc28gaW5pdGlhbGl6ZXMgbW9yZSB0aGFuIG9uZSBjb3VudGRvd24gdGltZXIhXHJcbiAgICAgICAgICBpZiAodGhpcy5fdXNlcklzQWJvdXRUb1RpbWVPdXQuZ2V0VmFsdWUoKSAhPT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl91c2VySXNBYm91dFRvVGltZU91dC5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gY2hlY2sgZm9yIHJlZnJlc2ggdG9rZW5cclxuICAgICAgICBsZXQgbXNUb0V4cGlyeSA9IChleHAudmFsdWVPZigpIC0gbmV3IERhdGUoKS52YWx1ZU9mKCkpO1xyXG5cclxuICAgICAgICAvLyBSZWZyZXNoIDYwIHNlY29uZHMgYmVmb3JlIGV4cGlyeVxyXG4gICAgICAgIGlmIChtc1RvRXhwaXJ5IDw9IDYwMDAwKSB7XHJcbiAgICAgICAgICB0aGlzLnJlZnJlc2hUb2tlbklmVXNlcklzQWN0aXZlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIHVuc3Vic2NyaWJlRnJvbVRva2VuUmVmcmVzaCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLl9yZWZyZXNoU3Vic2NyaXB0aW9uICYmICEgdGhpcy5fcmVmcmVzaFN1YnNjcmlwdGlvbi5jbG9zZWQpIHtcclxuICAgICAgdGhpcy5fcmVmcmVzaFN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0TWF4Vmlld1Blcm1pc3Npb24oKTogXCJ2aWV3XCIgfCBcInZpZXdpZGVudFwiIHwgXCJ2aWV3bGltaXRlZFwiIHtcclxuICAgIHJldHVybiB0aGlzLm1heFZpZXdQZXJtaXNzaW9uLmdldFZhbHVlKCk7XHJcbiAgfVxyXG5cclxuICBnZXRNYXhWaWV3UGVybWlzc2lvblN1YmplY3QoKTogQmVoYXZpb3JTdWJqZWN0PFwidmlld1wiIHwgXCJ2aWV3aWRlbnRcIiB8IFwidmlld2xpbWl0ZWRcIj4ge1xyXG4gICAgcmV0dXJuIHRoaXMubWF4Vmlld1Blcm1pc3Npb247XHJcbiAgfVxyXG5cclxuICBzZXRNYXhWaWV3UGVybWlzc2lvbihtYXhWaWV3UGVybWlzc2lvbjogXCJ2aWV3XCIgfCBcInZpZXdpZGVudFwiIHwgXCJ2aWV3bGltaXRlZFwiKTogdm9pZCB7XHJcbiAgICB0aGlzLl9sb2NhbFN0b3JhZ2VTZXJ2aWNlLnNldEl0ZW0oXCJtYXhWaWV3UGVybWlzc2lvblwiLCBtYXhWaWV3UGVybWlzc2lvbik7XHJcbiAgICB0aGlzLm1heFZpZXdQZXJtaXNzaW9uLm5leHQobWF4Vmlld1Blcm1pc3Npb24pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZWZyZXNoVG9rZW5JZlVzZXJJc0FjdGl2ZSgpOiB2b2lkIHtcclxuICAgIC8vT25seSByZWZyZXNoIGlmIHRoZSB1c2VyIGhhcyBiZWVuIGFjdGl2ZVxyXG4gICAgaWYgKHRoaXMuX2xhc3RVc2VySW50ZXJhY3Rpb24gJiYgKChuZXcgRGF0ZSgpLnZhbHVlT2YoKSAtIHRoaXMuX2xhc3RVc2VySW50ZXJhY3Rpb24udmFsdWVPZigpKSA8PSAodGhpcy5fbWF4SW5hY3Rpdml0eU1pbnV0ZXMgKiA2MCAqIDEwMDApKSkge1xyXG4gICAgICB0aGlzLnJlcXVlc3RBY2Nlc3NUb2tlbihmYWxzZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGhhc1ZhbGlkQ29uZmlnKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuX3Rva2VuRW5kcG9pbnQgPT0gbnVsbCAmJiAodGhpcy5fc2VydmVyVXJsID09PSBudWxsIHx8IHRoaXMuX2xvZ291dFBhdGggPT09IG51bGwpKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkJVRyBBTEVSVCEgSW52YWxpZCBBdXRoZW50aWNhdGlvblNlcnZpY2UgY29uZmlndXJhdGlvbi4gTm8gdmFsaWQgY29uZmlndXJhdGlvbiBmb3IgYXV0aGVudGljYXRpb24gZW5kcG9pbnQocykuXCIpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuX2xvY2FsU3RvcmFnZVNlcnZpY2UgPT09IG51bGwgfHwgdGhpcy5hdXRoZW50aWNhdGlvblByb3ZpZGVyLmF1dGhlbnRpY2F0aW9uVG9rZW5LZXkgPT09IG51bGwpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQlVHIEFMRVJUISBJbnZhbGlkIEF1dGhlbnRpY2F0aW9uU2VydmljZSBjb25maWd1cmF0aW9uLiBObyB2YWxpZCBjb25maWd1cmF0aW9uIGZvciBsb2NhbCBzdG9yYWdlXCIpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBoYW5kbGVFcnJvcihlcnJvcjogYW55KSA6IE9ic2VydmFibGU8bmV2ZXI+IHtcclxuICAgIGxldCBlcnJNc2cgPSAoZXJyb3IubWVzc2FnZSkgPyBlcnJvci5tZXNzYWdlIDogQXV0aGVudGljYXRpb25TZXJ2aWNlLkdFTkVSSUNfRVJSX01TRztcclxuICAgIHJldHVybiB0aHJvd0Vycm9yKGVyck1zZyk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Injectable, Injector, isDevMode } from "@angular/core";
|
|
2
|
+
import { throwError } from "rxjs";
|
|
3
|
+
import { catchError } from "rxjs/operators";
|
|
4
|
+
import { AuthenticationService } from "./authentication.service";
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export class AuthorizationInterceptor {
|
|
7
|
+
constructor(injector) {
|
|
8
|
+
this.injector = injector;
|
|
9
|
+
}
|
|
10
|
+
intercept(req, next) {
|
|
11
|
+
if (isDevMode()) {
|
|
12
|
+
console.debug("AuthorizationInterceptor.intercept");
|
|
13
|
+
}
|
|
14
|
+
let authService = this.injector.get(AuthenticationService);
|
|
15
|
+
//Don't want to include background token refreshes in considering the user 'active'
|
|
16
|
+
if (req.url !== authService.tokenLocation()) {
|
|
17
|
+
//Update user activity. Done here instead of the previous method using a subscription to a subject in AuthenticationProvider
|
|
18
|
+
authService.updateUserActivity();
|
|
19
|
+
}
|
|
20
|
+
let headers = authService.getHeaders(req);
|
|
21
|
+
let url = req.url;
|
|
22
|
+
if (url.startsWith("/")) {
|
|
23
|
+
url = authService.getBaseUrl() + url;
|
|
24
|
+
}
|
|
25
|
+
else if (!url.startsWith("http")) {
|
|
26
|
+
if (authService.getContextRoot().length > 0) {
|
|
27
|
+
url = authService.getBaseUrl() + "/" + authService.getContextRoot() + "/" + url;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
url = authService.getBaseUrl() + "/" + url;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
let params = req.params;
|
|
34
|
+
if (url.indexOf("/crud/") > 0) {
|
|
35
|
+
params = params.set("maxViewPermission", authService.getMaxViewPermission());
|
|
36
|
+
}
|
|
37
|
+
let reqClone = req.clone({
|
|
38
|
+
url: url,
|
|
39
|
+
withCredentials: true,
|
|
40
|
+
headers: headers,
|
|
41
|
+
params: params
|
|
42
|
+
});
|
|
43
|
+
return next.handle(reqClone)
|
|
44
|
+
.pipe(catchError((error) => {
|
|
45
|
+
if (isDevMode()) {
|
|
46
|
+
console.error("AuthorizationInterceptor.error");
|
|
47
|
+
console.error(error);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* If the token is not authenticated which angular does not know about, then a REST request to the backend will
|
|
51
|
+
* return a 401. To duplicate this, open Core in two tabs. In one tab, logout, in the other, perform a request
|
|
52
|
+
* that hits a protected resource.
|
|
53
|
+
*/
|
|
54
|
+
if (error.status === 401) {
|
|
55
|
+
authService.isAuthenticated().subscribe((authenticated) => {
|
|
56
|
+
if (authenticated) {
|
|
57
|
+
// If authenticated, then logout which will redirect.
|
|
58
|
+
authService.logout(true);
|
|
59
|
+
return throwError(error.message);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// Otherwise, for example, when the user first opens Core, 401s are expected.
|
|
63
|
+
return throwError(error);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
if (error.status === 403) {
|
|
68
|
+
// TODO: Trigger notification for unauthorized.
|
|
69
|
+
}
|
|
70
|
+
return throwError(error);
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
AuthorizationInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AuthorizationInterceptor, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
75
|
+
AuthorizationInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AuthorizationInterceptor });
|
|
76
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AuthorizationInterceptor, decorators: [{
|
|
77
|
+
type: Injectable
|
|
78
|
+
}], ctorParameters: function () { return [{ type: i0.Injector }]; } });
|
|
79
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aG9yaXphdGlvbi5pbnRlcmNlcHRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2F1dGhlbnRpY2F0aW9uL3NyYy9hdXRob3JpemF0aW9uLmludGVyY2VwdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxVQUFVLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUc5RCxPQUFPLEVBQWEsVUFBVSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzVDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUUxQyxPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQzs7QUFHL0QsTUFBTSxPQUFPLHdCQUF3QjtJQUVuQyxZQUFvQixRQUFrQjtRQUFsQixhQUFRLEdBQVIsUUFBUSxDQUFVO0lBQUcsQ0FBQztJQUUxQyxTQUFTLENBQUMsR0FBcUIsRUFBRSxJQUFpQjtRQUNoRCxJQUFJLFNBQVMsRUFBRSxFQUFFO1lBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO1NBQ3JEO1FBRUQsSUFBSSxXQUFXLEdBQTBCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFFbEYsbUZBQW1GO1FBQ25GLElBQUksR0FBRyxDQUFDLEdBQUcsS0FBSyxXQUFXLENBQUMsYUFBYSxFQUFFLEVBQUU7WUFDM0MsNEhBQTRIO1lBQzVILFdBQVcsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1NBQ2xDO1FBRUQsSUFBSSxPQUFPLEdBQWdCLFdBQVcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkQsSUFBSSxHQUFHLEdBQVcsR0FBRyxDQUFDLEdBQUcsQ0FBQztRQUMxQixJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDdkIsR0FBRyxHQUFHLFdBQVcsQ0FBQyxVQUFVLEVBQUUsR0FBRyxHQUFHLENBQUM7U0FDdEM7YUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNsQyxJQUFJLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUMzQyxHQUFHLEdBQUcsV0FBVyxDQUFDLFVBQVUsRUFBRSxHQUFHLEdBQUcsR0FBRyxXQUFXLENBQUMsY0FBYyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQzthQUNqRjtpQkFBTTtnQkFDTCxHQUFHLEdBQUcsV0FBVyxDQUFDLFVBQVUsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7YUFDNUM7U0FDRjtRQUVELElBQUksTUFBTSxHQUFlLEdBQUcsQ0FBQyxNQUFNLENBQUM7UUFDcEMsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUM3QixNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxXQUFXLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1NBQzlFO1FBRUQsSUFBSSxRQUFRLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQztZQUN2QixHQUFHLEVBQUUsR0FBRztZQUNSLGVBQWUsRUFBRSxJQUFJO1lBQ3JCLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLE1BQU0sRUFBRSxNQUFNO1NBQ2YsQ0FBQyxDQUFDO1FBRUgsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQzthQUN6QixJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDekIsSUFBSSxTQUFTLEVBQUUsRUFBRTtnQkFDZixPQUFPLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7Z0JBQ2hELE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDdEI7WUFFRDs7OztlQUlHO1lBQ0gsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLEdBQUcsRUFBRTtnQkFDeEIsV0FBVyxDQUFDLGVBQWUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLGFBQWEsRUFBRSxFQUFFO29CQUN4RCxJQUFJLGFBQWEsRUFBRTt3QkFDakIscURBQXFEO3dCQUNyRCxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO3dCQUN6QixPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7cUJBQ2xDO3lCQUFNO3dCQUNMLDZFQUE2RTt3QkFDN0UsT0FBTyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQzFCO2dCQUNILENBQUMsQ0FBQyxDQUFDO2FBQ0o7WUFDRCxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFO2dCQUN4QiwrQ0FBK0M7YUFDaEQ7WUFDRCxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQzs7cUhBdEVVLHdCQUF3Qjt5SEFBeEIsd0JBQXdCOzJGQUF4Qix3QkFBd0I7a0JBRHBDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdGFibGUsIEluamVjdG9yLCBpc0Rldk1vZGV9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCB7SHR0cFJlcXVlc3QsIEh0dHBIYW5kbGVyLCBIdHRwRXZlbnQsIEh0dHBJbnRlcmNlcHRvciwgSHR0cEhlYWRlcnMsIEh0dHBQYXJhbXN9IGZyb20gXCJAYW5ndWxhci9jb21tb24vaHR0cFwiO1xyXG5cclxuaW1wb3J0IHtPYnNlcnZhYmxlLCB0aHJvd0Vycm9yfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQge2NhdGNoRXJyb3J9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xyXG5cclxuaW1wb3J0IHtBdXRoZW50aWNhdGlvblNlcnZpY2V9IGZyb20gXCIuL2F1dGhlbnRpY2F0aW9uLnNlcnZpY2VcIjtcclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIEF1dGhvcml6YXRpb25JbnRlcmNlcHRvciBpbXBsZW1lbnRzIEh0dHBJbnRlcmNlcHRvciB7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaW5qZWN0b3I6IEluamVjdG9yKSB7fVxyXG5cclxuICBpbnRlcmNlcHQocmVxOiBIdHRwUmVxdWVzdDxhbnk+LCBuZXh0OiBIdHRwSGFuZGxlcik6IE9ic2VydmFibGU8SHR0cEV2ZW50PGFueT4+IHtcclxuICAgIGlmIChpc0Rldk1vZGUoKSkge1xyXG4gICAgICBjb25zb2xlLmRlYnVnKFwiQXV0aG9yaXphdGlvbkludGVyY2VwdG9yLmludGVyY2VwdFwiKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgbGV0IGF1dGhTZXJ2aWNlOiBBdXRoZW50aWNhdGlvblNlcnZpY2UgPSB0aGlzLmluamVjdG9yLmdldChBdXRoZW50aWNhdGlvblNlcnZpY2UpO1xyXG4gICAgXHJcbiAgICAvL0Rvbid0IHdhbnQgdG8gaW5jbHVkZSBiYWNrZ3JvdW5kIHRva2VuIHJlZnJlc2hlcyBpbiBjb25zaWRlcmluZyB0aGUgdXNlciAnYWN0aXZlJ1xyXG4gICAgaWYgKHJlcS51cmwgIT09IGF1dGhTZXJ2aWNlLnRva2VuTG9jYXRpb24oKSkge1xyXG4gICAgICAvL1VwZGF0ZSB1c2VyIGFjdGl2aXR5LiBEb25lIGhlcmUgaW5zdGVhZCBvZiB0aGUgcHJldmlvdXMgbWV0aG9kIHVzaW5nIGEgc3Vic2NyaXB0aW9uIHRvIGEgc3ViamVjdCBpbiBBdXRoZW50aWNhdGlvblByb3ZpZGVyXHJcbiAgICAgIGF1dGhTZXJ2aWNlLnVwZGF0ZVVzZXJBY3Rpdml0eSgpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBsZXQgaGVhZGVyczogSHR0cEhlYWRlcnMgPSBhdXRoU2VydmljZS5nZXRIZWFkZXJzKHJlcSk7XHJcbiAgICBsZXQgdXJsOiBzdHJpbmcgPSByZXEudXJsO1xyXG4gICAgaWYgKHVybC5zdGFydHNXaXRoKFwiL1wiKSkge1xyXG4gICAgICB1cmwgPSBhdXRoU2VydmljZS5nZXRCYXNlVXJsKCkgKyB1cmw7XHJcbiAgICB9IGVsc2UgaWYgKCF1cmwuc3RhcnRzV2l0aChcImh0dHBcIikpIHtcclxuICAgICAgaWYgKGF1dGhTZXJ2aWNlLmdldENvbnRleHRSb290KCkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHVybCA9IGF1dGhTZXJ2aWNlLmdldEJhc2VVcmwoKSArIFwiL1wiICsgYXV0aFNlcnZpY2UuZ2V0Q29udGV4dFJvb3QoKSArIFwiL1wiICsgdXJsO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHVybCA9IGF1dGhTZXJ2aWNlLmdldEJhc2VVcmwoKSArIFwiL1wiICsgdXJsO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHBhcmFtczogSHR0cFBhcmFtcyA9IHJlcS5wYXJhbXM7XHJcbiAgICBpZiAodXJsLmluZGV4T2YoXCIvY3J1ZC9cIikgPiAwKSB7XHJcbiAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoXCJtYXhWaWV3UGVybWlzc2lvblwiLCBhdXRoU2VydmljZS5nZXRNYXhWaWV3UGVybWlzc2lvbigpKTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgcmVxQ2xvbmUgPSByZXEuY2xvbmUoe1xyXG4gICAgICB1cmw6IHVybCxcclxuICAgICAgd2l0aENyZWRlbnRpYWxzOiB0cnVlLFxyXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzLFxyXG4gICAgICBwYXJhbXM6IHBhcmFtc1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIG5leHQuaGFuZGxlKHJlcUNsb25lKVxyXG4gICAgICAucGlwZShjYXRjaEVycm9yKChlcnJvcikgPT4ge1xyXG4gICAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xyXG4gICAgICAgICAgY29uc29sZS5lcnJvcihcIkF1dGhvcml6YXRpb25JbnRlcmNlcHRvci5lcnJvclwiKTtcclxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogSWYgdGhlIHRva2VuIGlzIG5vdCBhdXRoZW50aWNhdGVkIHdoaWNoIGFuZ3VsYXIgZG9lcyBub3Qga25vdyBhYm91dCwgdGhlbiBhIFJFU1QgcmVxdWVzdCB0byB0aGUgYmFja2VuZCB3aWxsXHJcbiAgICAgICAgICogcmV0dXJuIGEgNDAxLiAgVG8gZHVwbGljYXRlIHRoaXMsIG9wZW4gQ29yZSBpbiB0d28gdGFicy4gIEluIG9uZSB0YWIsIGxvZ291dCwgaW4gdGhlIG90aGVyLCBwZXJmb3JtIGEgcmVxdWVzdFxyXG4gICAgICAgICAqIHRoYXQgaGl0cyBhIHByb3RlY3RlZCByZXNvdXJjZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBpZiAoZXJyb3Iuc3RhdHVzID09PSA0MDEpIHtcclxuICAgICAgICAgIGF1dGhTZXJ2aWNlLmlzQXV0aGVudGljYXRlZCgpLnN1YnNjcmliZSgoYXV0aGVudGljYXRlZCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoYXV0aGVudGljYXRlZCkge1xyXG4gICAgICAgICAgICAgIC8vIElmIGF1dGhlbnRpY2F0ZWQsIHRoZW4gbG9nb3V0IHdoaWNoIHdpbGwgcmVkaXJlY3QuXHJcbiAgICAgICAgICAgICAgYXV0aFNlcnZpY2UubG9nb3V0KHRydWUpO1xyXG4gICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKGVycm9yLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgZm9yIGV4YW1wbGUsIHdoZW4gdGhlIHVzZXIgZmlyc3Qgb3BlbnMgQ29yZSwgNDAxcyBhcmUgZXhwZWN0ZWQuXHJcbiAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoZXJyb3IpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGVycm9yLnN0YXR1cyA9PT0gNDAzKSB7XHJcbiAgICAgICAgICAvLyBUT0RPOiBUcmlnZ2VyIG5vdGlmaWNhdGlvbiBmb3IgdW5hdXRob3JpemVkLlxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJvcik7XHJcbiAgICAgIH0pKTtcclxuICB9XHJcbn1cclxuIl19
|