UNPKG

@asgardeo/auth-angular

Version:
245 lines 30.8 kB
import { __awaiter } from "tslib"; /** * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ import { from, Subject } from "rxjs"; import { Inject, Injectable } from "@angular/core"; import { AsgardeoSPAClient, SPAUtils, } from "@asgardeo/auth-spa"; import { ASGARDEO_CONFIG } from "../configs/asgardeo-config"; import { Hooks } from "../models/asgardeo-spa.models"; import { AsgardeoNavigatorService } from "./asgardeo-navigator.service"; import { AsgardeoAuthStateStoreService } from "./asgardeo-auth-state-store.service"; import { takeUntil } from "rxjs/operators"; import * as i0 from "@angular/core"; import * as i1 from "../configs/asgardeo-config"; import * as i2 from "./asgardeo-navigator.service"; import * as i3 from "./asgardeo-auth-state-store.service"; export class AsgardeoAuthService { constructor(authConfig, navigator, stateStore) { this.authConfig = authConfig; this.navigator = navigator; this.stateStore = stateStore; this.state$ = this.stateStore.state$; this.auth = AsgardeoSPAClient.getInstance(); this.subscriptionDestroyer$ = new Subject(); /** * This method allows you to sign in silently. * First, this method sends a prompt none request to see if there is an active user session in the identity server. * If there is one, then it requests the access token and stores it. Else, it returns false. * * @return {Promise<BasicUserInfo | boolean>} - A Promise that resolves with the user information after signing in * or with `false` if the user is not signed in. * * @example *``` * this.auth.trySignInSilently() *``` */ this.trySignInSilently = () => __awaiter(this, void 0, void 0, function* () { this.stateStore.setIsLoading(true); return this.auth .trySignInSilently() .then((response) => __awaiter(this, void 0, void 0, function* () { if (!response) { return false; } if (yield this.auth.isAuthenticated()) { const basicUserInfo = response; this.stateStore.state = { allowedScopes: basicUserInfo.allowedScopes, displayName: basicUserInfo.displayName, email: basicUserInfo.email, isAuthenticated: true, isLoading: false, sub: basicUserInfo.sub, username: basicUserInfo.username }; } return response; })) .catch((error) => Promise.reject(error)) .finally(() => { this.stateStore.setIsLoading(false); }); }); this.config = authConfig; this.auth = AsgardeoSPAClient.getInstance(); this.initializeHooks(); (() => __awaiter(this, void 0, void 0, function* () { yield this.auth.initialize(this.authConfig); yield this.handleSingleLogoutOnRedirect(); this.handleAutoLogin() .pipe(takeUntil(this.subscriptionDestroyer$)) .subscribe(); }))(); } /** * Runs on service unmount. * @remarks Housekeeping logic such as un-subscribing should go here. */ ngOnDestroy() { this.subscriptionDestroyer$.next(true); this.subscriptionDestroyer$.unsubscribe(); } /** * Registering a sign-out hook clears user session data internally if there was a successful logout. */ initializeHooks() { this.auth.on(Hooks.SignOut, () => { }); } signIn(config, authorizationCode, sessionState) { this.stateStore.setIsLoading(true); return this.auth .signIn(config, authorizationCode, sessionState) .then((response) => __awaiter(this, void 0, void 0, function* () { if (!response) { return; } if (yield this.auth.isAuthenticated()) { this.stateStore.state = { allowedScopes: response.allowedScopes, displayName: response.displayName, email: response.email, isAuthenticated: true, isLoading: false, sub: response.sub, username: response.username }; } return response; })) .catch((error) => Promise.reject(error)) .finally(() => { this.stateStore.setIsLoading(false); }); } signInWithRedirect() { this.navigator.setRedirectUrl(); const redirectRoute = this.navigator.getRouteWithoutParams(this.authConfig.signInRedirectURL); return this.navigator.navigateByUrl(redirectRoute); } signOut() { this.stateStore.setIsLoading(true); return this.auth .signOut() .then((response) => { // Reset the state. this.stateStore.reset(); return response; }) .catch((error) => Promise.reject(error)) .finally(() => { this.stateStore.setIsLoading(false); }); } isAuthenticated() { return this.auth.isAuthenticated(); } getBasicUserInfo() { return this.auth.getBasicUserInfo(); } getAccessToken() { return this.auth.getAccessToken(); } getIDToken() { return this.auth.getIDToken(); } getDecodedIDToken() { return this.auth.getDecodedIDToken(); } getOIDCServiceEndpoints() { return this.auth.getOIDCServiceEndpoints(); } refreshAccessToken() { return this.auth.refreshAccessToken(); } revokeAccessToken() { return this.auth .revokeAccessToken() .then(() => { // Reset the state. this.stateStore.reset(); return true; }) .catch((error) => Promise.reject(error)) .finally(() => { this.stateStore.setIsLoading(false); }); } on(hook, callback, id) { if (hook === Hooks.CustomGrant) { return this.auth.on(hook, callback, id); } return this.auth.on(hook, callback); } requestCustomGrant(config) { return this.auth.requestCustomGrant(config); } httpRequest(config) { return this.auth.httpRequest(config); } httpRequestAll(config) { return this.auth.httpRequestAll(config); } /** * Handles auto login by trying to exchange tokens if auth params i.e `code` and `session_state` is * available in the URL or else, tries to silently login. * * @private * @return {Observable<BasicUserInfo | boolean>} */ handleAutoLogin() { this.stateStore.setIsLoading(true); // If `skipRedirectCallback` is not true, check if the URL has `code` and `session_state` params. // If so, initiate the sign in. If not, try to login silently. if (!this.config.skipRedirectCallback && SPAUtils.hasAuthSearchParamsInURL()) { return from(this.signIn()); } // This uses the RP iframe to get the session. Hence, will not work if 3rd party cookies are disabled. // If the browser has these cookies disabled, we'll not be able to retrieve the session on refreshes. return from(this.trySignInSilently()); } /** * Handles single logout if a prompt none sign in response is received with an error parameter on the URL. * * @private * @return {Promise<BasicUserInfo | void>} */ handleSingleLogoutOnRedirect() { return __awaiter(this, void 0, void 0, function* () { if (SPAUtils.hasErrorInURL()) { // The signIn method call will call receivePromptNoneResponse method internally to handle the prompt none // response in the single logout flow. return this.signIn({ callOnlyOnRedirect: true }); } }); } } AsgardeoAuthService.ɵprov = i0.ɵɵdefineInjectable({ factory: function AsgardeoAuthService_Factory() { return new AsgardeoAuthService(i0.ɵɵinject(i1.ASGARDEO_CONFIG), i0.ɵɵinject(i2.AsgardeoNavigatorService), i0.ɵɵinject(i3.AsgardeoAuthStateStoreService)); }, token: AsgardeoAuthService, providedIn: "root" }); AsgardeoAuthService.decorators = [ { type: Injectable, args: [{ providedIn: "root" },] } ]; AsgardeoAuthService.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [ASGARDEO_CONFIG,] }] }, { type: AsgardeoNavigatorService }, { type: AsgardeoAuthStateStoreService } ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNnYXJkZW8tYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9ob21lL3J1bm5lci93b3JrL2FzZ2FyZGVvLWF1dGgtYW5ndWxhci1zZGsvYXNnYXJkZW8tYXV0aC1hbmd1bGFyLXNkay9saWIvc3JjLyIsInNvdXJjZXMiOlsic2VydmljZXMvYXNnYXJkZW8tYXV0aC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFFSCxPQUFPLEVBQUUsSUFBSSxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNqRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUM5RCxPQUFPLEVBQ0gsaUJBQWlCLEVBRWpCLFFBQVEsR0FFWCxNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUU3RCxPQUFPLEVBSUgsS0FBSyxFQUtSLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDeEUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDcEYsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7OztBQUszQyxNQUFNLE9BQU8sbUJBQW1CO0lBTTVCLFlBRVksVUFBK0MsRUFDL0MsU0FBbUMsRUFDbkMsVUFBeUM7UUFGekMsZUFBVSxHQUFWLFVBQVUsQ0FBcUM7UUFDL0MsY0FBUyxHQUFULFNBQVMsQ0FBMEI7UUFDbkMsZUFBVSxHQUFWLFVBQVUsQ0FBK0I7UUFUckMsV0FBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDO1FBQ3hDLFNBQUksR0FBc0IsaUJBQWlCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFFMUQsMkJBQXNCLEdBQXFCLElBQUksT0FBTyxFQUFXLENBQUM7UUFxSzFF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SUFDMUMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ1csNEJBQTRCOztZQUV0QyxJQUFJLFFBQVEsQ0FBQyxhQUFhLEVBQUUsRUFBRTtnQkFDMUIseUdBQXlHO2dCQUN6RyxzQ0FBc0M7Z0JBQ3RDLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFDLGtCQUFrQixFQUFFLElBQUksRUFBQyxDQUFDLENBQUM7YUFDbEQ7UUFDTCxDQUFDO0tBQUE7Ozs7WUEvUEosVUFBVSxTQUFDO2dCQUNSLFVBQVUsRUFBRSxNQUFNO2FBQ3JCOzs7NENBUVEsTUFBTSxTQUFDLGVBQWU7WUFkdEIsd0JBQXdCO1lBQ3hCLDZCQUE2QiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDIxLCBXU08yIEluYy4gKGh0dHA6Ly93d3cud3NvMi5vcmcpIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogV1NPMiBJbmMuIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLFxuICogVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0XG4gKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xuICogdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IGZyb20sIE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlLCBPbkRlc3Ryb3kgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHtcbiAgICBBc2dhcmRlb1NQQUNsaWVudCxcbiAgICBBdXRoQ2xpZW50Q29uZmlnLFxuICAgIFNQQVV0aWxzLFxuICAgIEZldGNoUmVzcG9uc2UsXG59IGZyb20gXCJAYXNnYXJkZW8vYXV0aC1zcGFcIjtcbmltcG9ydCB7IEFTR0FSREVPX0NPTkZJRyB9IGZyb20gXCIuLi9jb25maWdzL2FzZ2FyZGVvLWNvbmZpZ1wiO1xuaW1wb3J0IHsgQXV0aEFuZ3VsYXJDb25maWcsIEF1dGhTdGF0ZUludGVyZmFjZSB9IGZyb20gXCIuLi9tb2RlbHNcIjtcbmltcG9ydCB7XG4gICAgQmFzaWNVc2VySW5mbyxcbiAgICBDdXN0b21HcmFudENvbmZpZyxcbiAgICBEZWNvZGVkSURUb2tlblBheWxvYWQsXG4gICAgSG9va3MsXG4gICAgSHR0cFJlcXVlc3RDb25maWcsXG4gICAgSHR0cFJlc3BvbnNlLFxuICAgIE9JRENFbmRwb2ludHMsXG4gICAgU2lnbkluQ29uZmlnXG59IGZyb20gXCIuLi9tb2RlbHMvYXNnYXJkZW8tc3BhLm1vZGVsc1wiO1xuaW1wb3J0IHsgQXNnYXJkZW9OYXZpZ2F0b3JTZXJ2aWNlIH0gZnJvbSBcIi4vYXNnYXJkZW8tbmF2aWdhdG9yLnNlcnZpY2VcIjtcbmltcG9ydCB7IEFzZ2FyZGVvQXV0aFN0YXRlU3RvcmVTZXJ2aWNlIH0gZnJvbSBcIi4vYXNnYXJkZW8tYXV0aC1zdGF0ZS1zdG9yZS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcblxuQEluamVjdGFibGUoe1xuICAgIHByb3ZpZGVkSW46IFwicm9vdFwiXG59KVxuZXhwb3J0IGNsYXNzIEFzZ2FyZGVvQXV0aFNlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICAgIHB1YmxpYyByZWFkb25seSBzdGF0ZSQgPSB0aGlzLnN0YXRlU3RvcmUuc3RhdGUkO1xuICAgIHByaXZhdGUgYXV0aDogQXNnYXJkZW9TUEFDbGllbnQgPSBBc2dhcmRlb1NQQUNsaWVudC5nZXRJbnN0YW5jZSgpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgY29uZmlnOiBBdXRoQ2xpZW50Q29uZmlnPEF1dGhBbmd1bGFyQ29uZmlnPjtcbiAgICBwcml2YXRlIHN1YnNjcmlwdGlvbkRlc3Ryb3llciQ6IFN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIEBJbmplY3QoQVNHQVJERU9fQ09ORklHKVxuICAgICAgICBwcml2YXRlIGF1dGhDb25maWc6IEF1dGhDbGllbnRDb25maWc8QXV0aEFuZ3VsYXJDb25maWc+LFxuICAgICAgICBwcml2YXRlIG5hdmlnYXRvcjogQXNnYXJkZW9OYXZpZ2F0b3JTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHN0YXRlU3RvcmU6IEFzZ2FyZGVvQXV0aFN0YXRlU3RvcmVTZXJ2aWNlXG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gYXV0aENvbmZpZztcbiAgICAgICAgdGhpcy5hdXRoID0gQXNnYXJkZW9TUEFDbGllbnQuZ2V0SW5zdGFuY2UoKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplSG9va3MoKTtcbiAgICAgICAgKGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuYXV0aC5pbml0aWFsaXplKHRoaXMuYXV0aENvbmZpZyk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmhhbmRsZVNpbmdsZUxvZ291dE9uUmVkaXJlY3QoKTtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlQXV0b0xvZ2luKClcbiAgICAgICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5zdWJzY3JpcHRpb25EZXN0cm95ZXIkKSlcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCk7XG4gICAgICAgIH0pKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVucyBvbiBzZXJ2aWNlIHVubW91bnQuXG4gICAgICogQHJlbWFya3MgSG91c2VrZWVwaW5nIGxvZ2ljIHN1Y2ggYXMgdW4tc3Vic2NyaWJpbmcgc2hvdWxkIGdvIGhlcmUuXG4gICAgICovXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9uRGVzdHJveWVyJC5uZXh0KHRydWUpO1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbkRlc3Ryb3llciQudW5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlcmluZyBhIHNpZ24tb3V0IGhvb2sgY2xlYXJzIHVzZXIgc2Vzc2lvbiBkYXRhIGludGVybmFsbHkgaWYgdGhlcmUgd2FzIGEgc3VjY2Vzc2Z1bCBsb2dvdXQuXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZUhvb2tzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmF1dGgub24oSG9va3MuU2lnbk91dCwgKCk9Pnt9KTtcbiAgICB9XG5cbiAgICBzaWduSW4oXG4gICAgICAgIGNvbmZpZz86IFNpZ25JbkNvbmZpZyxcbiAgICAgICAgYXV0aG9yaXphdGlvbkNvZGU/OiBzdHJpbmcsXG4gICAgICAgIHNlc3Npb25TdGF0ZT86IHN0cmluZ1xuICAgICk6IFByb21pc2U8QmFzaWNVc2VySW5mbz4ge1xuICAgICAgICB0aGlzLnN0YXRlU3RvcmUuc2V0SXNMb2FkaW5nKHRydWUpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmF1dGhcbiAgICAgICAgICAgIC5zaWduSW4oY29uZmlnLCBhdXRob3JpemF0aW9uQ29kZSwgc2Vzc2lvblN0YXRlKVxuICAgICAgICAgICAgLnRoZW4oYXN5bmMgKHJlc3BvbnNlOiBCYXNpY1VzZXJJbmZvKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGF3YWl0IHRoaXMuYXV0aC5pc0F1dGhlbnRpY2F0ZWQoKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlU3RvcmUuc3RhdGUgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbGxvd2VkU2NvcGVzOiByZXNwb25zZS5hbGxvd2VkU2NvcGVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheU5hbWU6IHJlc3BvbnNlLmRpc3BsYXlOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgZW1haWw6IHJlc3BvbnNlLmVtYWlsLFxuICAgICAgICAgICAgICAgICAgICAgICAgaXNBdXRoZW50aWNhdGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1YjogcmVzcG9uc2Uuc3ViLFxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlcm5hbWU6IHJlc3BvbnNlLnVzZXJuYW1lXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IFByb21pc2UucmVqZWN0KGVycm9yKSlcbiAgICAgICAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlU3RvcmUuc2V0SXNMb2FkaW5nKGZhbHNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIHNpZ25JbldpdGhSZWRpcmVjdCgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgdGhpcy5uYXZpZ2F0b3Iuc2V0UmVkaXJlY3RVcmwoKTtcbiAgICAgICAgY29uc3QgcmVkaXJlY3RSb3V0ZSA9IHRoaXMubmF2aWdhdG9yLmdldFJvdXRlV2l0aG91dFBhcmFtcyhcbiAgICAgICAgICAgIHRoaXMuYXV0aENvbmZpZy5zaWduSW5SZWRpcmVjdFVSTFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiB0aGlzLm5hdmlnYXRvci5uYXZpZ2F0ZUJ5VXJsKHJlZGlyZWN0Um91dGUpO1xuICAgIH1cblxuICAgIHNpZ25PdXQoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHRoaXMuc3RhdGVTdG9yZS5zZXRJc0xvYWRpbmcodHJ1ZSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aFxuICAgICAgICAgICAgLnNpZ25PdXQoKVxuICAgICAgICAgICAgLnRoZW4oKHJlc3BvbnNlOiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIHN0YXRlLlxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGVTdG9yZS5yZXNldCgpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IFByb21pc2UucmVqZWN0KGVycm9yKSlcbiAgICAgICAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlU3RvcmUuc2V0SXNMb2FkaW5nKGZhbHNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIGlzQXV0aGVudGljYXRlZCgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aC5pc0F1dGhlbnRpY2F0ZWQoKTtcbiAgICB9XG5cbiAgICBnZXRCYXNpY1VzZXJJbmZvKCk6IFByb21pc2U8QmFzaWNVc2VySW5mbz4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hdXRoLmdldEJhc2ljVXNlckluZm8oKTtcbiAgICB9XG5cbiAgICBnZXRBY2Nlc3NUb2tlbigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hdXRoLmdldEFjY2Vzc1Rva2VuKCk7XG4gICAgfVxuXG4gICAgZ2V0SURUb2tlbigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hdXRoLmdldElEVG9rZW4oKTtcbiAgICB9XG5cbiAgICBnZXREZWNvZGVkSURUb2tlbigpOiBQcm9taXNlPERlY29kZWRJRFRva2VuUGF5bG9hZD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hdXRoLmdldERlY29kZWRJRFRva2VuKCk7XG4gICAgfVxuXG4gICAgZ2V0T0lEQ1NlcnZpY2VFbmRwb2ludHMoKTogUHJvbWlzZTxPSURDRW5kcG9pbnRzPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmF1dGguZ2V0T0lEQ1NlcnZpY2VFbmRwb2ludHMoKTtcbiAgICB9XG5cbiAgICByZWZyZXNoQWNjZXNzVG9rZW4oKTogUHJvbWlzZTxCYXNpY1VzZXJJbmZvPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmF1dGgucmVmcmVzaEFjY2Vzc1Rva2VuKCk7XG4gICAgfVxuXG4gICAgcmV2b2tlQWNjZXNzVG9rZW4oKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmF1dGhcbiAgICAgICAgICAgIC5yZXZva2VBY2Nlc3NUb2tlbigpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIHN0YXRlLlxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGVTdG9yZS5yZXNldCgpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gUHJvbWlzZS5yZWplY3QoZXJyb3IpKVxuICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGVTdG9yZS5zZXRJc0xvYWRpbmcoZmFsc2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb24oXG4gICAgICAgIGhvb2s6IEhvb2tzLFxuICAgICAgICBjYWxsYmFjazogKHJlc3BvbnNlPzogYW55KSA9PiB2b2lkLFxuICAgICAgICBpZD86IHN0cmluZ1xuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoaG9vayA9PT0gSG9va3MuQ3VzdG9tR3JhbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmF1dGgub24oaG9vaywgY2FsbGJhY2ssIGlkIGFzIHN0cmluZyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5hdXRoLm9uKGhvb2ssIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICByZXF1ZXN0Q3VzdG9tR3JhbnQoXG4gICAgICAgIGNvbmZpZzogQ3VzdG9tR3JhbnRDb25maWdcbiAgICApOiBQcm9taXNlPEZldGNoUmVzcG9uc2U8YW55PiB8IEJhc2ljVXNlckluZm8+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aC5yZXF1ZXN0Q3VzdG9tR3JhbnQoY29uZmlnKTtcbiAgICB9XG5cbiAgICBodHRwUmVxdWVzdChjb25maWc6IEh0dHBSZXF1ZXN0Q29uZmlnKTogUHJvbWlzZTxIdHRwUmVzcG9uc2U8YW55Pj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hdXRoLmh0dHBSZXF1ZXN0KGNvbmZpZyk7XG4gICAgfVxuXG4gICAgaHR0cFJlcXVlc3RBbGwoY29uZmlnOiBIdHRwUmVxdWVzdENvbmZpZ1tdKTogUHJvbWlzZTxIdHRwUmVzcG9uc2U8YW55PltdPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmF1dGguaHR0cFJlcXVlc3RBbGwoY29uZmlnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBhbGxvd3MgeW91IHRvIHNpZ24gaW4gc2lsZW50bHkuXG4gICAgICogRmlyc3QsIHRoaXMgbWV0aG9kIHNlbmRzIGEgcHJvbXB0IG5vbmUgcmVxdWVzdCB0byBzZWUgaWYgdGhlcmUgaXMgYW4gYWN0aXZlIHVzZXIgc2Vzc2lvbiBpbiB0aGUgaWRlbnRpdHkgc2VydmVyLlxuICAgICAqIElmIHRoZXJlIGlzIG9uZSwgdGhlbiBpdCByZXF1ZXN0cyB0aGUgYWNjZXNzIHRva2VuIGFuZCBzdG9yZXMgaXQuIEVsc2UsIGl0IHJldHVybnMgZmFsc2UuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPEJhc2ljVXNlckluZm8gfCBib29sZWFuPn0gLSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSB1c2VyIGluZm9ybWF0aW9uIGFmdGVyIHNpZ25pbmcgaW5cbiAgICAgKiBvciB3aXRoIGBmYWxzZWAgaWYgdGhlIHVzZXIgaXMgbm90IHNpZ25lZCBpbi5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpgYGBcbiAgICAgKiB0aGlzLmF1dGgudHJ5U2lnbkluU2lsZW50bHkoKVxuICAgICAqYGBgXG4gICAgICovXG4gICAgcHVibGljIHRyeVNpZ25JblNpbGVudGx5ID0gYXN5bmMgKCk6IFByb21pc2U8QmFzaWNVc2VySW5mbyB8IGJvb2xlYW4+ID0+IHtcbiAgICAgICAgdGhpcy5zdGF0ZVN0b3JlLnNldElzTG9hZGluZyh0cnVlKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5hdXRoXG4gICAgICAgICAgICAudHJ5U2lnbkluU2lsZW50bHkoKVxuICAgICAgICAgICAgLnRoZW4oYXN5bmMgKHJlc3BvbnNlOiBCYXNpY1VzZXJJbmZvIHwgYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChhd2FpdCB0aGlzLmF1dGguaXNBdXRoZW50aWNhdGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmFzaWNVc2VySW5mbzogQmFzaWNVc2VySW5mbyA9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZSBhcyBCYXNpY1VzZXJJbmZvO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGVTdG9yZS5zdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93ZWRTY29wZXM6IGJhc2ljVXNlckluZm8uYWxsb3dlZFNjb3BlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXlOYW1lOiBiYXNpY1VzZXJJbmZvLmRpc3BsYXlOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgZW1haWw6IGJhc2ljVXNlckluZm8uZW1haWwsXG4gICAgICAgICAgICAgICAgICAgICAgICBpc0F1dGhlbnRpY2F0ZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3ViOiBiYXNpY1VzZXJJbmZvLnN1YixcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZXJuYW1lOiBiYXNpY1VzZXJJbmZvLnVzZXJuYW1lXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IFByb21pc2UucmVqZWN0KGVycm9yKSlcbiAgICAgICAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlU3RvcmUuc2V0SXNMb2FkaW5nKGZhbHNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIGF1dG8gbG9naW4gYnkgdHJ5aW5nIHRvIGV4Y2hhbmdlIHRva2VucyBpZiBhdXRoIHBhcmFtcyBpLmUgYGNvZGVgIGFuZCBgc2Vzc2lvbl9zdGF0ZWAgaXNcbiAgICAgKiBhdmFpbGFibGUgaW4gdGhlIFVSTCBvciBlbHNlLCB0cmllcyB0byBzaWxlbnRseSBsb2dpbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybiB7T2JzZXJ2YWJsZTxCYXNpY1VzZXJJbmZvIHwgYm9vbGVhbj59XG4gICAgICovXG4gICAgcHJpdmF0ZSBoYW5kbGVBdXRvTG9naW4oKTogT2JzZXJ2YWJsZTxCYXNpY1VzZXJJbmZvIHwgYm9vbGVhbj4ge1xuICAgICAgICB0aGlzLnN0YXRlU3RvcmUuc2V0SXNMb2FkaW5nKHRydWUpO1xuXG4gICAgICAgIC8vIElmIGBza2lwUmVkaXJlY3RDYWxsYmFja2AgaXMgbm90IHRydWUsIGNoZWNrIGlmIHRoZSBVUkwgaGFzIGBjb2RlYCBhbmQgYHNlc3Npb25fc3RhdGVgIHBhcmFtcy5cbiAgICAgICAgLy8gSWYgc28sIGluaXRpYXRlIHRoZSBzaWduIGluLiBJZiBub3QsIHRyeSB0byBsb2dpbiBzaWxlbnRseS5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgIXRoaXMuY29uZmlnLnNraXBSZWRpcmVjdENhbGxiYWNrICYmXG4gICAgICAgICAgICBTUEFVdGlscy5oYXNBdXRoU2VhcmNoUGFyYW1zSW5VUkwoKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBmcm9tKHRoaXMuc2lnbkluKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhpcyB1c2VzIHRoZSBSUCBpZnJhbWUgdG8gZ2V0IHRoZSBzZXNzaW9uLiBIZW5jZSwgd2lsbCBub3Qgd29yayBpZiAzcmQgcGFydHkgY29va2llcyBhcmUgZGlzYWJsZWQuXG4gICAgICAgIC8vIElmIHRoZSBicm93c2VyIGhhcyB0aGVzZSBjb29raWVzIGRpc2FibGVkLCB3ZSdsbCBub3QgYmUgYWJsZSB0byByZXRyaWV2ZSB0aGUgc2Vzc2lvbiBvbiByZWZyZXNoZXMuXG4gICAgICAgIHJldHVybiBmcm9tKHRoaXMudHJ5U2lnbkluU2lsZW50bHkoKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyBzaW5nbGUgbG9nb3V0IGlmIGEgcHJvbXB0IG5vbmUgc2lnbiBpbiByZXNwb25zZSBpcyByZWNlaXZlZCB3aXRoIGFuIGVycm9yIHBhcmFtZXRlciBvbiB0aGUgVVJMLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPEJhc2ljVXNlckluZm8gfCB2b2lkPn1cbiAgICAgKi9cbiAgICBwcml2YXRlIGFzeW5jIGhhbmRsZVNpbmdsZUxvZ291dE9uUmVkaXJlY3QoKTogUHJvbWlzZTxCYXNpY1VzZXJJbmZvIHwgdm9pZD4ge1xuXG4gICAgICAgIGlmIChTUEFVdGlscy5oYXNFcnJvckluVVJMKCkpIHtcbiAgICAgICAgICAgIC8vIFRoZSBzaWduSW4gbWV0aG9kIGNhbGwgd2lsbCBjYWxsIHJlY2VpdmVQcm9tcHROb25lUmVzcG9uc2UgbWV0aG9kIGludGVybmFsbHkgdG8gaGFuZGxlIHRoZSBwcm9tcHQgbm9uZVxuICAgICAgICAgICAgLy8gcmVzcG9uc2UgaW4gdGhlIHNpbmdsZSBsb2dvdXQgZmxvdy5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25Jbih7Y2FsbE9ubHlPblJlZGlyZWN0OiB0cnVlfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=