angular-auth-oidc-client
Version:
An OpenID Connect Code Flow with PKCE,Implicit Flow client for Angular
271 lines • 23.8 kB
JavaScript
/**
* @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=