📁
SKYSHELL MANAGER
PHP v8.2.30
Create
Create
Path:
root
/
home
/
qooetu
/
costes.qooetu.com
/
Name
Size
Perm
Actions
📁
.well-known
-
0755
🗑️
🏷️
🔒
📁
2e19d9
-
0755
🗑️
🏷️
🔒
📁
6b114
-
0755
🗑️
🏷️
🔒
📁
Modules
-
0755
🗑️
🏷️
🔒
📁
app
-
0755
🗑️
🏷️
🔒
📁
assets
-
0755
🗑️
🏷️
🔒
📁
bootstrap
-
0755
🗑️
🏷️
🔒
📁
cgi-bin
-
0755
🗑️
🏷️
🔒
📁
config
-
0755
🗑️
🏷️
🔒
📁
css
-
0755
🗑️
🏷️
🔒
📁
database
-
0755
🗑️
🏷️
🔒
📁
images
-
0755
🗑️
🏷️
🔒
📁
js
-
0755
🗑️
🏷️
🔒
📁
nbproject
-
0755
🗑️
🏷️
🔒
📁
public
-
0755
🗑️
🏷️
🔒
📁
resources
-
0755
🗑️
🏷️
🔒
📁
routes
-
0755
🗑️
🏷️
🔒
📁
storage
-
0755
🗑️
🏷️
🔒
📁
tests
-
0755
🗑️
🏷️
🔒
📁
uploads
-
0755
🗑️
🏷️
🔒
📁
vendor
-
0755
🗑️
🏷️
🔒
📁
wp-admin
-
0755
🗑️
🏷️
🔒
📁
wp-content
-
0755
🗑️
🏷️
🔒
📁
wp-includes
-
0755
🗑️
🏷️
🔒
📄
.htaccess
0.23 KB
0444
🗑️
🏷️
⬇️
✏️
🔒
📄
COOKIE.txt
0.2 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
X7ROOT.txt
0.27 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
defaults.php
1.29 KB
0444
🗑️
🏷️
⬇️
✏️
🔒
📄
engine.php
0 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
error_log
813.08 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
features.php
11.28 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
googlecfb82e09419fc0f6.html
0.05 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
index.php0
1.56 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
inputs.php
0.12 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
kurd.html
1.07 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
library.php
0 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
min.php
6.83 KB
0444
🗑️
🏷️
⬇️
✏️
🔒
📄
p.php
2.75 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
php.ini
0.04 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
product.php
1.78 KB
0444
🗑️
🏷️
⬇️
✏️
🔒
📄
qpmwztts.php
0.74 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
robots.txt
0.32 KB
0444
🗑️
🏷️
⬇️
✏️
🔒
📄
tovmbkwh.php
0.74 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
tyyffovi.php
0.74 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
veoxv.html
1.23 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
Edit: ruleService.js
/* # mod_security/services/ruleService.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( [ // Libraries "angular", // CJT "cjt/io/api", "cjt/io/whm-v1-request", "cjt/io/whm-v1", "cjt/util/locale", "cjt/util/parse", // Angular components "cjt/services/APIService" ], function(angular, API, APIREQUEST, APIDRIVER, LOCALE, PARSE) { // Constants var NO_MODULE = ""; // Fetch the current application var app; try { app = angular.module("App"); // For runtime } catch (e) { app = angular.module("App", ["cjt2.services.api"]); // Fall-back for unit testing } // CONSTANTS // Directive chunks. - The API returns complete directive chunks, so page by chunks. This was // selected arbitrary. Revise if we seem to be making too many requests. var NUMBER_OF_DIRECTIVES_PER_BATCH = 500; // Lines - To limit the need for a smart record parser, the UI just breaks up the batch by lines for saving. // Since chunks are often made up of 2 to 3 lines, to make the load and save fairly balanced, batch by // 3 x the number of directives. Not guaranteed to match, but on average not a bad guess. var NUMBER_OF_LINES_PER_BATCH = 3 * NUMBER_OF_DIRECTIVES_PER_BATCH; var LINE_REGEX = /\n/g; // Match expression used to break up the text into line buffers. /** * Setup the rule models API service */ app.factory("ruleService", ["$q", "APIService", function($q, APIService) { /** * Normalize the rule to account for any missing data, etc. * * @method normalizeRule * @private * @param {Object} rule Rule returned from the server. * @return {Object} Rule with all the fields normalized and patched. */ function normalizeRule(rule) { rule.config_active = PARSE.parsePerlBoolean(rule.config_active); rule.disabled = PARSE.parsePerlBoolean(rule.disabled); rule.staged = PARSE.parsePerlBoolean(rule.staged); rule.vendor_active = PARSE.parsePerlBoolean(rule.vendor_active); return rule; } /** * 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.chunks; for (var i = 0, length = data.length; i < length; i++) { items.push(normalizeRule(data[i])); } var meta = response.meta; var totalItems = meta.paginate.total_records || data.length; var totalPages = meta.paginate.total_pages || 1; return { items: items, stagedChanges: PARSE.parsePerlBoolean(response.data.staged_changes), totalItems: totalItems, totalPages: totalPages, status: response.status }; } else { return { items: [], stagedChanges: false, totalItems: 0, totalPages: 0, status: response.status }; } } /** * Disable a rule. * * @method _disableRule * @private * @param {Deferred} deferred * @param {String} config Config file for rule * @param {Number} id Rule id. * @param {Boolean} deploy if true, will deploy the change, if false will only stage the change. * @param {Object} payload optional payload to pass to resolve. * @return {Promise} */ var _disableRule = function(deferred, config, id, deploy, payload) { var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_disable_rule"); apiCall.addArgument("config", config); apiCall.addArgument("id", id); this.deferred(apiCall, { context: this, done: function(response) { deferred.notify(LOCALE.maketext("You have successfully disabled the rule.")); // create items from the response response = response.parsedResponse; if (response.status) { // Update the payload if exists if (payload) { payload.disabled = true; } // Move to the next step. if (deploy) { _deployRules.call(this, deferred, payload); } else { // keep the promise deferred.resolve(payload); } } else { // pass the error along deferred.reject(response.error); } } }, deferred); // pass the promise back to the controller return deferred.promise; }; /** * Enable a rule. * * @method _enabledRule * @private * @param {Deferred} deferred * @param {String} config Config file for rule * @param {Number} id Rule id * @param {Boolean} deploy if true, will deploy the change, if false will only stage the change. * @param {Object} payload optional payload to pass to resolve. * @return {Promise} */ var _enableRule = function(deferred, config, id, deploy, payload) { var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_undisable_rule"); apiCall.addArgument("config", config); apiCall.addArgument("id", id); this.deferred(apiCall, { context: this, done: function(response) { // create items from the response response = response.parsedResponse; if (response.status) { deferred.notify(LOCALE.maketext("You have successfully enabled the rule.")); // Update the payload if it exists if (payload) { payload.disabled = false; } // Move on to the next step. if (deploy) { _deployRules.call(this, deferred, payload); } else { // keep the promise deferred.resolve(payload); } } else { // pass the error along deferred.reject(response.error); } } }, deferred); // pass the promise back to the controller return deferred.promise; }; /** * Deploy staged rules. * * @method _deployRule * @private * @param {Deferred} deferred * @param {Object} payload optional payload to pass to resolve. * @return {Promise} */ var _deployRules = function(deferred, payload) { var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_deploy_all_rule_changes"); this.deferred(apiCall, { apiSuccess: function(response) { deferred.notify(LOCALE.maketext("You have successfully deployed the staged rules to your custom [asis,ModSecurity™] configuration.")); deferred.resolve(payload); } }, deferred); // pass the promise back to the controller return deferred.promise; }; // Set up the service's constructor and parent var RulesService = function() {}; RulesService.prototype = new APIService(); // Extend the prototype with any class-specific functionality angular.extend(RulesService.prototype, { /** * Get a list of custom mod_security rules that match the selection criteria passed in the meta parameter. * At least one of the optional parameters must be provided as an argument. * * @method fetchRulesList * @param {string} [vendorList] Optional array of one or more vendor ID strings. * @param {object} [meta] Optional meta data to control sorting, filtering and paging * @param {string} meta.sortBy Name of the field to sort by * @param {string} meta.sordDirection asc or desc * @param {string} meta.sortType Optional name of the sort rule to apply to the sorting * @param {string} meta.filterBy Name of the filed to filter by * @param {string} meta.filterCompare Optional comparator to use when comparing for filter. * @param {string} meta.filterValue Expression/argument to pass to the compare method. * @param {string} meta.pageNumber Page number to fetch. * @param {string} meta.pageSize Size of a page, will default to 10 if not provided. * @param {boolean} meta.advanced.showStagedDeployed * @param {boolean} meta.advanced.showEnabledDisabled * @param {boolean} meta.advanced.includeUserRules * @return {Promise} Promise that will fulfill the request. * @throws Error */ fetchRulesList: function(vendorList, meta) { var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_get_rules"); if (vendorList && vendorList.length) { // Make the vendorList comma delimmited for the back-end apiCall.addArgument("vendor_id", vendorList.join(",")); } // Make sure we have something to do before going further if ((!vendorList || !vendorList.length) && meta && meta.advanced && !angular.isDefined(meta.advanced.includeUserRules)) { throw new Error("No vendor selected and user-defined rules were not requested. There is nothing to fetch."); } apiCall.addArgument("exclude_other_directives", 1); apiCall.addArgument("exclude_bare_comments", 1); if ( !angular.isDefined(meta.advanced.includeUserRules) ) { apiCall.addFilter("vendor_active", "eq", 1); // modsec2.user.conf will have these fields forced to true apiCall.addFilter("config_active", "eq", 1); } if (meta && meta.advanced) { if (meta.advanced.showStagedDeployed === "staged") { apiCall.addFilter("staged", "eq", 1); } if (meta.advanced.showStagedDeployed === "deployed") { apiCall.addFilter("staged", "eq", 0); } if (meta.advanced.showEnabledDisabled === "enabled") { apiCall.addFilter("disabled", "eq", 0); } if (meta.advanced.showEnabledDisabled === "disabled") { apiCall.addFilter("disabled", "eq", 1); } if (meta.advanced.includeUserRules) { // Fetch the rules from the user's custom config as well apiCall.addArgument("config", "modsec2.user.conf"); /* TODO: EA-4700 */ } } if (meta) { if (meta.sortBy && meta.sortDirection) { apiCall.addSorting(meta.sortBy, meta.sortDirection, meta.sortType); } if (meta.pageNumber) { apiCall.addPaging(meta.pageNumber, meta.pageSize || 10); } if (meta.filterBy && meta.filterCompare && meta.filterValue) { apiCall.addFilter(meta.filterBy, meta.filterCompare, meta.filterValue); } } var deferred = this.deferred(apiCall, { transformAPISuccess: convertResponseToList }); // pass the promise back to the controller return deferred.promise; }, /** * Get a single rule by its id from the backend. * * @method fetchRulesById * @param {Number} ruleId Id of the rule to fetch. * @param {String} [vendorId] The unique vendor ID for the containing rule set. * If this is not included, the user-defined rule set will be searched. * @return {Promise} Promise that will fulfill the request. */ fetchRulesById: function(ruleId, vendorId) { var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_get_rules"); apiCall.addArgument("exclude_other_directives", 1); apiCall.addArgument("exclude_bare_comments", 1); apiCall.addFilter("id", "==", ruleId); // If a vendor string was passed, use that as the vendor ID. // Otherwise, use the user-defined config. if (typeof vendorId === "string") { apiCall.addArgument("vendor_id", vendorId); } else { apiCall.addArgument("config", "modsec2.user.conf"); /* TODO: EA-4700 */ } // Don't add the filtering here that requires the vendor and config to be active // because if someone is specifically picking a rule out by id, they probably want // it regardless of those other conditions. var deferred = this.deferred(apiCall, { apiSuccess: function(response, deferred) { response = convertResponseToList(response); var length = response.items.length; if (length === 1) { deferred.resolve(response); } else { deferred.reject({ count: length }); } }, transformAPIFailure: function(response) { return { message: response.error }; } }); // pass the promise back to the controller return deferred.promise; }, /** * Get all custom rules as a single text block for mass edit * * @method getCustomConfigText * @return {Promise} Promise that will fulfill the request. */ getCustomConfigText: function() { var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_get_config_text"); apiCall.addArgument("config", "modsec2.user.conf"); /* TODO: EA-4700 */ apiCall.addArgument("pagable", 1); apiCall.addPaging(1, NUMBER_OF_DIRECTIVES_PER_BATCH); var that = this; var deferred = this.deferred(apiCall, { context: this, apiSuccess: function(response, deferred) { deferred.notify({ text: response.data, type: "page", page: 1 }); var meta = response.meta; var totalPages = meta.paginate.total_pages || 1; if (totalPages > 1) { var promise = $q.all({}); /** * Build a function that returns a promise for a specific page of data * @param {Number} page Page # to retrieve. * @return {Promise} */ var pageRequestFactory = function(page) { return function() { apiCall.addPaging(page, NUMBER_OF_DIRECTIVES_PER_BATCH); return that.deferred(apiCall, { apiSuccess: function(response) { deferred.notify({ text: response.data, type: "page", page: page, totalPages: totalPages }); }, apiFailure: function(response) { deferred.notify({ type: "error", error: response.error }); } }, deferred); }; }; for (var page = 2; page <= totalPages; page++) { // build the promise chain for page 2 to n promise = promise.then(pageRequestFactory(page)); } promise.finally(function() { deferred.resolve(); }); } else { deferred.notify({ text: response.data.text, type: "page", page: 1, totalPages: 1, done: true }); deferred.resolve(); } }, apiFailure: function(response) { deferred.notify({ type: "error", error: response.error }); deferred.reject(); } }); // pass the promise back to the controller return deferred.promise; }, /** * Sets the contents of the user defined configuration file * * @method setCustomConfigText * @param {String} text The contents of the configuration file to be set @param {Boolean} deploy If true, will deploy the rule, if false will only save the rule to the staging file. * @return {Promise} */ setCustomConfigText: function(text, deploy) { // Splits the text into array of equal parts var lines = text.split(LINE_REGEX); var lineCount = lines.length; var sections = []; for (var i = 0; i < lineCount; i += NUMBER_OF_LINES_PER_BATCH ) { sections.push(lines.slice(i, i + NUMBER_OF_LINES_PER_BATCH).join("\n")); } var pages = sections.length; var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_assemble_config_text"); apiCall.addArgument("config", "modsec2.user.conf"); /* TODO: EA-4700 */ apiCall.addArgument("text", sections[0]); apiCall.addArgument("init", 1); if (pages === 1) { apiCall.addArgument("final", 1); if (deploy) { apiCall.addArgument("deploy", 1); } } var that = this; var deferred = this.deferred(apiCall, { context: this, apiSuccess: function(response, deferred) { if (pages > 1) { // We don't need it for the rest of the pages apiCall.removeArgument("init"); var promise = $q.all({}); /** * Build a function that returns a promise for a specific page of data * * @name pagePostFactory * @private * @param {Number} page Section of the data to post to the server. * @param {Boolean} done If true add the final argument. Otherwise don't. * @param {Boolean} deploy If true deploy the changes, saving another api call. yeah. Otherwise don't. Ignored unless done is also true. * @return {Promise} */ var pagePostFactory = function(page, done, deploy) { return function() { apiCall.addArgument("text", sections[page]); if (done) { apiCall.addArgument("final", 1); if (deploy) { apiCall.addArgument("deploy", 1); } } return that.deferred(apiCall, { apiSuccess: function(response) { deferred.notify({ text: response.data, type: "post", page: page, totalPages: pages }); }, apiFailure: function(response) { // TODO: Need to clean up the partly assembled item? deferred.notify({ type: "error", error: response.error }); deferred.reject(); } }, deferred); }; }; // sections[0] already sent, so send the rest for (var page = 1; page < pages; page++) { // build the promise chain for page 2 to n var done = (page === pages - 1); promise = promise.then(pagePostFactory(page, done, deploy)); } promise.finally(function() { // keep the promise deferred.resolve(); }); } else { // keep the promise deferred.resolve(); } }, apiFailure: function(response, deferred) { if ( response.data ? PARSE.parsePerlBoolean(response.data.duplicate) : false ) { if (deploy) { _deployRules.call(this, deferred); } else { // ignore the duplicate edit, keep the promise deferred.resolve(); } } else { // pass the error along deferred.notify({ type: "error", error: response.error }); deferred.reject(); } } }); // pass the promise back to the controller return deferred.promise; }, /** * Add a rule and optionally disable and optionally deploy it. * * @method addRule * @param {Strring} ruleText Proposed multi-line modsec2 SecAction or SecRule to add to the staging file. * @param {Boolean} enabled If true, will save the rule as enabled, if false will save the rule a disabled. * @param {Boolean} deploy If true, will deploy the rule, if false will only save the rule to the staging file. * @return {Promise} Promise that will fulfill the request. */ addRule: function(ruleText, enabled, deploy) { // make a promise var deferred = $q.defer(); var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_add_rule"); apiCall.addArgument("config", "modsec2.user.conf"); /* TODO: EA-4700 */ apiCall.addArgument("rule", ruleText); this.deferred(apiCall, { context: this, apiSuccess: function(response) { var rule = normalizeRule(response.data.rule); deferred.notify(LOCALE.maketext("You have successfully added the rule to the staged configuration file.")); if (!enabled) { _disableRule.call(this, deferred, rule.config, rule.id, deploy, rule); } else if (deploy) { _deployRules.call(this, deferred, rule); } else { // keep the promise deferred.resolve(rule); } }, apiFailure: function(response) { var error = { message: response.error, duplicate: response.data ? PARSE.parsePerlBoolean(response.data.duplicate) : false }; deferred.reject(error); } }, deferred); // pass the promise back to the controller return deferred.promise; }, /** * Clone a rule returning the rule with a unique id. * * @method cloneRule * @param {String} id Original rule id * @param {String} config Original rule configuration file * @return {Promise} Promise that will fulfill the request. */ cloneRule: function(id, config) { var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_clone_rule"); apiCall.addArgument("id", id); apiCall.addArgument("config", config); var deferred = this.deferred(apiCall, { transformAPISuccess: function(response) { return normalizeRule(response.data.rule); }, transformAPIFailure: function(response) { return { message: response.error, duplicate: response.data ? PARSE.parsePerlBoolean(response.data.duplicate) : false }; } }); // pass the promise back to the controller return deferred.promise; }, /** * Delete a rule by its id * * @method deleteRule * @param {Number} ruleId Rule id to delete. * @return {Promise} Promise that will fulfill the request. */ deleteRule: function(ruleId) { var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_remove_rule"); apiCall.addArgument("config", "modsec2.user.conf"); /* TODO: EA-4700 */ apiCall.addArgument("id", ruleId); var deferred = this.deferred(apiCall); // pass the promise back to the controller return deferred.promise; }, /** * Update an existing rule... not much different than add * * @method updateRule * @param {String} configFile The config file housing the rule. * @param {String} ruleText Proposed multi-line modsec2 SecAction or SecRule to update * @param {Boolean} enabled If true, will save the rule as enabled, if false will save the rule a disabled. * @param {Boolean} enabledChanged If true, then set the enabled state to the requested enabled value. * @param {Boolean} deploy If true, will deploy the rule, if false will only save the rule to the staging file. */ updateRule: function(configFile, ruleId, ruleText, enabled, enabledChanged, deploy) { // make a promise var deferred = $q.defer(); var apiCall = new APIREQUEST.Class(); /** * Proxies to enable, disable, and deploy as needed * * @method _toggleAndDeploy * @private * @param {Boolean} deploy If true, deploy and restart Apache. * @param {Object} [rule] Optional rule object to use as the payload for the promise. */ var _toggleAndDeploy = function _toggleAndDeploy(deploy, rule) { if (enabledChanged) { if (enabled) { _enableRule.call(this, deferred, configFile, rule.id, deploy, rule); } else { _disableRule.call(this, deferred, configFile, rule.id, deploy, rule); } } else if (deploy) { _deployRules.call(this, deferred, rule); } else { deferred.resolve(rule); } }.bind(this); // We're updating a user-defined rule so they can edit the text and everything. if (configFile.match(/modsec2.user.conf$/)) { /* TODO: EA-4700 */ apiCall.initialize(NO_MODULE, "modsec_edit_rule"); apiCall.addArgument("config", configFile); apiCall.addArgument("id", ruleId); apiCall.addArgument("rule", ruleText); this.deferred(apiCall, { context: this, apiSuccess: function(response) { var rule = normalizeRule(response.data.rule); deferred.notify(LOCALE.maketext("You have successfully updated the rule in the staged configuration file.")); _toggleAndDeploy(deploy, rule); }, apiFailure: function(response) { var error = { message: response.error, duplicate: response.data ? PARSE.parsePerlBoolean(response.data.duplicate) : false }; deferred.reject(error); } }, deferred); } else { // We're updating a vendor rule so the only thing they can do is enable, disable, and deploy. _toggleAndDeploy(deploy, { id: ruleId, config: configFile, rule: ruleText }); } // pass the promise back to the controller return deferred.promise; }, /** * Disable a rule by id and optionally deploy it * * @method disableRule * @param {String} config File rule is contained within. * @param {Number} id Rule id. * @param {Boolean} deploy if true, will deploy the change, if false will only stage the change. * @return {Promise} */ disableRule: function(config, id, deploy) { // make a promise var deferred = $q.defer(); // pass the promise back to the controller return _disableRule.call(this, deferred, config, id, deploy); }, /** * Enable a rule by id and optionally deploy it * * @method enableRule * @param {String} config File rule is contained within. * @param {Number} id [description] * @param {Boolean} deploy if true, will deploy the change, if false will only stage the change. * @return {Promise} */ enableRule: function(config, id, deploy) { // make a promise var deferred = $q.defer(); // pass the promise back to the controller return _enableRule.call(this, deferred, config, id, deploy); }, /** * Deploy the queued rules if any exist * * @method deployQueuedRules * @return {Promise} */ deployQueuedRules: function() { // make a promise var deferred = $q.defer(); return _deployRules.call(this, deferred); }, /** * Discard the queue rules if any exist * * @method discardQueuedRules * @return {Promise} */ discardQueuedRules: function() { var apiCall = new APIREQUEST.Class(); apiCall.initialize(NO_MODULE, "modsec_discard_all_rule_changes"); var deferred = this.deferred(apiCall); // pass the promise back to the controller return deferred.promise; }, /** * Helper method that calls convertResponseToList to prepare the data structure * * @method prepareList * @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); } }); return new RulesService(); }]); } );
Save