UNPKG

vix-ui

Version:

474 lines 34.2 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; import { OAuthService } from 'angular-oauth2-oidc'; import { Injectable } from '@angular/core'; import * as OktaAuth from '@okta/okta-auth-js'; import { AuthConfigService } from './auth-config.service'; import { OktaService } from './okta.service'; import { UserInfo } from './user-info'; import { UserGroups } from './user-groups'; /** * VixAuthService is the interface exported to users. It wraps all API and methods. */ var VixAuthService = /** @class */ (function () { function VixAuthService(oauth, authConfig, okta) { this.oauth = oauth; this.authConfig = authConfig; this.okta = okta; this.oktaAuth = new OktaAuth({ url: this.authConfig.getUrl(), issuer: this.authConfig.getIssuer() }); } /** * Check permissions by userGroups and requireGroups * * @param userGroups groups users are in * @param requireGroups groups application requires user to have * @returns true/false */ /** * Check permissions by userGroups and requireGroups * * @param {?} userGroups groups users are in * @param {?} requireGroups groups application requires user to have * @return {?} true/false */ VixAuthService.hasPermission = /** * Check permissions by userGroups and requireGroups * * @param {?} userGroups groups users are in * @param {?} requireGroups groups application requires user to have * @return {?} true/false */ function (userGroups, requireGroups) { return userGroups.hasPermission(requireGroups); }; /** * Use tokenManager to store userId * TODO: actually I have problems in create a cache object to hold all these cache variables, so I use tokenManager to do these works. * TODO: need to create a share service to provide cache service */ /** * Use tokenManager to store userId * TODO: actually I have problems in create a cache object to hold all these cache variables, so I use tokenManager to do these works. * TODO: need to create a share service to provide cache service * @param {?} userId * @return {?} */ VixAuthService.prototype.setUserId = /** * Use tokenManager to store userId * TODO: actually I have problems in create a cache object to hold all these cache variables, so I use tokenManager to do these works. * TODO: need to create a share service to provide cache service * @param {?} userId * @return {?} */ function (userId) { /** @type {?} */ var obj = { accessToken: 'userId', expiresAt: Math.round((new Date()).getTime() / 1000 + 3600), scopes: [userId] }; this.oktaAuth.tokenManager.add('userId', obj); }; /** * Use tokenManager to store userId * TODO: actually I have problems in create a cache object to hold all these cache variables, so I use tokenManager to do these works. * TODO: need to create a share service to provide cache service */ /** * Use tokenManager to store userId * TODO: actually I have problems in create a cache object to hold all these cache variables, so I use tokenManager to do these works. * TODO: need to create a share service to provide cache service * @param {?} sessionToken * @return {?} */ VixAuthService.prototype.setSessionToken = /** * Use tokenManager to store userId * TODO: actually I have problems in create a cache object to hold all these cache variables, so I use tokenManager to do these works. * TODO: need to create a share service to provide cache service * @param {?} sessionToken * @return {?} */ function (sessionToken) { /** @type {?} */ var obj = { accessToken: 'sessionToken', expiresAt: Math.round((new Date()).getTime() / 1000 + 3600), scopes: [sessionToken] }; this.oktaAuth.tokenManager.add('sessionToken', obj); }; /** * Get userId from tokenManager */ /** * Get userId from tokenManager * @return {?} */ VixAuthService.prototype.getUserId = /** * Get userId from tokenManager * @return {?} */ function () { /** @type {?} */ var userIdObj = this.oktaAuth.tokenManager.get('userId'); if (userIdObj) { return this.oktaAuth.tokenManager.get('userId').scopes[0]; } else { return null; } }; /** * Get acess token */ /** * Get acess token * @return {?} */ VixAuthService.prototype.getSessionToken = /** * Get acess token * @return {?} */ function () { /** @type {?} */ var sessionTokenObj = this.oktaAuth.tokenManager.get('sessionToken'); if (sessionTokenObj) { return this.oktaAuth.tokenManager.get('sessionToken').scopes[0]; } else { return null; } }; /** * Store userGroup and shared among browsers by TokenManager with key 'userGroup' */ /** * Store userGroup and shared among browsers by TokenManager with key 'userGroup' * @param {?} userGroups * @return {?} */ VixAuthService.prototype.setCurrentUserGroups = /** * Store userGroup and shared among browsers by TokenManager with key 'userGroup' * @param {?} userGroups * @return {?} */ function (userGroups) { /** @type {?} */ var obj = { accessToken: 'userGroups', expiresAt: Math.round((new Date()).getTime() / 1000 + 3600), scopes: userGroups.groups }; this.oktaAuth.tokenManager.add('userGroups', obj); }; /** * Get stored userGroups and refresh if expires */ /** * Get stored userGroups and refresh if expires * @return {?} */ VixAuthService.prototype.getLoginUserGroups = /** * Get stored userGroups and refresh if expires * @return {?} */ function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var userGroupsTokenObj, nowSecond, tmpUserGroups, userGroups; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: userGroupsTokenObj = this.oktaAuth.tokenManager.get('userGroups'); nowSecond = (new Date()).getTime() / 1000; if (!(!userGroupsTokenObj || nowSecond > userGroupsTokenObj.expireAt)) return [3 /*break*/, 2]; return [4 /*yield*/, this.getUserGroups(this.getUserId())]; case 1: tmpUserGroups = _a.sent(); this.setCurrentUserGroups(tmpUserGroups); _a.label = 2; case 2: userGroups = new UserGroups(null); userGroups.groups = this.oktaAuth.tokenManager.get('userGroups').scopes; return [2 /*return*/, userGroups]; } }); }); }; /** * Get current login userInfo * TODO: we can cache user info includes groups information when finished login */ /** * Get current login userInfo * TODO: we can cache user info includes groups information when finished login * @return {?} */ VixAuthService.prototype.getUserInfo = /** * Get current login userInfo * TODO: we can cache user info includes groups information when finished login * @return {?} */ function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var oktaUserInfo; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: if (!this.isLogin()) return [3 /*break*/, 3]; return [4 /*yield*/, this.okta.getUserInfo(this.getUserId())]; case 1: oktaUserInfo = _a.sent(); return [4 /*yield*/, new UserInfo(oktaUserInfo)]; case 2: return [2 /*return*/, _a.sent()]; case 3: return [2 /*return*/, Promise.reject('not login')]; } }); }); }; /** * get userGroup by given userId */ /** * get userGroup by given userId * @param {?} userId * @return {?} */ VixAuthService.prototype.getUserGroups = /** * get userGroup by given userId * @param {?} userId * @return {?} */ function (userId) { return tslib_1.__awaiter(this, void 0, void 0, function () { var oktaUserGroups, err_1; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: if (!this.isLogin()) return [3 /*break*/, 6]; _a.label = 1; case 1: _a.trys.push([1, 4, , 5]); return [4 /*yield*/, this.okta.getUserGroups(userId)]; case 2: oktaUserGroups = _a.sent(); return [4 /*yield*/, new UserGroups(oktaUserGroups)]; case 3: return [2 /*return*/, _a.sent()]; case 4: err_1 = _a.sent(); console.log('getUserGroups err', err_1); return [3 /*break*/, 5]; case 5: return [3 /*break*/, 7]; case 6: return [2 /*return*/, null]; case 7: return [2 /*return*/]; } }); }); }; /** * Return if already login by check the existence of accessToken */ /** * Return if already login by check the existence of accessToken * @return {?} */ VixAuthService.prototype.isLogin = /** * Return if already login by check the existence of accessToken * @return {?} */ function () { return !!this.getUserId(); }; /** * Redirect to url for Google login */ /** * Redirect to url for Google login * @param {?} redirectUrl * @return {?} */ VixAuthService.prototype.loginWithGoogle = /** * Redirect to url for Google login * @param {?} redirectUrl * @return {?} */ function (redirectUrl) { window.location.href = this.authConfig.getUrl() + "/oauth2/v1/authorize?" + ("idp=0oadulhuz78SMW8cD0h7&client_id=" + this.authConfig.getClientId() + "&response_type=id_token&") + "response_mode=fragment&scope=openid&scope=email&scope=picture&scope=name&" + ("state=WM6D&nonce=YsG76jo&redirect_uri=" + redirectUrl); }; /** * Login by username and password */ /** * Login by username and password * @param {?} username * @param {?} password * @return {?} */ VixAuthService.prototype.loginWithPassword = /** * Login by username and password * @param {?} username * @param {?} password * @return {?} */ function (username, password) { return tslib_1.__awaiter(this, void 0, void 0, function () { var nonce, signInResponse, session; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.oauth.createAndSaveNonce()]; case 1: nonce = _a.sent(); return [4 /*yield*/, this.oktaAuth.signIn({ username: username, password: password })]; case 2: signInResponse = _a.sent(); if (!(signInResponse.status === 'SUCCESS')) return [3 /*break*/, 5]; return [4 /*yield*/, this.oktaAuth.token.getWithoutPrompt({ clientId: this.authConfig.getClientId(), responseType: ['id_token', 'token'], scopes: ['openid', 'profile', 'email'], sessionToken: signInResponse.sessionToken, nonce: nonce, redirectUri: window.location.origin })]; case 3: _a.sent(); return [4 /*yield*/, this.getSession()]; case 4: session = _a.sent(); if (session.status === 'ACTIVE') { console.log('session ACTIVE'); this.setUserId(session.userId); this.setSessionToken(session.id); } return [2 /*return*/, Promise.resolve('login successfully')]; case 5: return [2 /*return*/, Promise.reject('username or password error')]; } }); }); }; /** * List all groups */ /** * List all groups * @return {?} */ VixAuthService.prototype.listGroups = /** * List all groups * @return {?} */ function () { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.okta.listGroups()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Get session */ /** * Get session * @return {?} */ VixAuthService.prototype.getSession = /** * Get session * @return {?} */ function () { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.oktaAuth.session.get()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Navigate browser to login page */ /** * Navigate browser to login page * @return {?} */ VixAuthService.prototype.navigateToLoginPage = /** * Navigate browser to login page * @return {?} */ function () { console.log('navigateToLoginPage:', this.authConfig.getLoginUrl()); document.location.href = this.authConfig.getLoginUrl(); }; /** * Navigate browser to redirect page */ /** * Navigate browser to redirect page * @return {?} */ VixAuthService.prototype.navigateToRedirectPage = /** * Navigate browser to redirect page * @return {?} */ function () { console.log('navigateToRedirectPage:', this.authConfig.getRedirectUrl()); document.location.href = this.authConfig.getRedirectUrl(); }; /** * Logout current user and clear token */ /** * Logout current user and clear token * @return {?} */ VixAuthService.prototype.logout = /** * Logout current user and clear token * @return {?} */ function () { var _this = this; if (this.isLogin()) { this.oktaAuth.tokenManager.clear(); console.log('start to logout'); this.oktaAuth.signOut().then(function () { console.log('logout done, to navigate', _this.authConfig.getLoginUrl()); _this.navigateToLoginPage(); }); } else { } }; VixAuthService.decorators = [ { type: Injectable } ]; VixAuthService.ctorParameters = function () { return [ { type: OAuthService }, { type: AuthConfigService }, { type: OktaService } ]; }; return VixAuthService; }()); export { VixAuthService }; if (false) { /** @type {?} */ VixAuthService.prototype.oktaAuth; /** @type {?} */ VixAuthService.prototype.oauth; /** @type {?} */ VixAuthService.prototype.authConfig; /** @type {?} */ VixAuthService.prototype.okta; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vdml4LXVpLyIsInNvdXJjZXMiOlsidml4LWF1dGgvYXV0aC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxLQUFLLFFBQVEsTUFBTSxvQkFBb0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7O0FBSzNDO0lBSUUsd0JBQW9CLEtBQW1CLEVBQ25CLFVBQTZCLEVBQzdCLElBQWlCO1FBRmpCLFVBQUssR0FBTCxLQUFLLENBQWM7UUFDbkIsZUFBVSxHQUFWLFVBQVUsQ0FBbUI7UUFDN0IsU0FBSSxHQUFKLElBQUksQ0FBYTtRQUNuQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksUUFBUSxDQUFDO1lBQzNCLEdBQUcsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRTtZQUM3QixNQUFNLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUU7U0FDcEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUdEOzs7Ozs7T0FNRzs7Ozs7Ozs7SUFDSSw0QkFBYTs7Ozs7OztJQUFwQixVQUFxQixVQUFzQixFQUFFLGFBQXVCO1FBQ2xFLE9BQU8sVUFBVSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQ7Ozs7T0FJRzs7Ozs7Ozs7SUFDSCxrQ0FBUzs7Ozs7OztJQUFULFVBQVUsTUFBYzs7WUFDaEIsR0FB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LEVBQUUsQ0FBQztJQUM1RCxDQUFDO0lBRUQ7O09BRUc7Ozs7O0lBQ0gsK0JBQU07Ozs7SUFBTjtRQUFBLGlCQVVDO1FBVEMsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDbEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbkMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDO2dCQUMzQixPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixFQUFFLEtBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztnQkFDdkUsS0FBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDN0IsQ0FBQyxDQUFDLENBQUM7U0FDSjthQUFNO1NBQ047SUFDSCxDQUFDOztnQkE3TkYsVUFBVTs7O2dCQVhGLFlBQVk7Z0JBR1osaUJBQWlCO2dCQUNqQixXQUFXOztJQXFPcEIscUJBQUM7Q0FBQSxBQTlORCxJQThOQztTQTdOWSxjQUFjOzs7SUFDekIsa0NBQXNCOztJQUVWLCtCQUEyQjs7SUFDM0Isb0NBQXFDOztJQUNyQyw4QkFBeUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPQXV0aFNlcnZpY2UgfSBmcm9tICdhbmd1bGFyLW9hdXRoMi1vaWRjJztcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIE9rdGFBdXRoIGZyb20gJ0Bva3RhL29rdGEtYXV0aC1qcyc7XG5pbXBvcnQgeyBBdXRoQ29uZmlnU2VydmljZSB9IGZyb20gJy4vYXV0aC1jb25maWcuc2VydmljZSc7XG5pbXBvcnQgeyBPa3RhU2VydmljZSB9IGZyb20gJy4vb2t0YS5zZXJ2aWNlJztcbmltcG9ydCB7IFVzZXJJbmZvIH0gZnJvbSAnLi91c2VyLWluZm8nO1xuaW1wb3J0IHsgVXNlckdyb3VwcyB9IGZyb20gJy4vdXNlci1ncm91cHMnO1xuXG4vKipcbiAqIFZpeEF1dGhTZXJ2aWNlIGlzIHRoZSBpbnRlcmZhY2UgZXhwb3J0ZWQgdG8gdXNlcnMuIEl0IHdyYXBzIGFsbCBBUEkgYW5kIG1ldGhvZHMuXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBWaXhBdXRoU2VydmljZSB7XG4gIHByaXZhdGUgb2t0YUF1dGg6IGFueTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG9hdXRoOiBPQXV0aFNlcnZpY2UsXG4gICAgICAgICAgICAgIHByaXZhdGUgYXV0aENvbmZpZzogQXV0aENvbmZpZ1NlcnZpY2UsXG4gICAgICAgICAgICAgIHByaXZhdGUgb2t0YTogT2t0YVNlcnZpY2UpIHtcbiAgICB0aGlzLm9rdGFBdXRoID0gbmV3IE9rdGFBdXRoKHtcbiAgICAgIHVybDogdGhpcy5hdXRoQ29uZmlnLmdldFVybCgpLFxuICAgICAgaXNzdWVyOiB0aGlzLmF1dGhDb25maWcuZ2V0SXNzdWVyKClcbiAgICB9KTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIENoZWNrIHBlcm1pc3Npb25zIGJ5IHVzZXJHcm91cHMgYW5kIHJlcXVpcmVHcm91cHNcbiAgICpcbiAgICogQHBhcmFtIHVzZXJHcm91cHMgZ3JvdXBzIHVzZXJzIGFyZSBpblxuICAgKiBAcGFyYW0gcmVxdWlyZUdyb3VwcyBncm91cHMgYXBwbGljYXRpb24gcmVxdWlyZXMgdXNlciB0byBoYXZlXG4gICAqIEByZXR1cm5zIHRydWUvZmFsc2VcbiAgICovXG4gIHN0YXRpYyBoYXNQZXJtaXNzaW9uKHVzZXJHcm91cHM6IFVzZXJHcm91cHMsIHJlcXVpcmVHcm91cHM6IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHVzZXJHcm91cHMuaGFzUGVybWlzc2lvbihyZXF1aXJlR3JvdXBzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2UgdG9rZW5NYW5hZ2VyIHRvIHN0b3JlIHVzZXJJZFxuICAgKiBUT0RPOiBhY3R1YWxseSBJIGhhdmUgcHJvYmxlbXMgaW4gY3JlYXRlIGEgY2FjaGUgb2JqZWN0IHRvIGhvbGQgYWxsIHRoZXNlIGNhY2hlIHZhcmlhYmxlcywgc28gSSB1c2UgdG9rZW5NYW5hZ2VyIHRvIGRvIHRoZXNlIHdvcmtzLlxuICAgKiBUT0RPOiBuZWVkIHRvIGNyZWF0ZSBhIHNoYXJlIHNlcnZpY2UgdG8gcHJvdmlkZSBjYWNoZSBzZXJ2aWNlXG4gICAqL1xuICBzZXRVc2VySWQodXNlcklkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBvYmogPSB7XG4gICAgICBhY2Nlc3NUb2tlbjogJ3VzZXJJZCcsXG4gICAgICBleHBpcmVzQXQ6IE1hdGgucm91bmQoKG5ldyBEYXRlKCkpLmdldFRpbWUoKSAvIDEwMDAgKyAzNjAwKSxcbiAgICAgIHNjb3BlczogW3VzZXJJZF1cbiAgICB9O1xuICAgIHRoaXMub2t0YUF1dGgudG9rZW5NYW5hZ2VyLmFkZCgndXNlcklkJywgb2JqKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2UgdG9rZW5NYW5hZ2VyIHRvIHN0b3JlIHVzZXJJZFxuICAgKiBUT0RPOiBhY3R1YWxseSBJIGhhdmUgcHJvYmxlbXMgaW4gY3JlYXRlIGEgY2FjaGUgb2JqZWN0IHRvIGhvbGQgYWxsIHRoZXNlIGNhY2hlIHZhcmlhYmxlcywgc28gSSB1c2UgdG9rZW5NYW5hZ2VyIHRvIGRvIHRoZXNlIHdvcmtzLlxuICAgKiBUT0RPOiBuZWVkIHRvIGNyZWF0ZSBhIHNoYXJlIHNlcnZpY2UgdG8gcHJvdmlkZSBjYWNoZSBzZXJ2aWNlXG4gICAqL1xuICBzZXRTZXNzaW9uVG9rZW4oc2Vzc2lvblRva2VuOiBzdHJpbmcpIHtcbiAgICBjb25zdCBvYmogPSB7XG4gICAgICBhY2Nlc3NUb2tlbjogJ3Nlc3Npb25Ub2tlbicsXG4gICAgICBleHBpcmVzQXQ6IE1hdGgucm91bmQoKG5ldyBEYXRlKCkpLmdldFRpbWUoKSAvIDEwMDAgKyAzNjAwKSxcbiAgICAgIHNjb3BlczogW3Nlc3Npb25Ub2tlbl1cbiAgICB9O1xuICAgIHRoaXMub2t0YUF1dGgudG9rZW5NYW5hZ2VyLmFkZCgnc2Vzc2lvblRva2VuJywgb2JqKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdXNlcklkIGZyb20gdG9rZW5NYW5hZ2VyXG4gICAqL1xuICBnZXRVc2VySWQoKSB7XG4gICAgY29uc3QgdXNlcklkT2JqID0gdGhpcy5va3RhQXV0aC50b2tlbk1hbmFnZXIuZ2V0KCd1c2VySWQnKTtcbiAgICBpZiAodXNlcklkT2JqKSB7XG4gICAgICByZXR1cm4gdGhpcy5va3RhQXV0aC50b2tlbk1hbmFnZXIuZ2V0KCd1c2VySWQnKS5zY29wZXNbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgICogR2V0IGFjZXNzIHRva2VuXG4gICovXG4gIHB1YmxpYyBnZXRTZXNzaW9uVG9rZW4oKSB7XG4gICAgY29uc3Qgc2Vzc2lvblRva2VuT2JqID0gdGhpcy5va3RhQXV0aC50b2tlbk1hbmFnZXIuZ2V0KCdzZXNzaW9uVG9rZW4nKTtcbiAgICBpZiAoc2Vzc2lvblRva2VuT2JqKSB7XG4gICAgICByZXR1cm4gdGhpcy5va3RhQXV0aC50b2tlbk1hbmFnZXIuZ2V0KCdzZXNzaW9uVG9rZW4nKS5zY29wZXNbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9yZSB1c2VyR3JvdXAgYW5kIHNoYXJlZCBhbW9uZyBicm93c2VycyBieSBUb2tlbk1hbmFnZXIgd2l0aCBrZXkgJ3VzZXJHcm91cCdcbiAgICovXG4gIHNldEN1cnJlbnRVc2VyR3JvdXBzKHVzZXJHcm91cHM6IFVzZXJHcm91cHMpIHtcbiAgICBjb25zdCBvYmogPSB7XG4gICAgICBhY2Nlc3NUb2tlbjogJ3VzZXJHcm91cHMnLFxuICAgICAgZXhwaXJlc0F0OiBNYXRoLnJvdW5kKChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkgLyAxMDAwICsgMzYwMCksXG4gICAgICBzY29wZXM6IHVzZXJHcm91cHMuZ3JvdXBzXG4gICAgfTtcbiAgICB0aGlzLm9rdGFBdXRoLnRva2VuTWFuYWdlci5hZGQoJ3VzZXJHcm91cHMnLCBvYmopO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBzdG9yZWQgdXNlckdyb3VwcyBhbmQgcmVmcmVzaCBpZiBleHBpcmVzXG4gICAqL1xuICBhc3luYyBnZXRMb2dpblVzZXJHcm91cHMoKTogUHJvbWlzZTxVc2VyR3JvdXBzPiB7XG4gICAgY29uc3QgdXNlckdyb3Vwc1Rva2VuT2JqID0gdGhpcy5va3RhQXV0aC50b2tlbk1hbmFnZXIuZ2V0KCd1c2VyR3JvdXBzJyk7XG4gICAgY29uc3Qgbm93U2Vjb25kID0gKG5ldyBEYXRlKCkpLmdldFRpbWUoKSAvIDEwMDA7XG4gICAgaWYgKCF1c2VyR3JvdXBzVG9rZW5PYmogfHwgbm93U2Vjb25kID4gdXNlckdyb3Vwc1Rva2VuT2JqLmV4cGlyZUF0KSB7XG4gICAgICBjb25zdCB0bXBVc2VyR3JvdXBzID0gYXdhaXQgdGhpcy5nZXRVc2VyR3JvdXBzKHRoaXMuZ2V0VXNlcklkKCkpO1xuICAgICAgdGhpcy5zZXRDdXJyZW50VXNlckdyb3Vwcyh0bXBVc2VyR3JvdXBzKTtcbiAgICB9XG4gICAgY29uc3QgdXNlckdyb3VwcyA9IG5ldyBVc2VyR3JvdXBzKG51bGwpO1xuICAgIHVzZXJHcm91cHMuZ3JvdXBzID0gdGhpcy5va3RhQXV0aC50b2tlbk1hbmFnZXIuZ2V0KCd1c2VyR3JvdXBzJykuc2NvcGVzO1xuICAgIHJldHVybiB1c2VyR3JvdXBzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IGxvZ2luIHVzZXJJbmZvXG4gICAqIFRPRE86IHdlIGNhbiBjYWNoZSB1c2VyIGluZm8gaW5jbHVkZXMgZ3JvdXBzIGluZm9ybWF0aW9uIHdoZW4gZmluaXNoZWQgbG9naW5cbiAgICovXG4gIGFzeW5jIGdldFVzZXJJbmZvKCk6IFByb21pc2U8VXNlckluZm8+IHtcbiAgICBpZiAodGhpcy5pc0xvZ2luKCkpIHtcbiAgICAgIGNvbnN0IG9rdGFVc2VySW5mbyA9IGF3YWl0IHRoaXMub2t0YS5nZXRVc2VySW5mbyh0aGlzLmdldFVzZXJJZCgpKTtcbiAgICAgIHJldHVybiBhd2FpdCBuZXcgVXNlckluZm8ob2t0YVVzZXJJbmZvKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdub3QgbG9naW4nKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHVzZXJHcm91cCBieSBnaXZlbiB1c2VySWRcbiAgICovXG4gIGFzeW5jIGdldFVzZXJHcm91cHModXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPFVzZXJHcm91cHM+IHtcbiAgICBpZiAodGhpcy5pc0xvZ2luKCkpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG9rdGFVc2VyR3JvdXBzID0gYXdhaXQgdGhpcy5va3RhLmdldFVzZXJHcm91cHModXNlcklkKTtcbiAgICAgICAgcmV0dXJuIGF3YWl0IG5ldyBVc2VyR3JvdXBzKG9rdGFVc2VyR3JvdXBzKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmxvZygnZ2V0VXNlckdyb3VwcyBlcnInLCBlcnIpO1xuICAgICAgICAvLyByZXR1cm4gbmV3IFVzZXJHcm91cHMobnVsbCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gaWYgYWxyZWFkeSBsb2dpbiBieSBjaGVjayB0aGUgZXhpc3RlbmNlIG9mIGFjY2Vzc1Rva2VuXG4gICAqL1xuICBpc0xvZ2luKCk6IGFueSB7XG4gICAgcmV0dXJuICEhdGhpcy5nZXRVc2VySWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWRpcmVjdCB0byB1cmwgZm9yIEdvb2dsZSBsb2dpblxuICAgKi9cbiAgbG9naW5XaXRoR29vZ2xlKHJlZGlyZWN0VXJsOiBzdHJpbmcpIHtcbiAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IGAke3RoaXMuYXV0aENvbmZpZy5nZXRVcmwoKX0vb2F1dGgyL3YxL2F1dGhvcml6ZT9gICtcbiAgICAgIGBpZHA9MG9hZHVsaHV6NzhTTVc4Y0QwaDcmY2xpZW50X2lkPSR7dGhpcy5hdXRoQ29uZmlnLmdldENsaWVudElkKCl9JnJlc3BvbnNlX3R5cGU9aWRfdG9rZW4mYCArXG4gICAgICBgcmVzcG9uc2VfbW9kZT1mcmFnbWVudCZzY29wZT1vcGVuaWQmc2NvcGU9ZW1haWwmc2NvcGU9cGljdHVyZSZzY29wZT1uYW1lJmAgK1xuICAgICAgYHN0YXRlPVdNNkQmbm9uY2U9WXNHNzZqbyZyZWRpcmVjdF91cmk9JHtyZWRpcmVjdFVybH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIExvZ2luIGJ5IHVzZXJuYW1lIGFuZCBwYXNzd29yZFxuICAgKi9cbiAgYXN5bmMgbG9naW5XaXRoUGFzc3dvcmQodXNlcm5hbWU6IHN0cmluZywgcGFzc3dvcmQ6IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3Qgbm9uY2UgPSBhd2FpdCB0aGlzLm9hdXRoLmNyZWF0ZUFuZFNhdmVOb25jZSgpO1xuICAgIGNvbnN0IHNpZ25JblJlc3BvbnNlID0gYXdhaXQgdGhpcy5va3RhQXV0aC5zaWduSW4oe3VzZXJuYW1lOiB1c2VybmFtZSwgcGFzc3dvcmQ6IHBhc3N3b3JkfSk7XG4gICAgaWYgKHNpZ25JblJlc3BvbnNlLnN0YXR1cyA9PT0gJ1NVQ0NFU1MnKSB7XG4gICAgICBhd2FpdCB0aGlzLm9rdGFBdXRoLnRva2VuLmdldFdpdGhvdXRQcm9tcHQoe1xuICAgICAgICBjbGllbnRJZDogdGhpcy5hdXRoQ29uZmlnLmdldENsaWVudElkKCksXG4gICAgICAgIHJlc3BvbnNlVHlwZTogWydpZF90b2tlbicsICd0b2tlbiddLFxuICAgICAgICBzY29wZXM6IFsnb3BlbmlkJywgJ3Byb2ZpbGUnLCAnZW1haWwnXSxcbiAgICAgICAgc2Vzc2lvblRva2VuOiBzaWduSW5SZXNwb25zZS5zZXNzaW9uVG9rZW4sXG4gICAgICAgIG5vbmNlOiBub25jZSxcbiAgICAgICAgcmVkaXJlY3RVcmk6IHdpbmRvdy5sb2NhdGlvbi5vcmlnaW5cbiAgICAgIH0pO1xuICAgICAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHRoaXMuZ2V0U2Vzc2lvbigpO1xuICAgICAgaWYgKHNlc3Npb24uc3RhdHVzID09PSAnQUNUSVZFJykge1xuICAgICAgICBjb25zb2xlLmxvZygnc2Vzc2lvbiBBQ1RJVkUnKTtcbiAgICAgICAgdGhpcy5zZXRVc2VySWQoc2Vzc2lvbi51c2VySWQpO1xuICAgICAgICB0aGlzLnNldFNlc3Npb25Ub2tlbihzZXNzaW9uLmlkKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoJ2xvZ2luIHN1Y2Nlc3NmdWxseScpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ3VzZXJuYW1lIG9yIHBhc3N3b3JkIGVycm9yJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExpc3QgYWxsIGdyb3Vwc1xuICAgKi9cbiAgcHVibGljIGFzeW5jIGxpc3RHcm91cHMoKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMub2t0YS5saXN0R3JvdXBzKCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHNlc3Npb25cbiAgICovXG4gIHB1YmxpYyBhc3luYyBnZXRTZXNzaW9uKCkge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLm9rdGFBdXRoLnNlc3Npb24uZ2V0KCk7XG4gIH1cblxuICAvKipcbiAgICogTmF2aWdhdGUgYnJvd3NlciB0byBsb2dpbiBwYWdlXG4gICAqL1xuICBwdWJsaWMgbmF2aWdhdGVUb0xvZ2luUGFnZSgpIHtcbiAgICBjb25zb2xlLmxvZygnbmF2aWdhdGVUb0xvZ2luUGFnZTonLCB0aGlzLmF1dGhDb25maWcuZ2V0TG9naW5VcmwoKSk7XG4gICAgZG9jdW1lbnQubG9jYXRpb24uaHJlZiA9IHRoaXMuYXV0aENvbmZpZy5nZXRMb2dpblVybCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE5hdmlnYXRlIGJyb3dzZXIgdG8gcmVkaXJlY3QgcGFnZVxuICAgKi9cbiAgbmF2aWdhdGVUb1JlZGlyZWN0UGFnZSgpIHtcbiAgICBjb25zb2xlLmxvZygnbmF2aWdhdGVUb1JlZGlyZWN0UGFnZTonLCB0aGlzLmF1dGhDb25maWcuZ2V0UmVkaXJlY3RVcmwoKSk7XG4gICAgZG9jdW1lbnQubG9jYXRpb24uaHJlZiA9IHRoaXMuYXV0aENvbmZpZy5nZXRSZWRpcmVjdFVybCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIExvZ291dCBjdXJyZW50IHVzZXIgYW5kIGNsZWFyIHRva2VuXG4gICAqL1xuICBsb2dvdXQoKSB7XG4gICAgaWYgKHRoaXMuaXNMb2dpbigpKSB7XG4gICAgICB0aGlzLm9rdGFBdXRoLnRva2VuTWFuYWdlci5jbGVhcigpO1xuICAgICAgY29uc29sZS5sb2coJ3N0YXJ0IHRvIGxvZ291dCcpO1xuICAgICAgdGhpcy5va3RhQXV0aC5zaWduT3V0KCkudGhlbigoKSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdsb2dvdXQgZG9uZSwgdG8gbmF2aWdhdGUnLCB0aGlzLmF1dGhDb25maWcuZ2V0TG9naW5VcmwoKSk7XG4gICAgICAgIHRoaXMubmF2aWdhdGVUb0xvZ2luUGFnZSgpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICB9XG4gIH1cbn1cbiJdfQ==