UNPKG

abp-ng2-module

Version:

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.0.7.

174 lines 28.5 kB
import { Injectable } from '@angular/core'; import { of, BehaviorSubject } from 'rxjs'; import { LogService } from '../services/log/log.service'; import { TokenService } from '../services/auth/token.service'; import { UtilsService } from '../services/utils/utils.service'; import { HttpResponse, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; import { switchMap, filter, take, catchError, map } from 'rxjs/operators'; import { throwError } from 'rxjs'; import { RefreshTokenService } from './refresh-token.service'; import * as i0 from "@angular/core"; import * as i1 from "./abp-http-configuration.service"; export class AbpHttpInterceptor { _injector; configuration; _tokenService = new TokenService(); _utilsService = new UtilsService(); _logService = new LogService(); constructor(configuration, _injector) { this._injector = _injector; this.configuration = configuration; } intercept(request, next) { var modifiedRequest = this.normalizeRequestHeaders(request); return next.handle(modifiedRequest) .pipe(catchError(error => { if (error instanceof HttpErrorResponse && error.status === 401) { return this.tryAuthWithRefreshToken(request, next, error); } else { return this.handleErrorResponse(error); } }), switchMap((event) => { return this.handleSuccessResponse(event); })); } tryGetRefreshTokenService() { var _refreshTokenService = this._injector.get(RefreshTokenService, null); if (_refreshTokenService) { return _refreshTokenService.tryAuthWithRefreshToken(); } return of(false); } isRefreshing = false; refreshTokenSubject = new BehaviorSubject(null); tryAuthWithRefreshToken(request, next, error) { if (!this.isRefreshing) { this.isRefreshing = true; this.refreshTokenSubject.next(null); return this.tryGetRefreshTokenService().pipe(switchMap((authResult) => { this.isRefreshing = false; if (authResult) { this.refreshTokenSubject.next(authResult); let modifiedRequest = this.normalizeRequestHeaders(request); return next.handle(modifiedRequest); } else { return this.handleErrorResponse(error); } })); } else { return this.refreshTokenSubject.pipe(filter(authResult => authResult != null), take(1), switchMap(authResult => { let modifiedRequest = this.normalizeRequestHeaders(request); return next.handle(modifiedRequest); })); } } normalizeRequestHeaders(request) { var modifiedHeaders = new HttpHeaders(); modifiedHeaders = request.headers.set("Pragma", "no-cache") .set("Cache-Control", "no-cache") .set("Expires", "Sat, 01 Jan 2000 00:00:00 GMT"); modifiedHeaders = this.addXRequestedWithHeader(modifiedHeaders); modifiedHeaders = this.addAuthorizationHeaders(modifiedHeaders); modifiedHeaders = this.addAspNetCoreCultureHeader(modifiedHeaders); modifiedHeaders = this.addAcceptLanguageHeader(modifiedHeaders); modifiedHeaders = this.addTenantIdHeader(modifiedHeaders); return request.clone({ headers: modifiedHeaders }); } addXRequestedWithHeader(headers) { if (headers) { headers = headers.set('X-Requested-With', 'XMLHttpRequest'); } return headers; } addAspNetCoreCultureHeader(headers) { let cookieLangValue = this._utilsService.getCookieValue("Abp.Localization.CultureName"); if (cookieLangValue && headers && !headers.has('.AspNetCore.Culture')) { headers = headers.set('.AspNetCore.Culture', cookieLangValue); } return headers; } addAcceptLanguageHeader(headers) { let cookieLangValue = this._utilsService.getCookieValue("Abp.Localization.CultureName"); if (cookieLangValue && headers && !headers.has('Accept-Language')) { headers = headers.set('Accept-Language', cookieLangValue); } return headers; } addTenantIdHeader(headers) { let cookieTenantIdValue = this._utilsService.getCookieValue(abp.multiTenancy.tenantIdCookieName); if (cookieTenantIdValue && headers && !headers.has(abp.multiTenancy.tenantIdCookieName)) { headers = headers.set(abp.multiTenancy.tenantIdCookieName, cookieTenantIdValue); } return headers; } addAuthorizationHeaders(headers) { let authorizationHeaders = headers ? headers.getAll('Authorization') : null; if (!authorizationHeaders) { authorizationHeaders = []; } if (!this.itemExists(authorizationHeaders, (item) => item.indexOf('Bearer ') == 0)) { let token = this._tokenService.getToken(); if (headers && token) { headers = headers.set('Authorization', 'Bearer ' + token); } } return headers; } handleSuccessResponse(event) { var self = this; if (event instanceof HttpResponse) { if (event.body instanceof Blob && event.body.type && event.body.type.indexOf("application/json") >= 0) { return self.configuration.blobToText(event.body).pipe(map(json => { const responseBody = json == "null" ? {} : JSON.parse(json); var modifiedResponse = self.configuration.handleResponse(event.clone({ body: responseBody })); return modifiedResponse.clone({ body: new Blob([JSON.stringify(modifiedResponse.body)], { type: 'application/json' }) }); })); } } return of(event); } handleErrorResponse(error) { if (!(error.error instanceof Blob)) { return throwError(error); } return this.configuration.blobToText(error.error).pipe(switchMap((json) => { const errorBody = (json == "" || json == "null") ? {} : JSON.parse(json); const errorResponse = new HttpResponse({ headers: error.headers, status: error.status, body: errorBody }); var ajaxResponse = this.configuration.getAbpAjaxResponseOrNull(errorResponse); if (ajaxResponse != null) { this.configuration.handleAbpResponse(errorResponse, ajaxResponse); } else { this.configuration.handleNonAbpErrorResponse(errorResponse); } return throwError(error); })); } itemExists(items, predicate) { for (let i = 0; i < items.length; i++) { if (predicate(items[i])) { return true; } } return false; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.1", ngImport: i0, type: AbpHttpInterceptor, deps: [{ token: i1.AbpHttpConfigurationService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.1", ngImport: i0, type: AbpHttpInterceptor }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.1", ngImport: i0, type: AbpHttpInterceptor, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.AbpHttpConfigurationService }, { type: i0.Injector }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJwSHR0cEludGVyY2VwdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYWJwLW5nMi1tb2R1bGUvc3JjL2xpYi9pbnRlcmNlcHRvcnMvYWJwSHR0cEludGVyY2VwdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQVksTUFBTSxlQUFlLENBQUM7QUFDckQsT0FBTyxFQUFjLEVBQUUsRUFBRSxlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdkQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM5RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDL0QsT0FBTyxFQUF3RCxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDMUksT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBTyxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRWxDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFBOzs7QUFJN0QsTUFBTSxPQUFPLGtCQUFrQjtJQVFmO0lBTkYsYUFBYSxDQUE4QjtJQUM3QyxhQUFhLEdBQWlCLElBQUksWUFBWSxFQUFFLENBQUM7SUFDakQsYUFBYSxHQUFpQixJQUFJLFlBQVksRUFBRSxDQUFDO0lBQ2pELFdBQVcsR0FBZSxJQUFJLFVBQVUsRUFBRSxDQUFDO0lBRW5ELFlBQVksYUFBMEMsRUFDMUMsU0FBbUI7UUFBbkIsY0FBUyxHQUFULFNBQVMsQ0FBVTtRQUMzQixJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztJQUN2QyxDQUFDO0lBRUQsU0FB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TSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ25DLElBQUksU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNyQixPQUFPLElBQUksQ0FBQzthQUNmO1NBQ0o7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO3VHQW5NUSxrQkFBa0I7MkdBQWxCLGtCQUFrQjs7MkZBQWxCLGtCQUFrQjtrQkFEOUIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIEluamVjdG9yIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgTG9nU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2xvZy9sb2cuc2VydmljZSc7XHJcbmltcG9ydCB7IFRva2VuU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2F1dGgvdG9rZW4uc2VydmljZSc7XHJcbmltcG9ydCB7IFV0aWxzU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL3V0aWxzL3V0aWxzLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBIdHRwSW50ZXJjZXB0b3IsIEh0dHBIYW5kbGVyLCBIdHRwUmVxdWVzdCwgSHR0cEV2ZW50LCBIdHRwUmVzcG9uc2UsIEh0dHBFcnJvclJlc3BvbnNlLCBIdHRwSGVhZGVycyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgc3dpdGNoTWFwLCBmaWx0ZXIsIHRha2UsIGNhdGNoRXJyb3IsIHRhcCwgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IEFicEh0dHBDb25maWd1cmF0aW9uU2VydmljZSB9IGZyb20gJy4vYWJwLWh0dHAtY29uZmlndXJhdGlvbi5zZXJ2aWNlJ1xyXG5pbXBvcnQgeyBSZWZyZXNoVG9rZW5TZXJ2aWNlIH0gZnJvbSAnLi9yZWZyZXNoLXRva2VuLnNlcnZpY2UnXHJcbmRlY2xhcmUgY29uc3QgYWJwOiBhbnk7XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBBYnBIdHRwSW50ZXJjZXB0b3IgaW1wbGVtZW50cyBIdHRwSW50ZXJjZXB0b3Ige1xyXG5cclxuICAgIHByb3RlY3RlZCBjb25maWd1cmF0aW9uOiBBYnBIdHRwQ29uZmlndXJhdGlvblNlcnZpY2U7XHJcbiAgICBwcml2YXRlIF90b2tlblNlcnZpY2U6IFRva2VuU2VydmljZSA9IG5ldyBUb2tlblNlcnZpY2UoKTtcclxuICAgIHByaXZhdGUgX3V0aWxzU2VydmljZTogVXRpbHNTZXJ2aWNlID0gbmV3IFV0aWxzU2VydmljZSgpO1xyXG4gICAgcHJpdmF0ZSBfbG9nU2VydmljZTogTG9nU2VydmljZSA9IG5ldyBMb2dTZXJ2aWNlKCk7XHJcblxyXG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogQWJwSHR0cENvbmZpZ3VyYXRpb25TZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgX2luamVjdG9yOiBJbmplY3Rvcikge1xyXG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb247XHJcbiAgICB9XHJcblxyXG4gICAgaW50ZXJjZXB0KHJlcXVlc3Q6IEh0dHBSZXF1ZXN0PGFueT4sIG5leHQ6IEh0dHBIYW5kbGVyKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4ge1xyXG4gICAgICAgIHZhciBtb2RpZmllZFJlcXVlc3QgPSB0aGlzLm5vcm1hbGl6ZVJlcXVlc3RIZWFkZXJzKHJlcXVlc3QpO1xyXG4gICAgICAgIHJldHVybiBuZXh0LmhhbmRsZShtb2RpZmllZFJlcXVlc3QpXHJcbiAgICAgICAgICAgIC5waXBlKFxyXG4gICAgICAgICAgICAgICAgY2F0Y2hFcnJvcihlcnJvciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgSHR0cEVycm9yUmVzcG9uc2UgJiYgZXJyb3Iuc3RhdHVzID09PSA0MDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudHJ5QXV0aFdpdGhSZWZyZXNoVG9rZW4ocmVxdWVzdCwgbmV4dCwgZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZUVycm9yUmVzcG9uc2UoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICAgICAgc3dpdGNoTWFwKChldmVudCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVN1Y2Nlc3NSZXNwb25zZShldmVudCk7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCB0cnlHZXRSZWZyZXNoVG9rZW5TZXJ2aWNlKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xyXG4gICAgICAgIHZhciBfcmVmcmVzaFRva2VuU2VydmljZSA9IHRoaXMuX2luamVjdG9yLmdldChSZWZyZXNoVG9rZW5TZXJ2aWNlLCBudWxsKTtcclxuXHJcbiAgICAgICAgaWYgKF9yZWZyZXNoVG9rZW5TZXJ2aWNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBfcmVmcmVzaFRva2VuU2VydmljZS50cnlBdXRoV2l0aFJlZnJlc2hUb2tlbigpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb2YoZmFsc2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaXNSZWZyZXNoaW5nID0gZmFsc2U7XHJcbiAgICBwcml2YXRlIHJlZnJlc2hUb2tlblN1YmplY3Q6IEJlaGF2aW9yU3ViamVjdDxhbnk+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxhbnk+KG51bGwpO1xyXG5cclxuICAgIHByaXZhdGUgdHJ5QXV0aFdpdGhSZWZyZXNoVG9rZW4ocmVxdWVzdDogSHR0cFJlcXVlc3Q8YW55PiwgbmV4dDogSHR0cEhhbmRsZXIsIGVycm9yOiBhbnkpIHtcclxuICAgICAgICBpZiAoIXRoaXMuaXNSZWZyZXNoaW5nKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaXNSZWZyZXNoaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5yZWZyZXNoVG9rZW5TdWJqZWN0Lm5leHQobnVsbCk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50cnlHZXRSZWZyZXNoVG9rZW5TZXJ2aWNlKCkucGlwZShcclxuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoYXV0aFJlc3VsdDogYm9vbGVhbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNSZWZyZXNoaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1dGhSZXN1bHQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWZyZXNoVG9rZW5TdWJqZWN0Lm5leHQoYXV0aFJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBtb2RpZmllZFJlcXVlc3QgPSB0aGlzLm5vcm1hbGl6ZVJlcXVlc3RIZWFkZXJzKHJlcXVlc3QpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV4dC5oYW5kbGUobW9kaWZpZWRSZXF1ZXN0KTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVFcnJvclJlc3BvbnNlKGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaFRva2VuU3ViamVjdC5waXBlKFxyXG4gICAgICAgICAgICAgICAgZmlsdGVyKGF1dGhSZXN1bHQgPT4gYXV0aFJlc3VsdCAhPSBudWxsKSxcclxuICAgICAgICAgICAgICAgIHRha2UoMSksXHJcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoYXV0aFJlc3VsdCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IG1vZGlmaWVkUmVxdWVzdCA9IHRoaXMubm9ybWFsaXplUmVxdWVzdEhlYWRlcnMocmVxdWVzdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5leHQuaGFuZGxlKG1vZGlmaWVkUmVxdWVzdCk7XHJcbiAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBub3JtYWxpemVSZXF1ZXN0SGVhZGVycyhyZXF1ZXN0OiBIdHRwUmVxdWVzdDxhbnk+KTogSHR0cFJlcXVlc3Q8YW55PiB7XHJcbiAgICAgICAgdmFyIG1vZGlmaWVkSGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpO1xyXG4gICAgICAgIG1vZGlmaWVkSGVhZGVycyA9IHJlcXVlc3QuaGVhZGVycy5zZXQoXCJQcmFnbWFcIiwgXCJuby1jYWNoZVwiKVxyXG4gICAgICAgICAgICAuc2V0KFwiQ2FjaGUtQ29udHJvbFwiLCBcIm5vLWNhY2hlXCIpXHJcbiAgICAgICAgICAgIC5zZXQoXCJFeHBpcmVzXCIsIFwiU2F0LCAwMSBKYW4gMjAwMCAwMDowMDowMCBHTVRcIik7XHJcblxyXG4gICAgICAgIG1vZGlmaWVkSGVhZGVycyA9IHRoaXMuYWRkWFJlcXVlc3RlZFdpdGhIZWFkZXIobW9kaWZpZWRIZWFkZXJzKTtcclxuICAgICAgICBtb2RpZmllZEhlYWRlcnMgPSB0aGlzLmFkZEF1dGhvcml6YXRpb25IZWFkZXJzKG1vZGlmaWVkSGVhZGVycyk7XHJcbiAgICAgICAgbW9kaWZpZWRIZWFkZXJzID0gdGhpcy5hZGRBc3BOZXRDb3JlQ3VsdHVyZUhlYWRlcihtb2RpZmllZEhlYWRlcnMpO1xyXG4gICAgICAgIG1vZGlmaWVkSGVhZGVycyA9IHRoaXMuYWRkQWNjZXB0TGFuZ3VhZ2VIZWFkZXIobW9kaWZpZWRIZWFkZXJzKTtcclxuICAgICAgICBtb2RpZmllZEhlYWRlcnMgPSB0aGlzLmFkZFRlbmFudElkSGVhZGVyKG1vZGlmaWVkSGVhZGVycyk7XHJcblxyXG4gICAgICAgIHJldHVybiByZXF1ZXN0LmNsb25lKHtcclxuICAgICAgICAgICAgaGVhZGVyczogbW9kaWZpZWRIZWFkZXJzXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGFkZFhSZXF1ZXN0ZWRXaXRoSGVhZGVyKGhlYWRlcnM6IEh0dHBIZWFkZXJzKTogSHR0cEhlYWRlcnMge1xyXG4gICAgICAgIGlmIChoZWFkZXJzKSB7XHJcbiAgICAgICAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLnNldCgnWC1SZXF1ZXN0ZWQtV2l0aCcsICdYTUxIdHRwUmVxdWVzdCcpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGhlYWRlcnM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGFkZEFzcE5ldENvcmVDdWx0dXJlSGVhZGVyKGhlYWRlcnM6IEh0dHBIZWFkZXJzKTogSHR0cEhlYWRlcnMge1xyXG4gICAgICAgIGxldCBjb29raWVMYW5nVmFsdWUgPSB0aGlzLl91dGlsc1NlcnZpY2UuZ2V0Q29va2llVmFsdWUoXCJBYnAuTG9jYWxpemF0aW9uLkN1bHR1cmVOYW1lXCIpO1xyXG4gICAgICAgIGlmIChjb29raWVMYW5nVmFsdWUgJiYgaGVhZGVycyAmJiAhaGVhZGVycy5oYXMoJy5Bc3BOZXRDb3JlLkN1bHR1cmUnKSkge1xyXG4gICAgICAgICAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQoJy5Bc3BOZXRDb3JlLkN1bHR1cmUnLCBjb29raWVMYW5nVmFsdWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGhlYWRlcnM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGFkZEFjY2VwdExhbmd1YWdlSGVhZGVyKGhlYWRlcnM6IEh0dHBIZWFkZXJzKTogSHR0cEhlYWRlcnMge1xyXG4gICAgICAgIGxldCBjb29raWVMYW5nVmFsdWUgPSB0aGlzLl91dGlsc1NlcnZpY2UuZ2V0Q29va2llVmFsdWUoXCJBYnAuTG9jYWxpemF0aW9uLkN1bHR1cmVOYW1lXCIpO1xyXG4gICAgICAgIGlmIChjb29raWVMYW5nVmFsdWUgJiYgaGVhZGVycyAmJiAhaGVhZGVycy5oYXMoJ0FjY2VwdC1MYW5ndWFnZScpKSB7XHJcbiAgICAgICAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLnNldCgnQWNjZXB0LUxhbmd1YWdlJywgY29va2llTGFuZ1ZhbHVlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBoZWFkZXJzO1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBhZGRUZW5hbnRJZEhlYWRlcihoZWFkZXJzOiBIdHRwSGVhZGVycyk6IEh0dHBIZWFkZXJzIHtcclxuICAgICAgICBsZXQgY29va2llVGVuYW50SWRWYWx1ZSA9IHRoaXMuX3V0aWxzU2VydmljZS5nZXRDb29raWVWYWx1ZShhYnAubXVsdGlUZW5hbmN5LnRlbmFudElkQ29va2llTmFtZSk7XHJcbiAgICAgICAgaWYgKGNvb2tpZVRlbmFudElkVmFsdWUgJiYgaGVhZGVycyAmJiAhaGVhZGVycy5oYXMoYWJwLm11bHRpVGVuYW5jeS50ZW5hbnRJZENvb2tpZU5hbWUpKSB7XHJcbiAgICAgICAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLnNldChhYnAubXVsdGlUZW5hbmN5LnRlbmFudElkQ29va2llTmFtZSwgY29va2llVGVuYW50SWRWYWx1ZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gaGVhZGVycztcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgYWRkQXV0aG9yaXphdGlvbkhlYWRlcnMoaGVhZGVyczogSHR0cEhlYWRlcnMpOiBIdHRwSGVhZGVycyB7XHJcbiAgICAgICAgbGV0IGF1dGhvcml6YXRpb25IZWFkZXJzID0gaGVhZGVycyA/IGhlYWRlcnMuZ2V0QWxsKCdBdXRob3JpemF0aW9uJykgOiBudWxsO1xyXG4gICAgICAgIGlmICghYXV0aG9yaXphdGlvbkhlYWRlcnMpIHtcclxuICAgICAgICAgICAgYXV0aG9yaXphdGlvbkhlYWRlcnMgPSBbXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5pdGVtRXhpc3RzKGF1dGhvcml6YXRpb25IZWFkZXJzLCAoaXRlbTogc3RyaW5nKSA9PiBpdGVtLmluZGV4T2YoJ0JlYXJlciAnKSA9PSAwKSkge1xyXG4gICAgICAgICAgICBsZXQgdG9rZW4gPSB0aGlzLl90b2tlblNlcnZpY2UuZ2V0VG9rZW4oKTtcclxuICAgICAgICAgICAgaWYgKGhlYWRlcnMgJiYgdG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLnNldCgnQXV0aG9yaXphdGlvbicsICdCZWFyZXIgJyArIHRva2VuKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGhlYWRlcnM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGhhbmRsZVN1Y2Nlc3NSZXNwb25zZShldmVudDogSHR0cEV2ZW50PGFueT4pOiBPYnNlcnZhYmxlPEh0dHBFdmVudDxhbnk+PiB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBIdHRwUmVzcG9uc2UpIHtcclxuICAgICAgICAgICAgaWYgKGV2ZW50LmJvZHkgaW5zdGFuY2VvZiBCbG9iICYmIGV2ZW50LmJvZHkudHlwZSAmJiBldmVudC5ib2R5LnR5cGUuaW5kZXhPZihcImFwcGxpY2F0aW9uL2pzb25cIikgPj0gMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuY29uZmlndXJhdGlvbi5ibG9iVG9UZXh0KGV2ZW50LmJvZHkpLnBpcGUoXHJcbiAgICAgICAgICAgICAgICAgICAgbWFwKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlQm9keSA9IGpzb24gPT0gXCJudWxsXCIgPyB7fSA6IEpTT04ucGFyc2UoanNvbik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1vZGlmaWVkUmVzcG9uc2UgPSBzZWxmLmNvbmZpZ3VyYXRpb24uaGFuZGxlUmVzcG9uc2UoZXZlbnQuY2xvbmUoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvZHk6IHJlc3BvbnNlQm9keVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtb2RpZmllZFJlc3BvbnNlLmNsb25lKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib2R5OiBuZXcgQmxvYihbSlNPTi5zdHJpbmdpZnkobW9kaWZpZWRSZXNwb25zZS5ib2R5KV0sIHsgdHlwZTogJ2FwcGxpY2F0aW9uL2pzb24nIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9mKGV2ZW50KTtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgaGFuZGxlRXJyb3JSZXNwb25zZShlcnJvcjogYW55KTogT2JzZXJ2YWJsZTxuZXZlcj4ge1xyXG4gICAgICAgIGlmICghKGVycm9yLmVycm9yIGluc3RhbmNlb2YgQmxvYikpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoZXJyb3IpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlndXJhdGlvbi5ibG9iVG9UZXh0KGVycm9yLmVycm9yKS5waXBlKFxyXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKGpzb24pID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yQm9keSA9IChqc29uID09IFwiXCIgfHwganNvbiA9PSBcIm51bGxcIikgPyB7fSA6IEpTT04ucGFyc2UoanNvbik7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBlcnJvclJlc3BvbnNlID0gbmV3IEh0dHBSZXNwb25zZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogZXJyb3IuaGVhZGVycyxcclxuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IGVycm9yLnN0YXR1cyxcclxuICAgICAgICAgICAgICAgICAgICBib2R5OiBlcnJvckJvZHlcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciBhamF4UmVzcG9uc2UgPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0QWJwQWpheFJlc3BvbnNlT3JOdWxsKGVycm9yUmVzcG9uc2UpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChhamF4UmVzcG9uc2UgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5oYW5kbGVBYnBSZXNwb25zZShlcnJvclJlc3BvbnNlLCBhamF4UmVzcG9uc2UpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uaGFuZGxlTm9uQWJwRXJyb3JSZXNwb25zZShlcnJvclJlc3BvbnNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJvcik7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGl0ZW1FeGlzdHM8VD4oaXRlbXM6IFRbXSwgcHJlZGljYXRlOiAoaXRlbTogVCkgPT4gYm9vbGVhbik6IGJvb2xlYW4ge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKHByZWRpY2F0ZShpdGVtc1tpXSkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbn1cclxuIl19