UNPKG

angular-auth-oidc-client

Version:
149 lines 29.2 kB
import { Injectable } from '@angular/core'; import { forkJoin, of, throwError } from 'rxjs'; import { catchError, map, switchMap, tap } from 'rxjs/operators'; import { EventTypes } from '../public-events/event-types'; import * as i0 from "@angular/core"; import * as i1 from "../iframe/check-session.service"; import * as i2 from "../utils/url/current-url.service"; import * as i3 from "../iframe/silent-renew.service"; import * as i4 from "../user-data/user.service"; import * as i5 from "../logging/logger.service"; import * as i6 from "../auth-state/auth-state.service"; import * as i7 from "../callback/callback.service"; import * as i8 from "../callback/refresh-session.service"; import * as i9 from "../callback/periodically-token-check.service"; import * as i10 from "../login/popup/popup.service"; import * as i11 from "../auto-login/auto-login.service"; import * as i12 from "../storage/storage-persistence.service"; import * as i13 from "../public-events/public-events.service"; export class CheckAuthService { constructor(checkSessionService, currentUrlService, silentRenewService, userService, loggerService, authStateService, callbackService, refreshSessionService, periodicallyTokenCheckService, popupService, autoLoginService, storagePersistenceService, publicEventsService) { this.checkSessionService = checkSessionService; this.currentUrlService = currentUrlService; this.silentRenewService = silentRenewService; this.userService = userService; this.loggerService = loggerService; this.authStateService = authStateService; this.callbackService = callbackService; this.refreshSessionService = refreshSessionService; this.periodicallyTokenCheckService = periodicallyTokenCheckService; this.popupService = popupService; this.autoLoginService = autoLoginService; this.storagePersistenceService = storagePersistenceService; this.publicEventsService = publicEventsService; } checkAuth(configuration, allConfigs, url) { this.publicEventsService.fireEvent(EventTypes.CheckingAuth); if (this.currentUrlService.currentUrlHasStateParam()) { const stateParamFromUrl = this.currentUrlService.getStateParamFromCurrentUrl(); configuration = this.getConfigurationWithUrlState([configuration], stateParamFromUrl); if (!configuration) { return throwError(() => new Error(`could not find matching config for state ${stateParamFromUrl}`)); } } return this.checkAuthWithConfig(configuration, allConfigs, url); } checkAuthMultiple(allConfigs, url) { if (this.currentUrlService.currentUrlHasStateParam()) { const stateParamFromUrl = this.currentUrlService.getStateParamFromCurrentUrl(); 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) { 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); return of({ isAuthenticated: false, errorMessage, userData: null, idToken: null, accessToken: null, configId: null }); } const currentUrl = url || this.currentUrlService.getCurrentUrl(); const { configId, authority } = config; this.loggerService.logDebug(config, `Working with config '${configId}' using ${authority}`); if (this.popupService.isCurrentlyInPopup()) { this.popupService.sendMessageToMainWindow(currentUrl); return of(null); } const isCallback = this.callbackService.isCallback(currentUrl); this.loggerService.logDebug(config, 'currentUrl to check auth with: ', currentUrl); const callback$ = isCallback ? this.callbackService.handleCallbackAndFireEvents(currentUrl, config, allConfigs) : of(null); return callback$.pipe(map(() => { const isAuthenticated = this.authStateService.areAuthStorageTokensValid(config); if (isAuthenticated) { this.startCheckSessionAndValidation(config, allConfigs); if (!isCallback) { this.authStateService.setAuthenticatedAndFireEvent(allConfigs); this.userService.publishUserDataIfExists(config, allConfigs); } } this.loggerService.logDebug(config, 'checkAuth completed - firing events now. isAuthenticated: ' + isAuthenticated); return { isAuthenticated, userData: this.userService.getUserDataFromStore(config), accessToken: this.authStateService.getAccessToken(config), idToken: this.authStateService.getIdToken(config), configId, }; }), tap(({ isAuthenticated }) => { this.publicEventsService.fireEvent(EventTypes.CheckingAuthFinished); if (isAuthenticated) { this.autoLoginService.checkSavedRedirectRouteAndNavigate(config); } }), catchError(({ message }) => { this.loggerService.logError(config, message); this.publicEventsService.fireEvent(EventTypes.CheckingAuthFinishedWithError, message); return of({ isAuthenticated: false, errorMessage: message, userData: null, idToken: null, accessToken: null, configId }); })); } 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) { 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]); } } CheckAuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: CheckAuthService, deps: [{ token: i1.CheckSessionService }, { token: i2.CurrentUrlService }, { token: i3.SilentRenewService }, { token: i4.UserService }, { token: i5.LoggerService }, { token: i6.AuthStateService }, { token: i7.CallbackService }, { token: i8.RefreshSessionService }, { token: i9.PeriodicallyTokenCheckService }, { token: i10.PopUpService }, { token: i11.AutoLoginService }, { token: i12.StoragePersistenceService }, { token: i13.PublicEventsService }], target: i0.ɵɵFactoryTarget.Injectable }); CheckAuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: CheckAuthService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: CheckAuthService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.CheckSessionService }, { type: i2.CurrentUrlService }, { type: i3.SilentRenewService }, { type: i4.UserService }, { type: i5.LoggerService }, { type: i6.AuthStateService }, { type: i7.CallbackService }, { type: i8.RefreshSessionService }, { type: i9.PeriodicallyTokenCheckService }, { type: i10.PopUpService }, { type: i11.AutoLoginService }, { type: i12.StoragePersistenceService }, { type: i13.PublicEventsService }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2stYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1hdXRoLW9pZGMtY2xpZW50L3NyYy9saWIvYXV0aC1zdGF0ZS9jaGVjay1hdXRoLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsUUFBUSxFQUFjLEVBQUUsRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDNUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBWWpFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7O0FBTzFELE1BQU0sT0FBTyxnQkFBZ0I7SUFDM0IsWUFDbUIsbUJBQXdDLEVBQ3hDLGlCQUFvQyxFQUNwQyxrQkFBc0MsRUFDdEMsV0FBd0IsRUFDeEIsYUFBNEIsRUFDNUIsZ0JBQWtDLEVBQ2xDLGVBQWdDLEVBQ2hDLHFCQUE0QyxFQUM1Qyw2QkFBNEQsRUFDNUQsWUFBMEIsRUFDMUIsZ0JBQWtDLEVBQ2xDLHlCQUFvRCxFQUNwRCxtQkFBd0M7UUFaeEMsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtRQUN4QyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ3BDLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDdEMsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyxvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFDaEMsMEJBQXFCLEdBQXJCLHFCQUFxQixDQUF1QjtRQUM1QyxrQ0FBNkIsR0FBN0IsNkJBQTZCLENBQStCO1FBQzVELGlCQUFZLEdB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MkIsQ0FDakMsY0FBcUMsRUFDckMsWUFBaUMsRUFDakMsR0FBWTtRQUVaLE1BQU0sZUFBZSxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLEtBQUssWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRTNGLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFlBQVksRUFBRSxjQUFjLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFeEYsTUFBTSxxQkFBcUIsR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDM0QsTUFBTSxFQUFFLFdBQVcsRUFBRSxHQUFHLE1BQU0sQ0FBQztZQUUvQixPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3ZFLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxRQUFRLENBQUMsQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLHFCQUFxQixDQUFDLENBQUMsQ0FBQztJQUNuRSxDQUFDOzs2R0FoTFUsZ0JBQWdCO2lIQUFoQixnQkFBZ0I7MkZBQWhCLGdCQUFnQjtrQkFENUIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgZm9ya0pvaW4sIE9ic2VydmFibGUsIG9mLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGNhdGNoRXJyb3IsIG1hcCwgc3dpdGNoTWFwLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IEF1dGhTdGF0ZVNlcnZpY2UgfSBmcm9tICcuLi9hdXRoLXN0YXRlL2F1dGgtc3RhdGUuc2VydmljZSc7XHJcbmltcG9ydCB7IEF1dG9Mb2dpblNlcnZpY2UgfSBmcm9tICcuLi9hdXRvLWxvZ2luL2F1dG8tbG9naW4uc2VydmljZSc7XHJcbmltcG9ydCB7IENhbGxiYWNrU2VydmljZSB9IGZyb20gJy4uL2NhbGxiYWNrL2NhbGxiYWNrLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBQZXJpb2RpY2FsbHlUb2tlbkNoZWNrU2VydmljZSB9IGZyb20gJy4uL2NhbGxiYWNrL3BlcmlvZGljYWxseS10b2tlbi1jaGVjay5zZXJ2aWNlJztcclxuaW1wb3J0IHsgUmVmcmVzaFNlc3Npb25TZXJ2aWNlIH0gZnJvbSAnLi4vY2FsbGJhY2svcmVmcmVzaC1zZXNzaW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBPcGVuSWRDb25maWd1cmF0aW9uIH0gZnJvbSAnLi4vY29uZmlnL29wZW5pZC1jb25maWd1cmF0aW9uJztcclxuaW1wb3J0IHsgQ2hlY2tTZXNzaW9uU2VydmljZSB9IGZyb20gJy4uL2lmcmFtZS9jaGVjay1zZXNzaW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBTaWxlbnRSZW5ld1NlcnZpY2UgfSBmcm9tICcuLi9pZnJhbWUvc2lsZW50LXJlbmV3LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMb2dnZXJTZXJ2aWNlIH0gZnJvbSAnLi4vbG9nZ2luZy9sb2dnZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IExvZ2luUmVzcG9uc2UgfSBmcm9tICcuLi9sb2dpbi9sb2dpbi1yZXNwb25zZSc7XHJcbmltcG9ydCB7IFBvcFVwU2VydmljZSB9IGZyb20gJy4uL2xvZ2luL3BvcHVwL3BvcHVwLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBFdmVudFR5cGVzIH0gZnJvbSAnLi4vcHVibGljLWV2ZW50cy9ldmVudC10eXBlcyc7XHJcbmltcG9ydCB7IFB1YmxpY0V2ZW50c1NlcnZpY2UgfSBmcm9tICcuLi9wdWJsaWMtZXZlbnRzL3B1YmxpYy1ldmVudHMuc2VydmljZSc7XHJcbmltcG9ydCB7IFN0b3JhZ2VQZXJzaXN0ZW5jZVNlcnZpY2UgfSBmcm9tICcuLi9zdG9yYWdlL3N0b3JhZ2UtcGVyc2lzdGVuY2Uuc2VydmljZSc7XHJcbmltcG9ydCB7IFVzZXJTZXJ2aWNlIH0gZnJvbSAnLi4vdXNlci1kYXRhL3VzZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IEN1cnJlbnRVcmxTZXJ2aWNlIH0gZnJvbSAnLi4vdXRpbHMvdXJsL2N1cnJlbnQtdXJsLnNlcnZpY2UnO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgQ2hlY2tBdXRoU2VydmljZSB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNoZWNrU2Vzc2lvblNlcnZpY2U6IENoZWNrU2Vzc2lvblNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGN1cnJlbnRVcmxTZXJ2aWNlOiBDdXJyZW50VXJsU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgc2lsZW50UmVuZXdTZXJ2aWNlOiBTaWxlbnRSZW5ld1NlcnZpY2UsXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IHVzZXJTZXJ2aWNlOiBVc2VyU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyU2VydmljZTogTG9nZ2VyU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgYXV0aFN0YXRlU2VydmljZTogQXV0aFN0YXRlU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2FsbGJhY2tTZXJ2aWNlOiBDYWxsYmFja1NlcnZpY2UsXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlZnJlc2hTZXNzaW9uU2VydmljZTogUmVmcmVzaFNlc3Npb25TZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBwZXJpb2RpY2FsbHlUb2tlbkNoZWNrU2VydmljZTogUGVyaW9kaWNhbGx5VG9rZW5DaGVja1NlcnZpY2UsXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IHBvcHVwU2VydmljZTogUG9wVXBTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBhdXRvTG9naW5TZXJ2aWNlOiBBdXRvTG9naW5TZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBzdG9yYWdlUGVyc2lzdGVuY2VTZXJ2aWNlOiBTdG9yYWdlUGVyc2lzdGVuY2VTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBwdWJsaWNFdmVudHNTZXJ2aWNlOiBQdWJsaWNFdmVudHNTZXJ2aWNlXHJcbiAgKSB7fVxyXG5cclxuICBjaGVja0F1dGgoY29uZmlndXJhdGlvbjogT3BlbklkQ29uZmlndXJhdGlvbiwgYWxsQ29uZmlnczogT3BlbklkQ29uZmlndXJhdGlvbltdLCB1cmw/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPExvZ2luUmVzcG9uc2U+IHtcclxuICAgIHRoaXMucHVibGljRXZlbnRzU2VydmljZS5maXJlRXZlbnQoRXZlbnRUeXBlcy5DaGVja2luZ0F1dGgpO1xyXG5cclxuICAgIGlmICh0aGlzLmN1cnJlbnRVcmxTZXJ2aWNlLmN1cnJlbnRVcmxIYXNTdGF0ZVBhcmFtKCkpIHtcclxuICAgICAgY29uc3Qgc3RhdGVQYXJhbUZyb21VcmwgPSB0aGlzLmN1cnJlbnRVcmxTZXJ2aWNlLmdldFN0YXRlUGFyYW1Gcm9tQ3VycmVudFVybCgpO1xyXG5cclxuICAgICAgY29uZmlndXJhdGlvbiA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbldpdGhVcmxTdGF0ZShbY29uZmlndXJhdGlvbl0sIHN0YXRlUGFyYW1Gcm9tVXJsKTtcclxuXHJcbiAgICAgIGlmICghY29uZmlndXJhdGlvbikge1xyXG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IG5ldyBFcnJvcihgY291bGQgbm90IGZpbmQgbWF0Y2hpbmcgY29uZmlnIGZvciBzdGF0ZSAke3N0YXRlUGFyYW1Gcm9tVXJsfWApKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLmNoZWNrQXV0aFdpdGhDb25maWcoY29uZmlndXJhdGlvbiwgYWxsQ29uZmlncywgdXJsKTtcclxuICB9XHJcblxyXG4gIGNoZWNrQXV0aE11bHRpcGxlKGFsbENvbmZpZ3M6IE9wZW5JZENvbmZpZ3VyYXRpb25bXSwgdXJsPzogc3RyaW5nKTogT2JzZXJ2YWJsZTxMb2dpblJlc3BvbnNlW10+IHtcclxuICAgIGlmICh0aGlzLmN1cnJlbnRVcmxTZXJ2aWNlLmN1cnJlbnRVcmxIYXNTdGF0ZVBhcmFtKCkpIHtcclxuICAgICAgY29uc3Qgc3RhdGVQYXJhbUZyb21VcmwgPSB0aGlzLmN1cnJlbnRVcmxTZXJ2aWNlLmdldFN0YXRlUGFyYW1Gcm9tQ3VycmVudFVybCgpO1xyXG4gICAgICBjb25zdCBjb25maWcgPSB0aGlzLmdldENvbmZpZ3VyYXRpb25XaXRoVXJsU3RhdGUoYWxsQ29uZmlncywgc3RhdGVQYXJhbUZyb21VcmwpO1xyXG5cclxuICAgICAgaWYgKCFjb25maWcpIHtcclxuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgRXJyb3IoYGNvdWxkIG5vdCBmaW5kIG1hdGNoaW5nIGNvbmZpZyBmb3Igc3RhdGUgJHtzdGF0ZVBhcmFtRnJvbVVybH1gKSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0aGlzLmNvbXBvc2VNdWx0aXBsZUxvZ2luUmVzdWx0cyhhbGxDb25maWdzLCBjb25maWcsIHVybCk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY29uZmlncyA9IGFsbENvbmZpZ3M7XHJcbiAgICBjb25zdCBhbGxDaGVja3MkID0gY29uZmlncy5tYXAoKHgpID0+IHRoaXMuY2hlY2tBdXRoV2l0aENvbmZpZyh4LCBjb25maWdzLCB1cmwpKTtcclxuXHJcbiAgICByZXR1cm4gZm9ya0pvaW4oYWxsQ2hlY2tzJCk7XHJcbiAgfVxyXG5cclxuICBjaGVja0F1dGhJbmNsdWRpbmdTZXJ2ZXIoY29uZmlndXJhdGlvbjogT3BlbklkQ29uZmlndXJhdGlvbiwgYWxsQ29uZmlnczogT3BlbklkQ29uZmlndXJhdGlvbltdKTogT2JzZXJ2YWJsZTxMb2dpblJlc3BvbnNlPiB7XHJcbiAgICByZXR1cm4gdGhpcy5jaGVja0F1dGhXaXRoQ29uZmlnKGNvbmZpZ3VyYXRpb24sIGFsbENvbmZpZ3MpLnBpcGUoXHJcbiAgICAgIHN3aXRjaE1hcCgobG9naW5SZXNwb25zZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHsgaXNBdXRoZW50aWNhdGVkIH0gPSBsb2dpblJlc3BvbnNlO1xyXG5cclxuICAgICAgICBpZiAoaXNBdXRoZW50aWNhdGVkKSB7XHJcbiAgICAgICAgICByZXR1cm4gb2YobG9naW5SZXNwb25zZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5yZWZyZXNoU2Vzc2lvblNlcnZpY2UuZm9yY2VSZWZyZXNoU2Vzc2lvbihjb25maWd1cmF0aW9uLCBhbGxDb25maWdzKS5waXBlKFxyXG4gICAgICAgICAgdGFwKChsb2dpblJlc3BvbnNlQWZ0ZXJSZWZyZXNoU2Vzc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBpZiAobG9naW5SZXNwb25zZUFmdGVyUmVmcmVzaFNlc3Npb24/LmlzQXV0aGVudGljYXRlZCkge1xyXG4gICAgICAgICAgICAgIHRoaXMuc3RhcnRDaGVja1Nlc3Npb25BbmRWYWxpZGF0aW9uKGNvbmZpZ3VyYXRpb24sIGFsbENvbmZpZ3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgICk7XHJcbiAgICAgIH0pXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjaGVja0F1dGhXaXRoQ29uZmlnKGNvbmZpZzogT3BlbklkQ29uZmlndXJhdGlvbiwgYWxsQ29uZmlnczogT3BlbklkQ29uZmlndXJhdGlvbltdLCB1cmw/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPExvZ2luUmVzcG9uc2U+IHtcclxuICAgIGlmICghY29uZmlnKSB7XHJcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9ICdQbGVhc2UgcHJvdmlkZSBhdCBsZWFzdCBvbmUgY29uZmlndXJhdGlvbiBiZWZvcmUgc2V0dGluZyB1cCB0aGUgbW9kdWxlJztcclxuXHJcbiAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dFcnJvcihjb25maWcsIGVycm9yTWVzc2FnZSk7XHJcblxyXG4gICAgICByZXR1cm4gb2YoeyBpc0F1dGhlbnRpY2F0ZWQ6IGZhbHNlLCBlcnJvck1lc3NhZ2UsIHVzZXJEYXRhOiBudWxsLCBpZFRva2VuOiBudWxsLCBhY2Nlc3NUb2tlbjogbnVsbCwgY29uZmlnSWQ6IG51bGwgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY3VycmVudFVybCA9IHVybCB8fCB0aGlzLmN1cnJlbnRVcmxTZXJ2aWNlLmdldEN1cnJlbnRVcmwoKTtcclxuICAgIGNvbnN0IHsgY29uZmlnSWQsIGF1dGhvcml0eSB9ID0gY29uZmlnO1xyXG5cclxuICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyhjb25maWcsIGBXb3JraW5nIHdpdGggY29uZmlnICcke2NvbmZpZ0lkfScgdXNpbmcgJHthdXRob3JpdHl9YCk7XHJcblxyXG4gICAgaWYgKHRoaXMucG9wdXBTZXJ2aWNlLmlzQ3VycmVudGx5SW5Qb3B1cCgpKSB7XHJcbiAgICAgIHRoaXMucG9wdXBTZXJ2aWNlLnNlbmRNZXNzYWdlVG9NYWluV2luZG93KGN1cnJlbnRVcmwpO1xyXG5cclxuICAgICAgcmV0dXJuIG9mKG51bGwpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGlzQ2FsbGJhY2sgPSB0aGlzLmNhbGxiYWNrU2VydmljZS5pc0NhbGxiYWNrKGN1cnJlbnRVcmwpO1xyXG5cclxuICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyhjb25maWcsICdjdXJyZW50VXJsIHRvIGNoZWNrIGF1dGggd2l0aDogJywgY3VycmVudFVybCk7XHJcblxyXG4gICAgY29uc3QgY2FsbGJhY2skID0gaXNDYWxsYmFjayA/IHRoaXMuY2FsbGJhY2tTZXJ2aWNlLmhhbmRsZUNhbGxiYWNrQW5kRmlyZUV2ZW50cyhjdXJyZW50VXJsLCBjb25maWcsIGFsbENvbmZpZ3MpIDogb2YobnVsbCk7XHJcblxyXG4gICAgcmV0dXJuIGNhbGxiYWNrJC5waXBlKFxyXG4gICAgICBtYXAoKCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGlzQXV0aGVudGljYXRlZCA9IHRoaXMuYXV0aFN0YXRlU2VydmljZS5hcmVBdXRoU3RvcmFnZVRva2Vuc1ZhbGlkKGNvbmZpZyk7XHJcblxyXG4gICAgICAgIGlmIChpc0F1dGhlbnRpY2F0ZWQpIHtcclxuICAgICAgICAgIHRoaXMuc3RhcnRDaGVja1Nlc3Npb25BbmRWYWxpZGF0aW9uKGNvbmZpZywgYWxsQ29uZmlncyk7XHJcblxyXG4gICAgICAgICAgaWYgKCFpc0NhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYXV0aFN0YXRlU2VydmljZS5zZXRBdXRoZW50aWNhdGVkQW5kRmlyZUV2ZW50KGFsbENvbmZpZ3MpO1xyXG4gICAgICAgICAgICB0aGlzLnVzZXJTZXJ2aWNlLnB1Ymxpc2hVc2VyRGF0YUlmRXhpc3RzKGNvbmZpZywgYWxsQ29uZmlncyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UubG9nRGVidWcoY29uZmlnLCAnY2hlY2tBdXRoIGNvbXBsZXRlZCAtIGZpcmluZyBldmVudHMgbm93LiBpc0F1dGhlbnRpY2F0ZWQ6ICcgKyBpc0F1dGhlbnRpY2F0ZWQpO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgaXNBdXRoZW50aWNhdGVkLFxyXG4gICAgICAgICAgdXNlckRhdGE6IHRoaXMudXNlclNlcnZpY2UuZ2V0VXNlckRhdGFGcm9tU3RvcmUoY29uZmlnKSxcclxuICAgICAgICAgIGFjY2Vzc1Rva2VuOiB0aGlzLmF1dGhTdGF0ZVNlcnZpY2UuZ2V0QWNjZXNzVG9rZW4oY29uZmlnKSxcclxuICAgICAgICAgIGlkVG9rZW46IHRoaXMuYXV0aFN0YXRlU2VydmljZS5nZXRJZFRva2VuKGNvbmZpZyksXHJcbiAgICAgICAgICBjb25maWdJZCxcclxuICAgICAgICB9O1xyXG4gICAgICB9KSxcclxuICAgICAgdGFwKCh7IGlzQXV0aGVudGljYXRlZCB9KSA9PiB7XHJcbiAgICAgICAgdGhpcy5wdWJsaWNFdmVudHNTZXJ2aWNlLmZpcmVFdmVudChFdmVudFR5cGVzLkNoZWNraW5nQXV0aEZpbmlzaGVkKTtcclxuXHJcbiAgICAgICAgaWYgKGlzQXV0aGVudGljYXRlZCkge1xyXG4gICAgICAgICAgdGhpcy5hdXRvTG9naW5TZXJ2aWNlLmNoZWNrU2F2ZWRSZWRpcmVjdFJvdXRlQW5kTmF2aWdhdGUoY29uZmlnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pLFxyXG4gICAgICBjYXRjaEVycm9yKCh7IG1lc3NhZ2UgfSkgPT4ge1xyXG4gICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2dFcnJvcihjb25maWcsIG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMucHVibGljRXZlbnRzU2VydmljZS5maXJlRXZlbnQoRXZlbnRUeXBlcy5DaGVja2luZ0F1dGhGaW5pc2hlZFdpdGhFcnJvciwgbWVzc2FnZSk7XHJcblxyXG4gICAgICAgIHJldHVybiBvZih7IGlzQXV0aGVudGljYXRlZDogZmFsc2UsIGVycm9yTWVzc2FnZTogbWVzc2FnZSwgdXNlckRhdGE6IG51bGwsIGlkVG9rZW46IG51bGwsIGFjY2Vzc1Rva2VuOiBudWxsLCBjb25maWdJZCB9KTtcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN0YXJ0Q2hlY2tTZXNzaW9uQW5kVmFsaWRhdGlvbihjb25maWc6IE9wZW5JZENvbmZpZ3VyYXRpb24sIGFsbENvbmZpZ3M6IE9wZW5JZENvbmZpZ3VyYXRpb25bXSk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuY2hlY2tTZXNzaW9uU2VydmljZS5pc0NoZWNrU2Vzc2lvbkNvbmZpZ3VyZWQoY29uZmlnKSkge1xyXG4gICAgICB0aGlzLmNoZWNrU2Vzc2lvblNlcnZpY2Uuc3RhcnQoY29uZmlnKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnBlcmlvZGljYWxseVRva2VuQ2hlY2tTZXJ2aWNlLnN0YXJ0VG9rZW5WYWxpZGF0aW9uUGVyaW9kaWNhbGx5KGFsbENvbmZpZ3MsIGNvbmZpZyk7XHJcblxyXG4gICAgaWYgKHRoaXMuc2lsZW50UmVuZXdTZXJ2aWNlLmlzU2lsZW50UmVuZXdDb25maWd1cmVkKGNvbmZpZykpIHtcclxuICAgICAgdGhpcy5zaWxlbnRSZW5ld1NlcnZpY2UuZ2V0T3JDcmVhdGVJZnJhbWUoY29uZmlnKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0Q29uZmlndXJhdGlvbldpdGhVcmxTdGF0ZShjb25maWd1cmF0aW9uczogT3BlbklkQ29uZmlndXJhdGlvbltdLCBzdGF0ZUZyb21Vcmw6IHN0cmluZyk6IE9wZW5JZENvbmZpZ3VyYXRpb24ge1xyXG4gICAgZm9yIChjb25zdCBjb25maWcgb2YgY29uZmlndXJhdGlvbnMpIHtcclxuICAgICAgY29uc3Qgc3RvcmVkU3RhdGUgPSB0aGlzLnN0b3JhZ2VQZXJzaXN0ZW5jZVNlcnZpY2UucmVhZCgnYXV0aFN0YXRlQ29udHJvbCcsIGNvbmZpZyk7XHJcblxyXG4gICAgICBpZiAoc3RvcmVkU3RhdGUgPT09IHN0YXRlRnJvbVVybCkge1xyXG4gICAgICAgIHJldHVybiBjb25maWc7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY29tcG9zZU11bHRpcGxlTG9naW5SZXN1bHRzKFxyXG4gICAgY29uZmlndXJhdGlvbnM6IE9wZW5JZENvbmZpZ3VyYXRpb25bXSxcclxuICAgIGFjdGl2ZUNvbmZpZzogT3BlbklkQ29uZmlndXJhdGlvbixcclxuICAgIHVybD86IHN0cmluZ1xyXG4gICk6IE9ic2VydmFibGU8TG9naW5SZXNwb25zZVtdPiB7XHJcbiAgICBjb25zdCBhbGxPdGhlckNvbmZpZ3MgPSBjb25maWd1cmF0aW9ucy5maWx0ZXIoKHgpID0+IHguY29uZmlnSWQgIT09IGFjdGl2ZUNvbmZpZy5jb25maWdJZCk7XHJcblxyXG4gICAgY29uc3QgY3VycmVudENvbmZpZ1Jlc3VsdCA9IHRoaXMuY2hlY2tBdXRoV2l0aENvbmZpZyhhY3RpdmVDb25maWcsIGNvbmZpZ3VyYXRpb25zLCB1cmwpO1xyXG5cclxuICAgIGNvbnN0IGFsbE90aGVyQ29uZmlnUmVzdWx0cyA9IGFsbE90aGVyQ29uZmlncy5tYXAoKGNvbmZpZykgPT4ge1xyXG4gICAgICBjb25zdCB7IHJlZGlyZWN0VXJsIH0gPSBjb25maWc7XHJcblxyXG4gICAgICByZXR1cm4gdGhpcy5jaGVja0F1dGhXaXRoQ29uZmlnKGNvbmZpZywgY29uZmlndXJhdGlvbnMsIHJlZGlyZWN0VXJsKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiBmb3JrSm9pbihbY3VycmVudENvbmZpZ1Jlc3VsdCwgLi4uYWxsT3RoZXJDb25maWdSZXN1bHRzXSk7XHJcbiAgfVxyXG59XHJcbiJdfQ==