UNPKG

angular-auth-oidc-client

Version:
205 lines 35.8 kB
import { inject, Injectable } from '@angular/core'; import { forkJoin, of, throwError } from 'rxjs'; import { catchError, map, switchMap, tap } from 'rxjs/operators'; import { AutoLoginService } from '../auto-login/auto-login.service'; import { CallbackService } from '../callback/callback.service'; import { PeriodicallyTokenCheckService } from '../callback/periodically-token-check.service'; import { RefreshSessionService } from '../callback/refresh-session.service'; import { CheckSessionService } from '../iframe/check-session.service'; import { SilentRenewService } from '../iframe/silent-renew.service'; import { LoggerService } from '../logging/logger.service'; import { PopUpService } from '../login/popup/popup.service'; import { EventTypes } from '../public-events/event-types'; import { PublicEventsService } from '../public-events/public-events.service'; import { StoragePersistenceService } from '../storage/storage-persistence.service'; import { UserService } from '../user-data/user.service'; import { CurrentUrlService } from '../utils/url/current-url.service'; import { AuthStateService } from './auth-state.service'; import * as i0 from "@angular/core"; export class CheckAuthService { constructor() { this.checkSessionService = inject(CheckSessionService); this.currentUrlService = inject(CurrentUrlService); this.silentRenewService = inject(SilentRenewService); this.userService = inject(UserService); this.loggerService = inject(LoggerService); this.authStateService = inject(AuthStateService); this.callbackService = inject(CallbackService); this.refreshSessionService = inject(RefreshSessionService); this.periodicallyTokenCheckService = inject(PeriodicallyTokenCheckService); this.popupService = inject(PopUpService); this.autoLoginService = inject(AutoLoginService); this.storagePersistenceService = inject(StoragePersistenceService); this.publicEventsService = inject(PublicEventsService); } getConfig(configuration, url) { const stateParamFromUrl = this.currentUrlService.getStateParamFromCurrentUrl(url); return Boolean(stateParamFromUrl) ? this.getConfigurationWithUrlState([configuration], stateParamFromUrl) : configuration; } checkAuth(configuration, allConfigs, url) { if (!configuration) { return throwError(() => new Error('Please provide a configuration before setting up the module')); } this.publicEventsService.fireEvent(EventTypes.CheckingAuth); const stateParamFromUrl = this.currentUrlService.getStateParamFromCurrentUrl(url); const config = this.getConfig(configuration, url); if (!config) { return throwError(() => new Error(`could not find matching config for state ${stateParamFromUrl}`)); } return this.checkAuthWithConfig(configuration, allConfigs, url); } checkAuthMultiple(allConfigs, url) { const stateParamFromUrl = this.currentUrlService.getStateParamFromCurrentUrl(url); if (stateParamFromUrl) { const config = this.getConfigurationWithUrlState(allConfigs, stateParamFromUrl); if (!config) { return throwError(() => new Error(`could not find matching config for state ${stateParamFromUrl}`)); } return this.composeMultipleLoginResults(allConfigs, config, url); } const configs = allConfigs; const allChecks$ = configs.map((x) => this.checkAuthWithConfig(x, configs, url)); return forkJoin(allChecks$); } checkAuthIncludingServer(configuration, allConfigs) { if (!configuration) { return throwError(() => new Error('Please provide a configuration before setting up the module')); } return this.checkAuthWithConfig(configuration, allConfigs).pipe(switchMap((loginResponse) => { const { isAuthenticated } = loginResponse; if (isAuthenticated) { return of(loginResponse); } return this.refreshSessionService .forceRefreshSession(configuration, allConfigs) .pipe(tap((loginResponseAfterRefreshSession) => { if (loginResponseAfterRefreshSession?.isAuthenticated) { this.startCheckSessionAndValidation(configuration, allConfigs); } })); })); } checkAuthWithConfig(config, allConfigs, url) { if (!config) { const errorMessage = 'Please provide at least one configuration before setting up the module'; this.loggerService.logError(config, errorMessage); const result = { isAuthenticated: false, errorMessage, userData: null, idToken: '', accessToken: '', configId: '', }; return of(result); } const currentUrl = url || this.currentUrlService.getCurrentUrl(); if (!currentUrl) { const errorMessage = 'No URL found!'; this.loggerService.logError(config, errorMessage); const result = { isAuthenticated: false, errorMessage, userData: null, idToken: '', accessToken: '', configId: '', }; return of(result); } const { configId, authority } = config; this.loggerService.logDebug(config, `Working with config '${configId}' using '${authority}'`); if (this.popupService.isCurrentlyInPopup(config)) { this.popupService.sendMessageToMainWindow(currentUrl, config); const result = { isAuthenticated: false, errorMessage: '', userData: null, idToken: '', accessToken: '', configId: '', }; return of(result); } const isCallback = this.callbackService.isCallback(currentUrl, config); this.loggerService.logDebug(config, `currentUrl to check auth with: '${currentUrl}'`); const callback$ = isCallback ? this.callbackService.handleCallbackAndFireEvents(currentUrl, config, allConfigs) : of({}); return callback$.pipe(map(() => { const isAuthenticated = this.authStateService.areAuthStorageTokensValid(config); this.loggerService.logDebug(config, `checkAuth completed. Firing events now. isAuthenticated: ${isAuthenticated}`); if (isAuthenticated) { this.startCheckSessionAndValidation(config, allConfigs); if (!isCallback) { this.authStateService.setAuthenticatedAndFireEvent(allConfigs); this.userService.publishUserDataIfExists(config, allConfigs); } } this.publicEventsService.fireEvent(EventTypes.CheckingAuthFinished); const result = { isAuthenticated, userData: this.userService.getUserDataFromStore(config), accessToken: this.authStateService.getAccessToken(config), idToken: this.authStateService.getIdToken(config), configId, }; return result; }), tap(({ isAuthenticated }) => { if (isAuthenticated) { this.autoLoginService.checkSavedRedirectRouteAndNavigate(config); } }), catchError(({ message }) => { this.loggerService.logError(config, message); this.publicEventsService.fireEvent(EventTypes.CheckingAuthFinishedWithError, message); const result = { isAuthenticated: false, errorMessage: message, userData: null, idToken: '', accessToken: '', configId, }; return of(result); })); } startCheckSessionAndValidation(config, allConfigs) { if (this.checkSessionService.isCheckSessionConfigured(config)) { this.checkSessionService.start(config); } this.periodicallyTokenCheckService.startTokenValidationPeriodically(allConfigs, config); if (this.silentRenewService.isSilentRenewConfigured(config)) { this.silentRenewService.getOrCreateIframe(config); } } getConfigurationWithUrlState(configurations, stateFromUrl) { if (!stateFromUrl) { return null; } for (const config of configurations) { const storedState = this.storagePersistenceService.read('authStateControl', config); if (storedState === stateFromUrl) { return config; } } return null; } composeMultipleLoginResults(configurations, activeConfig, url) { const allOtherConfigs = configurations.filter((x) => x.configId !== activeConfig.configId); const currentConfigResult = this.checkAuthWithConfig(activeConfig, configurations, url); const allOtherConfigResults = allOtherConfigs.map((config) => { const { redirectUrl } = config; return this.checkAuthWithConfig(config, configurations, redirectUrl); }); return forkJoin([currentConfigResult, ...allOtherConfigResults]); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CheckAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CheckAuthService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CheckAuthService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2stYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1hdXRoLW9pZGMtY2xpZW50L3NyYy9saWIvYXV0aC1zdGF0ZS9jaGVjay1hdXRoLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLFFBQVEsRUFBYyxFQUFFLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVELE9BQU8sRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNwRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDL0QsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDN0YsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFFNUUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDdEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTFELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDMUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDN0UsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDbkYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDJCQUEyQixDQUFD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QU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVPLDJCQUEyQixDQUNqQyxjQUFxQyxFQUNyQyxZQUFpQyxFQUNqQyxHQUFZO1FBRVosTUFBTSxlQUFlLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FDM0MsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLEtBQUssWUFBWSxDQUFDLFFBQVEsQ0FDNUMsQ0FBQztRQUVGLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUNsRCxZQUFZLEVBQ1osY0FBYyxFQUNkLEdBQUcsQ0FDSixDQUFDO1FBRUYsTUFBTSxxQkFBcUIsR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDM0QsTUFBTSxFQUFFLFdBQVcsRUFBRSxHQUFHLE1BQU0sQ0FBQztZQUUvQixPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3ZFLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxRQUFRLENBQUMsQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLHFCQUFxQixDQUFDLENBQUMsQ0FBQztJQUNuRSxDQUFDOzhHQW5WVSxnQkFBZ0I7a0hBQWhCLGdCQUFnQixjQURILE1BQU07OzJGQUNuQixnQkFBZ0I7a0JBRDVCLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IGZvcmtKb2luLCBPYnNlcnZhYmxlLCBvZiwgdGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtYXAsIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyBBdXRvTG9naW5TZXJ2aWNlIH0gZnJvbSAnLi4vYXV0by1sb2dpbi9hdXRvLWxvZ2luLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBDYWxsYmFja1NlcnZpY2UgfSBmcm9tICcuLi9jYWxsYmFjay9jYWxsYmFjay5zZXJ2aWNlJztcclxuaW1wb3J0IHsgUGVyaW9kaWNhbGx5VG9rZW5DaGVja1NlcnZpY2UgfSBmcm9tICcuLi9jYWxsYmFjay9wZXJpb2RpY2FsbHktdG9rZW4tY2hlY2suc2VydmljZSc7XHJcbmltcG9ydCB7IFJlZnJlc2hTZXNzaW9uU2VydmljZSB9IGZyb20gJy4uL2NhbGxiYWNrL3JlZnJlc2gtc2Vzc2lvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgT3BlbklkQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL2NvbmZpZy9vcGVuaWQtY29uZmlndXJhdGlvbic7XHJcbmltcG9ydCB7IENoZWNrU2Vzc2lvblNlcnZpY2UgfSBmcm9tICcuLi9pZnJhbWUvY2hlY2stc2Vzc2lvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgU2lsZW50UmVuZXdTZXJ2aWNlIH0gZnJvbSAnLi4vaWZyYW1lL3NpbGVudC1yZW5ldy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTG9nZ2VyU2VydmljZSB9IGZyb20gJy4uL2xvZ2dpbmcvbG9nZ2VyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMb2dpblJlc3BvbnNlIH0gZnJvbSAnLi4vbG9naW4vbG9naW4tcmVzcG9uc2UnO1xyXG5pbXBvcnQgeyBQb3BVcFNlcnZpY2UgfSBmcm9tICcuLi9sb2dpbi9wb3B1cC9wb3B1cC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRXZlbnRUeXBlcyB9IGZyb20gJy4uL3B1YmxpYy1ldmVudHMvZXZlbnQtdHlwZXMnO1xyXG5pbXBvcnQgeyBQdWJsaWNFdmVudHNTZXJ2aWNlIH0gZnJvbSAnLi4vcHVibGljLWV2ZW50cy9wdWJsaWMtZXZlbnRzLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBTdG9yYWdlUGVyc2lzdGVuY2VTZXJ2aWNlIH0gZnJvbSAnLi4vc3RvcmFnZS9zdG9yYWdlLXBlcnNpc3RlbmNlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBVc2VyU2VydmljZSB9IGZyb20gJy4uL3VzZXItZGF0YS91c2VyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBDdXJyZW50VXJsU2VydmljZSB9IGZyb20gJy4uL3V0aWxzL3VybC9jdXJyZW50LXVybC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQXV0aFN0YXRlU2VydmljZSB9IGZyb20gJy4vYXV0aC1zdGF0ZS5zZXJ2aWNlJztcclxuXHJcbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXHJcbmV4cG9ydCBjbGFzcyBDaGVja0F1dGhTZXJ2aWNlIHtcclxuICBwcml2YXRlIHJlYWRvbmx5IGNoZWNrU2Vzc2lvblNlcnZpY2UgPSBpbmplY3QoQ2hlY2tTZXNzaW9uU2VydmljZSk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgY3VycmVudFVybFNlcnZpY2UgPSBpbmplY3QoQ3VycmVudFVybFNlcnZpY2UpO1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IHNpbGVudFJlbmV3U2VydmljZSA9IGluamVjdChTaWxlbnRSZW5ld1NlcnZpY2UpO1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IHVzZXJTZXJ2aWNlID0gaW5qZWN0KFVzZXJTZXJ2aWNlKTtcclxuXHJcbiAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXJTZXJ2aWNlID0gaW5qZWN0KExvZ2dlclNlcnZpY2UpO1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IGF1dGhTdGF0ZVNlcnZpY2UgPSBpbmplY3QoQXV0aFN0YXRlU2VydmljZSk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgY2FsbGJhY2tTZXJ2aWNlID0gaW5qZWN0KENhbGxiYWNrU2VydmljZSk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVmcmVzaFNlc3Npb25TZXJ2aWNlID0gaW5qZWN0KFJlZnJlc2hTZXNzaW9uU2VydmljZSk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgcGVyaW9kaWNhbGx5VG9rZW5DaGVja1NlcnZpY2UgPSBpbmplY3QoXHJcbiAgICBQZXJpb2RpY2FsbHlUb2tlbkNoZWNrU2VydmljZVxyXG4gICk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgcG9wdXBTZXJ2aWNlID0gaW5qZWN0KFBvcFVwU2VydmljZSk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgYXV0b0xvZ2luU2VydmljZSA9IGluamVjdChBdXRvTG9naW5TZXJ2aWNlKTtcclxuXHJcbiAgcHJpdmF0ZSByZWFkb25seSBzdG9yYWdlUGVyc2lzdGVuY2VTZXJ2aWNlID0gaW5qZWN0KFxyXG4gICAgU3RvcmFnZVBlcnNpc3RlbmNlU2VydmljZVxyXG4gICk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgcHVibGljRXZlbnRzU2VydmljZSA9IGluamVjdChQdWJsaWNFdmVudHNTZXJ2aWNlKTtcclxuXHJcbiAgcHJpdmF0ZSBnZXRDb25maWcoXHJcbiAgICBjb25maWd1cmF0aW9uOiBPcGVuSWRDb25maWd1cmF0aW9uLFxyXG4gICAgdXJsOiBzdHJpbmcgfCB1bmRlZmluZWRcclxuICApOiBPcGVuSWRDb25maWd1cmF0aW9uIHwgbnVsbCB7XHJcbiAgICBjb25zdCBzdGF0ZVBhcmFtRnJvbVVybCA9XHJcbiAgICAgIHRoaXMuY3VycmVudFVybFNlcnZpY2UuZ2V0U3RhdGVQYXJhbUZyb21DdXJyZW50VXJsKHVybCk7XHJcblxyXG4gICAgcmV0dXJuIEJvb2xlYW4oc3RhdGVQYXJhbUZyb21VcmwpXHJcbiAgICAgID8gdGhpcy5nZXRDb25maWd1cmF0aW9uV2l0aFVybFN0YXRlKFtjb25maWd1cmF0aW9uXSwgc3RhdGVQYXJhbUZyb21VcmwpXHJcbiAgICAgIDogY29uZmlndXJhdGlvbjtcclxuICB9XHJcblxyXG4gIGNoZWNrQXV0aChcclxuICAgIGNvbmZpZ3VyYXRpb246IE9wZW5JZENvbmZpZ3VyYXRpb24gfCBudWxsLFxyXG4gICAgYWxsQ29uZmlnczogT3BlbklkQ29uZmlndXJhdGlvbltdLFxyXG4gICAgdXJsPzogc3RyaW5nXHJcbiAgKTogT2JzZXJ2YWJsZTxMb2dpblJlc3BvbnNlPiB7XHJcbiAgICBpZiAoIWNvbmZpZ3VyYXRpb24pIHtcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoXHJcbiAgICAgICAgKCkgPT5cclxuICAgICAgICAgIG5ldyBFcnJvcihcclxuICAgICAgICAgICAgJ1BsZWFzZSBwcm92aWRlIGEgY29uZmlndXJhdGlvbiBiZWZvcmUgc2V0dGluZyB1cCB0aGUgbW9kdWxlJ1xyXG4gICAgICAgICAgKVxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMucHVibGljRXZlbnRzU2VydmljZS5maXJlRXZlbnQoRXZlbnRUeXBlcy5DaGVja2luZ0F1dGgpO1xyXG5cclxuICAgIGNvbnN0IHN0YXRlUGFyYW1Gcm9tVXJsID1cclxuICAgICAgdGhpcy5jdXJyZW50VXJsU2VydmljZS5nZXRTdGF0ZVBhcmFtRnJvbUN1cnJlbnRVcmwodXJsKTtcclxuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKGNvbmZpZ3VyYXRpb24sIHVybCk7XHJcblxyXG4gICAgaWYgKCFjb25maWcpIHtcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoXHJcbiAgICAgICAgKCkgPT5cclxuICAgICAgICAgIG5ldyBFcnJvcihcclxuICAgICAgICAgICAgYGNvdWxkIG5vdCBmaW5kIG1hdGNoaW5nIGNvbmZpZyBmb3Igc3RhdGUgJHtzdGF0ZVBhcmFtRnJvbVVybH1gXHJcbiAgICAgICAgICApXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuY2hlY2tBdXRoV2l0aENvbmZpZyhjb25maWd1cmF0aW9uLCBhbGxDb25maWdzLCB1cmwpO1xyXG4gIH1cclxuXHJcbiAgY2hlY2tBdXRoTXVsdGlwbGUoXHJcbiAgICBhbGxDb25maWdzOiBPcGVuSWRDb25maWd1cmF0aW9uW10sXHJcbiAgICB1cmw/OiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPExvZ2luUmVzcG9uc2VbXT4ge1xyXG4gICAgY29uc3Qgc3RhdGVQYXJhbUZyb21VcmwgPVxyXG4gICAgICB0aGlzLmN1cnJlbnRVcmxTZXJ2aWNlLmdldFN0YXRlUGFyYW1Gcm9tQ3VycmVudFVybCh1cmwpO1xyXG5cclxuICAgIGlmIChzdGF0ZVBhcmFtRnJvbVVybCkge1xyXG4gICAgICBjb25zdCBjb25maWcgPSB0aGlzLmdldENvbmZpZ3VyYXRpb25XaXRoVXJsU3RhdGUoXHJcbiAgICAgICAgYWxsQ29uZmlncyxcclxuICAgICAgICBzdGF0ZVBhcmFtRnJvbVVybFxyXG4gICAgICApO1xyXG5cclxuICAgICAgaWYgKCFjb25maWcpIHtcclxuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcihcclxuICAgICAgICAgICgpID0+XHJcbiAgICAgICAgICAgIG5ldyBFcnJvcihcclxuICAgICAgICAgICAgICBgY291bGQgbm90IGZpbmQgbWF0Y2hpbmcgY29uZmlnIGZvciBzdGF0ZSAke3N0YXRlUGFyYW1Gcm9tVXJsfWBcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0aGlzLmNvbXBvc2VNdWx0aXBsZUxvZ2luUmVzdWx0cyhhbGxDb25maWdzLCBjb25maWcsIHVybCk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY29uZmlncyA9IGFsbENvbmZpZ3M7XHJcbiAgICBjb25zdCBhbGxDaGVja3MkID0gY29uZmlncy5tYXAoKHgpID0+XHJcbiAgICAgIHRoaXMuY2hlY2tBdXRoV2l0aENvbmZpZyh4LCBjb25maWdzLCB1cmwpXHJcbiAgICApO1xyXG5cclxuICAgIHJldHVybiBmb3JrSm9pbihhbGxDaGVja3MkKTtcclxuICB9XHJcblxyXG4gIGNoZWNrQXV0aEluY2x1ZGluZ1NlcnZlcihcclxuICAgIGNvbmZpZ3VyYXRpb246IE9wZW5JZENvbmZpZ3VyYXRpb24gfCBudWxsLFxyXG4gICAgYWxsQ29uZmlnczogT3BlbklkQ29uZmlndXJhdGlvbltdXHJcbiAgKTogT2JzZXJ2YWJsZTxMb2dpblJlc3BvbnNlPiB7XHJcbiAgICBpZiAoIWNvbmZpZ3VyYXRpb24pIHtcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoXHJcbiAgICAgICAgKCkgPT5cclxuICAgICAgICAgIG5ldyBFcnJvcihcclxuICAgICAgICAgICAgJ1BsZWFzZSBwcm92aWRlIGEgY29uZmlndXJhdGlvbiBiZWZvcmUgc2V0dGluZyB1cCB0aGUgbW9kdWxlJ1xyXG4gICAgICAgICAgKVxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLmNoZWNrQXV0aFdpdGhDb25maWcoY29uZmlndXJhdGlvbiwgYWxsQ29uZmlncykucGlwZShcclxuICAgICAgc3dpdGNoTWFwKChsb2dpblJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgY29uc3QgeyBpc0F1dGhlbnRpY2F0ZWQgfSA9IGxvZ2luUmVzcG9uc2U7XHJcblxyXG4gICAgICAgIGlmIChpc0F1dGhlbnRpY2F0ZWQpIHtcclxuICAgICAgICAgIHJldHVybiBvZihsb2dpblJlc3BvbnNlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnJlZnJlc2hTZXNzaW9uU2VydmljZVxyXG4gICAgICAgICAgLmZvcmNlUmVmcmVzaFNlc3Npb24oY29uZmlndXJhdGlvbiwgYWxsQ29uZmlncylcclxuICAgICAgICAgIC5waXBlKFxyXG4gICAgICAgICAgICB0YXAoKGxvZ2luUmVzcG9uc2VBZnRlclJlZnJlc2hTZXNzaW9uKSA9PiB7XHJcbiAgICAgICAgICAgICAgaWYgKGxvZ2luUmVzcG9uc2VBZnRlclJlZnJlc2hTZXNzaW9uPy5pc0F1dGhlbnRpY2F0ZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RhcnRDaGVja1Nlc3Npb25BbmRWYWxpZGF0aW9uKGNvbmZpZ3VyYXRpb24sIGFsbENvbmZpZ3MpO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICk7XHJcbiAgICAgIH0pXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjaGVja0F1dGhXaXRoQ29uZmlnKFxyXG4gICAgY29uZmlnOiBPcGVuSWRDb25maWd1cmF0aW9uLFxyXG4gICAgYWxsQ29uZmlnczogT3BlbklkQ29uZmlndXJhdGlvbltdLFxyXG4gICAgdXJsPzogc3RyaW5nXHJcbiAgKTogT2JzZXJ2YWJsZTxMb2dpblJlc3BvbnNlPiB7XHJcbiAgICBpZiAoIWNvbmZpZykge1xyXG4gICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPVxyXG4gICAgICAgICdQbGVhc2UgcHJvdmlkZSBhdCBsZWFzdCBvbmUgY29uZmlndXJhdGlvbiBiZWZvcmUgc2V0dGluZyB1cCB0aGUgbW9kdWxlJztcclxuXHJcbiAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dFcnJvcihjb25maWcsIGVycm9yTWVzc2FnZSk7XHJcblxyXG4gICAgICBjb25zdCByZXN1bHQ6IExvZ2luUmVzcG9uc2UgPSB7XHJcbiAgICAgICAgaXNBdXRoZW50aWNhdGVkOiBmYWxzZSxcclxuICAgICAgICBlcnJvck1lc3NhZ2UsXHJcbiAgICAgICAgdXNlckRhdGE6IG51bGwsXHJcbiAgICAgICAgaWRUb2tlbjogJycsXHJcbiAgICAgICAgYWNjZXNzVG9rZW46ICcnLFxyXG4gICAgICAgIGNvbmZpZ0lkOiAnJyxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHJldHVybiBvZihyZXN1bHQpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGN1cnJlbnRVcmwgPSB1cmwgfHwgdGhpcy5jdXJyZW50VXJsU2VydmljZS5nZXRDdXJyZW50VXJsKCk7XHJcblxyXG4gICAgaWYgKCFjdXJyZW50VXJsKSB7XHJcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9ICdObyBVUkwgZm91bmQhJztcclxuXHJcbiAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dFcnJvcihjb25maWcsIGVycm9yTWVzc2FnZSk7XHJcblxyXG4gICAgICBjb25zdCByZXN1bHQ6IExvZ2luUmVzcG9uc2UgPSB7XHJcbiAgICAgICAgaXNBdXRoZW50aWNhdGVkOiBmYWxzZSxcclxuICAgICAgICBlcnJvck1lc3NhZ2UsXHJcbiAgICAgICAgdXNlckRhdGE6IG51bGwsXHJcbiAgICAgICAgaWRUb2tlbjogJycsXHJcbiAgICAgICAgYWNjZXNzVG9rZW46ICcnLFxyXG4gICAgICAgIGNvbmZpZ0lkOiAnJyxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHJldHVybiBvZihyZXN1bHQpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHsgY29uZmlnSWQsIGF1dGhvcml0eSB9ID0gY29uZmlnO1xyXG5cclxuICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dEZWJ1ZyhcclxuICAgICAgY29uZmlnLFxyXG4gICAgICBgV29ya2luZyB3aXRoIGNvbmZpZyAnJHtjb25maWdJZH0nIHVzaW5nICcke2F1dGhvcml0eX0nYFxyXG4gICAgKTtcclxuXHJcbiAgICBpZiAodGhpcy5wb3B1cFNlcnZpY2UuaXNDdXJyZW50bHlJblBvcHVwKGNvbmZpZykpIHtcclxuICAgICAgdGhpcy5wb3B1cFNlcnZpY2Uuc2VuZE1lc3NhZ2VUb01haW5XaW5kb3coY3VycmVudFVybCwgY29uZmlnKTtcclxuXHJcbiAgICAgIGNvbnN0IHJlc3VsdDogTG9naW5SZXNwb25zZSA9IHtcclxuICAgICAgICBpc0F1dGhlbnRpY2F0ZWQ6IGZhbHNlLFxyXG4gICAgICAgIGVycm9yTWVzc2FnZTogJycsXHJcbiAgICAgICAgdXNlckRhdGE6IG51bGwsXHJcbiAgICAgICAgaWRUb2tlbjogJycsXHJcbiAgICAgICAgYWNjZXNzVG9rZW46ICcnLFxyXG4gICAgICAgIGNvbmZpZ0lkOiAnJyxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHJldHVybiBvZihyZXN1bHQpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGlzQ2FsbGJhY2sgPSB0aGlzLmNhbGxiYWNrU2VydmljZS5pc0NhbGxiYWNrKGN1cnJlbnRVcmwsIGNvbmZpZyk7XHJcblxyXG4gICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKFxyXG4gICAgICBjb25maWcsXHJcbiAgICAgIGBjdXJyZW50VXJsIHRvIGNoZWNrIGF1dGggd2l0aDogJyR7Y3VycmVudFVybH0nYFxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBjYWxsYmFjayQgPSBpc0NhbGxiYWNrXHJcbiAgICAgID8gdGhpcy5jYWxsYmFja1NlcnZpY2UuaGFuZGxlQ2FsbGJhY2tBbmRGaXJlRXZlbnRzKFxyXG4gICAgICAgICAgY3VycmVudFVybCxcclxuICAgICAgICAgIGNvbmZpZyxcclxuICAgICAgICAgIGFsbENvbmZpZ3NcclxuICAgICAgICApXHJcbiAgICAgIDogb2Yoe30pO1xyXG5cclxuICAgIHJldHVybiBjYWxsYmFjayQucGlwZShcclxuICAgICAgbWFwKCgpID0+IHtcclxuICAgICAgICBjb25zdCBpc0F1dGhlbnRpY2F0ZWQgPVxyXG4gICAgICAgICAgdGhpcy5hdXRoU3RhdGVTZXJ2aWNlLmFyZUF1dGhTdG9yYWdlVG9rZW5zVmFsaWQoY29uZmlnKTtcclxuXHJcbiAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKFxyXG4gICAgICAgICAgY29uZmlnLFxyXG4gICAgICAgICAgYGNoZWNrQXV0aCBjb21wbGV0ZWQuIEZpcmluZyBldmVudHMgbm93LiBpc0F1dGhlbnRpY2F0ZWQ6ICR7aXNBdXRoZW50aWNhdGVkfWBcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICBpZiAoaXNBdXRoZW50aWNhdGVkKSB7XHJcbiAgICAgICAgICB0aGlzLnN0YXJ0Q2hlY2tTZXNzaW9uQW5kVmFsaWRhdGlvbihjb25maWcsIGFsbENvbmZpZ3MpO1xyXG5cclxuICAgICAgICAgIGlmICghaXNDYWxsYmFjaykge1xyXG4gICAgICAgICAgICB0aGlzLmF1dGhTdGF0ZVNlcnZpY2Uuc2V0QXV0aGVudGljYXRlZEFuZEZpcmVFdmVudChhbGxDb25maWdzKTtcclxuICAgICAgICAgICAgdGhpcy51c2VyU2VydmljZS5wdWJsaXNoVXNlckRhdGFJZkV4aXN0cyhjb25maWcsIGFsbENvbmZpZ3MpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnB1YmxpY0V2ZW50c1NlcnZpY2UuZmlyZUV2ZW50KEV2ZW50VHlwZXMuQ2hlY2tpbmdBdXRoRmluaXNoZWQpO1xyXG5cclxuICAgICAgICBjb25zdCByZXN1bHQ6IExvZ2luUmVzcG9uc2UgPSB7XHJcbiAgICAgICAgICBpc0F1dGhlbnRpY2F0ZWQsXHJcbiAgICAgICAgICB1c2VyRGF0YTogdGhpcy51c2VyU2VydmljZS5nZXRVc2VyRGF0YUZyb21TdG9yZShjb25maWcpLFxyXG4gICAgICAgICAgYWNjZXNzVG9rZW46IHRoaXMuYXV0aFN0YXRlU2VydmljZS5nZXRBY2Nlc3NUb2tlbihjb25maWcpLFxyXG4gICAgICAgICAgaWRUb2tlbjogdGhpcy5hdXRoU3RhdGVTZXJ2aWNlLmdldElkVG9rZW4oY29uZmlnKSxcclxuICAgICAgICAgIGNvbmZpZ0lkLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgIH0pLFxyXG4gICAgICB0YXAoKHsgaXNBdXRoZW50aWNhdGVkIH0pID0+IHtcclxuICAgICAgICBpZiAoaXNBdXRoZW50aWNhdGVkKSB7XHJcbiAgICAgICAgICB0aGlzLmF1dG9Mb2dpblNlcnZpY2UuY2hlY2tTYXZlZFJlZGlyZWN0Um91dGVBbmROYXZpZ2F0ZShjb25maWcpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSksXHJcbiAgICAgIGNhdGNoRXJyb3IoKHsgbWVzc2FnZSB9KSA9PiB7XHJcbiAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZ0Vycm9yKGNvbmZpZywgbWVzc2FnZSk7XHJcbiAgICAgICAgdGhpcy5wdWJsaWNFdmVudHNTZXJ2aWNlLmZpcmVFdmVudChcclxuICAgICAgICAgIEV2ZW50VHlwZXMuQ2hlY2tpbmdBdXRoRmluaXNoZWRXaXRoRXJyb3IsXHJcbiAgICAgICAgICBtZXNzYWdlXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgY29uc3QgcmVzdWx0OiBMb2dpblJlc3BvbnNlID0ge1xyXG4gICAgICAgICAgaXNBdXRoZW50aWNhdGVkOiBmYWxzZSxcclxuICAgICAgICAgIGVycm9yTWVzc2FnZTogbWVzc2FnZSxcclxuICAgICAgICAgIHVzZXJEYXRhOiBudWxsLFxyXG4gICAgICAgICAgaWRUb2tlbjogJycsXHJcbiAgICAgICAgICBhY2Nlc3NUb2tlbjogJycsXHJcbiAgICAgICAgICBjb25maWdJZCxcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gb2YocmVzdWx0KTtcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN0YXJ0Q2hlY2tTZXNzaW9uQW5kVmFsaWRhdGlvbihcclxuICAgIGNvbmZpZzogT3BlbklkQ29uZmlndXJhdGlvbixcclxuICAgIGFsbENvbmZpZ3M6IE9wZW5JZENvbmZpZ3VyYXRpb25bXVxyXG4gICk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuY2hlY2tTZXNzaW9uU2VydmljZS5pc0NoZWNrU2Vzc2lvbkNvbmZpZ3VyZWQoY29uZmlnKSkge1xyXG4gICAgICB0aGlzLmNoZWNrU2Vzc2lvblNlcnZpY2Uuc3RhcnQoY29uZmlnKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnBlcmlvZGljYWxseVRva2VuQ2hlY2tTZXJ2aWNlLnN0YXJ0VG9rZW5WYWxpZGF0aW9uUGVyaW9kaWNhbGx5KFxyXG4gICAgICBhbGxDb25maWdzLFxyXG4gICAgICBjb25maWdcclxuICAgICk7XHJcblxyXG4gICAgaWYgKHRoaXMuc2lsZW50UmVuZXdTZXJ2aWNlLmlzU2lsZW50UmVuZXdDb25maWd1cmVkKGNvbmZpZykpIHtcclxuICAgICAgdGhpcy5zaWxlbnRSZW5ld1NlcnZpY2UuZ2V0T3JDcmVhdGVJZnJhbWUoY29uZmlnKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0Q29uZmlndXJhdGlvbldpdGhVcmxTdGF0ZShcclxuICAgIGNvbmZpZ3VyYXRpb25zOiBPcGVuSWRDb25maWd1cmF0aW9uW10sXHJcbiAgICBzdGF0ZUZyb21Vcmw6IHN0cmluZyB8IG51bGxcclxuICApOiBPcGVuSWRDb25maWd1cmF0aW9uIHwgbnVsbCB7XHJcbiAgICBpZiAoIXN0YXRlRnJvbVVybCkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiBjb25maWd1cmF0aW9ucykge1xyXG4gICAgICBjb25zdCBzdG9yZWRTdGF0ZSA9IHRoaXMuc3RvcmFnZVBlcnNpc3RlbmNlU2VydmljZS5yZWFkKFxyXG4gICAgICAgICdhdXRoU3RhdGVDb250cm9sJyxcclxuICAgICAgICBjb25maWdcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGlmIChzdG9yZWRTdGF0ZSA9PT0gc3RhdGVGcm9tVXJsKSB7XHJcbiAgICAgICAgcmV0dXJuIGNvbmZpZztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb21wb3NlTXVsdGlwbGVMb2dpblJlc3VsdHMoXHJcbiAgICBjb25maWd1cmF0aW9uczogT3BlbklkQ29uZmlndXJhdGlvbltdLFxyXG4gICAgYWN0aXZlQ29uZmlnOiBPcGVuSWRDb25maWd1cmF0aW9uLFxyXG4gICAgdXJsPzogc3RyaW5nXHJcbiAgKTogT2JzZXJ2YWJsZTxMb2dpblJlc3BvbnNlW10+IHtcclxuICAgIGNvbnN0IGFsbE90aGVyQ29uZmlncyA9IGNvbmZpZ3VyYXRpb25zLmZpbHRlcihcclxuICAgICAgKHgpID0+IHguY29uZmlnSWQgIT09IGFjdGl2ZUNvbmZpZy5jb25maWdJZFxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBjdXJyZW50Q29uZmlnUmVzdWx0ID0gdGhpcy5jaGVja0F1dGhXaXRoQ29uZmlnKFxyXG4gICAgICBhY3RpdmVDb25maWcsXHJcbiAgICAgIGNvbmZpZ3VyYXRpb25zLFxyXG4gICAgICB1cmxcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgYWxsT3RoZXJDb25maWdSZXN1bHRzID0gYWxsT3RoZXJDb25maWdzLm1hcCgoY29uZmlnKSA9PiB7XHJcbiAgICAgIGNvbnN0IHsgcmVkaXJlY3RVcmwgfSA9IGNvbmZpZztcclxuXHJcbiAgICAgIHJldHVybiB0aGlzLmNoZWNrQXV0aFdpdGhDb25maWcoY29uZmlnLCBjb25maWd1cmF0aW9ucywgcmVkaXJlY3RVcmwpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIGZvcmtKb2luKFtjdXJyZW50Q29uZmlnUmVzdWx0LCAuLi5hbGxPdGhlckNvbmZpZ1Jlc3VsdHNdKTtcclxuICB9XHJcbn1cclxuIl19