UNPKG

@codaglobal/ng-jwt-authentication

Version:

<a> <br> <h1 align="center">ng-jwt-authentication</h1> </a>

261 lines (260 loc) 34.9 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Injectable, Inject } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { CookieService } from 'ngx-cookie-service'; import { throwError } from 'rxjs'; import { map, catchError, switchMap } from 'rxjs/operators'; import { METHODS, Config, DEFAULTS } from './angular-jwt.constants'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common/http"; import * as i2 from "ngx-cookie-service/cookie-service/cookie.service"; export class JwtAuthenticationService { /** * @param {?} http * @param {?} cookie * @param {?} config */ constructor(http, cookie, config) { this.http = http; this.cookie = cookie; this.config = config; this.libraryConfig = new Config(); this.libraryConfig.refreshUrl = this.config.refreshUrl || DEFAULTS.refreshUrl; this.libraryConfig.headerKeyName = this.config.headerKeyName || DEFAULTS.headerKeyName; this.libraryConfig.accessTokenKey = this.config.accessTokenKey || DEFAULTS.accessTokenKey; this.libraryConfig.refreshTokenKey = this.config.refreshTokenKey || DEFAULTS.refreshTokenKey; this.libraryConfig.expiresInKey = this.config.expiresInKey || DEFAULTS.expiresInKey; this.libraryConfig.errorStatusCode = this.config.errorStatusCode || DEFAULTS.errorStatusCode; this.libraryConfig.authorizationSchema = this.config.authorizationSchema || DEFAULTS.authorizationSchema; this.libraryConfig.contentTypeKeyName = DEFAULTS.contentTypeKeyName; this.libraryConfig.contentType = DEFAULTS.contentType; this.libraryConfig.jwtResponse = this.config.jwtResponse || DEFAULTS.jwtResponse; } /** * @param {?} customHeaders * @return {?} */ setHeaders(customHeaders) { /** @type {?} */ let headers; /** * If custom header available append the Authorization header, * Otherwise creating the header with Authorization and default Content type */ if (customHeaders) { headers = customHeaders; } else { headers = new HttpHeaders(); } if (!headers.has(this.libraryConfig.contentTypeKeyName)) { headers = headers.set(this.libraryConfig.contentTypeKeyName, this.libraryConfig.contentType); } headers = headers.set(this.libraryConfig.headerKeyName, `${this.libraryConfig.authorizationSchema} ${this.cookie.get(this.libraryConfig.accessTokenKey)}`); return headers; } /** * @param {?} url * @param {?=} options * @return {?} */ jwtAuthGet(url, options) { /** @type {?} */ let observeParameter = 'body'; /** @type {?} */ const requestHeader = this.setHeaders(options ? options.headers : undefined); if (options) { observeParameter = options.observe ? options.observe : 'body'; } return this.http.get(url, { headers: requestHeader, observe: observeParameter }).pipe(map((res) => res), catchError((error) => this.handleServerError(error, url, METHODS.GET, options))); } /** * @param {?} url * @param {?} body * @param {?=} options * @return {?} */ jwtAuthPost(url, body, options) { /** @type {?} */ let observeParameter = 'body'; /** @type {?} */ const requestHeader = this.setHeaders(options ? options.headers : undefined); if (options) { observeParameter = options.observe ? options.observe : 'body'; } return this.http.post(url, body, { headers: requestHeader, observe: observeParameter }).pipe(map((res) => res), catchError((error) => this.handleServerError(error, url, METHODS.POST, body, options))); } /** * @param {?} url * @param {?} body * @param {?=} options * @return {?} */ jwtAuthPut(url, body, options) { /** @type {?} */ let observeParameter = 'body'; /** @type {?} */ const requestHeader = this.setHeaders(options ? options.headers : undefined); if (options) { observeParameter = options.observe ? options.observe : 'body'; } return this.http.put(url, body, { headers: requestHeader, observe: observeParameter }).pipe(map((res) => res), catchError((error) => this.handleServerError(error, url, METHODS.PUT, body, options))); } /** * @param {?} url * @param {?=} options * @return {?} */ jwtAuthDelete(url, options) { /** @type {?} */ let observeParameter = 'body'; /** @type {?} */ const requestHeader = this.setHeaders(options ? options.headers : undefined); if (options) { observeParameter = options.observe ? options.observe : 'body'; } return this.http.delete(url, { headers: requestHeader, observe: observeParameter }).pipe(map((res) => res), catchError((error) => this.handleServerError(error, url, METHODS.DELETE, options))); } /** * @param {?} url * @param {?} body * @param {?=} options * @return {?} */ jwtAuthPatch(url, body, options) { /** @type {?} */ let observeParameter = 'body'; /** @type {?} */ const requestHeader = this.setHeaders(options ? options.headers : undefined); if (options) { observeParameter = options.observe ? options.observe : 'body'; } return this.http.patch(url, body, { headers: requestHeader, observe: observeParameter }).pipe(map((res) => res), catchError((error) => this.handleServerError(error, url, METHODS.PATCH, body, options))); } /** * @param {?} error * @param {?} url * @param {?} method * @param {?=} body * @param {?=} options * @return {?} */ handleServerError(error, url, method, body, options) { /** @type {?} */ let observeParameter = 'body'; if (options) { observeParameter = options.observe ? options.observe : 'body'; } if (this.libraryConfig.refreshUrl) { if (error.status === this.libraryConfig.errorStatusCode) { return this.getToken() .pipe(switchMap(data => { this.cookie.set(this.libraryConfig.accessTokenKey, data[this.libraryConfig.accessTokenKey]); this.cookie.set(this.libraryConfig.expiresInKey, data[this.libraryConfig.expiresInKey]); switch (method) { case METHODS.GET: return this.http.get(url, { headers: this.setHeaders(options ? options.headers : undefined), observe: observeParameter }).pipe(map((res) => res)); case METHODS.POST: return this.http.post(url, JSON.stringify(body), { headers: this.setHeaders(options ? options.headers : undefined), observe: observeParameter }).pipe(map((res) => res)); case METHODS.PUT: return this.http.put(url, JSON.stringify(body), { headers: this.setHeaders(options ? options.headers : undefined), observe: observeParameter }).pipe(map((res) => res)); case METHODS.DELETE: return this.http.delete(url, { headers: this.setHeaders(options ? options.headers : undefined), observe: observeParameter }).pipe(map((res) => res)); case METHODS.PATCH: return this.http.patch(url, { headers: this.setHeaders(options ? options.headers : undefined), observe: observeParameter }).pipe(map((res) => res)); } })); } } return throwError(error || 'Server error'); } /** * @return {?} */ getToken() { /** @type {?} */ let data; data = {}; data[this.libraryConfig.accessTokenKey] = this.cookie.get(this.libraryConfig.accessTokenKey); data[this.libraryConfig.refreshTokenKey] = this.cookie.get(this.libraryConfig.refreshTokenKey); data[this.libraryConfig.expiresInKey] = this.cookie.get(this.libraryConfig.expiresInKey); return this.refreshToken(this.libraryConfig.refreshUrl, data); } /** * @param {?} url * @param {?} data * @return {?} */ refreshToken(url, data) { /** @type {?} */ const headers = new HttpHeaders() .set(this.libraryConfig.contentTypeKeyName, this.libraryConfig.contentType) .set(this.libraryConfig.headerKeyName, `${this.libraryConfig.authorizationSchema} ${this.cookie.get(this.libraryConfig.accessTokenKey)}`); /** @type {?} */ const observeParameter = this.libraryConfig.jwtResponse ? this.libraryConfig.jwtResponse : 'body'; return this.http.post(url, JSON.stringify(data), { headers: headers, observe: observeParameter }).pipe(map((res) => res)); } /** * @param {?} accessToken * @param {?} refreshToken * @param {?} expiresIn * @return {?} */ saveJwtToken(accessToken, refreshToken, expiresIn) { this.cookie.set(this.libraryConfig.accessTokenKey, accessToken); this.cookie.set(this.libraryConfig.refreshTokenKey, refreshToken); this.cookie.set(this.libraryConfig.expiresInKey, expiresIn); } /** * @return {?} */ clearJwtTokens() { this.cookie.delete(this.libraryConfig.accessTokenKey); this.cookie.delete(this.libraryConfig.refreshTokenKey); this.cookie.delete(this.libraryConfig.expiresInKey); } } JwtAuthenticationService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] }, ]; /** @nocollapse */ JwtAuthenticationService.ctorParameters = () => [ { type: HttpClient }, { type: CookieService }, { type: Config, decorators: [{ type: Inject, args: ['config',] }] } ]; /** @nocollapse */ JwtAuthenticationService.ngInjectableDef = i0.defineInjectable({ factory: function JwtAuthenticationService_Factory() { return new JwtAuthenticationService(i0.inject(i1.HttpClient), i0.inject(i2.CookieService), i0.inject("config")); }, token: JwtAuthenticationService, providedIn: "root" }); if (false) { /** @type {?} */ JwtAuthenticationService.prototype.libraryConfig; /** @type {?} */ JwtAuthenticationService.prototype.http; /** @type {?} */ JwtAuthenticationService.prototype.cookie; /** @type {?} */ JwtAuthenticationService.prototype.config; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1qd3Quc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Bjb2RhZ2xvYmFsL25nLWp3dC1hdXRoZW50aWNhdGlvbi8iLCJzb3VyY2VzIjpbImxpYi9hbmd1bGFyLWp3dC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBbUMsTUFBTSxzQkFBc0IsQ0FBQztBQUNoRyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxFQUFjLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM5QyxPQUFPLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7OztBQUtwRSxNQUFNOzs7Ozs7SUFJSixZQUFvQixJQUFnQixFQUFVLE1BQXFCLEVBQTRCLE1BQWM7UUFBekYsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUFVLFdBQU0sR0FBTixNQUFNLENBQWU7UUFBNEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTs2QkFGckYsSUFBSSxNQUFNLEVBQUU7UUFHbEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLElBQUksUUFBUSxDQUFDLFVBQVUsQ0FBQztRQUM5RSxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsSUFBSSxRQUFRLENBQUMsYUFBYSxDQUFDO1FBQ3ZGLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxJQUFJLFFBQVEsQ0FBQyxjQUFjLENBQUM7UUFD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LENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUNoRSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDOzRCQUMvRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7d0JBQzlELEtBQUssT0FBTyxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQzlELEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7NEJBQy9ELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQzt3QkFDOUQsS0FBSyxPQUFPLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQzlDLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7NEJBQy9ELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQzt3QkFDOUQsS0FBSyxPQUFPLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FB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Q0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztLQUNyRDs7O1lBdExGLFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQjs7OztZQVJRLFVBQVU7WUFDVixhQUFhO1lBR0osTUFBTSx1QkFTZ0QsTUFBTSxTQUFDLFFBQVEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBIZWFkZXJzLCBIdHRwRXJyb3JSZXNwb25zZSwgSHR0cFJlc3BvbnNlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgQ29va2llU2VydmljZSB9IGZyb20gJ25neC1jb29raWUtc2VydmljZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAsIGNhdGNoRXJyb3IsIHN3aXRjaE1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IE1FVEhPRFMsIENvbmZpZywgREVGQVVMVFMgfSBmcm9tICcuL2FuZ3VsYXItand0LmNvbnN0YW50cyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEp3dEF1dGhlbnRpY2F0aW9uU2VydmljZSB7XG5cbiAgbGlicmFyeUNvbmZpZzogQ29uZmlnID0gbmV3IENvbmZpZygpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaHR0cDogSHR0cENsaWVudCwgcHJpdmF0ZSBjb29raWU6IENvb2tpZVNlcnZpY2UsIEBJbmplY3QoJ2NvbmZpZycpIHByaXZhdGUgY29uZmlnOiBDb25maWcpIHtcbiAgICB0aGlzLmxpYnJhcnlDb25maWcucmVmcmVzaFVybCA9IHRoaXMuY29uZmlnLnJlZnJlc2hVcmwgfHwgREVGQVVMVFMucmVmcmVzaFVybDtcbiAgICB0aGlzLmxpYnJhcnlDb25maWcuaGVhZGVyS2V5TmFtZSA9IHRoaXMuY29uZmlnLmhlYWRlcktleU5hbWUgfHwgREVGQVVMVFMuaGVhZGVyS2V5TmFtZTtcbiAgICB0aGlzLmxpYnJhcnlDb25maWcuYWNjZXNzVG9rZW5LZXkgPSB0aGlzLmNvbmZpZy5hY2Nlc3NUb2tlbktleSB8fCBERUZBVUxUUy5hY2Nlc3NUb2tlbktleTtcbiAgICB0aGlzLmxpYnJhcnlDb25maWcucmVmcmVzaFRva2VuS2V5ID0gdGhpcy5jb25maWcucmVmcmVzaFRva2VuS2V5IHx8IERFRkFVTFRTLnJlZnJlc2hUb2tlbktleTtcbiAgICB0aGlzLmxpYnJhcnlDb25maWcuZXhwaXJlc0luS2V5ID0gdGhpcy5jb25maWcuZXhwaXJlc0luS2V5IHx8IERFRkFVTFRTLmV4cGlyZXNJbktleTtcbiAgICB0aGlzLmxpYnJhcnlDb25maWcuZXJyb3JTdGF0dXNDb2RlID0gdGhpcy5jb25maWcuZXJyb3JTdGF0dXNDb2RlIHx8IERFRkFVTFRTLmVycm9yU3RhdHVzQ29kZTtcbiAgICB0aGlzLmxpYnJhcnlDb25maWcuYXV0aG9yaXphdGlvblNjaGVtYSA9IHRoaXMuY29uZmlnLmF1dGhvcml6YXRpb25TY2hlbWEgfHwgREVGQVVMVFMuYXV0aG9yaXphdGlvblNjaGVtYTtcbiAgICB0aGlzLmxpYnJhcnlDb25maWcuY29udGVudFR5cGVLZXlOYW1lID0gREVGQVVMVFMuY29udGVudFR5cGVLZXlOYW1lO1xuICAgIHRoaXMubGlicmFyeUNvbmZpZy5jb250ZW50VHlwZSA9IERFRkFVTFRTLmNvbnRlbnRUeXBlO1xuICAgIHRoaXMubGlicmFyeUNvbmZpZy5qd3RSZXNwb25zZSA9IHRoaXMuY29uZmlnLmp3dFJlc3BvbnNlIHx8IERFRkFVTFRTLmp3dFJlc3BvbnNlO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRIZWFkZXJzKGN1c3RvbUhlYWRlcnM6IEh0dHBIZWFkZXJzKSB7XG4gICAgbGV0IGhlYWRlcnM6IEh0dHBIZWFkZXJzO1xuICAgIC8qKlxuICAgICAqIElmIGN1c3RvbSBoZWFkZXIgYXZhaWxhYmxlIGFwcGVuZCB0aGUgQXV0aG9yaXphdGlvbiBoZWFkZXIsXG4gICAgICogT3RoZXJ3aXNlIGNyZWF0aW5nIHRoZSAgaGVhZGVyIHdpdGggQXV0aG9yaXphdGlvbiBhbmQgZGVmYXVsdCBDb250ZW50IHR5cGVcbiAgICAgKi9cbiAgICBpZiAoY3VzdG9tSGVhZGVycykge1xuICAgICAgaGVhZGVycyA9IGN1c3RvbUhlYWRlcnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhlYWRlcnMgPSBuZXcgSHR0cEhlYWRlcnMoKTtcbiAgICB9XG4gICAgaWYgKCFoZWFkZXJzLmhhcyh0aGlzLmxpYnJhcnlDb25maWcuY29udGVudFR5cGVLZXlOYW1lKSkge1xuICAgICAgaGVhZGVycyA9IGhlYWRlcnMuc2V0KHRoaXMubGlicmFyeUNvbmZpZy5jb250ZW50VHlwZUtleU5hbWUsIHRoaXMubGlicmFyeUNvbmZpZy5jb250ZW50VHlwZSk7XG4gICAgfVxuICAgIGhlYWRlcnMgPSBoZWFkZXJzLnNldCh0aGlzLmxpYnJhcnlDb25maWcuaGVhZGVyS2V5TmFtZSxcbiAgICAgIGAke3RoaXMubGlicmFyeUNvbmZpZy5hdXRob3JpemF0aW9uU2NoZW1hfSAke3RoaXMuY29va2llLmdldCh0aGlzLmxpYnJhcnlDb25maWcuYWNjZXNzVG9rZW5LZXkpfWApO1xuICAgIHJldHVybiBoZWFkZXJzO1xuICB9XG5cbiAgand0QXV0aEdldCh1cmw6IHN0cmluZywgb3B0aW9ucz86IHsgaGVhZGVycz86IEh0dHBIZWFkZXJzLCBvYnNlcnZlPzogYW55IH0pIHtcbiAgICBsZXQgb2JzZXJ2ZVBhcmFtZXRlcjogYW55ID0gJ2JvZHknO1xuICAgIGNvbnN0IHJlcXVlc3RIZWFkZXI6IEh0dHBIZWFkZXJzID0gdGhpcy5zZXRIZWFkZXJzKG9wdGlvbnMgPyBvcHRpb25zLmhlYWRlcnMgOiB1bmRlZmluZWQpO1xuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICBvYnNlcnZlUGFyYW1ldGVyID0gb3B0aW9ucy5vYnNlcnZlID8gb3B0aW9ucy5vYnNlcnZlIDogJ2JvZHknO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5odHRwLmdldCh1cmwsIHtcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3RIZWFkZXIsXG4gICAgICBvYnNlcnZlOiBvYnNlcnZlUGFyYW1ldGVyXG4gICAgfSkucGlwZShtYXAoKHJlczogYW55KSA9PiByZXMpLCBjYXRjaEVycm9yKFxuICAgICAgKGVycm9yKSA9PiB0aGlzLmhhbmRsZVNlcnZlckVycm9yKFxuICAgICAgICBlcnJvciwgdXJsLCBNRVRIT0RTLkdFVCwgb3B0aW9ucykpKTtcblxuICB9XG5cbiAgand0QXV0aFBvc3QodXJsOiBzdHJpbmcsIGJvZHk6IGFueSwgb3B0aW9ucz86IHsgaGVhZGVycz86IEh0dHBIZWFkZXJzLCBvYnNlcnZlPzogYW55IH0pIHtcbiAgICBsZXQgb2JzZXJ2ZVBhcmFtZXRlcjogYW55ID0gJ2JvZHknO1xuICAgIGNvbnN0IHJlcXVlc3RIZWFkZXI6IEh0dHBIZWFkZXJzID0gdGhpcy5zZXRIZWFkZXJzKG9wdGlvbnMgPyBvcHRpb25zLmhlYWRlcnMgOiB1bmRlZmluZWQpO1xuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICBvYnNlcnZlUGFyYW1ldGVyID0gb3B0aW9ucy5vYnNlcnZlID8gb3B0aW9ucy5vYnNlcnZlIDogJ2JvZHknO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QodXJsLCBib2R5LCB7XG4gICAgICBoZWFkZXJzOiByZXF1ZXN0SGVhZGVyLFxuICAgICAgb2JzZXJ2ZTogb2JzZXJ2ZVBhcmFtZXRlclxuICAgIH0pLnBpcGUoXG4gICAgICBtYXAoKHJlczogSHR0cFJlc3BvbnNlPGFueT4pID0+IHJlcyksXG4gICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4gdGhpcy5oYW5kbGVTZXJ2ZXJFcnJvcihcbiAgICAgICAgZXJyb3IsIHVybCwgTUVUSE9EUy5QT1NULCBib2R5LCBvcHRpb25zKSkpO1xuXG4gIH1cblxuICBqd3RBdXRoUHV0KHVybDogc3RyaW5nLCBib2R5OiBhbnksIG9wdGlvbnM/OiB7IGhlYWRlcnM/OiBIdHRwSGVhZGVycywgb2JzZXJ2ZT86IGFueSB9KSB7XG4gICAgbGV0IG9ic2VydmVQYXJhbWV0ZXI6IGFueSA9ICdib2R5JztcbiAgICBjb25zdCByZXF1ZXN0SGVhZGVyOiBIdHRwSGVhZGVycyA9IHRoaXMuc2V0SGVhZGVycyhvcHRpb25zID8gb3B0aW9ucy5oZWFkZXJzIDogdW5kZWZpbmVkKTtcbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgb2JzZXJ2ZVBhcmFtZXRlciA9IG9wdGlvbnMub2JzZXJ2ZSA/IG9wdGlvbnMub2JzZXJ2ZSA6ICdib2R5JztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wdXQodXJsLCBib2R5LCB7XG4gICAgICBoZWFkZXJzOiByZXF1ZXN0SGVhZGVyLFxuICAgICAgb2JzZXJ2ZTogb2JzZXJ2ZVBhcmFtZXRlclxuICAgIH0pLnBpcGUobWFwKChyZXM6IGFueSkgPT4gcmVzKSxcbiAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB0aGlzLmhhbmRsZVNlcnZlckVycm9yKFxuICAgICAgICBlcnJvciwgdXJsLCBNRVRIT0RTLlBVVCwgYm9keSwgb3B0aW9ucykpKTtcblxuICB9XG5cbiAgand0QXV0aERlbGV0ZSh1cmw6IHN0cmluZywgb3B0aW9ucz86IHsgaGVhZGVycz86IEh0dHBIZWFkZXJzLCBvYnNlcnZlPzogYW55IH0pIHtcbiAgICBsZXQgb2JzZXJ2ZVBhcmFtZXRlcjogYW55ID0gJ2JvZHknO1xuICAgIGNvbnN0IHJlcXVlc3RIZWFkZXI6IEh0dHBIZWFkZXJzID0gdGhpcy5zZXRIZWFkZXJzKG9wdGlvbnMgPyBvcHRpb25zLmhlYWRlcnMgOiB1bmRlZmluZWQpO1xuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICBvYnNlcnZlUGFyYW1ldGVyID0gb3B0aW9ucy5vYnNlcnZlID8gb3B0aW9ucy5vYnNlcnZlIDogJ2JvZHknO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5odHRwLmRlbGV0ZSh1cmwsIHtcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3RIZWFkZXIsXG4gICAgICBvYnNlcnZlOiBvYnNlcnZlUGFyYW1ldGVyXG4gICAgfSkucGlwZShtYXAoKHJlczogYW55KSA9PiByZXMpLFxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHRoaXMuaGFuZGxlU2VydmVyRXJyb3IoXG4gICAgICAgIGVycm9yLCB1cmwsIE1FVEhPRFMuREVMRVRFLCBvcHRpb25zKSkpO1xuICB9XG5cbiAgand0QXV0aFBhdGNoKHVybDogc3RyaW5nLCBib2R5OiBhbnksIG9wdGlvbnM/OiB7IGhlYWRlcnM/OiBIdHRwSGVhZGVycywgb2JzZXJ2ZT86IGFueSB9KSB7XG4gICAgbGV0IG9ic2VydmVQYXJhbWV0ZXI6IGFueSA9ICdib2R5JztcbiAgICBjb25zdCByZXF1ZXN0SGVhZGVyOiBIdHRwSGVhZGVycyA9IHRoaXMuc2V0SGVhZGVycyhvcHRpb25zID8gb3B0aW9ucy5oZWFkZXJzIDogdW5kZWZpbmVkKTtcbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgb2JzZXJ2ZVBhcmFtZXRlciA9IG9wdGlvbnMub2JzZXJ2ZSA/IG9wdGlvbnMub2JzZXJ2ZSA6ICdib2R5JztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wYXRjaCh1cmwsIGJvZHksIHtcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3RIZWFkZXIsXG4gICAgICBvYnNlcnZlOiBvYnNlcnZlUGFyYW1ldGVyXG4gICAgfSkucGlwZShtYXAoKHJlczogYW55KSA9PiByZXMpLFxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHRoaXMuaGFuZGxlU2VydmVyRXJyb3IoXG4gICAgICAgIGVycm9yLCB1cmwsIE1FVEhPRFMuUEFUQ0gsIGJvZHksIG9wdGlvbnMpKSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVNlcnZlckVycm9yKGVycm9yOiBIdHRwRXJyb3JSZXNwb25zZSwgdXJsOiBzdHJpbmcsIG1ldGhvZDogc3RyaW5nLCBib2R5PzogYW55LFxuICAgIG9wdGlvbnM/OiB7IGhlYWRlcnM/OiBIdHRwSGVhZGVyczsgb2JzZXJ2ZT86IGFueSB9KSB7XG4gICAgbGV0IG9ic2VydmVQYXJhbWV0ZXI6IGFueSA9ICdib2R5JztcbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgb2JzZXJ2ZVBhcmFtZXRlciA9IG9wdGlvbnMub2JzZXJ2ZSA/IG9wdGlvbnMub2JzZXJ2ZSA6ICdib2R5JztcbiAgICB9XG4gICAgaWYgKHRoaXMubGlicmFyeUNvbmZpZy5yZWZyZXNoVXJsKSB7XG4gICAgICBpZiAoZXJyb3Iuc3RhdHVzID09PSB0aGlzLmxpYnJhcnlDb25maWcuZXJyb3JTdGF0dXNDb2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFRva2VuKClcbiAgICAgICAgICAucGlwZShzd2l0Y2hNYXAoZGF0YSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNvb2tpZS5zZXQodGhpcy5saWJyYXJ5Q29uZmlnLmFjY2Vzc1Rva2VuS2V5LCBkYXRhW3RoaXMubGlicmFyeUNvbmZpZy5hY2Nlc3NUb2tlbktleV0pO1xuICAgICAgICAgICAgdGhpcy5jb29raWUuc2V0KHRoaXMubGlicmFyeUNvbmZpZy5leHBpcmVzSW5LZXksIGRhdGFbdGhpcy5saWJyYXJ5Q29uZmlnLmV4cGlyZXNJbktleV0pO1xuICAgICAgICAgICAgc3dpdGNoIChtZXRob2QpIHtcbiAgICAgICAgICAgICAgY2FzZSBNRVRIT0RTLkdFVDogcmV0dXJuIHRoaXMuaHR0cC5nZXQodXJsLFxuICAgICAgICAgICAgICAgIHsgaGVhZGVyczogdGhpcy5zZXRIZWFkZXJzKG9wdGlvbnMgPyBvcHRpb25zLmhlYWRlcnMgOiB1bmRlZmluZWQpLFxuICAgICAgICAgICAgICAgICAgb2JzZXJ2ZTogb2JzZXJ2ZVBhcmFtZXRlciB9KS5waXBlKG1hcCgocmVzOiBhbnkpID0+IHJlcykpO1xuICAgICAgICAgICAgICBjYXNlIE1FVEhPRFMuUE9TVDogcmV0dXJuIHRoaXMuaHR0cC5wb3N0KHVybCwgSlNPTi5zdHJpbmdpZnkoYm9keSksXG4gICAgICAgICAgICAgICAgeyBoZWFkZXJzOiB0aGlzLnNldEhlYWRlcnMob3B0aW9ucyA/IG9wdGlvbnMuaGVhZGVycyA6IHVuZGVmaW5lZCksXG4gICAgICAgICAgICAgICAgICBvYnNlcnZlOiBvYnNlcnZlUGFyYW1ldGVyIH0pLnBpcGUobWFwKChyZXM6IGFueSkgPT4gcmVzKSk7XG4gICAgICAgICAgICAgIGNhc2UgTUVUSE9EUy5QVVQ6IHJldHVybiB0aGlzLmh0dHAucHV0KHVybCwgSlNPTi5zdHJpbmdpZnkoYm9keSksXG4gICAgICAgICAgICAgICAgeyBoZWFkZXJzOiB0aGlzLnNldEhlYWRlcnMob3B0aW9ucyA/IG9wdGlvbnMuaGVhZGVycyA6IHVuZGVmaW5lZCksXG4gICAgICAgICAgICAgICAgICBvYnNlcnZlOiBvYnNlcnZlUGFyYW1ldGVyIH0pLnBpcGUobWFwKChyZXM6IGFueSkgPT4gcmVzKSk7XG4gICAgICAgICAgICAgIGNhc2UgTUVUSE9EUy5ERUxFVEU6IHJldHVybiB0aGlzLmh0dHAuZGVsZXRlKHVybCxcbiAgICAgICAgICAgICAgICB7IGhlYWRlcnM6IHRoaXMuc2V0SGVhZGVycyhvcHRpb25zID8gb3B0aW9ucy5oZWFkZXJzIDogdW5kZWZpbmVkKSxcbiAgICAgICAgICAgICAgICAgIG9ic2VydmU6IG9ic2VydmVQYXJhbWV0ZXIgfSkucGlwZShtYXAoKHJlczogYW55KSA9PiByZXMpKTtcbiAgICAgICAgICAgICAgY2FzZSBNRVRIT0RTLlBBVENIOiByZXR1cm4gdGhpcy5odHRwLnBhdGNoKHVybCxcbiAgICAgICAgICAgICAgICB7IGhlYWRlcnM6IHRoaXMuc2V0SGVhZGVycyhvcHRpb25zID8gb3B0aW9ucy5oZWFkZXJzIDogdW5kZWZpbmVkKSxcbiAgICAgICAgICAgICAgICAgIG9ic2VydmU6IG9ic2VydmVQYXJhbWV0ZXIgfSkucGlwZShtYXAoKHJlczogYW55KSA9PiByZXMpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSk7XG5cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJvciB8fCAnU2VydmVyIGVycm9yJyk7XG4gIH1cblxuICBwcml2YXRlIGdldFRva2VuKCkge1xuICAgIGxldCBkYXRhO1xuICAgIGRhdGEgPSB7fTtcbiAgICBkYXRhW3RoaXMubGlicmFyeUNvbmZpZy5hY2Nlc3NUb2tlbktleV0gPSB0aGlzLmNvb2tpZS5nZXQodGhpcy5saWJyYXJ5Q29uZmlnLmFjY2Vzc1Rva2VuS2V5KTtcbiAgICBkYXRhW3RoaXMubGlicmFyeUNvbmZpZy5yZWZyZXNoVG9rZW5LZXldID0gdGhpcy5jb29raWUuZ2V0KHRoaXMubGlicmFyeUNvbmZpZy5yZWZyZXNoVG9rZW5LZXkpO1xuICAgIGRhdGFbdGhpcy5saWJyYXJ5Q29uZmlnLmV4cGlyZXNJbktleV0gPSB0aGlzLmNvb2tpZS5nZXQodGhpcy5saWJyYXJ5Q29uZmlnLmV4cGlyZXNJbktleSk7XG4gICAgcmV0dXJuIHRoaXMucmVmcmVzaFRva2VuKHRoaXMubGlicmFyeUNvbmZpZy5yZWZyZXNoVXJsLCBkYXRhKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVmcmVzaFRva2VuKHVybCwgZGF0YSkge1xuICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgSHR0cEhlYWRlcnMoKVxuICAgICAgLnNldCh0aGlzLmxpYnJhcnlDb25maWcuY29udGVudFR5cGVLZXlOYW1lLCB0aGlzLmxpYnJhcnlDb25maWcuY29udGVudFR5cGUpXG4gICAgICAuc2V0KHRoaXMubGlicmFyeUNvbmZpZy5oZWFkZXJLZXlOYW1lLFxuICAgICAgICBgJHt0aGlzLmxpYnJhcnlDb25maWcuYXV0aG9yaXphdGlvblNjaGVtYX0gJHt0aGlzLmNvb2tpZS5nZXQodGhpcy5saWJyYXJ5Q29uZmlnLmFjY2Vzc1Rva2VuS2V5KX1gKTtcbiAgICBjb25zdCBvYnNlcnZlUGFyYW1ldGVyOiBhbnkgPSB0aGlzLmxpYnJhcnlDb25maWcuand0UmVzcG9uc2UgPyB0aGlzLmxpYnJhcnlDb25maWcuand0UmVzcG9uc2UgOiAnYm9keSc7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KHVybCwgSlNPTi5zdHJpbmdpZnkoZGF0YSksXG4gICAgICB7XG4gICAgICAgIGhlYWRlcnM6IGhlYWRlcnMsXG4gICAgICAgIG9ic2VydmU6IG9ic2VydmVQYXJhbWV0ZXJcbiAgICAgIH0pLnBpcGUobWFwKChyZXM6IGFueSkgPT4gcmVzKSk7XG4gIH1cblxuICBzYXZlSnd0VG9rZW4oYWNjZXNzVG9rZW4sIHJlZnJlc2hUb2tlbiwgZXhwaXJlc0luKSB7XG4gICAgdGhpcy5jb29raWUuc2V0KHRoaXMubGlicmFyeUNvbmZpZy5hY2Nlc3NUb2tlbktleSwgYWNjZXNzVG9rZW4pO1xuICAgIHRoaXMuY29va2llLnNldCh0aGlzLmxpYnJhcnlDb25maWcucmVmcmVzaFRva2VuS2V5LCByZWZyZXNoVG9rZW4pO1xuICAgIHRoaXMuY29va2llLnNldCh0aGlzLmxpYnJhcnlDb25maWcuZXhwaXJlc0luS2V5LCBleHBpcmVzSW4pO1xuICB9XG5cbiAgY2xlYXJKd3RUb2tlbnMoKSB7XG4gICAgdGhpcy5jb29raWUuZGVsZXRlKHRoaXMubGlicmFyeUNvbmZpZy5hY2Nlc3NUb2tlbktleSk7XG4gICAgdGhpcy5jb29raWUuZGVsZXRlKHRoaXMubGlicmFyeUNvbmZpZy5yZWZyZXNoVG9rZW5LZXkpO1xuICAgIHRoaXMuY29va2llLmRlbGV0ZSh0aGlzLmxpYnJhcnlDb25maWcuZXhwaXJlc0luS2V5KTtcbiAgfVxufVxuIl19