angular-simple-oidc
Version:
Angular Library implementing Open Id Connect specification. Code Flow, Refresh Tokens, Session Management, Discovery Document.
81 lines • 15.7 kB
JavaScript
import { Injectable, Inject } from '@angular/core';
import { OidcDiscoveryDocClient } from '../discovery-document/oidc-discovery-doc-client.service';
import { DynamicIframeService } from '../dynamic-iframe/dynamic-iframe.service';
import { take, map, tap, switchMap, filter, timeout, catchError, withLatestFrom } from 'rxjs/operators';
import { TokenStorageService } from '../token-storage.service';
import { fromEvent, throwError } from 'rxjs';
import { WINDOW_REF, AUTH_CONFIG_SERVICE } from '../providers';
import { TokenUrlService } from 'angular-simple-oidc/core';
import { urlJoin } from '../utils/url-join';
import { OidcCodeFlowClient } from '../oidc-code-flow-client.service';
import { IframePostMessageTimeoutError } from './errors';
import { ConfigService } from 'angular-simple-oidc/config';
import { SESSION_MANAGEMENT_CONFIG_SERVICE } from './providers';
import { EventsService, SimpleOidcInfoEvent } from 'angular-simple-oidc/events';
// @dynamic
export class AuthorizeEndpointSilentClientService {
constructor(window, discoveryClient, dynamicIframe, tokenStorage, authConfig, sessionConfig, events, oidcClient, tokenUrl) {
this.window = window;
this.discoveryClient = discoveryClient;
this.dynamicIframe = dynamicIframe;
this.tokenStorage = tokenStorage;
this.authConfig = authConfig;
this.sessionConfig = sessionConfig;
this.events = events;
this.oidcClient = oidcClient;
this.tokenUrl = tokenUrl;
}
startCodeFlowInIframe() {
const iframeUrl$ = this.authConfig.current$
.pipe(withLatestFrom(this.sessionConfig.current$), map(([authConfig, sessionConfig]) => urlJoin(authConfig.baseUrl, sessionConfig.iframePath)));
return this.tokenStorage.currentState$
.pipe(take(1), tap(() => this.events.dispatch(new SimpleOidcInfoEvent(`Starting Code Flow in iframe`))), withLatestFrom(iframeUrl$), switchMap(([{ identityToken }, iframeUrl]) => this.oidcClient.generateCodeFlowMetadata({
redirectUri: iframeUrl,
prompt: 'none',
idTokenHint: identityToken
}).pipe(map(metadata => ({ metadata, iframeUrl })))), withLatestFrom(this.sessionConfig.current$), take(1), switchMap(([{ metadata, iframeUrl }, sessionConfig]) => {
this.events.dispatch(new SimpleOidcInfoEvent(`Creating iframe`, metadata));
const iframe = this.dynamicIframe
.create()
.hide()
.setSource(metadata.url)
.appendToBody();
return fromEvent(this.window, 'message')
.pipe(map((event) => ({ event, iframe, metadata, iframeUrl })), filter(({ event }) => event.data.startsWith(iframeUrl)), take(1), timeout(sessionConfig.iframeTimeout), catchError(e => {
if (e.name && e.name === 'TimeoutError') {
throw new IframePostMessageTimeoutError({
iframe,
e,
});
}
else {
return throwError(e);
}
}));
}), map(({ event, iframe, metadata, iframeUrl }) => {
const href = event.data;
this.events.dispatch(new SimpleOidcInfoEvent(`Obtained data from iframe`, { event, href }));
iframe.remove();
return {
href,
iframeUrl,
metadata
};
}), switchMap(({ href, iframeUrl, metadata }) => this.oidcClient.codeFlowCallback(href, iframeUrl, metadata)));
}
}
AuthorizeEndpointSilentClientService.decorators = [
{ type: Injectable }
];
AuthorizeEndpointSilentClientService.ctorParameters = () => [
{ type: Window, decorators: [{ type: Inject, args: [WINDOW_REF,] }] },
{ type: OidcDiscoveryDocClient },
{ type: DynamicIframeService },
{ type: TokenStorageService },
{ type: ConfigService, decorators: [{ type: Inject, args: [AUTH_CONFIG_SERVICE,] }] },
{ type: ConfigService, decorators: [{ type: Inject, args: [SESSION_MANAGEMENT_CONFIG_SERVICE,] }] },
{ type: EventsService },
{ type: OidcCodeFlowClient },
{ type: TokenUrlService }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aG9yaXplLWVuZHBvaW50LXNpbGVudC1jbGllbnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItc2ltcGxlLW9pZGMvc3JjL2xpYi9zZXNzaW9uLW1hbmFnZW1lbnQvYXV0aG9yaXplLWVuZHBvaW50LXNpbGVudC1jbGllbnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSx5REFBeUQsQ0FBQztBQUNqRyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUNoRixPQUFPLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hHLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQy9ELE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBQ3pELE9BQU8sRUFBRSxVQUFVLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDL0QsT0FBTyxFQUFFLGVBQWUsRUFBc0IsTUFBTSwwQkFBMEIsQ0FBQztBQUMvRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDNUMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdEUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ3pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUUzRCxPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFaEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRWhGLFdBQVc7QUFFWCxNQUFNLE9BQU8sb0NBQW9DO0lBRTdDLFlBRXVCLE1BQWMsRUFDZCxlQUF1QyxFQUN2QyxhQUFtQyxFQUNuQyxZQUFpQyxFQUVqQyxVQUFxQyxFQUVyQyxhQUFxRCxFQUNyRCxNQUFxQixFQUNyQixVQUE4QixFQUM5QixRQUF5QjtRQVZ6QixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2Qsb0JBQWUsR0FBZixlQUFlLENBQXdCO1FBQ3ZDLGtCQUFhLEdBQWIsYUFBYSxDQUFzQjtRQUNuQyxpQkFBWSxHQUFaLFlBQVksQ0FBcUI7UUFFakMsZUFBVSxHQUFWLFVBQVUsQ0FBMkI7UUFFckMsa0JBQWEsR0FBYixhQUFhLENBQXdDO1FBQ3JELFdBQU0sR0FBTixNQUFNLENBQWU7UUFDckIsZUFBVSxHQUFWLFVBQVUsQ0FBb0I7UUFDOUIsYUFBUSxHQUFSLFFBQVEsQ0FBaUI7SUFDNUMsQ0FBQztJQUVFLHFCQUFxQjtRQUN4QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVE7YUFDdEMsSUFBSSxDQUNELGNBQWMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxFQUMzQyxHQUFHLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRSxhQUFhLENBQUMsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQzlGLENBQUM7UUFFTixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYTthQUNqQyxJQUFJLENBQ0QsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLG1CQUFtQixDQUFDLDhCQUE4QixDQUFDLENBQUMsQ0FBQyxFQUN4RixjQUFjLENBQUMsVUFBVSxDQUFDLEVBQzFCLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxhQUFhLEVBQUUsRUFBRSxTQUFTLENBQUMsRUFBRSxFQUFFLENBQ3pDLElBQUksQ0FBQyxVQUFVLENBQUMsd0JBQXdCLENBQUM7WUFDckMsV0FBVyxFQUFFLFNBQVM7WUFDdEIsTUFBTSxFQUFFLE1BQU07WUFDZCxXQUFXLEVBQUUsYUFBYTtTQUM3QixDQUFDLENBQUMsSUFBSSxDQUNILEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUM3QyxDQUNKLEVBQ0QsY0FBYyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLEVBQzNDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDUCxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxFQUFFLGFBQWEsQ0FBQyxFQUFFLEVBQUU7WUFDbkQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxtQkFBbUIsQ0FBQyxpQkFBaUIsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQzNFLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxhQUFhO2lCQUM1QixNQUFNLEVBQUU7aUJBQ1IsSUFBSSxFQUFFO2lCQUNOLFNBQVMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO2lCQUN2QixZQUFZLEVBQUUsQ0FBQztZQUVwQixPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQztpQkFDbkMsSUFBSSxDQUNELEdBQUcsQ0FBQyxDQUFDLEtBQW1CLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLEVBQ3RFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFFLEtBQUssQ0FBQyxJQUFlLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQ25FLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDUCxPQUFPLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxFQUNwQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ1gsSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxJQUFJLEtBQUssY0FBYyxFQUFFO29CQUNyQyxNQUFNLElBQUksNkJBQTZCLENBQUM7d0JBQ3BDLE1BQU07d0JBQ04sQ0FBQztxQkFDSixDQUFDLENBQUM7aUJBQ047cUJBQU07b0JBQ0gsT0FBTyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ3hCO1lBQ0wsQ0FBQyxDQUFDLENBQ0wsQ0FBQztRQUNWLENBQUMsQ0FBQyxFQUNGLEdBQUcsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRTtZQUMzQyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksbUJBQW1CLENBQUMsMkJBQTJCLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzVGLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUVoQixPQUFPO2dCQUNILElBQUk7Z0JBQ0osU0FBUztnQkFDVCxRQUFRO2FBQ1gsQ0FBQztRQUNOLENBQUMsQ0FBQyxFQUNGLFNBQVMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQzVHLENBQUM7SUFDVixDQUFDOzs7WUFoRkosVUFBVTs7O1lBS3dCLE1BQU0sdUJBRGhDLE1BQU0sU0FBQyxVQUFVO1lBckJqQixzQkFBc0I7WUFDdEIsb0JBQW9CO1lBRXBCLG1CQUFtQjtZQU9uQixhQUFhLHVCQWdCYixNQUFNLFNBQUMsbUJBQW1CO1lBaEIxQixhQUFhLHVCQWtCYixNQUFNLFNBQUMsaUNBQWlDO1lBZHhDLGFBQWE7WUFOYixrQkFBa0I7WUFGbEIsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2lkY0Rpc2NvdmVyeURvY0NsaWVudCB9IGZyb20gJy4uL2Rpc2NvdmVyeS1kb2N1bWVudC9vaWRjLWRpc2NvdmVyeS1kb2MtY2xpZW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgRHluYW1pY0lmcmFtZVNlcnZpY2UgfSBmcm9tICcuLi9keW5hbWljLWlmcmFtZS9keW5hbWljLWlmcmFtZS5zZXJ2aWNlJztcbmltcG9ydCB7IHRha2UsIG1hcCwgdGFwLCBzd2l0Y2hNYXAsIGZpbHRlciwgdGltZW91dCwgY2F0Y2hFcnJvciwgd2l0aExhdGVzdEZyb20gfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUb2tlblN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vdG9rZW4tc3RvcmFnZS5zZXJ2aWNlJztcbmltcG9ydCB7IGZyb21FdmVudCwgdGhyb3dFcnJvciwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgV0lORE9XX1JFRiwgQVVUSF9DT05GSUdfU0VSVklDRSB9IGZyb20gJy4uL3Byb3ZpZGVycyc7XG5pbXBvcnQgeyBUb2tlblVybFNlcnZpY2UsIFRva2VuUmVxdWVzdFJlc3VsdCB9IGZyb20gJ2FuZ3VsYXItc2ltcGxlLW9pZGMvY29yZSc7XG5pbXBvcnQgeyB1cmxKb2luIH0gZnJvbSAnLi4vdXRpbHMvdXJsLWpvaW4nO1xuaW1wb3J0IHsgT2lkY0NvZGVGbG93Q2xpZW50IH0gZnJvbSAnLi4vb2lkYy1jb2RlLWZsb3ctY2xpZW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgSWZyYW1lUG9zdE1lc3NhZ2VUaW1lb3V0RXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQgeyBDb25maWdTZXJ2aWNlIH0gZnJvbSAnYW5ndWxhci1zaW1wbGUtb2lkYy9jb25maWcnO1xuaW1wb3J0IHsgQXV0aENvbmZpZyB9IGZyb20gJy4uL2NvbmZpZy9tb2RlbHMnO1xuaW1wb3J0IHsgU0VTU0lPTl9NQU5BR0VNRU5UX0NPTkZJR19TRVJWSUNFIH0gZnJvbSAnLi9wcm92aWRlcnMnO1xuaW1wb3J0IHsgU2Vzc2lvbk1hbmFnZW1lbnRDb25maWcgfSBmcm9tICcuL21vZGVscyc7XG5pbXBvcnQgeyBFdmVudHNTZXJ2aWNlLCBTaW1wbGVPaWRjSW5mb0V2ZW50IH0gZnJvbSAnYW5ndWxhci1zaW1wbGUtb2lkYy9ldmVudHMnO1xuXG4vLyBAZHluYW1pY1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEF1dGhvcml6ZUVuZHBvaW50U2lsZW50Q2xpZW50U2VydmljZSB7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgQEluamVjdChXSU5ET1dfUkVGKVxuICAgICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgd2luZG93OiBXaW5kb3csXG4gICAgICAgIHByb3RlY3RlZCByZWFkb25seSBkaXNjb3ZlcnlDbGllbnQ6IE9pZGNEaXNjb3ZlcnlEb2NDbGllbnQsXG4gICAgICAgIHByb3RlY3RlZCByZWFkb25seSBkeW5hbWljSWZyYW1lOiBEeW5hbWljSWZyYW1lU2VydmljZSxcbiAgICAgICAgcHJvdGVjdGVkIHJlYWRvbmx5IHRva2VuU3RvcmFnZTogVG9rZW5TdG9yYWdlU2VydmljZSxcbiAgICAgICAgQEluamVjdChBVVRIX0NPTkZJR19TRVJWSUNFKVxuICAgICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgYXV0aENvbmZpZzogQ29uZmlnU2VydmljZTxBdXRoQ29uZmlnPixcbiAgICAgICAgQEluamVjdChTRVNTSU9OX01BTkFHRU1FTlRfQ09ORklHX1NFUlZJQ0UpXG4gICAgICAgIHByb3RlY3RlZCByZWFkb25seSBzZXNzaW9uQ29uZmlnOiBDb25maWdTZXJ2aWNlPFNlc3Npb25NYW5hZ2VtZW50Q29uZmlnPixcbiAgICAgICAgcHJvdGVjdGVkIHJlYWRvbmx5IGV2ZW50czogRXZlbnRzU2VydmljZSxcbiAgICAgICAgcHJvdGVjdGVkIHJlYWRvbmx5IG9pZGNDbGllbnQ6IE9pZGNDb2RlRmxvd0NsaWVudCxcbiAgICAgICAgcHJvdGVjdGVkIHJlYWRvbmx5IHRva2VuVXJsOiBUb2tlblVybFNlcnZpY2UsXG4gICAgKSB7IH1cblxuICAgIHB1YmxpYyBzdGFydENvZGVGbG93SW5JZnJhbWUoKTogT2JzZXJ2YWJsZTxUb2tlblJlcXVlc3RSZXN1bHQ+IHtcbiAgICAgICAgY29uc3QgaWZyYW1lVXJsJCA9IHRoaXMuYXV0aENvbmZpZy5jdXJyZW50JFxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgd2l0aExhdGVzdEZyb20odGhpcy5zZXNzaW9uQ29uZmlnLmN1cnJlbnQkKSxcbiAgICAgICAgICAgICAgICBtYXAoKFthdXRoQ29uZmlnLCBzZXNzaW9uQ29uZmlnXSkgPT4gdXJsSm9pbihhdXRoQ29uZmlnLmJhc2VVcmwsIHNlc3Npb25Db25maWcuaWZyYW1lUGF0aCkpXG4gICAgICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnRva2VuU3RvcmFnZS5jdXJyZW50U3RhdGUkXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgICAgICAgIHRhcCgoKSA9PiB0aGlzLmV2ZW50cy5kaXNwYXRjaChuZXcgU2ltcGxlT2lkY0luZm9FdmVudChgU3RhcnRpbmcgQ29kZSBGbG93IGluIGlmcmFtZWApKSksXG4gICAgICAgICAgICAgICAgd2l0aExhdGVzdEZyb20oaWZyYW1lVXJsJCksXG4gICAgICAgICAgICAgICAgc3dpdGNoTWFwKChbeyBpZGVudGl0eVRva2VuIH0sIGlmcmFtZVVybF0pID0+XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub2lkY0NsaWVudC5nZW5lcmF0ZUNvZGVGbG93TWV0YWRhdGEoe1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVkaXJlY3RVcmk6IGlmcmFtZVVybCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21wdDogJ25vbmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgaWRUb2tlbkhpbnQ6IGlkZW50aXR5VG9rZW5cbiAgICAgICAgICAgICAgICAgICAgfSkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcChtZXRhZGF0YSA9PiAoeyBtZXRhZGF0YSwgaWZyYW1lVXJsIH0pKVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICB3aXRoTGF0ZXN0RnJvbSh0aGlzLnNlc3Npb25Db25maWcuY3VycmVudCQpLFxuICAgICAgICAgICAgICAgIHRha2UoMSksXG4gICAgICAgICAgICAgICAgc3dpdGNoTWFwKChbeyBtZXRhZGF0YSwgaWZyYW1lVXJsIH0sIHNlc3Npb25Db25maWddKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzLmRpc3BhdGNoKG5ldyBTaW1wbGVPaWRjSW5mb0V2ZW50KGBDcmVhdGluZyBpZnJhbWVgLCBtZXRhZGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZnJhbWUgPSB0aGlzLmR5bmFtaWNJZnJhbWVcbiAgICAgICAgICAgICAgICAgICAgICAgIC5jcmVhdGUoKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnNldFNvdXJjZShtZXRhZGF0YS51cmwpXG4gICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kVG9Cb2R5KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZyb21FdmVudCh0aGlzLndpbmRvdywgJ21lc3NhZ2UnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwKChldmVudDogTWVzc2FnZUV2ZW50KSA9PiAoeyBldmVudCwgaWZyYW1lLCBtZXRhZGF0YSwgaWZyYW1lVXJsIH0pKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoKHsgZXZlbnQgfSkgPT4gKGV2ZW50LmRhdGEgYXMgc3RyaW5nKS5zdGFydHNXaXRoKGlmcmFtZVVybCkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRha2UoMSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZW91dChzZXNzaW9uQ29uZmlnLmlmcmFtZVRpbWVvdXQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlLm5hbWUgJiYgZS5uYW1lID09PSAnVGltZW91dEVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElmcmFtZVBvc3RNZXNzYWdlVGltZW91dEVycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZnJhbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBtYXAoKHsgZXZlbnQsIGlmcmFtZSwgbWV0YWRhdGEsIGlmcmFtZVVybCB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGhyZWYgPSBldmVudC5kYXRhO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50cy5kaXNwYXRjaChuZXcgU2ltcGxlT2lkY0luZm9FdmVudChgT2J0YWluZWQgZGF0YSBmcm9tIGlmcmFtZWAsIHsgZXZlbnQsIGhyZWYgfSkpO1xuICAgICAgICAgICAgICAgICAgICBpZnJhbWUucmVtb3ZlKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhyZWYsXG4gICAgICAgICAgICAgICAgICAgICAgICBpZnJhbWVVcmwsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoeyBocmVmLCBpZnJhbWVVcmwsIG1ldGFkYXRhIH0pID0+IHRoaXMub2lkY0NsaWVudC5jb2RlRmxvd0NhbGxiYWNrKGhyZWYsIGlmcmFtZVVybCwgbWV0YWRhdGEpKVxuICAgICAgICAgICAgKTtcbiAgICB9XG59XG4iXX0=