@ebondu/angular2-keycloak
Version:
126 lines • 20.1 kB
JavaScript
/*
* Copyright 2024 ebondu and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { inject } from '@angular/core';
import { HttpErrorResponse, HttpEventType } from '@angular/common/http';
import { throwError } from 'rxjs';
import { KeycloakService } from '../service/keycloak.service';
import { catchError, filter, finalize, first, switchMap, tap } from 'rxjs/operators';
export const keycloakInterceptor = (req, next) => {
if (req.withCredentials && !req.headers.has('Authorization')) {
const keycloak = inject(KeycloakService);
keycloak.initializedObs.pipe(filter(initialized => initialized)).subscribe(initialized => {
keycloak.initializedAuthzObs.pipe(filter(authzInit => authzInit)).subscribe(authzInit => {
if (!keycloak.accessToken) {
// console.log('Login required...');
keycloak.login({});
}
});
});
let lastResponseWithToken;
let errorWithToken;
let lastResponseWithRptToken;
let errorWithRptToken;
return keycloak.authenticationObs.pipe(first(auth => auth), switchMap(initialized =>
// console.log('Using authz service...');
keycloak.updateToken(5).pipe(switchMap(token => {
const authToken = 'Bearer ' + token;
const authReq = req.clone({
headers: req.headers
.set('Authorization', authToken)
.set('Accept', 'application/json')
});
// const authReq = req.clone();
// send cloned request with header to the next handler.
// console.log('calling with auth token');
return next(authReq).pipe(tap(response => {
lastResponseWithToken = response;
// console.log('success with token response', response);
}), catchError((error) => {
errorWithToken = error;
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
// console.log('Need UMA authorization');
if (error.headers.has('WWW-Authenticate')) {
// console.log('using www-authenticate hearder');
return keycloak.authorize(error.headers.get('WWW-Authenticate'))
.pipe(filter(authorizedToken => !!authorizedToken), switchMap((authorizedToken) => {
// console.log('Using token from service after authz');
const authReqWithRpt = req.clone({
headers: req.headers
.set('Authorization', 'Bearer ' + authorizedToken)
.set('Accept', 'application/json')
});
return next(authReqWithRpt).pipe(tap((response) => {
lastResponseWithRptToken = response;
if (response.type === HttpEventType.Response) {
// console.log('success with rpt response', response);
}
}), catchError((err) => {
errorWithRptToken = err;
// console.log('error response', err);
return throwError(() => err);
}), finalize(() => {
if (lastResponseWithRptToken.type === HttpEventType.Sent && !errorWithRptToken) {
// last response type was 0, and we haven't received an error
// console.log('aborted with rpt request');
}
}));
}));
}
else {
return throwError(() => error);
}
}
else {
// console.log('Error while calling endpoint', error);
return throwError(() => error);
}
}
else {
return throwError(() => error);
}
}), finalize(() => {
if (lastResponseWithToken.type === HttpEventType.Sent && !errorWithToken) {
// last response type was 0, and we haven't received an error
// console.log('aborted with token request');
}
}));
}))));
}
else {
let lastResponse;
let error;
// console.log('calling without auth token');
return next(req).pipe(tap((response) => {
lastResponse = response;
if (response.type === HttpEventType.Response) {
// console.log('success response', response);
}
}), catchError((err) => {
error = err;
// console.log('error response', err);
// TODO: error handling if required
return throwError(() => error);
}), finalize(() => {
if (lastResponse.type === HttpEventType.Sent && !error) {
// last response type was 0, and we haven't received an error
// console.log('aborted request');
}
}));
}
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5Y2xvYWsuaW50ZXJjZXB0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9lYm9uZHUvYW5ndWxhci1rZXljbG9hay9zcmMvbGliL2ludGVyY2VwdG9yL2tleWNsb2FrLmludGVyY2VwdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkMsT0FBTyxFQUNMLGlCQUFpQixFQUVqQixhQUFhLEVBSWQsTUFBTSxzQkFBc0IsQ0FBQztBQUU5QixPQUFPLEVBQWMsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVyRixNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBc0IsQ0FBQyxHQUF5QixFQUFFLElBQW1CLEVBQWtDLEVBQUU7SUFDdkksSUFBSSxHQUFHLENBQUMsZUFBZSxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztRQUM3RCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDekMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLEVBQUU7WUFDdkYsUUFBUSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxT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LENBQUM7Z0JBQzdDLDZDQUE2QztZQUMvQyxDQUFDO1FBQ0gsQ0FBQyxDQUFDLEVBQ0YsVUFBVSxDQUFDLENBQUMsR0FBUSxFQUFFLEVBQUU7WUFDdEIsS0FBSyxHQUFHLEdBQUcsQ0FBQztZQUNaLHNDQUFzQztZQUN0QyxtQ0FBbUM7WUFDbkMsT0FBTyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakMsQ0FBQyxDQUFDLEVBQ0YsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUNaLElBQUksWUFBWSxDQUFDLElBQUksS0FBSyxhQUFhLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3ZELDZEQUE2RDtnQkFDN0Qsa0NBQWtDO1lBQ3BDLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgMjAyNCBlYm9uZHUgYW5kL29yIGl0cyBhZmZpbGlhdGVzXG4gKiBhbmQgb3RoZXIgY29udHJpYnV0b3JzIGFzIGluZGljYXRlZCBieSB0aGUgQGF1dGhvciB0YWdzLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgSHR0cEVycm9yUmVzcG9uc2UsXG4gIEh0dHBFdmVudCxcbiAgSHR0cEV2ZW50VHlwZSxcbiAgSHR0cEhhbmRsZXJGbixcbiAgSHR0cEludGVyY2VwdG9yRm4sXG4gIEh0dHBSZXF1ZXN0XG59IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgdGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgS2V5Y2xvYWtTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZS9rZXljbG9hay5zZXJ2aWNlJztcbmltcG9ydCB7IGNhdGNoRXJyb3IsIGZpbHRlciwgZmluYWxpemUsIGZpcnN0LCBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuZXhwb3J0IGNvbnN0IGtleWNsb2FrSW50ZXJjZXB0b3I6IEh0dHBJbnRlcmNlcHRvckZuID0gKHJlcTogSHR0cFJlcXVlc3Q8dW5rbm93bj4sIG5leHQ6IEh0dHBIYW5kbGVyRm4pOiBPYnNlcnZhYmxlPEh0dHBFdmVudDx1bmtub3duPj4gPT4ge1xuICBpZiAocmVxLndpdGhDcmVkZW50aWFscyAmJiAhcmVxLmhlYWRlcnMuaGFzKCdBdXRob3JpemF0aW9uJykpIHtcbiAgICBjb25zdCBrZXljbG9hayA9IGluamVjdChLZXljbG9ha1NlcnZpY2UpO1xuICAgIGtleWNsb2FrLmluaXRpYWxpemVkT2JzLnBpcGUoZmlsdGVyKGluaXRpYWxpemVkID0+IGluaXRpYWxpemVkKSkuc3Vic2NyaWJlKGluaXRpYWxpemVkID0+IHtcbiAgICAgIGtleWNsb2FrLmluaXRpYWxpemVkQXV0aHpPYnMucGlwZShmaWx0ZXIoYXV0aHpJbml0ID0+IGF1dGh6SW5pdCkpLnN1YnNjcmliZShhdXRoekluaXQgPT4ge1xuICAgICAgICBpZiAoIWtleWNsb2FrLmFjY2Vzc1Rva2VuKSB7XG4gICAgICAgICAgLy8gY29uc29sZS5sb2coJ0xvZ2luIHJlcXVpcmVkLi4uJyk7XG4gICAgICAgICAga2V5Y2xvYWsubG9naW4oe30pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBsZXQgbGFzdFJlc3BvbnNlV2l0aFRva2VuO1xuICAgIGxldCBlcnJvcldpdGhUb2tlbjtcbiAgICBsZXQgbGFzdFJlc3BvbnNlV2l0aFJwdFRva2VuO1xuICAgIGxldCBlcnJvcldpdGhScHRUb2tlbjtcbiAgICByZXR1cm4ga2V5Y2xvYWsuYXV0aGVudGljYXRpb25PYnMucGlwZShcbiAgICAgIGZpcnN0KGF1dGggPT4gYXV0aCksXG4gICAgICBzd2l0Y2hNYXAoaW5pdGlhbGl6ZWQgPT5cbiAgICAgICAgLy8gY29uc29sZS5sb2coJ1VzaW5nIGF1dGh6IHNlcnZpY2UuLi4nKTtcbiAgICAgICAga2V5Y2xvYWsudXBkYXRlVG9rZW4oNSkucGlwZShcbiAgICAgICAgICBzd2l0Y2hNYXAodG9rZW4gPT4ge1xuICAgICAgICAgICAgY29uc3QgYXV0aFRva2VuID0gJ0JlYXJlciAnICsgdG9rZW47XG4gICAgICAgICAgICBjb25zdCBhdXRoUmVxID0gcmVxLmNsb25lKHtcbiAgICAgICAgICAgICAgaGVhZGVyczogcmVxLmhlYWRlcnNcbiAgICAgICAgICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgYXV0aFRva2VuKVxuICAgICAgICAgICAgICAgIC5zZXQoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJylcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBjb25zdCBhdXRoUmVxID0gcmVxLmNsb25lKCk7XG4gICAgICAgICAgICAvLyBzZW5kIGNsb25lZCByZXF1ZXN0IHdpdGggaGVhZGVyIHRvIHRoZSBuZXh0IGhhbmRsZXIuXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnY2FsbGluZyB3aXRoIGF1dGggdG9rZW4nKTtcbiAgICAgICAgICAgIHJldHVybiBuZXh0KGF1dGhSZXEpLnBpcGUoXG4gICAgICAgICAgICAgIHRhcChyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgbGFzdFJlc3BvbnNlV2l0aFRva2VuID0gcmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ3N1Y2Nlc3Mgd2l0aCB0b2tlbiByZXNwb25zZScsIHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIGNhdGNoRXJyb3IoKGVycm9yOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBlcnJvcldpdGhUb2tlbiA9IGVycm9yO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEh0dHBFcnJvclJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICBpZiAoZXJyb3Iuc3RhdHVzID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ05lZWQgVU1BIGF1dGhvcml6YXRpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmhlYWRlcnMuaGFzKCdXV1ctQXV0aGVudGljYXRlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygndXNpbmcgd3d3LWF1dGhlbnRpY2F0ZSBoZWFyZGVyJyk7XG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGtleWNsb2FrLmF1dGhvcml6ZShlcnJvci5oZWFkZXJzLmdldCgnV1dXLUF1dGhlbnRpY2F0ZScpKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihhdXRob3JpemVkVG9rZW4gPT4gISFhdXRob3JpemVkVG9rZW4pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKGF1dGhvcml6ZWRUb2tlbjogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdVc2luZyB0b2tlbiBmcm9tIHNlcnZpY2UgYWZ0ZXIgYXV0aHonKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXV0aFJlcVdpdGhScHQgPSByZXEuY2xvbmUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHJlcS5oZWFkZXJzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnICsgYXV0aG9yaXplZFRva2VuKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5leHQoYXV0aFJlcVdpdGhScHQpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFwKChyZXNwb25zZTogSHR0cEV2ZW50PGFueT4pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RSZXNwb25zZVdpdGhScHRUb2tlbiA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLnR5cGUgPT09IEh0dHBFdmVudFR5cGUuUmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ3N1Y2Nlc3Mgd2l0aCBycHQgcmVzcG9uc2UnLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yV2l0aFJwdFRva2VuID0gZXJyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ2Vycm9yIHJlc3BvbnNlJywgZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxpemUoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RSZXNwb25zZVdpdGhScHRUb2tlbi50eXBlID09PSBIdHRwRXZlbnRUeXBlLlNlbnQgJiYgIWVycm9yV2l0aFJwdFRva2VuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxhc3QgcmVzcG9uc2UgdHlwZSB3YXMgMCwgYW5kIHdlIGhhdmVuJ3QgcmVjZWl2ZWQgYW4gZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ2Fib3J0ZWQgd2l0aCBycHQgcmVxdWVzdCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnRXJyb3Igd2hpbGUgY2FsbGluZyBlbmRwb2ludCcsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgZmluYWxpemUoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChsYXN0UmVzcG9uc2VXaXRoVG9rZW4udHlwZSA9PT0gSHR0cEV2ZW50VHlwZS5TZW50ICYmICFlcnJvcldpdGhUb2tlbikge1xuICAgICAgICAgICAgICAgICAgLy8gbGFzdCByZXNwb25zZSB0eXBlIHdhcyAwLCBhbmQgd2UgaGF2ZW4ndCByZWNlaXZlZCBhbiBlcnJvclxuICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ2Fib3J0ZWQgd2l0aCB0b2tlbiByZXF1ZXN0Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfSkpXG4gICAgICApXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICBsZXQgbGFzdFJlc3BvbnNlO1xuICAgIGxldCBlcnJvcjtcbiAgICAvLyBjb25zb2xlLmxvZygnY2FsbGluZyB3aXRob3V0IGF1dGggdG9rZW4nKTtcbiAgICByZXR1cm4gbmV4dChyZXEpLnBpcGUoXG4gICAgICB0YXAoKHJlc3BvbnNlOiBIdHRwRXZlbnQ8YW55PikgPT4ge1xuICAgICAgICBsYXN0UmVzcG9uc2UgPSByZXNwb25zZTtcbiAgICAgICAgaWYgKHJlc3BvbnNlLnR5cGUgPT09IEh0dHBFdmVudFR5cGUuUmVzcG9uc2UpIHtcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZygnc3VjY2VzcyByZXNwb25zZScsIHJlc3BvbnNlKTtcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICBjYXRjaEVycm9yKChlcnI6IGFueSkgPT4ge1xuICAgICAgICBlcnJvciA9IGVycjtcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ2Vycm9yIHJlc3BvbnNlJywgZXJyKTtcbiAgICAgICAgLy8gVE9ETzogZXJyb3IgaGFuZGxpbmcgaWYgcmVxdWlyZWRcbiAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuICAgICAgfSksXG4gICAgICBmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICAgIGlmIChsYXN0UmVzcG9uc2UudHlwZSA9PT0gSHR0cEV2ZW50VHlwZS5TZW50ICYmICFlcnJvcikge1xuICAgICAgICAgIC8vIGxhc3QgcmVzcG9uc2UgdHlwZSB3YXMgMCwgYW5kIHdlIGhhdmVuJ3QgcmVjZWl2ZWQgYW4gZXJyb3JcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZygnYWJvcnRlZCByZXF1ZXN0Jyk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgfVxufTtcbiJdfQ==