vix-ui
Version:
474 lines • 34.2 kB
JavaScript
/**
* @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==