File manager - Edit - /usr/local/cpanel/whostmgr/docroot/templates/mod_security/config.cmb.js
Back
/* # templates/mod_security/views/commonController.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 define */ /* ------------------------------------------------------------------------------ * DEVELOPER NOTES: * 1) Put all common application functionality here, maybe *-----------------------------------------------------------------------------*/ define( 'app/views/commonController',[ "angular", "cjt/filters/wrapFilter", "cjt/services/alertService", "cjt/directives/alertList", "uiBootstrap" ], function(angular) { var app; try { app = angular.module("App"); } catch (e) { app = angular.module("App", ["ui.bootstrap", "ngSanitize"]); } var controller = app.controller( "commonController", ["$scope", "$location", "$rootScope", "alertService", "PAGE", function($scope, $location, $rootScope, alertService, PAGE) { // Setup the installed bit... $scope.isInstalled = PAGE.installed; // Bind the alerts service to the local scope $scope.alerts = alertService.getAlerts(); $scope.route = null; /** * Closes an alert and removes it from the alerts service * * @method closeAlert * @param {String} index The array index of the alert to remove */ $scope.closeAlert = function(id) { alertService.remove(id); }; /** * Determines if the current view matches the supplied pattern * * @method isCurrentView * @param {String} view The path to the view to match */ $scope.isCurrentView = function(view) { if ( $scope.route && $scope.route.$$route ) { return $scope.route.$$route.originalPath === view; } return false; }; // register listener to watch route changes $rootScope.$on( "$routeChangeStart", function(event, next, current) { $scope.route = next; }); } ]); return controller; } ); /* # mod_security/services/configService.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 define: false */ define( 'app/services/configService',[ // Libraries "angular", // CJT "cjt/util/locale", "cjt/util/parse", "cjt/io/api", "cjt/io/whm-v1-request", "cjt/io/whm-v1", // IMPORTANT: Load the driver so its ready // Angular components "cjt/services/APIService" ], function(angular, LOCALE, PARSE, API, APIREQUEST, APIDRIVER) { // Constants var NO_MODULE = ""; // Fetch the current application var app = angular.module("App"); /** * Apply the defaults to the config if needed. * @param {Array} configs */ function applyDefaults(config) { if (config.default && config.missing) { if (config.type === "number") { config.state = parseInt(config.default, 10); } else { config.state = config.default; } } } /** * Converts the response to our application data structure * @method convertResponseToList * @private * @param {Object} response * @return {Object} Sanitized data structure. */ function convertResponseToList(response) { var items = []; if (response.status) { var data = response.data; for (var i = 0, length = data.length; i < length; i++) { var config = data[i]; // Clean up the boolean data if (typeof (config.engine) !== "undefined") { config.engine = PARSE.parsePerlBoolean(config.engine); } // Apply the default if the config is missing applyDefaults(config); // Mark the record as unchanged config.changed = false; items.push( config ); } return items; } else { return []; } } /** * Setup the configuration models API service */ app.factory("configService", ["$q", "APIService", function($q, APIService) { // Set up the service's constructor and parent var ConfigService = function() {}; ConfigService.prototype = new APIService(); // Extend the prototype with any class-specific functionality angular.extend(ConfigService.prototype, { /** * Get a list of mod_security rule hits that match the selection criteria passed in meta parameter * @return {Promise} Promise that will fulfill the request. */ fetchList: function() { var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_get_settings"); var deferred = this.deferred(apiCall, { transformAPISuccess: convertResponseToList }); return deferred.promise; }, /** * Save the changed configurations. * @param {Array} configs * @return {Promise} Promise that will fulfill the request. */ save: function(configs) { if (!configs) { return; } var toSave = []; for (var i = 0, l = configs.length; i < l; i++) { if (configs[i].changed) { toSave.push(configs[i]); } } if (toSave.length > 0 ) { var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_batch_settings"); for (var j = 0, jl = toSave.length; j < jl; j++) { var item = toSave[j]; if ( (!item.engine && item.default && ( // Not an engine and has a default ((item.type === "text" || item.type === "radio") && (item.state === item.default)) || // Text or radio field with a default set to default, but not missing from file (item.type === "number" && (parseInt(item.state, 10) === item.default)) // Number field with a default set to default, but not missing from file )) || (item.state === "") // Text or number that has been cleared, but isn't missing from file ) { if (!item.missing) { apiCall.addArgument("setting_id", toSave[j].setting_id, true); apiCall.addArgument("remove", 1, true); // Otherwise, nothing to do here. } } else { apiCall.addArgument("setting_id", toSave[j].setting_id, true); apiCall.addArgument("state", item.state, true); } apiCall.incrementAuto(); } apiCall.addArgument("commit", 1); var deferred = this.deferred(apiCall, { apiSuccess: function(response, deferred) { for (var i = 0, l = configs.length; i < l; i++) { if (configs[i].changed) { configs[i].changed = false; } } deferred.resolve(response.data); }, apiFailure: function(response) { // TODO: Get the list from the data deferred.reject(response.error); } }); // pass the promise back to the controller return deferred.promise; } }, /** * Helper method that calls convertResponseToList to prepare the data structure * @param {Object} response * @return {Object} Sanitized data structure. */ prepareList: function(response) { // Since this is coming from the backend, but not through the api.js layer, // we need to parse it to the frontend format. response = APIDRIVER.parse_response(response).parsedResponse; return convertResponseToList(response); }, /** * Apply the defaults to the config if needed. * @param {Array} configs */ applyDefaults: applyDefaults }); return new ConfigService(); }]); } ); /* # templates/mod_security/views/configController.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 define: false */ define( 'app/views/configController',[ "angular", "lodash", "cjt/validator/datatype-validators", "cjt/validator/ascii-data-validators", "cjt/util/locale", "uiBootstrap", "cjt/directives/autoFocus", "cjt/filters/wrapFilter", "cjt/directives/spinnerDirective", "app/services/configService", "cjt/directives/validationContainerDirective", "cjt/validator/validateDirectiveFactory", "cjt/directives/dynamicValidatorDirective", "cjt/decorators/dynamicName" ], function(angular, _, DATA_TYPE_VALIDATORS, ASCII_DATA_VALIDATORS, LOCALE) { // Retrieve the current application var app = angular.module("App"); var controller = app.controller( "configController", ["$scope", "$location", "$anchorScroll", "$routeParams", "$q", "configService", "spinnerAPI", "PAGE", function($scope, $location, $anchorScroll, $routeParams, $q, configService, spinnerAPI, PAGE) { // Setup some scope variables to defaults $scope.saveSuccess = false; $scope.saveError = false; // setup data structures for the view $scope.configs = []; // Setup the installed bit... $scope.isInstalled = PAGE.installed; /** * SecAuditEngine directive's 'Log All' option is * not recommended security wise. For this we are * re-ordered the log options in UI to make sure it shows up in the end. * @param {Array} configs * @return {Array} */ var reorderSecAuditEngineOptions = function(configs) { _.each(configs, function(cfg) { if (cfg.directive !== "SecAuditEngine") { return; } _.reverse(cfg.radio_options); return false; }); return configs; }; /** * Validate rules for the dynamic validation * @param {Any} value * @param {String} name * @param {Any} arg * @param {Result} result * @return {Boolean} */ $scope.validateField = function(value, name, arg, result) { var regex; if (!value) { result.isValid = true; return true; } var ret; switch (name) { case "path": break; case "startsWith": ret = ASCII_DATA_VALIDATORS.methods.startsWith(value, arg); if (!ret.isValid) { result.isValid = false; result.add(name, LOCALE.maketext("The value must start with the “[_1]” character.", "|")); } break; case "honeypotAccessKey": // http://www.projecthoneypot.org/httpbl_api.php // All Access Keys are 12-characters in length, lower case, and contain only alpha characters regex = /^[a-z]{12}$/; if (!regex.test(value)) { result.isValid = false; result.add(name, LOCALE.maketext("The value that you provided is not a valid [asis,honeypot] access key. This value must be a sequence of 12 lower-case alphabetic characters.")); } break; case "positiveInteger": ret = DATA_TYPE_VALIDATORS.methods.positiveInteger(value); if (!ret.isValid) { result.isValid = false; result.add(name, ret.get("positiveInteger").message); } break; default: if (window.console) { window.console.log("Unknown validation type."); } break; } return result.isValid; }; /** * Toggles the clear button and conditionally performs a search. * The expected behavior is if the user clicks the button or focuses the button and hits enter the button state rules. * If the user hits <enter> in the field, its a submit action with just request the data. * @param {Boolean} inSearch Toggle button clicked. */ $scope.toggleSearch = function(inSearch) { if ( !inSearch ) { $scope.searchPattern = ""; } }; /** * Clears the search field when the user * presses the Esc key * @param {Event} event - The event object */ $scope.clearSearch = function(event) { if (event.keyCode === 27) { $scope.searchPattern = ""; } }; /** * Fetch the list of hits from the server * @return {Promise} Promise that when fulfilled will result in the list being loaded with the new criteria. */ $scope.fetch = function() { $scope.saveSuccess = false; $scope.saveError = false; spinnerAPI.startGroup("loadingSpinner"); return configService .fetchList() .then(function(results) { $scope.configs = reorderSecAuditEngineOptions(results); spinnerAPI.stopGroup("loadingSpinner"); }, function(error) { $scope.saveError = error; spinnerAPI.stopGroup("loadingSpinner"); }); }; /** * Disable the save button based on form state * @param {FormController} form * @return {Boolean} */ $scope.disableSave = function(form) { return form.$pristine || (form.$dirty && form.$invalid); }; /** * Update the changed flag based on the event * @param {Object} setting Setting that changed. */ $scope.changed = function(setting) { setting.changed = true; }; /** * Get the field type for text fields. Either text or number. * @param {Object} setting * @return {String} text || number. */ $scope.getFieldType = function(setting) { return setting.field_type || "text"; }; /** * Construct the model name from the parts * @param {String} prefix * @param {String} id * @return {String} */ $scope.makeModelName = function(prefix, id) { return prefix + id; }; /** * Save the changes * @param {FormController} form * @return {Promise} */ $scope.save = function(form) { $scope.saveSuccess = false; $scope.saveError = false; if (!form.$valid) { return; } var promise = configService.save($scope.configs); // Since the service may not return a promise, // we check this first. if (promise) { promise.then( function(data) { $scope.saveError = false; $scope.saveSuccess = true; form.$setPristine(); var comparisonFactory = function(test) { return function(item) { return item.setting_id === test.setting_id; }; }; // Patch the defaults for items not in default state. for (var j = 0, ll = $scope.configs.length; j < ll; j++) { configService.applyDefaults($scope.configs[j]); } // Patch the state for returned items for (var i = 0, l = data.length; i < l; i++) { var config = _.find($scope.configs, comparisonFactory(data[i])); if (config) { config.state = data[i].state || data[i].default; config.missing = data[i].missing; } } }, function(error) { $scope.saveError = error ? error : LOCALE.maketext("The system experienced an unknown error when it attempted to save the file."); $scope.saveSuccess = false; } ).then(function() { $scope.scrollTo("top", true); }); return promise; } return promise; }; $scope.showLogAllWarning = function(radioOption, directive) { return (radioOption === "On" && directive === "SecAuditEngine"); }; $scope.showLogNoteworthyLabel = function(radioOption, directive) { return (radioOption === "RelevantOnly" && directive === "SecAuditEngine"); }; // check for page data in the template if this is a first load if (app.firstLoad.configs && PAGE.configs) { app.firstLoad.configs = false; $scope.configs = configService.prepareList(PAGE.configs); $scope.configs = reorderSecAuditEngineOptions($scope.configs); } else { // Otherwise, retrieve it via ajax $scope.fetch(); } } ]); return controller; } ); /* # templates/mod_security/config.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, define, PAGE */ define( 'app/config',[ "angular", "jquery", "lodash", "cjt/core", "cjt/modules", "ngRoute", "uiBootstrap" ], function(angular, $, _, CJT) { // First create the application angular.module("App", [ "cjt2.config.whm.configProvider", // This needs to load first "ngRoute", "ui.bootstrap", "cjt2.whm" ]); // Then load the application dependencies var app = require( [ "cjt/bootstrap", "cjt/util/locale", // Application Modules "cjt/views/applicationController", "app/views/commonController", "app/views/configController", "cjt/services/autoTopService", "cjt/services/whm/breadcrumbService", "cjt/services/whm/titleService" ], function(BOOTSTRAP, LOCALE) { var app = angular.module("App"); app.value("PAGE", PAGE); app.firstLoad = { configs: true, vendors: true }; // routing app.config(["$routeProvider", function($routeProvider) { // Configuration $routeProvider.when("/config", { controller: "configController", templateUrl: CJT.buildFullPath("mod_security/views/configView.ptt"), breadcrumb: LOCALE.maketext("Configure Global Directives"), title: LOCALE.maketext("Configure Global Directives"), reloadOnSearch: false, group: "config", name: "config" }); $routeProvider.otherwise({ redirectTo: function(routeParams, path, search) { return "/config?" + window.location.search; } }); } ]); app.run(["autoTopService", "breadcrumbService", "titleService", function(autoTopService, breadcrumbService, titleService) { // Setup the automatic scroll to top for view changes autoTopService.initialize(); // Setup the breadcrumbs service breadcrumbService.initialize(); // Setup the title update service titleService.initialize(); }]); BOOTSTRAP(document); }); return app; } );
| ver. 1.4 |
Github
|
.
| PHP 8.1.34 | Generation time: 0.04 |
proxy
|
phpinfo
|
Settings