@codaglobal/ng-jwt-authentication
Version:
<a> <br> <h1 align="center">ng-jwt-authentication</h1> </a>
261 lines (260 loc) • 34.9 kB
JavaScript
/**
* @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