@dbg-riskit/angular-auth
Version:
148 lines • 21.1 kB
JavaScript
import { Inject, Injectable } from '@angular/core';
import { defer, EMPTY, merge, of } from 'rxjs';
import { defaultIfEmpty, first, map, switchMap } from 'rxjs/operators';
import { AUTH_CONFIG, AuthFlow } from './auth.config';
import { RequestUtils } from './request.utils';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
import * as i2 from "@dbg-riskit/angular-http";
import * as i3 from "./auth.service";
import * as i4 from "./auth.storage.service";
import * as i5 from "./well.known.service";
export class AuthRoutingFlowService {
constructor(router, http, authService, storage, authConfig, wellKnownService) {
this.router = router;
this.http = http;
this.authService = authService;
this.storage = storage;
this.authConfig = authConfig;
this.wellKnownService = wellKnownService;
// Subscribe for login changes so we do correct navigation after logout
this.authService.loggedIn
.subscribe(() => {
try {
merge(this.http.unauthorized.pipe(map(() => false)), this.authService.loggedInStream)
.subscribe((loggedIn) => {
if (!loggedIn) {
this.logout().pipe(first()).subscribe();
}
});
}
catch (ignore) {
// Happens in tests only
}
});
}
get authFlow() {
return this.authConfig.flow;
}
get authorizationCodeFlow() {
return this.authFlow === AuthFlow.AUTHORIZATION_CODE;
}
get implicitFlow() {
return this.authFlow === AuthFlow.IMPLICIT;
}
get hybridFlow() {
return this.authFlow === AuthFlow.HYBRID;
}
get directFlow() {
return this.authFlow === AuthFlow.DIRECT;
}
logout(state) {
return this.authService.loggedIn.pipe(switchMap((res) => {
if (res) {
return this.authService.logout();
}
return EMPTY;
}), defaultIfEmpty(0), switchMap(() => {
this.storeRequestedPath(state);
return this.doLogin();
}));
}
login(username, password) {
return defer(() => {
switch (this.authFlow) {
case AuthFlow.DIRECT:
if (username == null || password == null) {
throw new Error('Username and password expexted!');
}
return this.authService.directLogin(username, password).pipe(switchMap((res) => this.loginRedirect(res)));
case AuthFlow.AUTHORIZATION_CODE:
case AuthFlow.IMPLICIT:
case AuthFlow.HYBRID:
return this.doLogin();
default:
throw new Error('Unsupported auth flow detected!');
}
});
}
loginViaService() {
return this.authService.loggedIn.pipe(switchMap((res) => {
switch (this.authFlow) {
case AuthFlow.AUTHORIZATION_CODE:
case AuthFlow.IMPLICIT:
case AuthFlow.HYBRID:
if (res) {
return this.loginRedirect(res);
}
if (!RequestUtils.hasOpenIDQueryParams()) {
return this.doLogin().pipe(map(() => res));
}
return this.authService.checkLocationForLoginData().pipe(switchMap((loggedIn) => this.loginRedirect(loggedIn)));
case AuthFlow.DIRECT:
return of(true);
default:
throw new Error('Unknown auth flow detected!');
}
}));
}
storeRequestedPath(state = this.router.routerState.snapshot) {
if (state.url.startsWith(this.authConfig.loginRoute)) {
this.storage.authRequestedPath = null;
}
else {
this.storage.authRequestedPath = state.url;
}
}
loginRedirect(res) {
return this.wellKnownService.wellKnown.pipe(switchMap(() => {
if (res) {
if (this.storage.authRequestedPath) {
this.router.navigateByUrl(this.storage.authRequestedPath);
this.storage.authRequestedPath = null;
}
else {
this.router.navigate([this.authConfig.afterLoginRedirectRoute]);
}
return of(res);
}
else {
return this.doLogin().pipe(map(() => res));
}
}));
}
doLogin() {
switch (this.authFlow) {
case AuthFlow.DIRECT:
return this.wellKnownService.wellKnown.pipe(map(() => {
this.router.navigate([this.authConfig.loginRoute]);
return true;
}));
case AuthFlow.AUTHORIZATION_CODE:
case AuthFlow.IMPLICIT:
case AuthFlow.HYBRID:
return this.authService.loginViaAuthService();
default:
throw new Error('Unknown auth flow detected!');
}
}
}
AuthRoutingFlowService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.6", ngImport: i0, type: AuthRoutingFlowService, deps: [{ token: i1.Router }, { token: i2.HttpService }, { token: i3.AuthService }, { token: i4.AuthStorageService }, { token: AUTH_CONFIG }, { token: i5.WellKnownService }], target: i0.ɵɵFactoryTarget.Injectable });
AuthRoutingFlowService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.6", ngImport: i0, type: AuthRoutingFlowService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.6", ngImport: i0, type: AuthRoutingFlowService, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: i1.Router }, { type: i2.HttpService }, { type: i3.AuthService }, { type: i4.AuthStorageService }, { type: undefined, decorators: [{
type: Inject,
args: [AUTH_CONFIG]
}] }, { type: i5.WellKnownService }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5yb3V0aW5nLmZsb3cuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BrZy9kYmctcmlza2l0L2FuZ3VsYXItYXV0aC9zcmMvbGliL2F1dGgucm91dGluZy5mbG93LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFHakQsT0FBTyxFQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFjLEVBQUUsRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUN6RCxPQUFPLEVBQUMsY0FBYyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDckUsT0FBTyxFQUFDLFdBQVcsRUFBYyxRQUFRLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFHaEUsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGlCQUFpQixDQUFDOzs7Ozs7O0FBSTdDLE1BQU0sT0FBTyxzQkFBc0I7SUFFL0IsWUFBb0MsTUFBYyxFQUNkLElBQWlCLEVBQ2pCLFdBQXdCLEVBQ3hCLE9BQTJCLEVBQ04sVUFBc0IsRUFDM0MsZ0JBQWtDO1FBTGxDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxTQUFJLEdBQUosSUFBSSxDQUFhO1FBQ2pCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLFlBQU8sR0FBUCxPQUFPLENBQW9CO1FBQ04sZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUMzQyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBRWxFLHVFQUF1RTtRQUN2RSxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVE7YUFDcEIsU0FBUyxDQUNOLEdBQUcsRUFBRTtZQUNELElBQUk7Z0JBQ0EsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFDL0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUM7cUJBQy9CLFNBQVMsQ0FBQyxDQUFDLFFBQWlCLEVBQUUsRUFBRTtvQkFDN0IsSUFBSSxDQUFDLFFBQVEsRUFBRTt3QkFDWCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7cUJBQzNDO2dCQUNMLENBQUMsQ0FBQyxDQUFDO2FBQ1Y7WUFBQyxPQUFPLE1BQU0sRUFBRTtnQkFDYix3QkFBd0I7YUFDM0I7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNmLENBQUM7SUFFRCxJQUFXLFFBQVE7UUFDZixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxJQUFXLHFCQUFxQjtRQUM1QixPQUFPLElBQUksQ0FBQyxRQUFRLEtBQUssUUFBUSxDQUFDLGtCQUFrQixDQUFDO0lBQ3pELENBQUM7SUFFRCxJQUFXLFlBQVk7UUFDbkIsT0FBTyxJQUFJLENBQUMsUUFBUSxLQUFLLFFBQVEsQ0FBQyxRQUFRLENBQUM7SUFDL0MsQ0FBQztJQUVELElBQVcsVUFBVTtRQUNqQixPQUFPLElBQUksQ0FBQyxRQUFRLEtBQUssUUFBUSxDQUFDLE1BQU0sQ0FBQztJQUM3QyxDQUFDO0lBRUQsSUFBVyxVQUFVO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUMsTUFBTSxDQUFDO0lBQzdDLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBMkI7UUFDckMsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQ2pDLFNBQVMsQ0FBQyxDQUFDLEdBQVksRUFBRSxFQUFFO1lBQ3ZCLElBQUksR0FBRyxFQUFFO2dCQUNMLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQzthQUNwQztZQUNELE9BQU8sS0FBSyxDQUFDO1FBQ2pCLENBQUMsQ0FBQyxFQUNGLGNBQWMsQ0FBQyxDQUFDLENBQUMsRUFDakIsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNYLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMvQixPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FDTCxDQUFDO0lBQ04sQ0FBQztJQUVNLEtBQUssQ0FBQyxRQUFpQixFQUFFLFFBQWlCO1FBQzdDLE9BQU8sS0FBSyxDQUFDLEdBQUcsRUFBRTtZQUNkLFFBQVEsSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDbkIsS0FBSyxRQUFRLENBQUMsTUFBTTtvQkFDaEIsSUFBSSxRQUFRLElBQUksSUFBSSxJQUFJLFFBQVEsSUFBSSxJQUFJLEVBQUU7d0JBQ3RDLE1BQU0sSUFBSSxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQztxQkFDdEQ7b0JBQ0QsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUN4RCxTQUFTLENBQUMsQ0FBQyxHQUFZLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FDdkQsQ0FBQztnQkFDTixLQUFLLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQztnQkFDakMsS0FBSyxRQUFRLENBQUMsUUFBUSxDQUFDO2dCQUN2QixLQUFLLFFBQVEsQ0FBQyxNQUFNO29CQUNoQixPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDMUI7b0JBQ0ksTUFBTSxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO2FBQzFEO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU0sZUFBZTtRQUNsQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksQ0FDakMsU0FBUyxDQUFDLENBQUMsR0FBWSxFQUFFLEVBQUU7WUFDdkIsUUFBUSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNuQixLQUFLLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQztnQkFDakMsS0FBSyxRQUFRLENBQUMsUUFBUSxDQUFDO2dCQUN2QixLQUFLLFFBQVEsQ0FBQyxNQUFNO29CQUNoQixJQUFJLEdBQUcsRUFBRTt3QkFDTCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7cUJBQ2xDO29CQUNELElBQUksQ0FBQyxZQUFZLENBQUMsb0JBQW9CLEVBQUUsRUFBRTt3QkFDdEMsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO3FCQUM5QztvQkFDRCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxJQUFJLENBQ3BELFNBQVMsQ0FBQyxDQUFDLFFBQWlCLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FDakUsQ0FBQztnQkFDTixLQUFLLFFBQVEsQ0FBQyxNQUFNO29CQUNoQixPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDcEI7b0JBQ0ksTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO2FBQ3REO1FBQ0wsQ0FBQyxDQUFDLENBQ0wsQ0FBQztJQUNOLENBQUM7SUFFTSxrQkFBa0IsQ0FBQyxRQUE2QixJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFRO1FBQ25GLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUNsRCxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztTQUN6QzthQUFNO1lBQ0gsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDO1NBQzlDO0lBQ0wsQ0FBQztJQUVPLGFBQWEsQ0FBQyxHQUFZO1FBQzlCLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQ3ZDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDWCxJQUFJLEdBQUcsRUFBRTtnQkFDTCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLEVBQUU7b0JBQ2hDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FBQztvQkFDMUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7aUJBQ3pDO3FCQUFNO29CQUNILElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUM7aUJBQ25FO2dCQUNELE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ2xCO2lCQUFNO2dCQUNILE9BQU8sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQzthQUM5QztRQUNMLENBQUMsQ0FBQyxDQUNMLENBQUM7SUFDTixDQUFDO0lBRU8sT0FBTztRQUNYLFFBQVEsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNuQixLQUFNLFFBQVEsQ0FBQyxNQUFNO2dCQUNqQixPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUN2QyxHQUFHLENBQUMsR0FBRyxFQUFFO29CQUNMLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO29CQUNuRCxPQUFPLElBQUksQ0FBQztnQkFDaEIsQ0FBQyxDQUFDLENBQ0wsQ0FBQztZQUNOLEtBQUssUUFBUSxDQUFDLGtCQUFrQixDQUFDO1lBQ2pDLEtBQUssUUFBUSxDQUFDLFFBQVEsQ0FBQztZQUN2QixLQUFLLFFBQVEsQ0FBQyxNQUFNO2dCQUNoQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUNsRDtnQkFDSSxNQUFNLElBQUksS0FBSyxDQUFDLDZCQUE2QixDQUFDLENBQUM7U0FDdEQ7SUFDTCxDQUFDOzttSEF0SlEsc0JBQXNCLGdJQU1KLFdBQVc7dUhBTjdCLHNCQUFzQjsyRkFBdEIsc0JBQXNCO2tCQURsQyxVQUFVOzswQkFPYSxNQUFNOzJCQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdCwgSW5qZWN0YWJsZX0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1JvdXRlciwgUm91dGVyU3RhdGVTbmFwc2hvdH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7SHR0cFNlcnZpY2V9IGZyb20gJ0BkYmctcmlza2l0L2FuZ3VsYXItaHR0cCc7XG5pbXBvcnQge2RlZmVyLCBFTVBUWSwgbWVyZ2UsIE9ic2VydmFibGUsIG9mfSBmcm9tICdyeGpzJztcbmltcG9ydCB7ZGVmYXVsdElmRW1wdHksIGZpcnN0LCBtYXAsIHN3aXRjaE1hcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtBVVRIX0NPTkZJRywgQXV0aENvbmZpZywgQXV0aEZsb3d9IGZyb20gJy4vYXV0aC5jb25maWcnO1xuaW1wb3J0IHtBdXRoU2VydmljZX0gZnJvbSAnLi9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHtBdXRoU3RvcmFnZVNlcnZpY2V9IGZyb20gJy4vYXV0aC5zdG9yYWdlLnNlcnZpY2UnO1xuaW1wb3J0IHtSZXF1ZXN0VXRpbHN9IGZyb20gJy4vcmVxdWVzdC51dGlscyc7XG5pbXBvcnQge1dlbGxLbm93blNlcnZpY2V9IGZyb20gJy4vd2VsbC5rbm93bi5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEF1dGhSb3V0aW5nRmxvd1NlcnZpY2Uge1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgcm91dGVyOiBSb3V0ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgIHByaXZhdGUgcmVhZG9ubHkgaHR0cDogSHR0cFNlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgICAgIHByaXZhdGUgcmVhZG9ubHkgYXV0aFNlcnZpY2U6IEF1dGhTZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlIHJlYWRvbmx5IHN0b3JhZ2U6IEF1dGhTdG9yYWdlU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgQEluamVjdChBVVRIX0NPTkZJRykgcHJpdmF0ZSByZWFkb25seSBhdXRoQ29uZmlnOiBBdXRoQ29uZmlnLFxuICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlIHJlYWRvbmx5IHdlbGxLbm93blNlcnZpY2U6IFdlbGxLbm93blNlcnZpY2UpIHtcblxuICAgICAgICAvLyBTdWJzY3JpYmUgZm9yIGxvZ2luIGNoYW5nZXMgc28gd2UgZG8gY29ycmVjdCBuYXZpZ2F0aW9uIGFmdGVyIGxvZ291dFxuICAgICAgICB0aGlzLmF1dGhTZXJ2aWNlLmxvZ2dlZEluXG4gICAgICAgICAgICAuc3Vic2NyaWJlKFxuICAgICAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlKHRoaXMuaHR0cC51bmF1dGhvcml6ZWQucGlwZShtYXAoKCkgPT4gZmFsc2UpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmF1dGhTZXJ2aWNlLmxvZ2dlZEluU3RyZWFtKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKGxvZ2dlZEluOiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbG9nZ2VkSW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nb3V0KCkucGlwZShmaXJzdCgpKS5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChpZ25vcmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhhcHBlbnMgaW4gdGVzdHMgb25seVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBhdXRoRmxvdygpOiBBdXRoRmxvdyB7XG4gICAgICAgIHJldHVybiB0aGlzLmF1dGhDb25maWcuZmxvdztcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGF1dGhvcml6YXRpb25Db2RlRmxvdygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aEZsb3cgPT09IEF1dGhGbG93LkFVVEhPUklaQVRJT05fQ09ERTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGltcGxpY2l0RmxvdygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aEZsb3cgPT09IEF1dGhGbG93LklNUExJQ0lUO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgaHlicmlkRmxvdygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aEZsb3cgPT09IEF1dGhGbG93LkhZQlJJRDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGRpcmVjdEZsb3coKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmF1dGhGbG93ID09PSBBdXRoRmxvdy5ESVJFQ1Q7XG4gICAgfVxuXG4gICAgcHVibGljIGxvZ291dChzdGF0ZT86IFJvdXRlclN0YXRlU25hcHNob3QpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aFNlcnZpY2UubG9nZ2VkSW4ucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgocmVzOiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hdXRoU2VydmljZS5sb2dvdXQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVNUFRZO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBkZWZhdWx0SWZFbXB0eSgwKSxcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdG9yZVJlcXVlc3RlZFBhdGgoc3RhdGUpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRvTG9naW4oKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIGxvZ2luKHVzZXJuYW1lPzogc3RyaW5nLCBwYXNzd29yZD86IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgICAgICByZXR1cm4gZGVmZXIoKCkgPT4ge1xuICAgICAgICAgICAgc3dpdGNoICh0aGlzLmF1dGhGbG93KSB7XG4gICAgICAgICAgICAgICAgY2FzZSBBdXRoRmxvdy5ESVJFQ1Q6XG4gICAgICAgICAgICAgICAgICAgIGlmICh1c2VybmFtZSA9PSBudWxsIHx8IHBhc3N3b3JkID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVXNlcm5hbWUgYW5kIHBhc3N3b3JkIGV4cGV4dGVkIScpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmF1dGhTZXJ2aWNlLmRpcmVjdExvZ2luKHVzZXJuYW1lLCBwYXNzd29yZCkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgocmVzOiBib29sZWFuKSA9PiB0aGlzLmxvZ2luUmVkaXJlY3QocmVzKSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBjYXNlIEF1dGhGbG93LkFVVEhPUklaQVRJT05fQ09ERTpcbiAgICAgICAgICAgICAgICBjYXNlIEF1dGhGbG93LklNUExJQ0lUOlxuICAgICAgICAgICAgICAgIGNhc2UgQXV0aEZsb3cuSFlCUklEOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kb0xvZ2luKCk7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBhdXRoIGZsb3cgZGV0ZWN0ZWQhJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBsb2dpblZpYVNlcnZpY2UoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmF1dGhTZXJ2aWNlLmxvZ2dlZEluLnBpcGUoXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKHJlczogYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGhpcy5hdXRoRmxvdykge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIEF1dGhGbG93LkFVVEhPUklaQVRJT05fQ09ERTpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBBdXRoRmxvdy5JTVBMSUNJVDpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBBdXRoRmxvdy5IWUJSSUQ6XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9naW5SZWRpcmVjdChyZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFSZXF1ZXN0VXRpbHMuaGFzT3BlbklEUXVlcnlQYXJhbXMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRvTG9naW4oKS5waXBlKG1hcCgoKSA9PiByZXMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmF1dGhTZXJ2aWNlLmNoZWNrTG9jYXRpb25Gb3JMb2dpbkRhdGEoKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgobG9nZ2VkSW46IGJvb2xlYW4pID0+IHRoaXMubG9naW5SZWRpcmVjdChsb2dnZWRJbikpXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIEF1dGhGbG93LkRJUkVDVDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZih0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBhdXRoIGZsb3cgZGV0ZWN0ZWQhJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RvcmVSZXF1ZXN0ZWRQYXRoKHN0YXRlOiBSb3V0ZXJTdGF0ZVNuYXBzaG90ID0gdGhpcy5yb3V0ZXIucm91dGVyU3RhdGUuc25hcHNob3QpOiB2b2lkIHtcbiAgICAgICAgaWYgKHN0YXRlLnVybC5zdGFydHNXaXRoKHRoaXMuYXV0aENvbmZpZy5sb2dpblJvdXRlKSkge1xuICAgICAgICAgICAgdGhpcy5zdG9yYWdlLmF1dGhSZXF1ZXN0ZWRQYXRoID0gbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5hdXRoUmVxdWVzdGVkUGF0aCA9IHN0YXRlLnVybDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgbG9naW5SZWRpcmVjdChyZXM6IGJvb2xlYW4pOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2VsbEtub3duU2VydmljZS53ZWxsS25vd24ucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdG9yYWdlLmF1dGhSZXF1ZXN0ZWRQYXRoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZUJ5VXJsKHRoaXMuc3RvcmFnZS5hdXRoUmVxdWVzdGVkUGF0aCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UuYXV0aFJlcXVlc3RlZFBhdGggPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW3RoaXMuYXV0aENvbmZpZy5hZnRlckxvZ2luUmVkaXJlY3RSb3V0ZV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihyZXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRvTG9naW4oKS5waXBlKG1hcCgoKSA9PiByZXMpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgZG9Mb2dpbigpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICAgICAgc3dpdGNoICh0aGlzLmF1dGhGbG93KSB7XG4gICAgICAgICAgICBjYXNlICBBdXRoRmxvdy5ESVJFQ1Q6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMud2VsbEtub3duU2VydmljZS53ZWxsS25vd24ucGlwZShcbiAgICAgICAgICAgICAgICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFt0aGlzLmF1dGhDb25maWcubG9naW5Sb3V0ZV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNhc2UgQXV0aEZsb3cuQVVUSE9SSVpBVElPTl9DT0RFOlxuICAgICAgICAgICAgY2FzZSBBdXRoRmxvdy5JTVBMSUNJVDpcbiAgICAgICAgICAgIGNhc2UgQXV0aEZsb3cuSFlCUklEOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmF1dGhTZXJ2aWNlLmxvZ2luVmlhQXV0aFNlcnZpY2UoKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGF1dGggZmxvdyBkZXRlY3RlZCEnKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==