UNPKG

angular-auth-oidc-client

Version:

An OpenID Connect Code Flow with PKCE,Implicit Flow client for Angular

271 lines 23.8 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Injectable, NgZone } from '@angular/core'; import { from, Observable, Subject } from 'rxjs'; import { take } from 'rxjs/operators'; import { ConfigurationProvider } from './auth-configuration.provider'; import { IFrameService } from './existing-iframe.service'; import { LoggerService } from './oidc.logger.service'; import { OidcSecurityCommon } from './oidc.security.common'; /** @type {?} */ const IFRAME_FOR_CHECK_SESSION_IDENTIFIER = 'myiFrameForCheckSession'; // http://openid.net/specs/openid-connect-session-1_0-ID4.html export class OidcSecurityCheckSession { /** * @param {?} oidcSecurityCommon * @param {?} loggerService * @param {?} iFrameService * @param {?} zone * @param {?} configurationProvider */ constructor(oidcSecurityCommon, loggerService, iFrameService, zone, configurationProvider) { this.oidcSecurityCommon = oidcSecurityCommon; this.loggerService = loggerService; this.iFrameService = iFrameService; this.zone = zone; this.configurationProvider = configurationProvider; this.lastIFrameRefresh = 0; this.outstandingMessages = 0; this.heartBeatInterval = 3000; this.iframeRefreshInterval = 60000; this._onCheckSessionChanged = new Subject(); } /** * @return {?} */ get onCheckSessionChanged() { return this._onCheckSessionChanged.asObservable(); } /** * @private * @return {?} */ doesSessionExist() { /** @type {?} */ const existingIFrame = this.iFrameService.getExistingIFrame(IFRAME_FOR_CHECK_SESSION_IDENTIFIER); if (!existingIFrame) { return false; } this.sessionIframe = existingIFrame; return true; } /** * @private * @return {?} */ init() { if (this.lastIFrameRefresh + this.iframeRefreshInterval > Date.now()) { return from([this]); } if (!this.doesSessionExist()) { this.sessionIframe = this.iFrameService.addIFrameToWindowBody(IFRAME_FOR_CHECK_SESSION_IDENTIFIER); this.iframeMessageEvent = this.messageHandler.bind(this); window.addEventListener('message', this.iframeMessageEvent, false); } if (!this.configurationProvider.wellKnownEndpoints) { this.loggerService.logWarning('init check session: authWellKnownEndpoints is undefined. Returning.'); return; } if (this.configurationProvider.wellKnownEndpoints.check_session_iframe) { this.sessionIframe.contentWindow.location.replace(this.configurationProvider.wellKnownEndpoints.check_session_iframe); } else { this.loggerService.logWarning('init check session: authWellKnownEndpoints is undefined'); } return Observable.create((/** * @param {?} observer * @return {?} */ (observer) => { this.sessionIframe.onload = (/** * @return {?} */ () => { this.lastIFrameRefresh = Date.now(); observer.next(this); observer.complete(); }); })); } /** * @param {?} clientId * @return {?} */ startCheckingSession(clientId) { if (this.scheduledHeartBeat) { return; } this.pollServerSession(clientId); } /** * @return {?} */ stopCheckingSession() { if (!this.scheduledHeartBeat) { return; } this.clearScheduledHeartBeat(); } /** * @private * @param {?} clientId * @return {?} */ pollServerSession(clientId) { /** @type {?} */ const _pollServerSessionRecur = (/** * @return {?} */ () => { this.init() .pipe(take(1)) .subscribe((/** * @return {?} */ () => { if (this.sessionIframe && clientId) { this.loggerService.logDebug(this.sessionIframe); /** @type {?} */ const session_state = this.oidcSecurityCommon.sessionState; if (session_state) { this.outstandingMessages++; this.sessionIframe.contentWindow.postMessage(clientId + ' ' + session_state, this.configurationProvider.openIDConfiguration.stsServer); } else { this.loggerService.logDebug('OidcSecurityCheckSession pollServerSession session_state is blank'); this._onCheckSessionChanged.next(); } } else { this.loggerService.logWarning('OidcSecurityCheckSession pollServerSession sessionIframe does not exist'); this.loggerService.logDebug(clientId); this.loggerService.logDebug(this.sessionIframe); // this.init(); } // after sending three messages with no response, fail. if (this.outstandingMessages > 3) { this.loggerService.logError(`OidcSecurityCheckSession not receiving check session response messages. Outstanding messages: ${this.outstandingMessages}. Server unreachable?`); this._onCheckSessionChanged.next(); } this.scheduledHeartBeat = setTimeout(_pollServerSessionRecur, this.heartBeatInterval); })); }); this.outstandingMessages = 0; this.zone.runOutsideAngular((/** * @return {?} */ () => { this.scheduledHeartBeat = setTimeout(_pollServerSessionRecur, this.heartBeatInterval); })); } /** * @private * @return {?} */ clearScheduledHeartBeat() { clearTimeout(this.scheduledHeartBeat); this.scheduledHeartBeat = null; } /** * @private * @param {?} e * @return {?} */ messageHandler(e) { this.outstandingMessages = 0; if (this.sessionIframe && e.origin === this.configurationProvider.openIDConfiguration.stsServer && e.source === this.sessionIframe.contentWindow) { if (e.data === 'error') { this.loggerService.logWarning('error from checksession messageHandler'); } else if (e.data === 'changed') { this._onCheckSessionChanged.next(); } else { this.loggerService.logDebug(e.data + ' from checksession messageHandler'); } } } } OidcSecurityCheckSession.decorators = [ { type: Injectable } ]; /** @nocollapse */ OidcSecurityCheckSession.ctorParameters = () => [ { type: OidcSecurityCommon }, { type: LoggerService }, { type: IFrameService }, { type: NgZone }, { type: ConfigurationProvider } ]; if (false) { /** * @type {?} * @private */ OidcSecurityCheckSession.prototype.sessionIframe; /** * @type {?} * @private */ OidcSecurityCheckSession.prototype.iframeMessageEvent; /** * @type {?} * @private */ OidcSecurityCheckSession.prototype.scheduledHeartBeat; /** * @type {?} * @private */ OidcSecurityCheckSession.prototype.lastIFrameRefresh; /** * @type {?} * @private */ OidcSecurityCheckSession.prototype.outstandingMessages; /** * @type {?} * @private */ OidcSecurityCheckSession.prototype.heartBeatInterval; /** * @type {?} * @private */ OidcSecurityCheckSession.prototype.iframeRefreshInterval; /** * @type {?} * @private */ OidcSecurityCheckSession.prototype._onCheckSessionChanged; /** * @type {?} * @private */ OidcSecurityCheckSession.prototype.oidcSecurityCommon; /** * @type {?} * @private */ OidcSecurityCheckSession.prototype.loggerService; /** * @type {?} * @private */ OidcSecurityCheckSession.prototype.iFrameService; /** * @type {?} * @private */ OidcSecurityCheckSession.prototype.zone; /** * @type {?} * @private */ OidcSecurityCheckSession.prototype.configurationProvider; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2lkYy5zZWN1cml0eS5jaGVjay1zZXNzaW9uLmpzIiwic291cmNlUm9vdCI6Im5nOi8vYW5ndWxhci1hdXRoLW9pZGMtY2xpZW50LyIsInNvdXJjZXMiOlsibGliL3NlcnZpY2VzL29pZGMuc2VjdXJpdHkuY2hlY2stc2Vzc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQVksT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0QyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUN0RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3RELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDOztNQUV0RCxtQ0FBbUMsR0FBRyx5QkFBeUI7O0FBS3JFLE1BQU0sT0FBTyx3QkFBd0I7Ozs7Ozs7O0lBY2pDLFlBQ1ksa0JBQXNDLEVBQ3RDLGFBQTRCLEVBQzVCLGFBQTRCLEVBQzVCLElBQVksRUFDSCxxQkFBNEM7UUFKckQsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUN0QyxrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM1QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM1QixTQUFJLEdBQUosSUFBSSxDQUFRO1FBQ0gsMEJBQXFCLEdBQXJCLHFCQUFxQixDQUF1QjtRQWZ6RCxzQkFBaUIsR0FBRyxDQUFDLENBQUM7UUFDdEIsd0JBQW1CLEdBQUcsQ0FBQyxDQUFDO1FBQ3hCLHNCQUFpQixHQUFHLElBQUksQ0FBQztRQUN6QiwwQkFBcUIsR0FBRyxLQUFLLENBQUM7UUFDOUIsMkJB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SUFDM0Isc0RBQWdDOzs7OztJQUNoQyxzREFBZ0M7Ozs7O0lBQ2hDLHFEQUE4Qjs7Ozs7SUFDOUIsdURBQWdDOzs7OztJQUNoQyxxREFBaUM7Ozs7O0lBQ2pDLHlEQUFzQzs7Ozs7SUFDdEMsMERBQW9EOzs7OztJQU9oRCxzREFBOEM7Ozs7O0lBQzlDLGlEQUFvQzs7Ozs7SUFDcEMsaURBQW9DOzs7OztJQUNwQyx3Q0FBb0I7Ozs7O0lBQ3BCLHlEQUE2RCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIE5nWm9uZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZnJvbSwgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBDb25maWd1cmF0aW9uUHJvdmlkZXIgfSBmcm9tICcuL2F1dGgtY29uZmlndXJhdGlvbi5wcm92aWRlcic7XG5pbXBvcnQgeyBJRnJhbWVTZXJ2aWNlIH0gZnJvbSAnLi9leGlzdGluZy1pZnJhbWUuc2VydmljZSc7XG5pbXBvcnQgeyBMb2dnZXJTZXJ2aWNlIH0gZnJvbSAnLi9vaWRjLmxvZ2dlci5zZXJ2aWNlJztcbmltcG9ydCB7IE9pZGNTZWN1cml0eUNvbW1vbiB9IGZyb20gJy4vb2lkYy5zZWN1cml0eS5jb21tb24nO1xuXG5jb25zdCBJRlJBTUVfRk9SX0NIRUNLX1NFU1NJT05fSURFTlRJRklFUiA9ICdteWlGcmFtZUZvckNoZWNrU2Vzc2lvbic7XG5cbi8vIGh0dHA6Ly9vcGVuaWQubmV0L3NwZWNzL29wZW5pZC1jb25uZWN0LXNlc3Npb24tMV8wLUlENC5odG1sXG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBPaWRjU2VjdXJpdHlDaGVja1Nlc3Npb24ge1xuICAgIHByaXZhdGUgc2Vzc2lvbklmcmFtZTogYW55O1xuICAgIHByaXZhdGUgaWZyYW1lTWVzc2FnZUV2ZW50OiBhbnk7XG4gICAgcHJpdmF0ZSBzY2hlZHVsZWRIZWFydEJlYXQ6IGFueTtcbiAgICBwcml2YXRlIGxhc3RJRnJhbWVSZWZyZXNoID0gMDtcbiAgICBwcml2YXRlIG91dHN0YW5kaW5nTWVzc2FnZXMgPSAwO1xuICAgIHByaXZhdGUgaGVhcnRCZWF0SW50ZXJ2YWwgPSAzMDAwO1xuICAgIHByaXZhdGUgaWZyYW1lUmVmcmVzaEludGVydmFsID0gNjAwMDA7XG4gICAgcHJpdmF0ZSBfb25DaGVja1Nlc3Npb25DaGFuZ2VkID0gbmV3IFN1YmplY3Q8YW55PigpO1xuXG4gICAgcHVibGljIGdldCBvbkNoZWNrU2Vzc2lvbkNoYW5nZWQoKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29uQ2hlY2tTZXNzaW9uQ2hhbmdlZC5hc09ic2VydmFibGUoKTtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBvaWRjU2VjdXJpdHlDb21tb246IE9pZGNTZWN1cml0eUNvbW1vbixcbiAgICAgICAgcHJpdmF0ZSBsb2dnZXJTZXJ2aWNlOiBMb2dnZXJTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGlGcmFtZVNlcnZpY2U6IElGcmFtZVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgem9uZTogTmdab25lLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGNvbmZpZ3VyYXRpb25Qcm92aWRlcjogQ29uZmlndXJhdGlvblByb3ZpZGVyXG4gICAgKSB7fVxuXG4gICAgcHJpdmF0ZSBkb2VzU2Vzc2lvbkV4aXN0KCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBleGlzdGluZ0lGcmFtZSA9IHRoaXMuaUZyYW1lU2VydmljZS5nZXRFeGlzdGluZ0lGcmFtZShJRlJBTUVfRk9SX0NIRUNLX1NFU1NJT05fSURFTlRJRklFUik7XG5cbiAgICAgICAgaWYgKCFleGlzdGluZ0lGcmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXNzaW9uSWZyYW1lID0gZXhpc3RpbmdJRnJhbWU7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdCgpIHtcbiAgICAgICAgaWYgKHRoaXMubGFzdElGcmFtZVJlZnJlc2ggKyB0aGlzLmlmcmFtZVJlZnJlc2hJbnRlcnZhbCA+IERhdGUubm93KCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmcm9tKFt0aGlzXSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuZG9lc1Nlc3Npb25FeGlzdCgpKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb25JZnJhbWUgPSB0aGlzLmlGcmFtZVNlcnZpY2UuYWRkSUZyYW1lVG9XaW5kb3dCb2R5KElGUkFNRV9GT1JfQ0hFQ0tfU0VTU0lPTl9JREVOVElGSUVSKTtcbiAgICAgICAgICAgIHRoaXMuaWZyYW1lTWVzc2FnZUV2ZW50ID0gdGhpcy5tZXNzYWdlSGFuZGxlci5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0aGlzLmlmcmFtZU1lc3NhZ2VFdmVudCwgZmFsc2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZ3VyYXRpb25Qcm92aWRlci53ZWxsS25vd25FbmRwb2ludHMpIHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dXYXJuaW5nKCdpbml0IGNoZWNrIHNlc3Npb246IGF1dGhXZWxsS25vd25FbmRwb2ludHMgaXMgdW5kZWZpbmVkLiBSZXR1cm5pbmcuJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5jb25maWd1cmF0aW9uUHJvdmlkZXIud2VsbEtub3duRW5kcG9pbnRzLmNoZWNrX3Nlc3Npb25faWZyYW1lKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb25JZnJhbWUuY29udGVudFdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKHRoaXMuY29uZmlndXJhdGlvblByb3ZpZGVyLndlbGxLbm93bkVuZHBvaW50cy5jaGVja19zZXNzaW9uX2lmcmFtZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UubG9nV2FybmluZygnaW5pdCBjaGVjayBzZXNzaW9uOiBhdXRoV2VsbEtub3duRW5kcG9pbnRzIGlzIHVuZGVmaW5lZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIE9ic2VydmFibGUuY3JlYXRlKChvYnNlcnZlcjogT2JzZXJ2ZXI8T2lkY1NlY3VyaXR5Q2hlY2tTZXNzaW9uPikgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWZyYW1lLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RJRnJhbWVSZWZyZXNoID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KHRoaXMpO1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzdGFydENoZWNraW5nU2Vzc2lvbihjbGllbnRJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNjaGVkdWxlZEhlYXJ0QmVhdCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5wb2xsU2VydmVyU2Vzc2lvbihjbGllbnRJZCk7XG4gICAgfVxuXG4gICAgc3RvcENoZWNraW5nU2Vzc2lvbigpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnNjaGVkdWxlZEhlYXJ0QmVhdCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jbGVhclNjaGVkdWxlZEhlYXJ0QmVhdCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcG9sbFNlcnZlclNlc3Npb24oY2xpZW50SWQ6IHN0cmluZykge1xuICAgICAgICBjb25zdCBfcG9sbFNlcnZlclNlc3Npb25SZWN1ciA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdCgpXG4gICAgICAgICAgICAgICAgLnBpcGUodGFrZSgxKSlcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbklmcmFtZSAmJiBjbGllbnRJZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuc2Vzc2lvbklmcmFtZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXNzaW9uX3N0YXRlID0gdGhpcy5vaWRjU2VjdXJpdHlDb21tb24uc2Vzc2lvblN0YXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlc3Npb25fc3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm91dHN0YW5kaW5nTWVzc2FnZXMrKztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb25JZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50SWQgKyAnICcgKyBzZXNzaW9uX3N0YXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb25Qcm92aWRlci5vcGVuSURDb25maWd1cmF0aW9uLnN0c1NlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dEZWJ1ZygnT2lkY1NlY3VyaXR5Q2hlY2tTZXNzaW9uIHBvbGxTZXJ2ZXJTZXNzaW9uIHNlc3Npb25fc3RhdGUgaXMgYmxhbmsnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9vbkNoZWNrU2Vzc2lvbkNoYW5nZWQubmV4dCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZ1dhcm5pbmcoJ09pZGNTZWN1cml0eUNoZWNrU2Vzc2lvbiBwb2xsU2VydmVyU2Vzc2lvbiBzZXNzaW9uSWZyYW1lIGRvZXMgbm90IGV4aXN0Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UubG9nRGVidWcoY2xpZW50SWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuc2Vzc2lvbklmcmFtZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzLmluaXQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIGFmdGVyIHNlbmRpbmcgdGhyZWUgbWVzc2FnZXMgd2l0aCBubyByZXNwb25zZSwgZmFpbC5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3V0c3RhbmRpbmdNZXNzYWdlcyA+IDMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgT2lkY1NlY3VyaXR5Q2hlY2tTZXNzaW9uIG5vdCByZWNlaXZpbmcgY2hlY2sgc2Vzc2lvbiByZXNwb25zZSBtZXNzYWdlcy4gT3V0c3RhbmRpbmcgbWVzc2FnZXM6ICR7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3V0c3RhbmRpbmdNZXNzYWdlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0uIFNlcnZlciB1bnJlYWNoYWJsZT9gXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fb25DaGVja1Nlc3Npb25DaGFuZ2VkLm5leHQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2NoZWR1bGVkSGVhcnRCZWF0ID0gc2V0VGltZW91dChfcG9sbFNlcnZlclNlc3Npb25SZWN1ciwgdGhpcy5oZWFydEJlYXRJbnRlcnZhbCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5vdXRzdGFuZGluZ01lc3NhZ2VzID0gMDtcblxuICAgICAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zY2hlZHVsZWRIZWFydEJlYXQgPSBzZXRUaW1lb3V0KF9wb2xsU2VydmVyU2Vzc2lvblJlY3VyLCB0aGlzLmhlYXJ0QmVhdEludGVydmFsKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHByaXZhdGUgY2xlYXJTY2hlZHVsZWRIZWFydEJlYXQoKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnNjaGVkdWxlZEhlYXJ0QmVhdCk7XG4gICAgICAgIHRoaXMuc2NoZWR1bGVkSGVhcnRCZWF0ID0gbnVsbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIG1lc3NhZ2VIYW5kbGVyKGU6IGFueSkge1xuICAgICAgICB0aGlzLm91dHN0YW5kaW5nTWVzc2FnZXMgPSAwO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLnNlc3Npb25JZnJhbWUgJiZcbiAgICAgICAgICAgIGUub3JpZ2luID09PSB0aGlzLmNvbmZpZ3VyYXRpb25Qcm92aWRlci5vcGVuSURDb25maWd1cmF0aW9uLnN0c1NlcnZlciAmJlxuICAgICAgICAgICAgZS5zb3VyY2UgPT09IHRoaXMuc2Vzc2lvbklmcmFtZS5jb250ZW50V2luZG93XG4gICAgICAgICkge1xuICAgICAgICAgICAgaWYgKGUuZGF0YSA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dXYXJuaW5nKCdlcnJvciBmcm9tIGNoZWNrc2Vzc2lvbiBtZXNzYWdlSGFuZGxlcicpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChlLmRhdGEgPT09ICdjaGFuZ2VkJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX29uQ2hlY2tTZXNzaW9uQ2hhbmdlZC5uZXh0KCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dEZWJ1ZyhlLmRhdGEgKyAnIGZyb20gY2hlY2tzZXNzaW9uIG1lc3NhZ2VIYW5kbGVyJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=