UNPKG

@koalarx/ui

Version:

Koala UI is a Design System developed in Angular whose objective is to facilitate and make your development faster and simpler, making this framework your greatest ally.

188 lines 28.2 kB
import { Injectable } from '@angular/core'; import { BehaviorSubject, interval } from 'rxjs'; import { koala } from "@koalarx/utils"; import { KoalaOauthConfig } from "./koala.oauth.config"; import { delay } from "@koalarx/utils/operators/delay"; import { randomString } from "@koalarx/utils/operators/string"; import * as i0 from "@angular/core"; import * as i1 from "@angular/common/http"; import * as i2 from "@angular/router"; import * as i3 from "../token/koala.token.service"; const STATE_STORAGE_NAME = 'koala_openid_state'; export class KoalaOAuth2Service { constructor(http, router, tokenService) { this.http = http; this.router = router; this.tokenService = tokenService; this.events = new BehaviorSubject(null); this.token = {}; this.generateState(); } ngOnDestroy() { this.eventSubscription?.unsubscribe(); this.refreshTokenInterval?.unsubscribe(); } hasOpenIdConfig() { return !!this.openIdOptions; } configure(options) { this.config = options; } loadDiscoveryDocumentAndTryLogin() { if (this.eventSubscription) { this.eventSubscription.unsubscribe(); } this.eventSubscription = this.events.subscribe(event => { if (event === 'authenticate') { this.generateState(); localStorage.setItem(STATE_STORAGE_NAME, this.state); window.location.href = `${this.openIdOptions.authorization_endpoint}?response_type=${this.config.responseType}&client_id=${this.config.clientId}&state=${this.state}&redirect_uri=${this.config.redirectUri}&scope=${this.config.scope}`; } else if (event === 'getToken') { const urlParams = new URLSearchParams(window.location.search); const state = urlParams.get('state'); if (state === this.state) { const code = urlParams.get('code'); this.getToken(code); } else { this.logout(); } } else if (event === 'getClaims' || (event === 'refreshToken' && !this.claims)) { this.getClaims(); } }); return new Promise((resolve, reject) => { this.http.get(`${this.config.issuer}/.well-known/openid-configuration`).subscribe(options => { this.openIdOptions = options; if (window.location.href.indexOf(`state=${this.state}`) >= 0) { this.events.next('getToken'); } else if (!this.tokenService.getOAuth2Token()) { this.events.next('loadedConfig'); } resolve(true); }, e => { console.error(e); this.events.next('errorLoadConfig'); reject(e); }); }); } async initLoginFlow(name) { if (name) { KoalaOauthConfig.setConfig(name); await delay(1000); } this.events.next('authenticate'); } getIdentityClaims() { return this.claims; } getAccessToken() { return this.token.access_token; } getIdToken() { return this.token.id_token; } getRefreshToken() { return this.token.refresh_token; } getAccessTokenExpiration() { const expires_in = new Date(); expires_in.setSeconds(this.token.expires_in); return expires_in.toString(); } getCode() { return this.code; } logout() { const logoutInterval = setInterval(() => { if (this.hasOpenIdConfig()) { if (this.openIdOptions.end_session_endpoint) { this.claims = null; this.token = null; const iframeLogout = document.createElement('iframe'); iframeLogout.style.display = 'none'; iframeLogout.src = this.openIdOptions.end_session_endpoint; document.querySelector('body').appendChild(iframeLogout); } this.events.next('logout'); clearInterval(logoutInterval); } }, 300); } initRefreshTokenInterval(code, refreshToken) { this.refreshTokenInterval?.unsubscribe(); this.refreshTokenInterval = interval(1000).subscribe(() => { const refreshTokenDate = new Date(); refreshTokenDate.setMinutes(refreshTokenDate.getMinutes() + 1); const token = this.tokenService.getOAuth2Token(); if (token) { const expires_in = token.expired; if (expires_in) { if (new Date(expires_in) <= refreshTokenDate) { this.getToken(code, refreshToken); } } } }); } getToken(code, refreshToken) { if (refreshToken) { this.refreshTokenInterval?.unsubscribe(); } const formData = new URLSearchParams(); let data = koala({ grant_type: (refreshToken ? 'refresh_token' : 'authorization_code'), code, redirect_uri: this.config.redirectUri, client_id: this.config.clientId }).object().merge(this.config.customQueryParams ?? {}).getValue(); if (refreshToken) { data = koala(data).object().merge({ refresh_token: refreshToken }).getValue(); } if (!this.code) { this.code = code; } Object.keys(data).forEach(indexName => { formData.append(indexName, data[indexName]); }); this.http.post(this.config.endpointToken ?? this.openIdOptions.token_endpoint, formData.toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).subscribe((token) => { this.token = token; this.events.next((refreshToken ? 'refreshToken' : 'getClaims')); }, () => this.events.next('getTokenError')); } getClaims() { this.http.get((this.config.endpointClaims ?? this.openIdOptions.userinfo_endpoint), { headers: { Authorization: `Bearer ${this.getAccessToken()}` } }).subscribe(userInfo => { this.claims = userInfo; this.state = null; localStorage.removeItem(STATE_STORAGE_NAME); this.events.next(this.events.getValue() === 'refreshToken' ? 'refreshToken' : 'userAuthenticated'); }, () => this.events.next('loadedConfig')); } generateState() { this.state = localStorage.getItem(STATE_STORAGE_NAME) ? localStorage.getItem(STATE_STORAGE_NAME) : randomString(30, { numbers: true, uppercase: true, lowercase: true }); } } KoalaOAuth2Service.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KoalaOAuth2Service, deps: [{ token: i1.HttpClient }, { token: i2.Router }, { token: i3.KoalaTokenService }], target: i0.ɵɵFactoryTarget.Injectable }); KoalaOAuth2Service.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KoalaOAuth2Service }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KoalaOAuth2Service, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.Router }, { type: i3.KoalaTokenService }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia29hbGEub2F1dGgyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9saWIvc2VydmljZXMvb3BlbmlkL2tvYWxhLm9hdXRoMi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDdEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBRS9ELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUd2QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDdkQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlDQUFpQyxDQUFDOzs7OztBQXlEL0QsTUFBTSxrQkFBa0IsR0FBRyxvQkFBb0IsQ0FBQztBQUdoRCxNQUFNLE9BQU8sa0JBQWtCO0lBVzdCLFlBQ1UsSUFBZ0IsRUFDaEIsTUFBYyxFQUNkLFlBQStCO1FBRi9CLFNBQUksR0FBSixJQUFJLENBQVk7UUFDaEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLGlCQUFZLEdBQVosWUFBWSxDQUFtQjtRQWJsQyxXQUFNLEdBQUcsSUFBSSxlQUFlLENBQVksSUFBSSxDQUFDLENBQUM7UUFNN0MsVUFBSyxHQUFTLEVBQUUsQ0FBQztRQVN2QixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLFdBQVcsRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFFTSxlQUFlO1FBQ3BCLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUM7SUFD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LElBQUksQ0FBQyxLQUFLLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7WUFDMUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7WUFDMUMsWUFBWSxDQUFDLEVBQUUsRUFBRTtnQkFDZixPQUFPLEVBQUUsSUFBSTtnQkFDYixTQUFTLEVBQUUsSUFBSTtnQkFDZixTQUFTLEVBQUUsSUFBSTthQUNoQixDQUFDLENBQUM7SUFDbEIsQ0FBQzs7K0dBdE1VLGtCQUFrQjttSEFBbEIsa0JBQWtCOzJGQUFsQixrQkFBa0I7a0JBRDlCLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgaW50ZXJ2YWwsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IGtvYWxhIH0gZnJvbSBcIkBrb2FsYXJ4L3V0aWxzXCI7XG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tIFwiQGFuZ3VsYXIvcm91dGVyXCI7XG5pbXBvcnQgeyBLb2FsYVRva2VuU2VydmljZSB9IGZyb20gXCIuLi90b2tlbi9rb2FsYS50b2tlbi5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBLb2FsYU9hdXRoQ29uZmlnIH0gZnJvbSBcIi4va29hbGEub2F1dGguY29uZmlnXCI7XG5pbXBvcnQgeyBkZWxheSB9IGZyb20gXCJAa29hbGFyeC91dGlscy9vcGVyYXRvcnMvZGVsYXlcIjtcbmltcG9ydCB7IHJhbmRvbVN0cmluZyB9IGZyb20gXCJAa29hbGFyeC91dGlscy9vcGVyYXRvcnMvc3RyaW5nXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgS29hbGFPQXV0aDJDb25maWcge1xuICByZWRpcmVjdFVyaTogc3RyaW5nO1xuICByZXNwb25zZVR5cGU6IHN0cmluZztcbiAgY2xpZW50SWQ6IHN0cmluZztcbiAgc2NvcGU6IHN0cmluZztcbiAgaXNzdWVyOiBzdHJpbmc7XG4gIHJlZGlyZWN0VXJpQWZ0ZXJBdXRoPzogc3RyaW5nO1xuICBjdXN0b21RdWVyeVBhcmFtcz86IG9iamVjdDtcbiAgZW5kcG9pbnRUb2tlbj86IHN0cmluZztcbiAgZW5kcG9pbnRDbGFpbXM/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgS29hbGFPcGVuSWRDb25maWcge1xuICBhdXRob3JpemF0aW9uX2VuZHBvaW50OiBzdHJpbmc7XG4gIGNoZWNrX3Nlc3Npb25faWZyYW1lOiBzdHJpbmc7XG4gIGNsYWltX3R5cGVzX3N1cHBvcnRlZDogc3RyaW5nW107XG4gIGNsYWltc19wYXJhbWV0ZXJfc3VwcG9ydGVkOiBib29sZWFuO1xuICBjbGFpbXNfc3VwcG9ydGVkOiBzdHJpbmdbXTtcbiAgY29kZV9jaGFsbGVuZ2VfbWV0aG9kc19zdXBwb3J0ZWQ6IHN0cmluZ1tdO1xuICBlbmRfc2Vzc2lvbl9lbmRwb2ludDogc3RyaW5nO1xuICBncmFudF90eXBlc19zdXBwb3J0ZWQ6IHN0cmluZ1tdO1xuICBpZF90b2tlbl9lbmNyeXB0aW9uX2FsZ192YWx1ZXNfc3VwcG9ydGVkOiBzdHJpbmdbXTtcbiAgaWRfdG9rZW5fZW5jcnlwdGlvbl9lbmNfdmFsdWVzX3N1cHBvcnRlZDogc3RyaW5nW107XG4gIGlkX3Rva2VuX3NpZ25pbmdfYWxnX3ZhbHVlc19zdXBwb3J0ZWQ6IHN0cmluZ1tdO1xuICBpbnRyb3NwZWN0aW9uX2VuZHBvaW50OiBzdHJpbmc7XG4gIGlzc3Vlcjogc3RyaW5nO1xuICBqd2tzX3VyaTogc3RyaW5nO1xuICByZWdpc3RyYXRpb25fZW5kcG9pbnQ6IHN0cmluZztcbiAgcmVxdWVzdF9vYmplY3Rfc2lnbmluZ19hbGdfdmFsdWVzX3N1cHBvcnRlZDogc3RyaW5nW107XG4gIHJlcXVlc3RfcGFyYW1ldGVyX3N1cHBvcnRlZDogYm9vbGVhbjtcbiAgcmVxdWVzdF91cmlfcGFyYW1ldGVyX3N1cHBvcnRlZDogYm9vbGVhbjtcbiAgcmVzcG9uc2VfbW9kZXNfc3VwcG9ydGVkOiBzdHJpbmdbXTtcbiAgcmVzcG9uc2VfdHlwZXNfc3VwcG9ydGVkOiBzdHJpbmdbXTtcbiAgc2NvcGVzX3N1cHBvcnRlZDogc3RyaW5nW107XG4gIHN1YmplY3RfdHlwZXNfc3VwcG9ydGVkOiBzdHJpbmdbXTtcbiAgdGxzX2NsaWVudF9jZXJ0aWZpY2F0ZV9ib3VuZF9hY2Nlc3NfdG9rZW5zOiBib29sZWFuO1xuICB0b2tlbl9lbmRwb2ludDogc3RyaW5nO1xuICB0b2tlbl9lbmRwb2ludF9hdXRoX21ldGhvZHNfc3VwcG9ydGVkOiBzdHJpbmdbXTtcbiAgdG9rZW5fZW5kcG9pbnRfYXV0aF9zaWduaW5nX2FsZ192YWx1ZXNfc3VwcG9ydGVkOiBzdHJpbmdbXTtcbiAgdG9rZW5faW50cm9zcGVjdGlvbl9lbmRwb2ludDogc3RyaW5nO1xuICB1c2VyaW5mb19lbmRwb2ludDogc3RyaW5nO1xuICB1c2VyaW5mb19zaWduaW5nX2FsZ192YWx1ZXNfc3VwcG9ydGVkOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IHR5cGUgRXZlbnRUeXBlID1cbiAgJ2xvYWRlZENvbmZpZydcbiAgfCAnZ2V0VG9rZW4nXG4gIHwgJ2dldFRva2VuRXJyb3InXG4gIHwgJ3JlZnJlc2hUb2tlbidcbiAgfCAnZ2V0Q2xhaW1zJ1xuICB8ICd1c2VyQXV0aGVudGljYXRlZCdcbiAgfCAnYXV0aGVudGljYXRlJ1xuICB8ICdsb2dvdXQnXG4gIHwgJ2Vycm9yTG9hZENvbmZpZyc7XG5cbmNvbnN0IFNUQVRFX1NUT1JBR0VfTkFNRSA9ICdrb2FsYV9vcGVuaWRfc3RhdGUnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgS29hbGFPQXV0aDJTZXJ2aWNlIGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgcHVibGljIGV2ZW50cyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RXZlbnRUeXBlPihudWxsKTtcbiAgcHJpdmF0ZSBjb25maWc6IEtvYWxhT0F1dGgyQ29uZmlnO1xuICBwcml2YXRlIG9wZW5JZE9wdGlvbnM6IEtvYWxhT3BlbklkQ29uZmlnO1xuICBwcml2YXRlIGV2ZW50U3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG4gIHByaXZhdGUgc3RhdGU/OiBzdHJpbmc7XG4gIHByaXZhdGUgY29kZT86IHN0cmluZztcbiAgcHJpdmF0ZSB0b2tlbj86IGFueSA9IHt9O1xuICBwcml2YXRlIGNsYWltcz86IGFueTtcbiAgcHJpdmF0ZSByZWZyZXNoVG9rZW5JbnRlcnZhbD86IFN1YnNjcmlwdGlvbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcbiAgICBwcml2YXRlIHRva2VuU2VydmljZTogS29hbGFUb2tlblNlcnZpY2VcbiAgKSB7XG4gICAgdGhpcy5nZW5lcmF0ZVN0YXRlKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmV2ZW50U3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMucmVmcmVzaFRva2VuSW50ZXJ2YWw/LnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBwdWJsaWMgaGFzT3BlbklkQ29uZmlnKCkge1xuICAgIHJldHVybiAhIXRoaXMub3BlbklkT3B0aW9ucztcbiAgfVxuXG4gIHB1YmxpYyBjb25maWd1cmUob3B0aW9uczogS29hbGFPQXV0aDJDb25maWcpIHtcbiAgICB0aGlzLmNvbmZpZyA9IG9wdGlvbnM7XG4gIH1cblxuICBwdWJsaWMgbG9hZERpc2NvdmVyeURvY3VtZW50QW5kVHJ5TG9naW4oKSB7XG5cbiAgICBpZiAodGhpcy5ldmVudFN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5ldmVudFN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICB0aGlzLmV2ZW50U3Vic2NyaXB0aW9uID0gdGhpcy5ldmVudHMuc3Vic2NyaWJlKGV2ZW50ID0+IHtcbiAgICAgIGlmIChldmVudCA9PT0gJ2F1dGhlbnRpY2F0ZScpIHtcbiAgICAgICAgdGhpcy5nZW5lcmF0ZVN0YXRlKCk7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKFNUQVRFX1NUT1JBR0VfTkFNRSwgdGhpcy5zdGF0ZSk7XG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gYCR7dGhpcy5vcGVuSWRPcHRpb25zLmF1dGhvcml6YXRpb25fZW5kcG9pbnR9P3Jlc3BvbnNlX3R5cGU9JHt0aGlzLmNvbmZpZy5yZXNwb25zZVR5cGV9JmNsaWVudF9pZD0ke3RoaXMuY29uZmlnLmNsaWVudElkfSZzdGF0ZT0ke3RoaXMuc3RhdGV9JnJlZGlyZWN0X3VyaT0ke3RoaXMuY29uZmlnLnJlZGlyZWN0VXJpfSZzY29wZT0ke3RoaXMuY29uZmlnLnNjb3BlfWA7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50ID09PSAnZ2V0VG9rZW4nKSB7XG4gICAgICAgIGNvbnN0IHVybFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaCk7XG4gICAgICAgIGNvbnN0IHN0YXRlID0gdXJsUGFyYW1zLmdldCgnc3RhdGUnKTtcbiAgICAgICAgaWYgKHN0YXRlID09PSB0aGlzLnN0YXRlKSB7XG4gICAgICAgICAgY29uc3QgY29kZSA9IHVybFBhcmFtcy5nZXQoJ2NvZGUnKTtcbiAgICAgICAgICB0aGlzLmdldFRva2VuKGNvZGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMubG9nb3V0KCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQgPT09ICdnZXRDbGFpbXMnIHx8IChldmVudCA9PT0gJ3JlZnJlc2hUb2tlbicgJiYgIXRoaXMuY2xhaW1zKSkge1xuICAgICAgICB0aGlzLmdldENsYWltcygpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuaHR0cC5nZXQ8S29hbGFPcGVuSWRDb25maWc+KGAke3RoaXMuY29uZmlnLmlzc3Vlcn0vLndlbGwta25vd24vb3BlbmlkLWNvbmZpZ3VyYXRpb25gKS5zdWJzY3JpYmUob3B0aW9ucyA9PiB7XG4gICAgICAgIHRoaXMub3BlbklkT3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgIGlmICh3aW5kb3cubG9jYXRpb24uaHJlZi5pbmRleE9mKGBzdGF0ZT0ke3RoaXMuc3RhdGV9YCkgPj0gMCkge1xuICAgICAgICAgIHRoaXMuZXZlbnRzLm5leHQoJ2dldFRva2VuJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoIXRoaXMudG9rZW5TZXJ2aWNlLmdldE9BdXRoMlRva2VuKCkpIHtcbiAgICAgICAgICB0aGlzLmV2ZW50cy5uZXh0KCdsb2FkZWRDb25maWcnKTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgfSwgZSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIHRoaXMuZXZlbnRzLm5leHQoJ2Vycm9yTG9hZENvbmZpZycpO1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBpbml0TG9naW5GbG93KG5hbWU/OiBzdHJpbmcpIHtcbiAgICBpZiAobmFtZSkge1xuICAgICAgS29hbGFPYXV0aENvbmZpZy5zZXRDb25maWcobmFtZSk7XG4gICAgICBhd2FpdCBkZWxheSgxMDAwKTtcbiAgICB9XG5cbiAgICB0aGlzLmV2ZW50cy5uZXh0KCdhdXRoZW50aWNhdGUnKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRJZGVudGl0eUNsYWltcygpIHtcbiAgICByZXR1cm4gdGhpcy5jbGFpbXM7XG4gIH1cblxuICBwdWJsaWMgZ2V0QWNjZXNzVG9rZW4oKSB7XG4gICAgcmV0dXJuIHRoaXMudG9rZW4uYWNjZXNzX3Rva2VuO1xuICB9XG5cbiAgcHVibGljIGdldElkVG9rZW4oKSB7XG4gICAgcmV0dXJuIHRoaXMudG9rZW4uaWRfdG9rZW47XG4gIH1cblxuICBwdWJsaWMgZ2V0UmVmcmVzaFRva2VuKCkge1xuICAgIHJldHVybiB0aGlzLnRva2VuLnJlZnJlc2hfdG9rZW47XG4gIH1cblxuICBwdWJsaWMgZ2V0QWNjZXNzVG9rZW5FeHBpcmF0aW9uKCkge1xuICAgIGNvbnN0IGV4cGlyZXNfaW4gPSBuZXcgRGF0ZSgpO1xuICAgIGV4cGlyZXNfaW4uc2V0U2Vjb25kcyh0aGlzLnRva2VuLmV4cGlyZXNfaW4pO1xuICAgIHJldHVybiBleHBpcmVzX2luLnRvU3RyaW5nKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q29kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb2RlO1xuICB9XG5cbiAgcHVibGljIGxvZ291dCgpIHtcbiAgICBjb25zdCBsb2dvdXRJbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmhhc09wZW5JZENvbmZpZygpKSB7XG4gICAgICAgIGlmICh0aGlzLm9wZW5JZE9wdGlvbnMuZW5kX3Nlc3Npb25fZW5kcG9pbnQpIHtcbiAgICAgICAgICB0aGlzLmNsYWltcyA9IG51bGw7XG4gICAgICAgICAgdGhpcy50b2tlbiA9IG51bGw7XG4gICAgICAgICAgY29uc3QgaWZyYW1lTG9nb3V0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgICAgICAgaWZyYW1lTG9nb3V0LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgaWZyYW1lTG9nb3V0LnNyYyA9IHRoaXMub3BlbklkT3B0aW9ucy5lbmRfc2Vzc2lvbl9lbmRwb2ludDtcbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuYXBwZW5kQ2hpbGQoaWZyYW1lTG9nb3V0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmV2ZW50cy5uZXh0KCdsb2dvdXQnKTtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChsb2dvdXRJbnRlcnZhbCk7XG4gICAgICB9XG4gICAgfSwgMzAwKTtcbiAgfVxuXG4gIHB1YmxpYyBpbml0UmVmcmVzaFRva2VuSW50ZXJ2YWwoY29kZTogc3RyaW5nLCByZWZyZXNoVG9rZW46IHN0cmluZykge1xuICAgIHRoaXMucmVmcmVzaFRva2VuSW50ZXJ2YWw/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5yZWZyZXNoVG9rZW5JbnRlcnZhbCA9IGludGVydmFsKDEwMDApLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICBjb25zdCByZWZyZXNoVG9rZW5EYXRlID0gbmV3IERhdGUoKTtcbiAgICAgIHJlZnJlc2hUb2tlbkRhdGUuc2V0TWludXRlcyhyZWZyZXNoVG9rZW5EYXRlLmdldE1pbnV0ZXMoKSArIDEpO1xuICAgICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuU2VydmljZS5nZXRPQXV0aDJUb2tlbigpO1xuICAgICAgaWYgKHRva2VuKSB7XG4gICAgICAgIGNvbnN0IGV4cGlyZXNfaW4gPSB0b2tlbi5leHBpcmVkO1xuICAgICAgICBpZiAoZXhwaXJlc19pbikge1xuICAgICAgICAgIGlmIChuZXcgRGF0ZShleHBpcmVzX2luKSA8PSByZWZyZXNoVG9rZW5EYXRlKSB7XG4gICAgICAgICAgICB0aGlzLmdldFRva2VuKGNvZGUsIHJlZnJlc2hUb2tlbik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldFRva2VuKGNvZGU6IHN0cmluZywgcmVmcmVzaFRva2VuPzogc3RyaW5nKSB7XG4gICAgaWYgKHJlZnJlc2hUb2tlbikge1xuICAgICAgdGhpcy5yZWZyZXNoVG9rZW5JbnRlcnZhbD8udW5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICBjb25zdCBmb3JtRGF0YSA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcbiAgICBsZXQgZGF0YSA9IGtvYWxhKHtcbiAgICAgIGdyYW50X3R5cGU6IChyZWZyZXNoVG9rZW4gPyAncmVmcmVzaF90b2tlbicgOiAnYXV0aG9yaXphdGlvbl9jb2RlJyksXG4gICAgICBjb2RlLFxuICAgICAgcmVkaXJlY3RfdXJpOiB0aGlzLmNvbmZpZy5yZWRpcmVjdFVyaSxcbiAgICAgIGNsaWVudF9pZDogdGhpcy5jb25maWcuY2xpZW50SWRcbiAgICB9KS5vYmplY3QoKS5tZXJnZSh0aGlzLmNvbmZpZy5jdXN0b21RdWVyeVBhcmFtcyA/PyB7fSkuZ2V0VmFsdWUoKTtcblxuICAgIGlmIChyZWZyZXNoVG9rZW4pIHtcbiAgICAgIGRhdGEgPSBrb2FsYShkYXRhKS5vYmplY3QoKS5tZXJnZSh7cmVmcmVzaF90b2tlbjogcmVmcmVzaFRva2VufSkuZ2V0VmFsdWUoKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuY29kZSkge1xuICAgICAgdGhpcy5jb2RlID0gY29kZTtcbiAgICB9XG5cbiAgICBPYmplY3Qua2V5cyhkYXRhKS5mb3JFYWNoKGluZGV4TmFtZSA9PiB7XG4gICAgICBmb3JtRGF0YS5hcHBlbmQoaW5kZXhOYW1lLCBkYXRhW2luZGV4TmFtZV0pO1xuICAgIH0pO1xuXG4gICAgdGhpcy5odHRwLnBvc3QodGhpcy5jb25maWcuZW5kcG9pbnRUb2tlbiA/PyB0aGlzLm9wZW5JZE9wdGlvbnMudG9rZW5fZW5kcG9pbnQsIGZvcm1EYXRhLnRvU3RyaW5nKCksIHtcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXG4gICAgICB9XG4gICAgfSkuc3Vic2NyaWJlKCh0b2tlbjogYW55KSA9PiB7XG4gICAgICB0aGlzLnRva2VuID0gdG9rZW47XG4gICAgICB0aGlzLmV2ZW50cy5uZXh0KChyZWZyZXNoVG9rZW4gPyAncmVmcmVzaFRva2VuJyA6ICdnZXRDbGFpbXMnKSk7XG4gICAgfSwgKCkgPT4gdGhpcy5ldmVudHMubmV4dCgnZ2V0VG9rZW5FcnJvcicpKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q2xhaW1zKCkge1xuICAgIHRoaXMuaHR0cC5nZXQoKHRoaXMuY29uZmlnLmVuZHBvaW50Q2xhaW1zID8/IHRoaXMub3BlbklkT3B0aW9ucy51c2VyaW5mb19lbmRwb2ludCksIHtcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke3RoaXMuZ2V0QWNjZXNzVG9rZW4oKX1gXG4gICAgICB9XG4gICAgfSkuc3Vic2NyaWJlKHVzZXJJbmZvID0+IHtcbiAgICAgIHRoaXMuY2xhaW1zID0gdXNlckluZm87XG4gICAgICB0aGlzLnN0YXRlID0gbnVsbDtcbiAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKFNUQVRFX1NUT1JBR0VfTkFNRSk7XG4gICAgICB0aGlzLmV2ZW50cy5uZXh0KHRoaXMuZXZlbnRzLmdldFZhbHVlKCkgPT09ICdyZWZyZXNoVG9rZW4nID8gJ3JlZnJlc2hUb2tlbicgOiAndXNlckF1dGhlbnRpY2F0ZWQnKTtcbiAgICB9LCAoKSA9PiB0aGlzLmV2ZW50cy5uZXh0KCdsb2FkZWRDb25maWcnKSk7XG4gIH1cblxuICBwcml2YXRlIGdlbmVyYXRlU3RhdGUoKSB7XG4gICAgdGhpcy5zdGF0ZSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKFNUQVRFX1NUT1JBR0VfTkFNRSkgP1xuICAgICAgICAgICAgICAgICBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShTVEFURV9TVE9SQUdFX05BTUUpIDpcbiAgICAgICAgICAgICAgICAgcmFuZG9tU3RyaW5nKDMwLCB7XG4gICAgICAgICAgICAgICAgICAgbnVtYmVyczogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICB1cHBlcmNhc2U6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgbG93ZXJjYXNlOiB0cnVlXG4gICAgICAgICAgICAgICAgIH0pO1xuICB9XG59XG4iXX0=