UNPKG

@ebondu/angular2-keycloak

Version:
126 lines 20.1 kB
/* * 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==