File manager - Edit - /usr/local/cpanel/whostmgr/docroot/templates/api_tokens/index.cmb.js
Back
/* # cpanel - whostmgr/docroot/templates/api_tokens/services/api_tokens.js # Copyright 2022 cPanel, L.L.C. # All rights reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited */ define( 'app/services/api_tokens',[ "angular", "lodash", "cjt/util/locale", "cjt/io/whm-v1-request", "cjt/util/parse", "cjt/io/api", "cjt/io/whm-v1", "cjt/services/APIService" ], function(angular, _, LOCALE, APIREQUEST, PARSE) { "use strict"; var app = angular.module("whm.apiTokens.apiCallService", []); app.factory( "Tokens", ["$q", "APIService", function($q, APIService) { var TokensService = function() {}; TokensService.prototype = new APIService(); var isEmptyObject = function(obj) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { return false; } } return true; }; var addAclsTo = function addAclsTo(apiCall, acls) { if (typeof acls !== "undefined") { var i = 0, apiCount = acls.length; for (; i < apiCount; i++) { apiCall.addArgument("acl-" + i, acls[i]); } } }; var tokensData = {}; var userPrivileges = {}; angular.extend(TokensService.prototype, { getTokens: function getTokens(force) { if (force || isEmptyObject(tokensData)) { var apiCall = new APIREQUEST.Class(); apiCall.initialize("", "api_token_list"); return this.deferred(apiCall).promise .then(function(response) { tokensData = response.data.tokens; return tokensData; }) .catch(function(error) { return $q.reject(error); }); } else { return $q.when(tokensData); } }, createToken: function createToken(name, acls, expiresAt, whitelistIps) { var apiCall = new APIREQUEST.Class(); apiCall.initialize("", "api_token_create"); apiCall.addArgument("token_name", name); if (expiresAt) { apiCall.addArgument("expires_at", expiresAt); } if (whitelistIps && whitelistIps.length) { whitelistIps.forEach(function(ip, index) { apiCall.addArgument("whitelist_ip-" + index, ip); }); } addAclsTo(apiCall, acls); return this.deferred(apiCall).promise .then(function(data) { return data; }) .catch(function(error) { return $q.reject(error); }); }, updateToken: function updateToken(name, newName, acls, expiresAt, whitelistIps) { var apiCall = new APIREQUEST.Class(); apiCall.initialize("", "api_token_update"); apiCall.addArgument("token_name", name); if (expiresAt) { apiCall.addArgument("expires_at", expiresAt); } if (whitelistIps && whitelistIps.length) { whitelistIps.forEach(function(ip, index) { apiCall.addArgument("whitelist_ip-" + index, ip); }); } if (whitelistIps && !whitelistIps.length) { apiCall.addArgument("whitelist_ip", "any"); } if (newName !== name) { apiCall.addArgument("new_name", newName); } addAclsTo(apiCall, acls); return this.deferred(apiCall).promise .then(function(data) { return data; }) .catch(function(error) { return $q.reject(error); }); }, revokeToken: function revokeToken(name) { var apiCall = new APIREQUEST.Class(); apiCall.initialize("", "api_token_revoke"); if (typeof (name) === "string") { apiCall.addArgument("token_name", name); } else if (Array.isArray(name)) { var i = 0, nameCount = name.length; for (; i < nameCount; i++) { apiCall.addArgument("token_name-" + i, name[i]); } } return this.deferred(apiCall).promise .then(function(data) { return data; }) .catch(function(error) { return $q.reject(error); }); }, getPrivileges: function getPrivileges(force) { if (force || isEmptyObject(userPrivileges)) { var apiCall = new APIREQUEST.Class(); apiCall.initialize("", "myprivs"); return this.deferred(apiCall).promise .then(function(result) { var obj = {}; var hasAll = false; if (result.data) { obj = result.data[0]; if (obj !== null && typeof obj !== "undefined") { hasAll = Object.prototype.hasOwnProperty.call(obj, "all") && obj.all === 1; // Remove the "demo" acl since it is not a real acl delete obj.demo; var keys = Object.keys(obj); for (var i = 0, len = keys.length; i < len; i++) { if (keys[i] !== "all" && (hasAll || obj[keys[i]] === 1)) { userPrivileges[keys[i]] = true; } } if (hasAll) { userPrivileges["all"] = false; } } } return userPrivileges; }) .catch(function(error) { return $q.reject(error); }); } else { return $q.when(userPrivileges); } }, getDetailsFor: function getDetailsFor(tokenName) { return this.getTokens(false) .then(function(data) { if (data !== null && typeof data !== "undefined" && Object.prototype.hasOwnProperty.call(data, tokenName)) { if (data[tokenName] && Object.prototype.hasOwnProperty.call(data[tokenName], "acls")) { var acls = data[tokenName].acls; // Remove the "demo" acl since it is not a real acl delete acls.demo; for (var acl in acls) { if (Object.prototype.hasOwnProperty.call(acls, acl)) { acls[acl] = PARSE.parsePerlBoolean(acls[acl]); } } } return data[tokenName]; } return $q.reject(LOCALE.maketext("The [asis,API] token “[_1]” does not exist.", _.escape(tokenName))); }); } }); return new TokensService(); } ]); }); // Copyright 2022 cPanel, L.L.C. - All rights reserved. // copyright@cpanel.net // https://cpanel.net // This code is subject to the cPanel license. Unauthorized copying is prohibited function ipv6short(input) { "use strict"; // remove all zeros to the right input = input.replace(/^(0{4}:)+/g, "::"); // remove all zeros to the left input = input.replace(/(?::?0{4})+(\/\d+)?$/g, "::$1"); // remove all leading zeros input = input.replace(/(:|^)(0{1,3})(?=[^0])/g, "$1"); // find the longest group of continuous empty 16-bit hexets if string doesn't alreay contain :: if (input.match("::") === null) { var matches = input.match(/(:0{4})+/g); if (!matches) { return input; } var match = matches.reduce((a, b) => a.length > b.length ? a : b); input = input.replace(match, ":"); } // replace remaning empty 16-bit hexets with a single 0 return input.replace(/(?!:)(0{4})/g, "0"); } define( 'app/filters',[ "angular", ], function(angular) { "use strict"; var module = angular.module("whm.apiTokens.filters", []); module.filter("ipv6short", function() { return ipv6short; }); return module; }); /* # cpanel - whostmgr/docroot/templates/api_tokens/views/home.js # Copyright(c) 2020 cPanel, L.L.C. # All rights reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited */ define( 'app/views/home',[ "angular", "cjt/util/locale", "cjt/util/table", "uiBootstrap", "cjt/decorators/growlDecorator", "cjt/decorators/paginationDecorator", "cjt/directives/actionButtonDirective", "cjt/directives/searchDirective", "cjt/directives/pageSizeDirective", "cjt/directives/alertList", "cjt/directives/toggleSortDirective", "cjt/services/viewNavigationApi", "cjt/directives/autoFocus", ], function(angular, LOCALE, Table) { "use strict"; var app = angular.module("whm.apiTokens"); var controller = app.controller( "homeController", ["$q", "growl", "Tokens", "$uibModal", "viewNavigationApi", "PAGE", function($q, growl, Tokens, $uibModal, viewNavigationApi, PAGE) { var home = this; home.loading = false; home.showFormToggleBtn = true; home.tokenAdded = false; home.loadingError = false; home.loadingErrorMessage = ""; home.allChecked = false; home.checkedCount = 0; home.paginationMessage = ""; home.showChildAccountsExistWarning = PAGE.childAccountsExist; home.childAccountsExistWarning = ""; home.childAccountsExistWarning += LOCALE.maketext("There are accounts on this server controlled by a parent node."); home.childAccountsExistWarning += " "; home.childAccountsExistWarning += LOCALE.maketext("Do not delete [asis,API] tokens a parent node uses to communicate with this server."); function searchByName(item, searchText) { return item.name.toLowerCase().indexOf(searchText.toLowerCase()) !== -1; } var table = new Table(); table.setSearchFunction(searchByName); table.setSort("create_time,name", "desc"); home.meta = table.getMetadata(); home.filteredList = table.getList(); home.allTokens = []; home.render = function() { home.resetCheckAll(); home.filteredList = table.update(); home.paginationMessage = table.paginationMessage(); }; home.sortList = function() { home.render(); }; home.selectPage = function() { home.render(); }; home.selectPageSize = function() { home.render(); }; home.searchList = function() { home.render(); }; home.resetCheckAll = function() { home.allChecked = false; home.toggleCheckAll(); home.checkedCount = 0; }; home.getIndeterminateState = function() { return home.checkedCount > 0 && !home.allChecked; }; home.toggleCheckAll = function() { if (home.filteredList.length === 0) { return; } var i = 0, listLength = home.filteredList.length; for (i; i < listLength; i++) { home.filteredList[i].checked = home.allChecked; } if (home.allChecked) { home.checkedCount = listLength; } else { home.checkedCount = 0; } }; home.syncCheckAll = function(listItem) { if (listItem.checked) { home.checkedCount++; } else { home.checkedCount--; } home.allChecked = home.checkedCount === home.filteredList.length; }; home.checkAll = function() { home.allChecked = true; home.toggleCheckAll(); }; home.editToken = function(token) { if (token === void 0) { viewNavigationApi.loadView("/edit"); } else { viewNavigationApi.loadView("/edit/" + token.name); } }; home.getSelectedTokens = function() { var selectedTokens = []; for (var i = 0; i < home.filteredList.length; i++) { if (home.filteredList[i].checked) { selectedTokens.push(home.filteredList[i]); } } return selectedTokens; }; home.getHumanReadableTime = function(epochTime) { return LOCALE.local_datetime(epochTime, "datetime_format_medium"); }; function RevokeTokenModalController($uibModalInstance, token) { var ctrl = this; var tokenCount = 0; ctrl.cancel = function() { $uibModalInstance.dismiss("cancel"); }; ctrl.buildTokenNameList = function() { tokenCount = token.length; var i = 0, tokensToDelete = []; for (i = 0; i < tokenCount; i++) { tokensToDelete.push(token[i].name); } return tokensToDelete; }; var revokeParam; if (Array.isArray(token) && token.length === home.allTokens.length) { ctrl.prompt = LOCALE.maketext("Are you certain that you want to revoke all of your [asis,API] tokens?" ); revokeParam = ctrl.buildTokenNameList(); } else if (Array.isArray(token)) { ctrl.prompt = LOCALE.maketext("Are you certain that you want to revoke [numf,_1] [asis,API] [numerate,_1,token,tokens]?", token.length); revokeParam = ctrl.buildTokenNameList(); } else { ctrl.prompt = LOCALE.maketext("Are you certain that you want to revoke the [asis,API] token, “[_1]”?", token.name); revokeParam = token.name; } ctrl.confirm = function() { return Tokens.revokeToken(revokeParam) .then(function() { if (Array.isArray(token)) { if (token.length === home.allTokens.length) { growl.success(LOCALE.maketext("You successfully revoked all of your [asis,API] tokens.")); table.clear(); home.allTokens = []; } else { growl.success(LOCALE.maketext("You successfully revoked [numf,_1] [asis,API] [numerate,_1,token,tokens].", token.length)); for (var i = 0; i < tokenCount; i++) { table.remove(token[i]); } } } else { growl.success(LOCALE.maketext("You successfully revoked the [asis,API] token “[_1]”.", token.name)); table.remove(token); } home.render(); }) .catch(function(error) { growl.error(error); }) .finally(function() { $uibModalInstance.close(); }); }; } RevokeTokenModalController.$inject = ["$uibModalInstance", "token"]; home.confirmRevokeToken = function(token) { $uibModal.open({ templateUrl: "confirm_token_revocation.html", controller: RevokeTokenModalController, controllerAs: "ctrl", resolve: { token: function() { return token; }, }, }); }; home.refreshList = function() { home.filteredList = []; home.allTokens = []; return load(); }; function load() { home.loading = true; var _currentDateTime = new Date(); _currentDateTime = _currentDateTime.getTime() / 1000; var _twentyFourHours = 24 * 60 * 60; // In addition to getting the list of api tokens, we want to fetch the // privileges for the user now to cache them for when the user will // need to create a token. This helps avoid showing a spinner on the // create view. return $q.all([ Tokens.getTokens(true), Tokens.getPrivileges(true)]) .then(function(data) { var tableData = []; var tokenData = data[0]; if (tokenData !== null && typeof tokenData !== "undefined") { for (var tokenName in tokenData) { if (tokenData.hasOwnProperty(tokenName)) { tokenData[tokenName].checked = false; tokenData[tokenName].create_time_friendly = LOCALE.local_datetime(tokenData[tokenName].create_time, "datetime_format_medium"); tokenData[tokenName].expiresAtFriendly = ""; if (tokenData[tokenName].expires_at) { var expiresAt = parseInt(tokenData[tokenName].expires_at, 10); if (expiresAt <= _currentDateTime) { tokenData[tokenName].expired = true; } else if (expiresAt - _currentDateTime < _twentyFourHours) { tokenData[tokenName].expiresSoon = true; } tokenData[tokenName].expiresAtFriendly = LOCALE.local_datetime(tokenData[tokenName].expires_at, "datetime_format_medium"); } tableData.push(tokenData[tokenName]); } } table.load(tableData); home.allTokens = tableData; home.render(); } }) .catch(function(error) { home.loadingError = true; home.loadingErrorMessage = error; }) .finally(function() { home.loading = false; }); } function init() { load(); } init(); }, ]); return controller; } ); /* # cpanel - whostmgr/docroot/templates/api_tokens/views/edit.js # Copyright 2022 cPanel, L.L.C. # All rights reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited */ define( 'app/views/edit',[ "angular", "lodash", "cjt/util/locale", "cjt/util/parse", "cjt/validator/ip-validators", "cjt/validator/validator-utils", "cjt/util/table", "uiBootstrap", "cjt/decorators/growlDecorator", "cjt/directives/alertList", "cjt/directives/autoFocus", "cjt/directives/triStateCheckbox", "cjt/directives/timePicker", "cjt/directives/datePicker", "cjt/services/viewNavigationApi", "cjt/directives/validationContainerDirective", "cjt/directives/validationItemDirective", ], function(angular, _, LOCALE, PARSE, VALIDATORS, UTILS) { "use strict"; /** * Parse the text block into a list of IPv4 and CIDR items. These can * be separated by a \n, \r\n, a comma, or a sequence of 1 or more * whitespaces. Excess leading and trailing whitespace is removed from * each item and blank entries are removed from the list. * * @param {string} txtIps * @returns {string[]} */ function parseIps(txtIps) { if (!txtIps) { return []; } var ips = txtIps.split(/\r?\n|,|\s+/); return ips.map(function(ip) { return _.trim(ip); }).filter(function(ip) { return !!ip; }); } /** * Try to guess the IP version based on group separator * defaults to ipv4 if ipv6 checks fail * * @param {string} ip - any string. * @returns {string} - ip version. */ function guessIpVersion(ip) { if (/:/.test(ip)) { return "ipv6"; } return "ipv4"; } /** * Validate ipv6 address and the prefix length of ipv6 range * * @param {string} ipOrCidr - ipv6 range specified in CIDR notation. * @returns {ValidationResult} */ function cidr6(str) { var cidr = str.split("/"); var range = cidr[1], address = cidr[0]; var result = VALIDATORS.methods.ipv6(address); if (!range) { result.isValid = false; result.add("cidr", LOCALE.maketext("The [asis,IP] address prefix must include a ‘/’ followed by the prefix length.")); } if (range < 1 || range > 128 || !range) { result.isValid = false; result.add("cidr", LOCALE.maketext("You must specify a valid prefix length between 1 and 128.")); } return result; } /** * Validate the string is either a valid IPv4 address or * that it is a valid CIDR address range. * * @param {string} ipOrCidr - an unvalidated string from the ui. * @returns {ValidationResult} */ function validateIp(ipOrCidr) { var result; var ipversion = guessIpVersion(ipOrCidr); if (/[/]/.test(ipOrCidr)) { result = ipversion === "ipv4" ? VALIDATORS.methods.cidr4(ipOrCidr) : cidr6(ipOrCidr); if (!result.isValid) { if (result.lookup["cidr"]) { result.lookup["cidr"].message = ipOrCidr + " - " + result.lookup["cidr"].message; } else { if (result.lookup["cidr-details"]) { result.lookup["cidr-details"].message = ipOrCidr + " - " + result.lookup["cidr-details"].message; } } // Handle cases where an invalid ipv4 address is used along with a CIDR range if (result.lookup[ipversion]) { result.lookup[ipversion].message = ipOrCidr + " - " + result.lookup[ipversion].message; } } } else { result = ipversion === "ipv4" ? VALIDATORS.methods.ipv4(ipOrCidr) : VALIDATORS.methods.ipv6(ipOrCidr); if (!result.isValid) { result.lookup[ipversion].message = ipOrCidr + " - " + result.lookup[ipversion].message; } } return result; } var app = angular.module("whm.apiTokens"); /** * Add a custom parser and validator for a list of IPv4 addresses * or CIDR ranges. */ app.directive("ipv4OrCidr4List", function() { return { restrict: "A", require: "ngModel", link: function(scope, elem, attr, ctrl) { var form = elem.controller("form"); UTILS.initializeExtendedReporting(ctrl, form); ctrl.$parsers.push(function(value) { return parseIps(value); }); ctrl.$formatters.push(function(value) { return value.join("\r\n"); }); ctrl.$isEmpty = function(value) { return angular.isUndefined(value) || value === "" || value === null || value !== value || value.length && value.length === 0; }; ctrl.$validators.ipv4OrCidr4 = function(modelValue, viewValue) { // Adapter to support multiple flags in a validator ["ipv6", "ipv4", "cidr", "cidr-details", "size-exceeded"].forEach(function(key) { delete ctrl.$error[key]; }); ctrl.$error_details.clear(); if (ctrl.$isEmpty(modelValue)) { // consider empty models to be valid return true; } if (modelValue.length > 100) { var sizeResult = UTILS.initializeValidationResult(); sizeResult.isValid = false; sizeResult.add("size-exceeded", LOCALE.maketext("You have exceeded the limit of 100 whitelisted [asis,IP] addresses per token.")); ctrl.$error["size-exceeded"] = true; UTILS.updateExtendedReportingList(ctrl, form, ["size-exceeded"], sizeResult); return false; } // Perform progressive validation, rather the all at the same time for (var i = 0, l = modelValue.length; i < l; i++) { var ipOrCidr = modelValue[i]; var result = validateIp(ipOrCidr); if (!result.isValid) { var possibleErrors = ["ipv6", "ipv4", "cidr", "cidr-details"]; // Package the additional error messages into the collections possibleErrors.forEach(function(key) { var isError = result.lookup[key] ? true : false; if (isError) { ctrl.$error[key] = true; } else { delete ctrl.$error[key]; } }); UTILS.updateExtendedReportingList(ctrl, form, possibleErrors, result); return false; } } // it is valid if all the individual items are valid return true; }; scope.$watch(attr.ngModel, function(newVal) { ctrl.$validate(); } ); }, }; }); var controller = app.controller( "editController", ["$routeParams", "growl", "Tokens", "viewNavigationApi", "PAGE", "growlMessages", function($routeParams, growl, Tokens, viewNavigationApi, PAGE, growlMessages) { var edit = this; var minDate = new Date(); minDate.setHours(0); minDate.setMinutes(0); minDate.setSeconds(0, 0); edit.datePickerOptions = { minDate: minDate, }; edit.timePickerOptions = { min: minDate, }; edit.stringify = function(obj) { return JSON.stringify(obj, undefined, 2); }; var defaultExpiresDate = new Date(minDate.getTime()); defaultExpiresDate.setHours(23); defaultExpiresDate.setMinutes(59); defaultExpiresDate.setSeconds(59, 999); defaultExpiresDate.setFullYear(defaultExpiresDate.getFullYear() + 1); edit.loading = false; edit.loadingError = false; edit.loadingErrorMessage = ""; edit.showExtraHelp = false; edit.onToggleHelp = function() { edit.showExtraHelp = !edit.showExtraHelp; }; edit.tokenAdded = false; edit.editingToken = false; edit.hasPrivs = false; edit.availableAcls = {}; edit.aclsToEdit = []; edit.aclsToSend = {}; edit.newToken = { name: "", originalName: "", token: "", acls: [], tokenExpires: false, expiresAt: defaultExpiresDate, whitelistIps: [], }; var isDnsOnly = PARSE.parsePerlBoolean(PAGE.is_dns_only); edit.aclWarningVisible = function(acl) { if (acl.name === "all") { return true; } if (!Object.prototype.hasOwnProperty.call(acl, "is_warning_visible")) { acl.is_warning_visible = false; } return acl.is_warning_visible; }; edit.toggleAclWarning = function(acl) { if (!Object.prototype.hasOwnProperty.call(acl, "is_warning_visible")) { acl.is_warning_visible = true; } else { acl.is_warning_visible = !acl.is_warning_visible; } }; edit.handleWarningIconKey = function(acl, event) { if (event.type !== "keypress") { return; } if (event.charCode === 32 || event.charCode === 13) { edit.toggleAclWarning(acl); event.preventDefault(); } }; edit.toggleAcl = function(acl) { var isRootSelected = edit.aclsToSend["all"] && acl.name !== "all"; var areWeSelectingRoot = acl.name === "all" && acl.selected; if (acl.selected) { edit.aclsToSend[acl.name] = true; } else { delete edit.aclsToSend[acl.name]; } if (isRootSelected && !acl.selected) { edit.removeAllToken(); } if (areWeSelectingRoot) { // select all the subcatgories except for the root subcategory edit.selectAllSubcategories("Everything"); } }; edit.updateAclsToSend = function(subcategory) { for (var i = 0, len = subcategory.acls.length; i < len; i++) { edit.toggleAcl(subcategory.acls[i]); } }; /** * Select all Privileges on the interface and update the data storage we * use to send privileges when we trigger the "save" call. * * @param except {String} - a subcategory that we do not want to select */ edit.selectAllSubcategories = function(except) { var subcategories = edit.aclsToEdit; for (var i = 0, len = subcategories.length; i < len; i++) { if (subcategories[i].title === except) { continue; } for (var j = 0, aclLen = subcategories[i].acls.length; j < aclLen; j++) { subcategories[i].acls[j].selected = true; edit.aclsToSend[subcategories[i].acls[j].name] = true; } } }; edit.hasSelectedPrivs = function() { return edit.hasPrivs && Object.keys(edit.aclsToSend).length > 0; }; edit.disableSave = function(form) { return (edit.newToken.tokenExpires && edit.datePickerOptions.minDate > edit.newToken.expiresAt) || (form.$pristine || form.$invalid || !edit.hasSelectedPrivs()); }; edit.dateValidator = function(input) { if (edit.newToken.tokenExpires && edit.newToken.expiresAt) { edit.newToken.expiresAt.setHours(23); edit.newToken.expiresAt.setMinutes(59); edit.newToken.expiresAt.setSeconds(59, 999); } if (edit.newToken.tokenExpires && edit.datePickerOptions.minDate > edit.newToken.expiresAt) { input.$invalid = true; input.$valid = false; } }; edit.resetDate = function() { if (edit.newToken.tokenExpires) { edit.newToken.expiresAt = defaultExpiresDate; } }; edit.goHome = function() { viewNavigationApi.loadView("/home"); }; edit.newTokenExpiresMessage = function newTokenExpiresMessage(token) { var expirationDate = LOCALE.local_datetime(token.expiresAt, "datetime_format_medium"); return LOCALE.maketext("This [asis,API] token will expire on [_1][comment,Bareword is a date].", expirationDate); }; edit.minimumIpRows = function() { return this.newToken.whitelistIps.length ? this.newToken.whitelistIps.length : 4; }; edit.saveToken = function(form) { if (form.$invalid) { return; } edit.newToken.acls = Object.keys(edit.aclsToSend); if ( edit.newToken.tokenExpires ) { edit.newToken.expiresAt.setHours(23); edit.newToken.expiresAt.setMinutes(59); edit.newToken.expiresAt.setSeconds(59, 999); } var expiresAt = edit.newToken.tokenExpires ? Math.floor(edit.newToken.expiresAt / 1000) : "0"; growlMessages.destroyAllMessages(); if (edit.editingToken) { return Tokens.updateToken(edit.newToken.originalName, edit.newToken.name, edit.newToken.acls, expiresAt, edit.newToken.whitelistIps) .then(function success(results) { growl.success(LOCALE.maketext("You successfully updated the [asis,API] token, “[_1]”.", results.data.name)); viewNavigationApi.loadView("/home"); }) .catch(function error(data) { growl.error(_.escape(data)); }); } else { return Tokens.createToken(edit.newToken.name, edit.newToken.acls, expiresAt, edit.newToken.whitelistIps) .then(function success(results) { // notify the user of the new token edit.newToken.token = results.data.token; edit.tokenAdded = true; }) .catch(function error(data) { growl.error(_.escape(data)); }); } }; edit.getAvailableAcls = function() { return Tokens.getPrivileges(false) .then(function success(results) { if (results !== null && typeof results !== "undefined" ) { edit.availableAcls = results; } }) .catch(function error(data) { growl.error(_.escape(data)); }); }; edit.removeAllToken = function() { var allSubcategory = edit.aclsToEdit[edit.aclsToEdit.length - 1]; allSubcategory.acls[0].selected = false; delete edit.aclsToSend.all; growl.info(LOCALE.maketext("The system deselected the “all” privilege.")); }; /** * Create a data structure that is easy to deal with from the interface * Should create the following data structure * [ * { * "categoryName": "standardprivileges", * "categoryTitle": "Standard Privileges", * "name": "accountinformation", * "title": "Account Information", * "selected": true, * "acls": [ * { * "name": "list-accts", * "title": "List Accounts", * "selected": true * } * ] * } * ] * @param {Object} selectedPrivs - contains the privileges * should appear in the interface and be selected. * @return {Array} the data structure mapped out above */ function prepareAclsForEdit(selectedPrivs) { var formattedAcls = []; var category = {}; var subcategory = {}; var acl = {}; var availabeAclsInSubcategory = 0; selectedPrivs = (typeof selectedPrivs === "undefined") ? {} : selectedPrivs; for (var i = 0, len = PAGE.ordered_categories.length; i < len; i++) { // the additional software group may not have any entries, so check for definedness first if (typeof PAGE.categories_metadata[PAGE.ordered_categories[i]].ordered_subcategories !== "undefined") { category = { orderedSubcategories: PAGE.categories_metadata[PAGE.ordered_categories[i]].ordered_subcategories, name: PAGE.ordered_categories[i], title: PAGE.categories_metadata[PAGE.ordered_categories[i]].title, }; for (var j = 0, jlen = category.orderedSubcategories.length; j < jlen; j++) { subcategory = { title: PAGE.subcategories_metadata[category.orderedSubcategories[j]].title, orderedAcls: PAGE.subcategories_metadata[category.orderedSubcategories[j]].ordered_acls, categoryTitle: category.title, categoryName: category.name, name: category.orderedSubcategories[j], acls: [], }; availabeAclsInSubcategory = 0; for (var k = 0, klen = subcategory.orderedAcls.length, enabledCount = 0; k < klen; k++) { if (!Object.prototype.hasOwnProperty.call(selectedPrivs, subcategory.orderedAcls[k])) { continue; } if (isDnsOnly && (!PAGE.acl_metadata[subcategory.orderedAcls[k]] || !PAGE.acl_metadata[subcategory.orderedAcls[k]].dnsonly)) { continue; } availabeAclsInSubcategory++; acl = { name: subcategory.orderedAcls[k], title: PAGE.acl_metadata[subcategory.orderedAcls[k]].title, }; if (PAGE.acl_metadata[subcategory.orderedAcls[k]].description) { acl.description = PAGE.acl_metadata[subcategory.orderedAcls[k]].description; acl.description_is_warning = PAGE.acl_metadata[subcategory.orderedAcls[k]].description_is_warning ? true : false; } if (selectedPrivs[acl.name]) { acl.selected = true; enabledCount++; } else { acl.selected = false; } subcategory.acls.push(acl); } subcategory.orderedAcls = void 0; subcategory.selected = (enabledCount === availabeAclsInSubcategory) ? true : false; if (availabeAclsInSubcategory > 0) { formattedAcls.push(subcategory); } } } } return formattedAcls; } function init() { edit.loading = true; var _currentDateTime = new Date(); _currentDateTime = _currentDateTime.getTime() / 1000; var _twentyFourHours = 24 * 60 * 60; if (Object.prototype.hasOwnProperty.call($routeParams, "name")) { return Tokens.getDetailsFor($routeParams.name) .then(function(results) { edit.newToken.name = $routeParams.name; edit.newToken.originalName = $routeParams.name; edit.editingToken = true; edit.newToken.expiresAtFriendly = ""; if (results.expires_at) { edit.newToken.expiresAt = new Date(results.expires_at * 1000); edit.newToken.tokenExpires = true; var expiresAt = parseInt(results.expires_at, 10); if (expiresAt <= _currentDateTime) { edit.newToken.expired = true; } else if (expiresAt - _currentDateTime < _twentyFourHours) { edit.newToken.expiresSoon = true; } edit.newToken.expiresAtFriendly = LOCALE.local_datetime(expiresAt, "datetime_format_medium"); } edit.newToken.whitelistIps = results.whitelist_ips || []; for (var acl in results.acls) { if (results.acls[acl]) { if (isDnsOnly && (!PAGE.acl_metadata[acl] || !PAGE.acl_metadata[acl].dnsonly)) { continue; } edit.aclsToSend[acl] = true; } } edit.aclsToEdit = prepareAclsForEdit(results.acls); edit.hasPrivs = edit.aclsToEdit.length > 0; }) .catch(function(error) { edit.loadingError = true; edit.loadingErrorMessage = error; }) .finally(function() { edit.loading = false; }); } else { return Tokens.getPrivileges(false) .then(function(results) { if (results !== null && typeof results !== "undefined" ) { for (var acl in results) { if (results[acl]) { if (isDnsOnly && !PAGE.acl_metadata[acl].dnsonly) { continue; } edit.aclsToSend[acl] = true; } } edit.aclsToEdit = prepareAclsForEdit(results); edit.hasPrivs = edit.aclsToEdit.length > 0; } }) .catch(function(error) { edit.loadingError = true; edit.loadingErrorMessage = error; }) .finally(function() { edit.loading = false; }); } } init(); }, ]); return controller; } ); /* # cpanel - whostmgr/docroot/templates/api_tokens/index.js # Copyright(c) 2020 cPanel, L.L.C. # All rights reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited */ /* global require: false, define: false */ define( 'app/index',[ "angular", "jquery", "cjt/core", "cjt/modules", "ngRoute", "ngAnimate", "ngAria", "uiBootstrap", "app/services/api_tokens", "app/filters", ], function(angular) { "use strict"; return function() { angular.module("whm.apiTokens", [ "cjt2.config.whm.configProvider", // This needs to load first "ngRoute", "ngAnimate", "ngAria", "ui.bootstrap", "angular-growl", "cjt2.whm", "whm.apiTokens.apiCallService", "whm.apiTokens.filters", ]); var app = require( [ "cjt/bootstrap", "app/views/home", "app/views/edit", ], function(BOOTSTRAP) { var app = angular.module("whm.apiTokens"); app.value("PAGE", PAGE); app.config([ "$routeProvider", function($routeProvider) { $routeProvider.when("/home", { controller: "homeController", controllerAs: "home", templateUrl: "api_tokens/views/home.ptt", }); $routeProvider.when("/edit/:name?", { controller: "editController", controllerAs: "edit", templateUrl: "api_tokens/views/edit.ptt", }); $routeProvider.otherwise({ "redirectTo": "/home", }); }, ]); BOOTSTRAP(document, "whm.apiTokens"); }); return app; }; } );
| ver. 1.4 |
Github
|
.
| PHP 8.1.34 | Generation time: 0.05 |
proxy
|
phpinfo
|
Settings