📁
SKYSHELL MANAGER
PHP v8.2.31
Create
Create
Path:
root
/
home
/
thevaxnx
/
nativize.com
/
staging
/
wp-includes
/
js
/
tinymce
/
themes
/
Name
Size
Perm
Actions
📁
inlite
-
0755
🗑️
🏷️
🔒
📁
modern
-
0755
🗑️
🏷️
🔒
📄
wp-links-opml.php
6.83 KB
0444
🗑️
🏷️
⬇️
✏️
🔒
Edit: profile.js
/* # cpanel - whostmgr/docroot/templates/easyapache4/views/profile.js # Copyright 2026 WebPros International, LLC # All rights reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited */ define( [ "angular", "cjt/util/locale", "lodash", "cjt/services/alertService", "cjt/directives/alertList", "cjt/decorators/growlDecorator", "app/directives/fileModel", "app/directives/fileType", "app/directives/fileSize", "app/services/ea4Data", "app/services/ea4Util", "app/services/pkgResolution", ], function(angular, LOCALE, _) { "use strict"; // Retrieve the current application var app = angular.module("App"); app.controller("profile", [ "$scope", "$timeout", "$location", "$uibModal", "$q", "ea4Data", "ea4Util", "alertService", "growl", "growlMessages", function($scope, $timeout, $location, $uibModal, $q, ea4Data, ea4Util, alertService, growl, growlMessages) { $scope.profileList = []; $scope.activeProfile = {}; $scope.loadingProfiles = false; $scope.errorOccurred = false; $scope.noProfiles = false; $scope.upload = { show: false, profile: {}, content: {}, disableLocalSec: true, localSecIsOpen: true, disableUrlSec: false, urlSecIsOpen: false, url: { value: "", filename: "", filenameValMsg: "", showFilenameInput: false, }, overwrite: false, highlightOverwrite: false, }; $scope.convertProfile = { show: false }; var _ea4Recommendations = {}; $scope.isLoading = function() { return ( $scope.loadingProfiles || $scope.loadingProfileData ); }; var resetEA4UI = function() { // Reset wizard attributes. // TODO: This will stay here until ui.router is implemented // in the next template refactor. $scope.customize.wizard.currentStep = ""; $scope.customize.wizard.showWizard = false; alertService.clear(); // This cancels any previously customized packages. ea4Data.clearEA4LocalStorageItems(); }; var customizeProfile = function(thisProfile) { // This cancels any previously customized packages. ea4Data.clearEA4LocalStorageItems(); ea4Data.setData( { "selectedPkgs": thisProfile.pkgs, "customize": true, "ea4Recommendations": _ea4Recommendations, }); $location.path("loadPackages"); }; var goProvision = function(thisProfile) { ea4Data.setData( { "selectedProfile": thisProfile } ); $location.path("review"); }; $scope.$on("$viewContentLoaded", function() { resetEA4UI(); $scope.loadProfiles(); }); $scope.checkForEA4Updates = function() { $scope.customize.checkUpdateInfo = angular.copy(ea4Util.checkUpdateInfo); var promise = ea4Data.getPkgInfoList(); promise.then(function(data) { if (typeof data !== "undefined") { var rawPkgList = data; ea4Data.setData({ "ea4RawPkgList": rawPkgList }); var updatePkgs = _.map(_.filter(rawPkgList, ["state", "updatable"]), function(pkg) { return pkg.package; }); // Count the number of packages in updatable state. $scope.customize.checkUpdateInfo.pkgNumber = updatePkgs.length; $scope.customize.toggleUpdateButton(); } $scope.customize.checkUpdateInfo.isLoading = false; }, function(error) { alertService.add({ type: "danger", message: error, id: "alertMessages", closeable: false, }); }); }; $scope.loadProfiles = function() { $scope.profileList = []; $scope.loadingProfiles = true; var metaPromise = ea4Data.getEA4MetaInfo().then(function(response) { if (response.data) { ea4Util.cacheMetaInfo(response.data); } }).catch(function() { ea4Util.cacheMetaInfo(null); return null; }); var prefixesPromise = ea4Data.getAdditionalPkgPrefixes().then(function(prefixes) { ea4Util.cachePrefixes(prefixes || []); ea4Util.updateRegexForPrefixes(prefixes || []); }).catch(function() { ea4Util.cachePrefixes([]); ea4Util.updateRegexForPrefixes([]); return null; }); $q.all([metaPromise, prefixesPromise]).finally(function() { ea4Data.getProfiles().then(function(profData) { if (typeof profData !== "undefined") { $scope.noProfiles = false; $scope.checkForEA4Updates(); $scope.loadingProfileData = true; ea4Data.getEA4Recommendations(). then(function(result) { _ea4Recommendations = result.data; setProfileData(profData, _ea4Recommendations); }, function(error) { showProfileErrors(error); }).finally(function() { $scope.loadingProfileData = false; }); } else { $scope.noProfiles = true; } }, function(error) { if (error) { $scope.errorOccurred = true; ea4Data.setData( { "ea4ThrewError": true } ); $location.path("yumUpdate"); } }).finally(function() { $scope.loadingProfiles = false; }); }); }; $scope.viewProfile = function(thisProfile) { var viewingProfile = angular.copy(thisProfile); $uibModal.open({ templateUrl: "profileModalContent.tmpl", controller: "ModalInstanceCtrl", resolve: { data: function() { return viewingProfile; }, }, }); }; $scope.customizeCurrentProfile = function(thisProfile) { customizeProfile(thisProfile); }; $scope.proceedNext = function(thisProfile, customize) { // Track if customize button clicked or provision button clicked. $scope.clickedCustomize = customize; // Show a warning if there are packages in profile not on server. if (!thisProfile.isValid) { thisProfile.showValidationWarning = true; return; } thisProfile.showValidationWarning = false; $scope.continueAction(thisProfile); }; $scope.continueAction = function(thisProfile) { var customize = $scope.clickedCustomize; // Reset the clicked variable for next use. $scope.clickedCustomize = false; // Insert Apache 2.4 into the profile. This ensures people // get apache in whatever state their profile is. if (thisProfile.pkgs.indexOf("ea-apache24") === -1) { thisProfile.pkgs.push("ea-apache24"); } if (customize) { customizeProfile(thisProfile); } else { goProvision(thisProfile); } }; /** * Resets the clicked variable for next use. * * @method reset */ $scope.reset = function(thisProfile) { $scope.clickedCustomize = false; thisProfile.showValidationWarning = false; }; $scope.hideRecommendations = function(activeProfile) { activeProfile.showRecommendations = false; // Upon closing recommendation panel, return focus to recommendation link for screenreader/keyboard users $timeout(function() { angular.element("#toggleRecommendations").focus(); }); }; $scope.showRecommendations = function(activeProfile) { activeProfile.showRecommendations = true; // Apply focus to recommendation container for screenreader/keyboard users $timeout(function() { angular.element("#recommendations_container").focus(); }); }; var recommendationsOfActiveProfile = function(activeProfile, recommendations) { var currPkgList = activeProfile.pkgs; var filterPkgsWithRecos = _.intersection(currPkgList, _.keys(recommendations)); var filteredRecos = {}; _.each(filterPkgsWithRecos, function(pkg) { var reco = recommendations[pkg]; var recosList = ea4Util.decideShowHideRecommendations(reco, currPkgList, true, pkg); // passing 'true' as args to get recommendations of installed packages. // On the profiles page show only recommendations that have level: danger. recosList = _.filter(recosList, ["level", "danger"]); if (!_.isEmpty(recosList)) { filteredRecos[pkg] = {}; filteredRecos[pkg].recosList = recosList; filteredRecos[pkg].show = !_.every(recosList, [ "show", false ]); // Set the footnote. filteredRecos[pkg].footNote = LOCALE.maketext("These recommendations appear because you have “[_1]” installed on your system.", pkg); } }); return filteredRecos; }; /* Upload Popover section */ var resetValidators = function(formInput) { var valErrors = formInput.$error; if (typeof valErrors !== "undefined") { _.each(_.keys(valErrors), function(valKey) { $scope.formUpload.profile_file.$setValidity(valKey, true); }); } }; /** * Clears everything in the upload popover. * * @method clearUploadPopover */ var clearUploadPopover = function() { // Destroy all growls before attempting to submit something. growlMessages.destroyAllMessages(); // reseting model values var uploadData = $scope.upload; uploadData.content = {}; uploadData.overwrite = false; uploadData.highlightOverwrite = false; uploadData.disableLocalSec = true; uploadData.localSecIsOpen = true; uploadData.disableUrlSec = false; uploadData.urlSecIsOpen = false; clearUploadLocalForm($scope.upload); clearUploadUrlForm($scope.upload.url); }; /** * Clears the upload local section in Upload accordion. * * @method clearUploadLocalForm */ function clearUploadLocalForm(uploadData) { // reseting upload local section. uploadData.profile = {}; if ($scope.formUpload && $scope.formUpload.$dirty) { resetValidators($scope.formUpload.profile_file); // mark the form pristine $scope.formUpload.$setPristine(); try { angular.element("#profile_file").val(null); // for IE11, latest browsers } catch (error) { console.error("Error resetting form:", error); // For IE10 and others angular.element("#form_upload_profile").reset(); } } } /** * Clears the upload url section in Upload accordion. * * @method clearUploadUrlForm */ function clearUploadUrlForm(uploadUrlData) { // var uploadData = $scope.upload; uploadUrlData.filename = ""; uploadUrlData.filenameValMsg = ""; uploadUrlData.value = ""; uploadUrlData.showFilenameInput = false; if ($scope.formUpload && $scope.formUpload.$dirty) { var valErrors = $scope.formUpload.profile_file_url.$error; if (typeof valErrors !== "undefined") { _.each(_.keys(valErrors), function(valKey) { $scope.formUpload.profile_file.$setValidity(valKey, true); }); } resetValidators($scope.formUpload.profile_file_url); resetValidators($scope.formUpload.txtUploadUrlFilename); // mark the form pristine $scope.formUpload.$setPristine(); } } /** * Validates the profile content to * check if it contains name & at least * one package. * * @method validateProfile */ var validateProfile = function(fileContent) { var valid = true; if (_.isEmpty(fileContent.name) || _.isEmpty(fileContent.pkgs)) { valid = false; } return valid; }; /** * Validate the uploaded filename to see if it contains * restricted characters. * * @method validateFilename */ var validateFilename = function(filename) { var valid = true; if (/(?:\.\.|\\|\/)/.test(filename)) { valid = false; } return valid; }; /** * Reads the uploaded file to validate it. * * @method getAndValidateUploadData */ var getAndValidateUploadData = function() { // Destroy all growls before attempting to submit something. growlMessages.destroyAllMessages(); var fileData = $scope.upload.profile; if (!validateFilename(fileData.name)) { $scope.$apply($scope.formUpload.profile_file.$setValidity("invalidfilename", false)); return; } else { $scope.$apply($scope.formUpload.profile_file.$setValidity("invalidfilename", true)); } var reader = new FileReader(); reader.readAsText(fileData); reader.onloadend = function() { if (reader.readyState && !reader.error) { // Check if the file has the required data. var upContent = validateUploadContent(reader.result); _.each(_.keys(upContent.val_results), function(valKey) { $scope.$apply($scope.formUpload.profile_file.$setValidity(valKey, upContent.val_results[valKey])); }); if ($scope.formUpload.profile_file_url.$valid) { $scope.upload.content = upContent.content; } } }; }; /** * This validates the given content * and updates the validators accordingly. * * @method validateUploadContent */ function validateUploadContent(uploadContent) { // Check if the file has the required data. var content = ""; var valResults = {}; try { content = JSON.parse(uploadContent); valResults["invalidformat"] = true; if (!validateProfile(content)) { valResults["content"] = false; } else { valResults["content"] = true; } } catch (e) { valResults["invalidformat"] = false; console.error("Error parsing upload content:", e); } return { "content": content, "val_results": valResults }; } /** * Cancels the upload action for local section. * * @method cancelUpload */ $scope.cancelUpload = function() { $scope.upload.show = false; clearUploadPopover(); }; /** * Cancels the upload action for url section. * * @method resetUploadUrl */ $scope.resetUploadUrl = function() { clearUploadUrlForm($scope.upload.url); }; /** * Gets the content from the provided url and performs * validation checks to make sure it is a valid JSON * content with valid profile data. * * @method getAndValidateUploadDataFromURL */ $scope.getAndValidateUploadDataFromURL = function() { // Destroy all growls before attempting to submit something. growlMessages.destroyAllMessages(); return ea4Data.getUploadContentFromUrl($scope.upload.url.value) .then(function(data) { if (typeof data !== "undefined" && data.status === "200") { var contentType = data.headers["content-type"]; var validType = /^(application|text)\/json/.test(contentType); if (!validType) { $scope.formUpload.profile_file_url.$setValidity("filetype", false); return; } else { $scope.formUpload.profile_file_url.$setValidity("filetype", true); } // Check if the file has the required data. var upContent = validateUploadContent(data.content); _.each(_.keys(upContent.val_results), function(valKey) { $scope.formUpload.profile_file_url.$setValidity(valKey, upContent.val_results[valKey]); }); if ($scope.formUpload.profile_file_url.$valid) { $scope.upload.content = upContent.content; $scope.upload.url.showFilenameInput = true; } else { $scope.upload.url.showFilenameInput = false; } } else { var errorMsg = LOCALE.maketext("Status: “[output,strong,_1]”. Reason: “[output,em,_2]”.", _.escape(data.status), _.escape(data.reason)); growl.error(errorMsg); } }, function(error) { growl.error(_.escape(error)); }); }; /** * Scope method that calls ea4Util service's validateFilename method and * sets the validation message accordingly. * * @method validateFilenameInput */ $scope.validateFilenameInput = function() { var valData = ea4Util.validateFilename($scope.upload.url.filename); $scope.upload.url.filenameValMsg = valData.valMsg; $scope.formUpload.txtUploadUrlFilename.$setValidity("valFilename", valData.valid); }; /** * Uploads Profiles. * * @method uploadProfile */ $scope.uploadProfile = function() { // Destroy all growls before attempting to submit something. growlMessages.destroyAllMessages(); if ($scope.formUpload.$valid) { // upload profile var overwrite = $scope.upload.overwrite ? 1 : 0; var filenameWithExt = (typeof $scope.upload.profile.name !== "undefined") ? $scope.upload.profile.name : $scope.upload.url.filename + ".json"; return ea4Data.saveAsNewProfile($scope.upload.content, filenameWithExt, overwrite) .then(function(data) { if (typeof data !== "undefined" && !_.isEmpty(data.path)) { $scope.loadProfiles(); growl.success(LOCALE.maketext("The system successfully uploaded your profile.")); $scope.cancelUpload(); } }, function(response) { if (!_.isEmpty(response.data) && response.data.already_exists) { $scope.upload.highlightOverwrite = true; } growl.error(_.escape(response.error)); }); } }; /** * This toggle function handles enabling/disabling sections * so that at least one upload section is always open. * * @method handleAccordionToggle */ $scope.handleAccordionToggle = function() { clearUploadLocalForm($scope.upload); clearUploadUrlForm($scope.upload.url); if ($scope.upload.urlSecIsOpen) { $scope.upload.disableLocalSec = false; $scope.upload.disableUrlSec = true; } else { $scope.upload.disableUrlSec = false; $scope.upload.disableLocalSec = true; } }; /** * Shows the given popover with their initialization logic. * * @method showPopover */ $scope.showPopover = function(popoverName) { $scope.convertProfile.cancel(); switch (popoverName) { case "upload": $scope.upload.show = true; document.querySelector("#profile_file").onchange = getAndValidateUploadData; var accordionLinkEls = document.querySelectorAll(".panel-heading a"); _.each(accordionLinkEls, function(el) { el.onclick = $scope.handleAccordionToggle; }); break; case "convert": $scope.convertProfile.show = true; break; } }; /** * This method sets all the profile data including recommendations. * * @method setProfileData */ function setProfileData(data, recommendations) { var profileTypes = _.sortBy(_.keys(data)); _.each(profileTypes, function(type) { if (typeof data[type] !== "undefined") { _.each(data[type], function(profile) { profile.profileType = type; // Custom profile also handles tags like ActiveProfile for currently installed packages if (type === "custom") { var profileTags = ea4Util.createTagsForActiveProfile(profile.pkgs); profile.tags = profileTags; profile.tagsAsString = LOCALE.list_and(profileTags); } else { profile.tagsAsString = LOCALE.list_and(profile.tags); } // Initialize with a valid flag. profile.isValid = true; profile.showValidationWarning = false; if (!profile.active) { // Active profile is shown separately. profile.isValid = _.isEmpty(profile.validation_data.not_on_server); if (!profile.isValid) { profile.validation_data.not_on_server_without_prefix = ea4Util.getFormattedPackageList(profile.validation_data.not_on_server); } profile.id = type + "_" + profile.path.replace(/\.json/, ""); // If the type is other than cPanel Or Custom, it should be a vendor in which case the // path changes a bit. var pathByType = ( type !== "cpanel" && type !== "custom" ) ? "vendor/" + type : type; profile.downloadUrl = "ea4_profile_download/" + pathByType + "?filename=" + profile.path; $scope.profileList.push(profile); } else { $scope.activeProfile = profile; // need active profile packages in customize scope so can run packages updates $scope.customize.activeProfilePkgs = profile.pkgs; var recos = recommendationsOfActiveProfile($scope.activeProfile, recommendations); if (!_.isEmpty(_.keys(recos))) { $scope.activeProfile.showRecommendations = false; var actualRecos = _.pickBy(recos, function(value, key) { return recos[key].show; }); var recoCnt = 0; _.each(_.keys(actualRecos), function(key) { recoCnt += _.filter(actualRecos[key].recosList, ["show", true]).length; } ); $scope.activeProfile.recommendations = actualRecos; $scope.activeProfile.recommendationLabel = LOCALE.maketext("[quant,_1,Recommendation,Recommendations]", recoCnt); $scope.activeProfile.recommendationsExist = recoCnt ? true : false; } else { $scope.activeProfile.recommendations = {}; } } }); } }); // Check if there are any profiles. $scope.noProfiles = ($scope.profileList.length <= 0); // Active Profile. At present active profile will always be 'Currently Installed Packages' // This may change in future. // TODO: Add this method to ea4Util var tags = ea4Util.createTagsForActiveProfile($scope.activeProfile.pkgs); $scope.activeProfile.tags = tags; $scope.activeProfile.tagsAsString = LOCALE.list_and(tags); } /** * Error handling method for profile load failures. * * @method showProfileErrors */ function showProfileErrors(error) { $scope.errorOccurred = true; alertService.add({ type: "danger", message: error, id: "alertMessages", closeable: false, }); } }, ] ); app.controller("ModalInstanceCtrl", ["$scope", "$uibModalInstance", "data", "ea4Util", function($scope, $uibModalInstance, data, ea4Util) { $scope.modalData = {}; var profileInfo = data; profileInfo.pkgs = ea4Util.getProfilePackagesByCategories(profileInfo.pkgs); $scope.modalData = profileInfo; $scope.closeModal = function() { $uibModalInstance.close(); }; }, ] ); } );
Save