@spartacus/core
Version:
Spartacus - the core framework
144 lines • 18.8 kB
JavaScript
import { __awaiter } from "tslib";
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { distinctUntilChanged, filter, map, take } from 'rxjs/operators';
import { OCC_USER_ID_CURRENT } from '../../../occ/utils/occ-constants';
import { AuthActions } from '../store/actions/index';
import * as i0 from "@angular/core";
import * as i1 from "@ngrx/store";
import * as i2 from "./user-id.service";
import * as i3 from "../services/oauth-lib-wrapper.service";
import * as i4 from "../services/auth-storage.service";
import * as i5 from "../services/auth-redirect.service";
import * as i6 from "../../../routing/facade/routing.service";
/**
* Auth service for normal user authentication.
* Use to check auth status, login/logout with different OAuth flows.
*/
export class AuthService {
constructor(store, userIdService, oAuthLibWrapperService, authStorageService, authRedirectService, routingService) {
this.store = store;
this.userIdService = userIdService;
this.oAuthLibWrapperService = oAuthLibWrapperService;
this.authStorageService = authStorageService;
this.authRedirectService = authRedirectService;
this.routingService = routingService;
/**
* Indicates whether the access token is being refreshed
*/
this.refreshInProgress$ = new BehaviorSubject(false);
/**
* Indicates whether the logout is being performed
*/
this.logoutInProgress$ = new BehaviorSubject(false);
}
/**
* Check params in url and if there is an code/token then try to login with those.
*/
checkOAuthParamsInUrl() {
return __awaiter(this, void 0, void 0, function* () {
// We use the 'token_received' event to check if we have returned
// from the auth server.
let tokenReceivedEvent;
const subscription = this.oAuthLibWrapperService.events$
.pipe(filter((event) => event.type === 'token_received'), take(1))
.subscribe((event) => (tokenReceivedEvent = event));
// The method `oAuthLibWrapperService.tryLogin()` obtains the token either from the URL params
// or from the storage. To distinguish those 2 cases, we observe the event `token_received`.
//
// The event 'token_received' is emitted, when the method `oAuthLibWrapperService.tryLogin()`
// can derive the token from the URL params (which means we've just returned from
// an external authorization page to Spartacus).
//
// But the event 'token_received' is not emitted when the method `oAuthLibWrapperService.tryLogin()`
// can obtain the token from the storage (e.g. on refresh of the Spartacus page).
try {
const result = yield this.oAuthLibWrapperService.tryLogin();
const token = this.authStorageService.getItem('access_token');
// We get the result in the code flow even if we did not logged in that why we also need to check if we have access_token
if (result && token) {
this.userIdService.setUserId(OCC_USER_ID_CURRENT);
this.store.dispatch(new AuthActions.Login());
// Only redirect if we have received a token,
// otherwise we are not returning from authentication server.
if (tokenReceivedEvent) {
this.authRedirectService.redirect();
}
}
}
catch (_a) { }
subscription.unsubscribe();
});
}
/**
* Initialize Implicit/Authorization Code flow by redirecting to OAuth server.
*/
loginWithRedirect() {
this.oAuthLibWrapperService.initLoginFlow();
return true;
}
/**
* Loads a new user token with Resource Owner Password Flow.
* @param userId
* @param password
*/
loginWithCredentials(userId, password) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield this.oAuthLibWrapperService.authorizeWithPasswordFlow(userId, password);
// OCC specific user id handling. Customize when implementing different backend
this.userIdService.setUserId(OCC_USER_ID_CURRENT);
this.store.dispatch(new AuthActions.Login());
this.authRedirectService.redirect();
}
catch (_a) { }
});
}
/**
* Revokes tokens and clears state for logged user (tokens, userId).
* To perform logout it is best to use `logout` method. Use this method with caution.
*/
coreLogout() {
this.setLogoutProgress(true);
this.userIdService.clearUserId();
return new Promise((resolve) => {
this.oAuthLibWrapperService.revokeAndLogout().finally(() => {
this.store.dispatch(new AuthActions.Logout());
resolve();
});
});
}
/**
* Returns `true` if the user is logged in; and `false` if the user is anonymous.
*/
isUserLoggedIn() {
return this.authStorageService.getToken().pipe(map((userToken) => Boolean(userToken === null || userToken === void 0 ? void 0 : userToken.access_token)), distinctUntilChanged());
}
/**
* Logout a storefront customer. It will initialize logout procedure by redirecting to the `logout` endpoint.
*/
logout() {
this.routingService.go({ cxRoute: 'logout' });
}
/**
* Start or stop the refresh process
*/
setRefreshProgress(progress) {
this.refreshInProgress$.next(progress);
}
/**
* Start or stop the logout process
*/
setLogoutProgress(progress) {
this.logoutInProgress$.next(progress);
}
}
AuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: AuthService, deps: [{ token: i1.Store }, { token: i2.UserIdService }, { token: i3.OAuthLibWrapperService }, { token: i4.AuthStorageService }, { token: i5.AuthRedirectService }, { token: i6.RoutingService }], target: i0.ɵɵFactoryTarget.Injectable });
AuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: AuthService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: AuthService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return [{ type: i1.Store }, { type: i2.UserIdService }, { type: i3.OAuthLibWrapperService }, { type: i4.AuthStorageService }, { type: i5.AuthRedirectService }, { type: i6.RoutingService }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29yZS9zcmMvYXV0aC91c2VyLWF1dGgvZmFjYWRlL2F1dGguc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUczQyxPQUFPLEVBQUUsZUFBZSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBTXZFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7Ozs7Ozs7QUFHckQ7OztHQUdHO0FBSUgsTUFBTSxPQUFPLFdBQVc7SUFXdEIsWUFDWSxLQUFpQyxFQUNqQyxhQUE0QixFQUM1QixzQkFBOEMsRUFDOUMsa0JBQXNDLEVBQ3RDLG1CQUF3QyxFQUN4QyxjQUE4QjtRQUw5QixVQUFLLEdBQUwsS0FBSyxDQUE0QjtRQUNqQyxrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM1QiwyQkFBc0IsR0FBdEIsc0JBQXNCLENBQXdCO1FBQzlDLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDdEMsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtRQUN4QyxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFoQjFDOztXQUVHO1FBQ0gsdUJBQWtCLEdBQXdCLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFDO1FBRTlFOztXQUVHO1FBQ0gsc0JBQWlCLEdBQXdCLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBUzFFLENBQUM7SUFFSjs7T0FFRztJQUNHLHFCQUFxQjs7WUFDekIsaUVBQWlFO1lBQ2pFLHdCQUF3QjtZQUN4QixJ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QkFBVCxTQUFTLENBQUUsWUFBWSxDQUFDLENBQUMsRUFDcEQsb0JBQW9CLEVBQUUsQ0FDdkIsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU07UUFDSixJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRDs7T0FFRztJQUNILGtCQUFrQixDQUFDLFFBQWlCO1FBQ2pDLElBQUksQ0FBQyxrQkFBK0MsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdkUsQ0FBQztJQUVEOztPQUVHO0lBQ0gsaUJBQWlCLENBQUMsUUFBaUI7UUFDaEMsSUFBSSxDQUFDLGlCQUE4QyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN0RSxDQUFDOzt3R0F4SVUsV0FBVzs0R0FBWCxXQUFXLGNBRlYsTUFBTTsyRkFFUCxXQUFXO2tCQUh2QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN0b3JlIH0gZnJvbSAnQG5ncngvc3RvcmUnO1xuaW1wb3J0IHsgT0F1dGhFdmVudCB9IGZyb20gJ2FuZ3VsYXItb2F1dGgyLW9pZGMnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgZmlsdGVyLCBtYXAsIHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBPQ0NfVVNFUl9JRF9DVVJSRU5UIH0gZnJvbSAnLi4vLi4vLi4vb2NjL3V0aWxzL29jYy1jb25zdGFudHMnO1xuaW1wb3J0IHsgUm91dGluZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9yb3V0aW5nL2ZhY2FkZS9yb3V0aW5nLnNlcnZpY2UnO1xuaW1wb3J0IHsgU3RhdGVXaXRoQ2xpZW50QXV0aCB9IGZyb20gJy4uLy4uL2NsaWVudC1hdXRoL3N0b3JlL2NsaWVudC1hdXRoLXN0YXRlJztcbmltcG9ydCB7IEF1dGhSZWRpcmVjdFNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9hdXRoLXJlZGlyZWN0LnNlcnZpY2UnO1xuaW1wb3J0IHsgQXV0aFN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvYXV0aC1zdG9yYWdlLnNlcnZpY2UnO1xuaW1wb3J0IHsgT0F1dGhMaWJXcmFwcGVyU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL29hdXRoLWxpYi13cmFwcGVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXV0aEFjdGlvbnMgfSBmcm9tICcuLi9zdG9yZS9hY3Rpb25zL2luZGV4JztcbmltcG9ydCB7IFVzZXJJZFNlcnZpY2UgfSBmcm9tICcuL3VzZXItaWQuc2VydmljZSc7XG5cbi8qKlxuICogQXV0aCBzZXJ2aWNlIGZvciBub3JtYWwgdXNlciBhdXRoZW50aWNhdGlvbi5cbiAqIFVzZSB0byBjaGVjayBhdXRoIHN0YXR1cywgbG9naW4vbG9nb3V0IHdpdGggZGlmZmVyZW50IE9BdXRoIGZsb3dzLlxuICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgQXV0aFNlcnZpY2Uge1xuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGFjY2VzcyB0b2tlbiBpcyBiZWluZyByZWZyZXNoZWRcbiAgICovXG4gIHJlZnJlc2hJblByb2dyZXNzJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgbG9nb3V0IGlzIGJlaW5nIHBlcmZvcm1lZFxuICAgKi9cbiAgbG9nb3V0SW5Qcm9ncmVzcyQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgc3RvcmU6IFN0b3JlPFN0YXRlV2l0aENsaWVudEF1dGg+LFxuICAgIHByb3RlY3RlZCB1c2VySWRTZXJ2aWNlOiBVc2VySWRTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBvQXV0aExpYldyYXBwZXJTZXJ2aWNlOiBPQXV0aExpYldyYXBwZXJTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBhdXRoU3RvcmFnZVNlcnZpY2U6IEF1dGhTdG9yYWdlU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgYXV0aFJlZGlyZWN0U2VydmljZTogQXV0aFJlZGlyZWN0U2VydmljZSxcbiAgICBwcm90ZWN0ZWQgcm91dGluZ1NlcnZpY2U6IFJvdXRpbmdTZXJ2aWNlXG4gICkge31cblxuICAvKipcbiAgICogQ2hlY2sgcGFyYW1zIGluIHVybCBhbmQgaWYgdGhlcmUgaXMgYW4gY29kZS90b2tlbiB0aGVuIHRyeSB0byBsb2dpbiB3aXRoIHRob3NlLlxuICAgKi9cbiAgYXN5bmMgY2hlY2tPQXV0aFBhcmFtc0luVXJsKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIFdlIHVzZSB0aGUgJ3Rva2VuX3JlY2VpdmVkJyBldmVudCB0byBjaGVjayBpZiB3ZSBoYXZlIHJldHVybmVkXG4gICAgLy8gZnJvbSB0aGUgYXV0aCBzZXJ2ZXIuXG4gICAgbGV0IHRva2VuUmVjZWl2ZWRFdmVudDogT0F1dGhFdmVudCB8IHVuZGVmaW5lZDtcbiAgICBjb25zdCBzdWJzY3JpcHRpb24gPSB0aGlzLm9BdXRoTGliV3JhcHBlclNlcnZpY2UuZXZlbnRzJFxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcigoZXZlbnQpID0+IGV2ZW50LnR5cGUgPT09ICd0b2tlbl9yZWNlaXZlZCcpLFxuICAgICAgICB0YWtlKDEpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKChldmVudCkgPT4gKHRva2VuUmVjZWl2ZWRFdmVudCA9IGV2ZW50KSk7XG5cbiAgICAvLyBUaGUgbWV0aG9kIGBvQXV0aExpYldyYXBwZXJTZXJ2aWNlLnRyeUxvZ2luKClgIG9idGFpbnMgdGhlIHRva2VuIGVpdGhlciBmcm9tIHRoZSBVUkwgcGFyYW1zXG4gICAgLy8gb3IgZnJvbSB0aGUgc3RvcmFnZS4gVG8gZGlzdGluZ3Vpc2ggdGhvc2UgMiBjYXNlcywgd2Ugb2JzZXJ2ZSB0aGUgZXZlbnQgYHRva2VuX3JlY2VpdmVkYC5cbiAgICAvL1xuICAgIC8vIFRoZSBldmVudCAndG9rZW5fcmVjZWl2ZWQnIGlzIGVtaXR0ZWQsIHdoZW4gdGhlIG1ldGhvZCBgb0F1dGhMaWJXcmFwcGVyU2VydmljZS50cnlMb2dpbigpYFxuICAgIC8vIGNhbiBkZXJpdmUgdGhlIHRva2VuIGZyb20gdGhlIFVSTCBwYXJhbXMgKHdoaWNoIG1lYW5zIHdlJ3ZlIGp1c3QgcmV0dXJuZWQgZnJvbVxuICAgIC8vIGFuIGV4dGVybmFsIGF1dGhvcml6YXRpb24gcGFnZSB0byBTcGFydGFjdXMpLlxuICAgIC8vXG4gICAgLy8gQnV0IHRoZSBldmVudCAndG9rZW5fcmVjZWl2ZWQnIGlzIG5vdCBlbWl0dGVkIHdoZW4gdGhlIG1ldGhvZCBgb0F1dGhMaWJXcmFwcGVyU2VydmljZS50cnlMb2dpbigpYFxuICAgIC8vIGNhbiBvYnRhaW4gdGhlIHRva2VuIGZyb20gdGhlIHN0b3JhZ2UgKGUuZy4gb24gcmVmcmVzaCBvZiB0aGUgU3BhcnRhY3VzIHBhZ2UpLlxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLm9BdXRoTGliV3JhcHBlclNlcnZpY2UudHJ5TG9naW4oKTtcblxuICAgICAgY29uc3QgdG9rZW4gPSB0aGlzLmF1dGhTdG9yYWdlU2VydmljZS5nZXRJdGVtKCdhY2Nlc3NfdG9rZW4nKTtcblxuICAgICAgLy8gV2UgZ2V0IHRoZSByZXN1bHQgaW4gdGhlIGNvZGUgZmxvdyBldmVuIGlmIHdlIGRpZCBub3QgbG9nZ2VkIGluIHRoYXQgd2h5IHdlIGFsc28gbmVlZCB0byBjaGVjayBpZiB3ZSBoYXZlIGFjY2Vzc190b2tlblxuICAgICAgaWYgKHJlc3VsdCAmJiB0b2tlbikge1xuICAgICAgICB0aGlzLnVzZXJJZFNlcnZpY2Uuc2V0VXNlcklkKE9DQ19VU0VSX0lEX0NVUlJFTlQpO1xuICAgICAgICB0aGlzLnN0b3JlLmRpc3BhdGNoKG5ldyBBdXRoQWN0aW9ucy5Mb2dpbigpKTtcblxuICAgICAgICAvLyBPbmx5IHJlZGlyZWN0IGlmIHdlIGhhdmUgcmVjZWl2ZWQgYSB0b2tlbixcbiAgICAgICAgLy8gb3RoZXJ3aXNlIHdlIGFyZSBub3QgcmV0dXJuaW5nIGZyb20gYXV0aGVudGljYXRpb24gc2VydmVyLlxuICAgICAgICBpZiAodG9rZW5SZWNlaXZlZEV2ZW50KSB7XG4gICAgICAgICAgdGhpcy5hdXRoUmVkaXJlY3RTZXJ2aWNlLnJlZGlyZWN0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIHt9XG5cbiAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIEltcGxpY2l0L0F1dGhvcml6YXRpb24gQ29kZSBmbG93IGJ5IHJlZGlyZWN0aW5nIHRvIE9BdXRoIHNlcnZlci5cbiAgICovXG4gIGxvZ2luV2l0aFJlZGlyZWN0KCk6IGJvb2xlYW4ge1xuICAgIHRoaXMub0F1dGhMaWJXcmFwcGVyU2VydmljZS5pbml0TG9naW5GbG93KCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogTG9hZHMgYSBuZXcgdXNlciB0b2tlbiB3aXRoIFJlc291cmNlIE93bmVyIFBhc3N3b3JkIEZsb3cuXG4gICAqIEBwYXJhbSB1c2VySWRcbiAgICogQHBhcmFtIHBhc3N3b3JkXG4gICAqL1xuICBhc3luYyBsb2dpbldpdGhDcmVkZW50aWFscyh1c2VySWQ6IHN0cmluZywgcGFzc3dvcmQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLm9BdXRoTGliV3JhcHBlclNlcnZpY2UuYXV0aG9yaXplV2l0aFBhc3N3b3JkRmxvdyhcbiAgICAgICAgdXNlcklkLFxuICAgICAgICBwYXNzd29yZFxuICAgICAgKTtcbiAgICAgIC8vIE9DQyBzcGVjaWZpYyB1c2VyIGlkIGhhbmRsaW5nLiBDdXN0b21pemUgd2hlbiBpbXBsZW1lbnRpbmcgZGlmZmVyZW50IGJhY2tlbmRcbiAgICAgIHRoaXMudXNlcklkU2VydmljZS5zZXRVc2VySWQoT0NDX1VTRVJfSURfQ1VSUkVOVCk7XG5cbiAgICAgIHRoaXMuc3RvcmUuZGlzcGF0Y2gobmV3IEF1dGhBY3Rpb25zLkxvZ2luKCkpO1xuXG4gICAgICB0aGlzLmF1dGhSZWRpcmVjdFNlcnZpY2UucmVkaXJlY3QoKTtcbiAgICB9IGNhdGNoIHt9XG4gIH1cblxuICAvKipcbiAgICogUmV2b2tlcyB0b2tlbnMgYW5kIGNsZWFycyBzdGF0ZSBmb3IgbG9nZ2VkIHVzZXIgKHRva2VucywgdXNlcklkKS5cbiAgICogVG8gcGVyZm9ybSBsb2dvdXQgaXQgaXMgYmVzdCB0byB1c2UgYGxvZ291dGAgbWV0aG9kLiBVc2UgdGhpcyBtZXRob2Qgd2l0aCBjYXV0aW9uLlxuICAgKi9cbiAgY29yZUxvZ291dCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnNldExvZ291dFByb2dyZXNzKHRydWUpO1xuICAgIHRoaXMudXNlcklkU2VydmljZS5jbGVhclVzZXJJZCgpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgdGhpcy5vQXV0aExpYldyYXBwZXJTZXJ2aWNlLnJldm9rZUFuZExvZ291dCgpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICB0aGlzLnN0b3JlLmRpc3BhdGNoKG5ldyBBdXRoQWN0aW9ucy5Mb2dvdXQoKSk7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYHRydWVgIGlmIHRoZSB1c2VyIGlzIGxvZ2dlZCBpbjsgYW5kIGBmYWxzZWAgaWYgdGhlIHVzZXIgaXMgYW5vbnltb3VzLlxuICAgKi9cbiAgaXNVc2VyTG9nZ2VkSW4oKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuYXV0aFN0b3JhZ2VTZXJ2aWNlLmdldFRva2VuKCkucGlwZShcbiAgICAgIG1hcCgodXNlclRva2VuKSA9PiBCb29sZWFuKHVzZXJUb2tlbj8uYWNjZXNzX3Rva2VuKSksXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2dvdXQgYSBzdG9yZWZyb250IGN1c3RvbWVyLiBJdCB3aWxsIGluaXRpYWxpemUgbG9nb3V0IHByb2NlZHVyZSBieSByZWRpcmVjdGluZyB0byB0aGUgYGxvZ291dGAgZW5kcG9pbnQuXG4gICAqL1xuICBsb2dvdXQoKTogdm9pZCB7XG4gICAgdGhpcy5yb3V0aW5nU2VydmljZS5nbyh7IGN4Um91dGU6ICdsb2dvdXQnIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IG9yIHN0b3AgdGhlIHJlZnJlc2ggcHJvY2Vzc1xuICAgKi9cbiAgc2V0UmVmcmVzaFByb2dyZXNzKHByb2dyZXNzOiBib29sZWFuKTogdm9pZCB7XG4gICAgKHRoaXMucmVmcmVzaEluUHJvZ3Jlc3MkIGFzIEJlaGF2aW9yU3ViamVjdDxib29sZWFuPikubmV4dChwcm9ncmVzcyk7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgb3Igc3RvcCB0aGUgbG9nb3V0IHByb2Nlc3NcbiAgICovXG4gIHNldExvZ291dFByb2dyZXNzKHByb2dyZXNzOiBib29sZWFuKTogdm9pZCB7XG4gICAgKHRoaXMubG9nb3V0SW5Qcm9ncmVzcyQgYXMgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KS5uZXh0KHByb2dyZXNzKTtcbiAgfVxufVxuIl19