UNPKG

angular-auth-oidc-client

Version:
133 lines 27.2 kB
import { Injectable } from '@angular/core'; import { forkJoin, of, throwError } from 'rxjs'; import { catchError, switchMap } from 'rxjs/operators'; import { EventTypes } from '../public-events/event-types'; import * as i0 from "@angular/core"; import * as i1 from "../flows/reset-auth-data.service"; import * as i2 from "../utils/flowHelper/flow-helper.service"; import * as i3 from "../flows/flows-data.service"; import * as i4 from "../logging/logger.service"; import * as i5 from "../user-data/user.service"; import * as i6 from "../auth-state/auth-state.service"; import * as i7 from "../iframe/refresh-session-iframe.service"; import * as i8 from "./refresh-session-refresh-token.service"; import * as i9 from "./interval.service"; import * as i10 from "../storage/storage-persistence.service"; import * as i11 from "../public-events/public-events.service"; import * as i12 from "../config/config.service"; export class PeriodicallyTokenCheckService { constructor(resetAuthDataService, flowHelper, flowsDataService, loggerService, userService, authStateService, refreshSessionIframeService, refreshSessionRefreshTokenService, intervalService, storagePersistenceService, publicEventsService, configurationService) { this.resetAuthDataService = resetAuthDataService; this.flowHelper = flowHelper; this.flowsDataService = flowsDataService; this.loggerService = loggerService; this.userService = userService; this.authStateService = authStateService; this.refreshSessionIframeService = refreshSessionIframeService; this.refreshSessionRefreshTokenService = refreshSessionRefreshTokenService; this.intervalService = intervalService; this.storagePersistenceService = storagePersistenceService; this.publicEventsService = publicEventsService; this.configurationService = configurationService; } startTokenValidationPeriodically(allConfigs, currentConfig) { const configsWithSilentRenewEnabled = this.getConfigsWithSilentRenewEnabled(allConfigs); if (configsWithSilentRenewEnabled.length <= 0) { return; } if (this.intervalService.isTokenValidationRunning()) { return; } const refreshTimeInSeconds = this.getSmallestRefreshTimeFromConfigs(configsWithSilentRenewEnabled); const periodicallyCheck$ = this.intervalService.startPeriodicTokenCheck(refreshTimeInSeconds).pipe(switchMap(() => { const objectWithConfigIdsAndRefreshEvent = {}; configsWithSilentRenewEnabled.forEach((config) => { objectWithConfigIdsAndRefreshEvent[config.configId] = this.getRefreshEvent(config, allConfigs); }); return forkJoin(objectWithConfigIdsAndRefreshEvent); })); this.intervalService.runTokenValidationRunning = periodicallyCheck$ .pipe(catchError((error) => throwError(() => new Error(error)))) .subscribe({ next: (objectWithConfigIds) => { for (const [configId, _] of Object.entries(objectWithConfigIds)) { this.configurationService.getOpenIDConfiguration(configId).subscribe((config) => { this.loggerService.logDebug(config, 'silent renew, periodic check finished!'); if (this.flowHelper.isCurrentFlowCodeFlowWithRefreshTokens(config)) { this.flowsDataService.resetSilentRenewRunning(config); } }); } }, error: (error) => { this.loggerService.logError(currentConfig, 'silent renew failed!', error); }, }); } getRefreshEvent(config, allConfigs) { const shouldStartRefreshEvent = this.shouldStartPeriodicallyCheckForConfig(config); if (!shouldStartRefreshEvent) { return of(null); } const refreshEvent$ = this.createRefreshEventForConfig(config, allConfigs); this.publicEventsService.fireEvent(EventTypes.SilentRenewStarted); const refreshEventWithErrorHandler$ = refreshEvent$.pipe(catchError((error) => { this.loggerService.logError(config, 'silent renew failed!', error); this.flowsDataService.resetSilentRenewRunning(config); return throwError(() => new Error(error)); })); return refreshEventWithErrorHandler$; } getSmallestRefreshTimeFromConfigs(configsWithSilentRenewEnabled) { const result = configsWithSilentRenewEnabled.reduce((prev, curr) => prev.tokenRefreshInSeconds < curr.tokenRefreshInSeconds ? prev : curr); return result.tokenRefreshInSeconds; } getConfigsWithSilentRenewEnabled(allConfigs) { return allConfigs.filter((x) => x.silentRenew); } createRefreshEventForConfig(configuration, allConfigs) { this.loggerService.logDebug(configuration, 'starting silent renew...'); return this.configurationService.getOpenIDConfiguration(configuration.configId).pipe(switchMap((config) => { if (!config?.silentRenew) { this.resetAuthDataService.resetAuthorizationData(config, allConfigs); return of(null); } this.flowsDataService.setSilentRenewRunning(config); if (this.flowHelper.isCurrentFlowCodeFlowWithRefreshTokens(config)) { // Retrieve Dynamically Set Custom Params for refresh body const customParamsRefresh = this.storagePersistenceService.read('storageCustomParamsRefresh', config) || {}; const { customParamsRefreshTokenRequest } = config; const mergedParams = { ...customParamsRefreshTokenRequest, ...customParamsRefresh }; // Refresh Session using Refresh tokens return this.refreshSessionRefreshTokenService.refreshSessionWithRefreshTokens(config, allConfigs, mergedParams); } // Retrieve Dynamically Set Custom Params const customParams = this.storagePersistenceService.read('storageCustomParamsAuthRequest', config); return this.refreshSessionIframeService.refreshSessionWithIframe(config, allConfigs, customParams); })); } shouldStartPeriodicallyCheckForConfig(config) { const idToken = this.authStateService.getIdToken(config); const isSilentRenewRunning = this.flowsDataService.isSilentRenewRunning(config); const isCodeFlowinProgress = this.flowsDataService.isCodeFlowInProgress(config); const userDataFromStore = this.userService.getUserDataFromStore(config); this.loggerService.logDebug(config, `Checking: silentRenewRunning: ${isSilentRenewRunning}, isCodeFlowInProgress: ${isCodeFlowinProgress} - has idToken: ${!!idToken} - has userData: ${!!userDataFromStore}`); const shouldBeExecuted = !!userDataFromStore && !isSilentRenewRunning && !!idToken && !isCodeFlowinProgress; if (!shouldBeExecuted) { return false; } const idTokenStillValid = this.authStateService.hasIdTokenExpiredAndRenewCheckIsEnabled(config); const accessTokenHasExpired = this.authStateService.hasAccessTokenExpiredIfExpiryExists(config); if (!idTokenStillValid && !accessTokenHasExpired) { return false; } return true; } } PeriodicallyTokenCheckService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: PeriodicallyTokenCheckService, deps: [{ token: i1.ResetAuthDataService }, { token: i2.FlowHelper }, { token: i3.FlowsDataService }, { token: i4.LoggerService }, { token: i5.UserService }, { token: i6.AuthStateService }, { token: i7.RefreshSessionIframeService }, { token: i8.RefreshSessionRefreshTokenService }, { token: i9.IntervalService }, { token: i10.StoragePersistenceService }, { token: i11.PublicEventsService }, { token: i12.ConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable }); PeriodicallyTokenCheckService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: PeriodicallyTokenCheckService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: PeriodicallyTokenCheckService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: i1.ResetAuthDataService }, { type: i2.FlowHelper }, { type: i3.FlowsDataService }, { type: i4.LoggerService }, { type: i5.UserService }, { type: i6.AuthStateService }, { type: i7.RefreshSessionIframeService }, { type: i8.RefreshSessionRefreshTokenService }, { type: i9.IntervalService }, { type: i10.StoragePersistenceService }, { type: i11.PublicEventsService }, { type: i12.ConfigurationService }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVyaW9kaWNhbGx5LXRva2VuLWNoZWNrLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWF1dGgtb2lkYy1jbGllbnQvc3JjL2xpYi9jYWxsYmFjay9wZXJpb2RpY2FsbHktdG9rZW4tY2hlY2suc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxRQUFRLEVBQWMsRUFBRSxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM1RCxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBU3ZELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7QUFTMUQsTUFBTSxPQUFPLDZCQUE2QjtJQUN4QyxZQUNtQixvQkFBMEMsRUFDMUMsVUFBc0IsRUFDdEIsZ0JBQWtDLEVBQ2xDLGFBQTRCLEVBQzVCLFdBQXdCLEVBQ3hCLGdCQUFrQyxFQUNsQywyQkFBd0QsRUFDeEQsaUNBQW9FLEVBQzdFLGVBQWdDLEVBQ3ZCLHlCQUFvRCxFQUNwRCxtQkFBd0MsRUFDeEMsb0JBQTBDO1FBWDFDLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFDMUMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ2xDLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsZ0NBQTJCLEdBQTNCLDJCQUEyQixDQUE2QjtRQUN4RCxzQ0FBaUMsR0FBakMsaUNBQWlDLENBQW1DO1FBQzdFLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQUN2Qiw4QkFBeUIsR0FBekIseUJBQXlCLENB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Q2hGLE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hGLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUV4RSxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FDekIsTUFBTSxFQUNOLGlDQUFpQyxvQkFBb0IsMkJBQTJCLG9CQUFvQixtQkFBbUIsQ0FBQyxDQUFDLE9BQU8sb0JBQW9CLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxDQUMxSyxDQUFDO1FBRUYsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsaUJBQWlCLElBQUksQ0FBQyxvQkFBb0IsSUFBSSxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQUM7UUFFNUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQ3JCLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7UUFFRCxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyx1Q0FBdUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoRyxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxtQ0FBbUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVoRyxJQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxxQkFBcUIsRUFBRTtZQUNoRCxPQUFPLEtBQUssQ0FBQztTQUNkO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDOzswSEFoS1UsNkJBQTZCOzhIQUE3Qiw2QkFBNkIsY0FEaEIsTUFBTTsyRkFDbkIsNkJBQTZCO2tCQUR6QyxVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgZm9ya0pvaW4sIE9ic2VydmFibGUsIG9mLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGNhdGNoRXJyb3IsIHN3aXRjaE1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgQXV0aFN0YXRlU2VydmljZSB9IGZyb20gJy4uL2F1dGgtc3RhdGUvYXV0aC1zdGF0ZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ29uZmlndXJhdGlvblNlcnZpY2UgfSBmcm9tICcuLi9jb25maWcvY29uZmlnLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBPcGVuSWRDb25maWd1cmF0aW9uIH0gZnJvbSAnLi4vY29uZmlnL29wZW5pZC1jb25maWd1cmF0aW9uJztcclxuaW1wb3J0IHsgQ2FsbGJhY2tDb250ZXh0IH0gZnJvbSAnLi4vZmxvd3MvY2FsbGJhY2stY29udGV4dCc7XHJcbmltcG9ydCB7IEZsb3dzRGF0YVNlcnZpY2UgfSBmcm9tICcuLi9mbG93cy9mbG93cy1kYXRhLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBSZXNldEF1dGhEYXRhU2VydmljZSB9IGZyb20gJy4uL2Zsb3dzL3Jlc2V0LWF1dGgtZGF0YS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgUmVmcmVzaFNlc3Npb25JZnJhbWVTZXJ2aWNlIH0gZnJvbSAnLi4vaWZyYW1lL3JlZnJlc2gtc2Vzc2lvbi1pZnJhbWUuc2VydmljZSc7XHJcbmltcG9ydCB7IExvZ2dlclNlcnZpY2UgfSBmcm9tICcuLi9sb2dnaW5nL2xvZ2dlci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRXZlbnRUeXBlcyB9IGZyb20gJy4uL3B1YmxpYy1ldmVudHMvZXZlbnQtdHlwZXMnO1xyXG5pbXBvcnQgeyBQdWJsaWNFdmVudHNTZXJ2aWNlIH0gZnJvbSAnLi4vcHVibGljLWV2ZW50cy9wdWJsaWMtZXZlbnRzLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBTdG9yYWdlUGVyc2lzdGVuY2VTZXJ2aWNlIH0gZnJvbSAnLi4vc3RvcmFnZS9zdG9yYWdlLXBlcnNpc3RlbmNlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBVc2VyU2VydmljZSB9IGZyb20gJy4uL3VzZXItZGF0YS91c2VyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBGbG93SGVscGVyIH0gZnJvbSAnLi4vdXRpbHMvZmxvd0hlbHBlci9mbG93LWhlbHBlci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgSW50ZXJ2YWxTZXJ2aWNlIH0gZnJvbSAnLi9pbnRlcnZhbC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgUmVmcmVzaFNlc3Npb25SZWZyZXNoVG9rZW5TZXJ2aWNlIH0gZnJvbSAnLi9yZWZyZXNoLXNlc3Npb24tcmVmcmVzaC10b2tlbi5zZXJ2aWNlJztcclxuXHJcbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXHJcbmV4cG9ydCBjbGFzcyBQZXJpb2RpY2FsbHlUb2tlbkNoZWNrU2VydmljZSB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlc2V0QXV0aERhdGFTZXJ2aWNlOiBSZXNldEF1dGhEYXRhU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgZmxvd0hlbHBlcjogRmxvd0hlbHBlcixcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgZmxvd3NEYXRhU2VydmljZTogRmxvd3NEYXRhU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyU2VydmljZTogTG9nZ2VyU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgdXNlclNlcnZpY2U6IFVzZXJTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBhdXRoU3RhdGVTZXJ2aWNlOiBBdXRoU3RhdGVTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSByZWZyZXNoU2Vzc2lvbklmcmFtZVNlcnZpY2U6IFJlZnJlc2hTZXNzaW9uSWZyYW1lU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVmcmVzaFNlc3Npb25SZWZyZXNoVG9rZW5TZXJ2aWNlOiBSZWZyZXNoU2Vzc2lvblJlZnJlc2hUb2tlblNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGludGVydmFsU2VydmljZTogSW50ZXJ2YWxTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBzdG9yYWdlUGVyc2lzdGVuY2VTZXJ2aWNlOiBTdG9yYWdlUGVyc2lzdGVuY2VTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBwdWJsaWNFdmVudHNTZXJ2aWNlOiBQdWJsaWNFdmVudHNTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25maWd1cmF0aW9uU2VydmljZTogQ29uZmlndXJhdGlvblNlcnZpY2VcclxuICApIHt9XHJcblxyXG4gIHN0YXJ0VG9rZW5WYWxpZGF0aW9uUGVyaW9kaWNhbGx5KGFsbENvbmZpZ3M6IE9wZW5JZENvbmZpZ3VyYXRpb25bXSwgY3VycmVudENvbmZpZzogT3BlbklkQ29uZmlndXJhdGlvbik6IHZvaWQge1xyXG4gICAgY29uc3QgY29uZmlnc1dpdGhTaWxlbnRSZW5ld0VuYWJsZWQgPSB0aGlzLmdldENvbmZpZ3NXaXRoU2lsZW50UmVuZXdFbmFibGVkKGFsbENvbmZpZ3MpO1xyXG5cclxuICAgIGlmIChjb25maWdzV2l0aFNpbGVudFJlbmV3RW5hYmxlZC5sZW5ndGggPD0gMCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuaW50ZXJ2YWxTZXJ2aWNlLmlzVG9rZW5WYWxpZGF0aW9uUnVubmluZygpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCByZWZyZXNoVGltZUluU2Vjb25kcyA9IHRoaXMuZ2V0U21hbGxlc3RSZWZyZXNoVGltZUZyb21Db25maWdzKGNvbmZpZ3NXaXRoU2lsZW50UmVuZXdFbmFibGVkKTtcclxuICAgIGNvbnN0IHBlcmlvZGljYWxseUNoZWNrJCA9IHRoaXMuaW50ZXJ2YWxTZXJ2aWNlLnN0YXJ0UGVyaW9kaWNUb2tlbkNoZWNrKHJlZnJlc2hUaW1lSW5TZWNvbmRzKS5waXBlKFxyXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IG9iamVjdFdpdGhDb25maWdJZHNBbmRSZWZyZXNoRXZlbnQgPSB7fTtcclxuXHJcbiAgICAgICAgY29uZmlnc1dpdGhTaWxlbnRSZW5ld0VuYWJsZWQuZm9yRWFjaCgoY29uZmlnKSA9PiB7XHJcbiAgICAgICAgICBvYmplY3RXaXRoQ29uZmlnSWRzQW5kUmVmcmVzaEV2ZW50W2NvbmZpZy5jb25maWdJZF0gPSB0aGlzLmdldFJlZnJlc2hFdmVudChjb25maWcsIGFsbENvbmZpZ3MpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gZm9ya0pvaW4ob2JqZWN0V2l0aENvbmZpZ0lkc0FuZFJlZnJlc2hFdmVudCk7XHJcbiAgICAgIH0pXHJcbiAgICApO1xyXG5cclxuICAgIHRoaXMuaW50ZXJ2YWxTZXJ2aWNlLnJ1blRva2VuVmFsaWRhdGlvblJ1bm5pbmcgPSBwZXJpb2RpY2FsbHlDaGVjayRcclxuICAgICAgLnBpcGUoY2F0Y2hFcnJvcigoZXJyb3IpID0+IHRocm93RXJyb3IoKCkgPT4gbmV3IEVycm9yKGVycm9yKSkpKVxyXG4gICAgICAuc3Vic2NyaWJlKHtcclxuICAgICAgICBuZXh0OiAob2JqZWN0V2l0aENvbmZpZ0lkcykgPT4ge1xyXG4gICAgICAgICAgZm9yIChjb25zdCBbY29uZmlnSWQsIF9dIG9mIE9iamVjdC5lbnRyaWVzKG9iamVjdFdpdGhDb25maWdJZHMpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvblNlcnZpY2UuZ2V0T3BlbklEQ29uZmlndXJhdGlvbihjb25maWdJZCkuc3Vic2NyaWJlKChjb25maWcpID0+IHtcclxuICAgICAgICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UubG9nRGVidWcoY29uZmlnLCAnc2lsZW50IHJlbmV3LCBwZXJpb2RpYyBjaGVjayBmaW5pc2hlZCEnKTtcclxuXHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMuZmxvd0hlbHBlci5pc0N1cnJlbnRGbG93Q29kZUZsb3dXaXRoUmVmcmVzaFRva2Vucyhjb25maWcpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZsb3dzRGF0YVNlcnZpY2UucmVzZXRTaWxlbnRSZW5ld1J1bm5pbmcoY29uZmlnKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZXJyb3I6IChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZ0Vycm9yKGN1cnJlbnRDb25maWcsICdzaWxlbnQgcmVuZXcgZmFpbGVkIScsIGVycm9yKTtcclxuICAgICAgICB9LFxyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0UmVmcmVzaEV2ZW50KGNvbmZpZzogT3BlbklkQ29uZmlndXJhdGlvbiwgYWxsQ29uZmlnczogT3BlbklkQ29uZmlndXJhdGlvbltdKTogT2JzZXJ2YWJsZTxhbnk+IHtcclxuICAgIGNvbnN0IHNob3VsZFN0YXJ0UmVmcmVzaEV2ZW50ID0gdGhpcy5zaG91bGRTdGFydFBlcmlvZGljYWxseUNoZWNrRm9yQ29uZmlnKGNvbmZpZyk7XHJcblxyXG4gICAgaWYgKCFzaG91bGRTdGFydFJlZnJlc2hFdmVudCkge1xyXG4gICAgICByZXR1cm4gb2YobnVsbCk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgcmVmcmVzaEV2ZW50JCA9IHRoaXMuY3JlYXRlUmVmcmVzaEV2ZW50Rm9yQ29uZmlnKGNvbmZpZywgYWxsQ29uZmlncyk7XHJcblxyXG4gICAgdGhpcy5wdWJsaWNFdmVudHNTZXJ2aWNlLmZpcmVFdmVudChFdmVudFR5cGVzLlNpbGVudFJlbmV3U3RhcnRlZCk7XHJcblxyXG4gICAgY29uc3QgcmVmcmVzaEV2ZW50V2l0aEVycm9ySGFuZGxlciQgPSByZWZyZXNoRXZlbnQkLnBpcGUoXHJcbiAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZ0Vycm9yKGNvbmZpZywgJ3NpbGVudCByZW5ldyBmYWlsZWQhJywgZXJyb3IpO1xyXG4gICAgICAgIHRoaXMuZmxvd3NEYXRhU2VydmljZS5yZXNldFNpbGVudFJlbmV3UnVubmluZyhjb25maWcpO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgRXJyb3IoZXJyb3IpKTtcclxuICAgICAgfSlcclxuICAgICk7XHJcblxyXG4gICAgcmV0dXJuIHJlZnJlc2hFdmVudFdpdGhFcnJvckhhbmRsZXIkO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRTbWFsbGVzdFJlZnJlc2hUaW1lRnJvbUNvbmZpZ3MoY29uZmlnc1dpdGhTaWxlbnRSZW5ld0VuYWJsZWQ6IE9wZW5JZENvbmZpZ3VyYXRpb25bXSk6IG51bWJlciB7XHJcbiAgICBjb25zdCByZXN1bHQgPSBjb25maWdzV2l0aFNpbGVudFJlbmV3RW5hYmxlZC5yZWR1Y2UoKHByZXYsIGN1cnIpID0+XHJcbiAgICAgIHByZXYudG9rZW5SZWZyZXNoSW5TZWNvbmRzIDwgY3Vyci50b2tlblJlZnJlc2hJblNlY29uZHMgPyBwcmV2IDogY3VyclxyXG4gICAgKTtcclxuXHJcbiAgICByZXR1cm4gcmVzdWx0LnRva2VuUmVmcmVzaEluU2Vjb25kcztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0Q29uZmlnc1dpdGhTaWxlbnRSZW5ld0VuYWJsZWQoYWxsQ29uZmlnczogT3BlbklkQ29uZmlndXJhdGlvbltdKTogT3BlbklkQ29uZmlndXJhdGlvbltdIHtcclxuICAgIHJldHVybiBhbGxDb25maWdzLmZpbHRlcigoeCkgPT4geC5zaWxlbnRSZW5ldyk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNyZWF0ZVJlZnJlc2hFdmVudEZvckNvbmZpZyhcclxuICAgIGNvbmZpZ3VyYXRpb246IE9wZW5JZENvbmZpZ3VyYXRpb24sXHJcbiAgICBhbGxDb25maWdzOiBPcGVuSWRDb25maWd1cmF0aW9uW11cclxuICApOiBPYnNlcnZhYmxlPGJvb2xlYW4gfCBDYWxsYmFja0NvbnRleHQ+IHtcclxuICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyhjb25maWd1cmF0aW9uLCAnc3RhcnRpbmcgc2lsZW50IHJlbmV3Li4uJyk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuY29uZmlndXJhdGlvblNlcnZpY2UuZ2V0T3BlbklEQ29uZmlndXJhdGlvbihjb25maWd1cmF0aW9uLmNvbmZpZ0lkKS5waXBlKFxyXG4gICAgICBzd2l0Y2hNYXAoKGNvbmZpZykgPT4ge1xyXG4gICAgICAgIGlmICghY29uZmlnPy5zaWxlbnRSZW5ldykge1xyXG4gICAgICAgICAgdGhpcy5yZXNldEF1dGhEYXRhU2VydmljZS5yZXNldEF1dGhvcml6YXRpb25EYXRhKGNvbmZpZywgYWxsQ29uZmlncyk7XHJcblxyXG4gICAgICAgICAgcmV0dXJuIG9mKG51bGwpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5mbG93c0RhdGFTZXJ2aWNlLnNldFNpbGVudFJlbmV3UnVubmluZyhjb25maWcpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5mbG93SGVscGVyLmlzQ3VycmVudEZsb3dDb2RlRmxvd1dpdGhSZWZyZXNoVG9rZW5zKGNvbmZpZykpIHtcclxuICAgICAgICAgIC8vIFJldHJpZXZlIER5bmFtaWNhbGx5IFNldCBDdXN0b20gUGFyYW1zIGZvciByZWZyZXNoIGJvZHlcclxuICAgICAgICAgIGNvbnN0IGN1c3RvbVBhcmFtc1JlZnJlc2g6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB9ID1cclxuICAgICAgICAgICAgdGhpcy5zdG9yYWdlUGVyc2lzdGVuY2VTZXJ2aWNlLnJlYWQoJ3N0b3JhZ2VDdXN0b21QYXJhbXNSZWZyZXNoJywgY29uZmlnKSB8fCB7fTtcclxuXHJcbiAgICAgICAgICBjb25zdCB7IGN1c3RvbVBhcmFtc1JlZnJlc2hUb2tlblJlcXVlc3QgfSA9IGNvbmZpZztcclxuXHJcbiAgICAgICAgICBjb25zdCBtZXJnZWRQYXJhbXMgPSB7IC4uLmN1c3RvbVBhcmFtc1JlZnJlc2hUb2tlblJlcXVlc3QsIC4uLmN1c3RvbVBhcmFtc1JlZnJlc2ggfTtcclxuXHJcbiAgICAgICAgICAvLyBSZWZyZXNoIFNlc3Npb24gdXNpbmcgUmVmcmVzaCB0b2tlbnNcclxuICAgICAgICAgIHJldHVybiB0aGlzLnJlZnJlc2hTZXNzaW9uUmVmcmVzaFRva2VuU2VydmljZS5yZWZyZXNoU2Vzc2lvbldpdGhSZWZyZXNoVG9rZW5zKGNvbmZpZywgYWxsQ29uZmlncywgbWVyZ2VkUGFyYW1zKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFJldHJpZXZlIER5bmFtaWNhbGx5IFNldCBDdXN0b20gUGFyYW1zXHJcbiAgICAgICAgY29uc3QgY3VzdG9tUGFyYW1zOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfSA9IHRoaXMuc3RvcmFnZVBlcnNpc3RlbmNlU2VydmljZS5yZWFkKFxyXG4gICAgICAgICAgJ3N0b3JhZ2VDdXN0b21QYXJhbXNBdXRoUmVxdWVzdCcsXHJcbiAgICAgICAgICBjb25maWdcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5yZWZyZXNoU2Vzc2lvbklmcmFtZVNlcnZpY2UucmVmcmVzaFNlc3Npb25XaXRoSWZyYW1lKGNvbmZpZywgYWxsQ29uZmlncywgY3VzdG9tUGFyYW1zKTtcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNob3VsZFN0YXJ0UGVyaW9kaWNhbGx5Q2hlY2tGb3JDb25maWcoY29uZmlnOiBPcGVuSWRDb25maWd1cmF0aW9uKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBpZFRva2VuID0gdGhpcy5hdXRoU3RhdGVTZXJ2aWNlLmdldElkVG9rZW4oY29uZmlnKTtcclxuICAgIGNvbnN0IGlzU2lsZW50UmVuZXdSdW5uaW5nID0gdGhpcy5mbG93c0RhdGFTZXJ2aWNlLmlzU2lsZW50UmVuZXdSdW5uaW5nKGNvbmZpZyk7XHJcbiAgICBjb25zdCBpc0NvZGVGbG93aW5Qcm9ncmVzcyA9IHRoaXMuZmxvd3NEYXRhU2VydmljZS5pc0NvZGVGbG93SW5Qcm9ncmVzcyhjb25maWcpO1xyXG4gICAgY29uc3QgdXNlckRhdGFGcm9tU3RvcmUgPSB0aGlzLnVzZXJTZXJ2aWNlLmdldFVzZXJEYXRhRnJvbVN0b3JlKGNvbmZpZyk7XHJcblxyXG4gICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKFxyXG4gICAgICBjb25maWcsXHJcbiAgICAgIGBDaGVja2luZzogc2lsZW50UmVuZXdSdW5uaW5nOiAke2lzU2lsZW50UmVuZXdSdW5uaW5nfSwgaXNDb2RlRmxvd0luUHJvZ3Jlc3M6ICR7aXNDb2RlRmxvd2luUHJvZ3Jlc3N9IC0gaGFzIGlkVG9rZW46ICR7ISFpZFRva2VufSAtIGhhcyB1c2VyRGF0YTogJHshIXVzZXJEYXRhRnJvbVN0b3JlfWBcclxuICAgICk7XHJcblxyXG4gICAgY29uc3Qgc2hvdWxkQmVFeGVjdXRlZCA9ICEhdXNlckRhdGFGcm9tU3RvcmUgJiYgIWlzU2lsZW50UmVuZXdSdW5uaW5nICYmICEhaWRUb2tlbiAmJiAhaXNDb2RlRmxvd2luUHJvZ3Jlc3M7XHJcblxyXG4gICAgaWYgKCFzaG91bGRCZUV4ZWN1dGVkKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBpZFRva2VuU3RpbGxWYWxpZCA9IHRoaXMuYXV0aFN0YXRlU2VydmljZS5oYXNJZFRva2VuRXhwaXJlZEFuZFJlbmV3Q2hlY2tJc0VuYWJsZWQoY29uZmlnKTtcclxuICAgIGNvbnN0IGFjY2Vzc1Rva2VuSGFzRXhwaXJlZCA9IHRoaXMuYXV0aFN0YXRlU2VydmljZS5oYXNBY2Nlc3NUb2tlbkV4cGlyZWRJZkV4cGlyeUV4aXN0cyhjb25maWcpO1xyXG5cclxuICAgIGlmICghaWRUb2tlblN0aWxsVmFsaWQgJiYgIWFjY2Vzc1Rva2VuSGFzRXhwaXJlZCkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG59XHJcbiJdfQ==