diff --git a/deploy-createuser-fix.sh b/deploy-createuser-fix.sh
new file mode 100755
index 000000000..a4bcc4fe7
--- /dev/null
+++ b/deploy-createuser-fix.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# Deploy Create User page fix (userCreationFailed / "Unknown error" on load)
+# Run this on the CyberPanel server (e.g. after pulling repo or copying fixed files)
+# Usage: sudo bash deploy-createuser-fix.sh
+
+set -e
+
+CYBERCP_ROOT="${CYBERCP_ROOT:-/usr/local/CyberCP}"
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PYTHON="${CYBERCP_ROOT}/bin/python"
+if [ ! -x "$PYTHON" ]; then
+ PYTHON="python3"
+fi
+
+echo "[$(date +%Y-%m-%d\ %H:%M:%S)] Deploying Create User fix..."
+
+# If running from repo (this workspace), copy fixed JS into CyberCP
+if [ -f "$SCRIPT_DIR/userManagment/static/userManagment/userManagment.js" ]; then
+ echo " Copying userManagment.js from repo app static..."
+ mkdir -p "$CYBERCP_ROOT/userManagment/static/userManagment"
+ cp -f "$SCRIPT_DIR/userManagment/static/userManagment/userManagment.js" \
+ "$CYBERCP_ROOT/userManagment/static/userManagment/userManagment.js"
+fi
+if [ -f "$SCRIPT_DIR/static/userManagment/userManagment.js" ]; then
+ echo " Copying userManagment.js from repo static..."
+ mkdir -p "$CYBERCP_ROOT/static/userManagment"
+ cp -f "$SCRIPT_DIR/static/userManagment/userManagment.js" \
+ "$CYBERCP_ROOT/static/userManagment/userManagment.js"
+fi
+if [ -f "$SCRIPT_DIR/public/static/userManagment/userManagment.js" ]; then
+ echo " Copying userManagment.js from repo public/static..."
+ mkdir -p "$CYBERCP_ROOT/public/static/userManagment"
+ cp -f "$SCRIPT_DIR/public/static/userManagment/userManagment.js" \
+ "$CYBERCP_ROOT/public/static/userManagment/userManagment.js"
+fi
+
+# Run collectstatic so served static gets the fix
+if [ -f "$CYBERCP_ROOT/manage.py" ]; then
+ echo " Running collectstatic..."
+ cd "$CYBERCP_ROOT"
+ "$PYTHON" manage.py collectstatic --noinput --clear 2>&1 | tail -5
+ echo " collectstatic done."
+else
+ echo " No $CYBERCP_ROOT/manage.py found; skipping collectstatic."
+fi
+
+echo "[$(date +%Y-%m-%d\ %H:%M:%S)] Create User fix deployed. Hard-refresh browser (Ctrl+F5) on the Create User page."
diff --git a/public/static/userManagment/userManagment.js b/public/static/userManagment/userManagment.js
index f706d487f..0f0b677af 100644
--- a/public/static/userManagment/userManagment.js
+++ b/public/static/userManagment/userManagment.js
@@ -9,7 +9,7 @@ app.controller('createUserCtr', function ($scope, $http) {
$scope.acctsLimit = true;
$scope.webLimits = true;
$scope.userCreated = true;
- $scope.userCreationFailed = true;
+ $scope.userCreationFailed = false; // false = don't show error alert on load
$scope.couldNotConnect = true;
$scope.userCreationLoading = true;
$scope.combinedLength = true;
@@ -18,7 +18,7 @@ app.controller('createUserCtr', function ($scope, $http) {
$scope.webLimits = false;
$scope.userCreated = true;
- $scope.userCreationFailed = true;
+ $scope.userCreationFailed = false; // hide error until we know the result
$scope.couldNotConnect = true;
$scope.userCreationLoading = false;
$scope.combinedLength = true;
@@ -61,7 +61,7 @@ app.controller('createUserCtr', function ($scope, $http) {
if (response.data.createStatus == 1) {
$scope.userCreated = false;
- $scope.userCreationFailed = true;
+ $scope.userCreationFailed = false; // hide error on success
$scope.couldNotConnect = true;
$scope.userCreationLoading = true;
@@ -73,11 +73,11 @@ app.controller('createUserCtr', function ($scope, $http) {
$scope.acctsLimit = false;
$scope.webLimits = false;
$scope.userCreated = true;
- $scope.userCreationFailed = false;
+ $scope.userCreationFailed = true; // show error on failure
$scope.couldNotConnect = true;
$scope.userCreationLoading = true;
- $scope.errorMessage = response.data.error_message;
+ $scope.errorMessage = (response.data && (response.data.error_message || response.data.message || response.data.errorMessage)) || 'Unknown error';
}
@@ -90,7 +90,7 @@ app.controller('createUserCtr', function ($scope, $http) {
$scope.acctsLimit = false;
$scope.webLimits = false;
$scope.userCreated = true;
- $scope.userCreationFailed = true;
+ $scope.userCreationFailed = false; // show "Could not connect" instead
$scope.couldNotConnect = false;
$scope.userCreationLoading = true;
@@ -138,10 +138,10 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.acctDetailsFetched = true;
$scope.userAccountsLimit = true;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // false = don't show error alert on load
$scope.couldNotConnect = true;
- $scope.canotFetchDetails = true;
- $scope.detailsFetched = true;
+ $scope.canotFetchDetails = false; // false = don't show fetch error on load
+ $scope.detailsFetched = false; // false = don't show "details loaded" on load
$scope.accountTypeView = true;
$scope.websitesLimit = true;
$scope.qrHidden = true;
@@ -200,9 +200,9 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.userModificationLoading = true;
$scope.acctDetailsFetched = false;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error (we only fetched details)
$scope.couldNotConnect = true;
- $scope.canotFetchDetails = true;
+ $scope.canotFetchDetails = false; // hide fetch error on success
$scope.detailsFetched = false;
$scope.userAccountsLimit = true;
$scope.websitesLimit = true;
@@ -212,13 +212,13 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.acctDetailsFetched = true;
$scope.userAccountsLimit = true;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error (only fetch failed)
$scope.couldNotConnect = true;
- $scope.canotFetchDetails = false;
- $scope.detailsFetched = true;
+ $scope.canotFetchDetails = true; // show fetch error
+ $scope.detailsFetched = false;
- $scope.errorMessage = response.data.error_message;
+ $scope.errorMessage = (response.data && (response.data.error_message || response.data.message || response.data.errorMessage)) || 'Unknown error';
}
@@ -232,7 +232,7 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.acctDetailsFetched = true;
$scope.userAccountsLimit = true;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error (only connection/fetch failed)
$scope.couldNotConnect = false;
$scope.canotFetchDetails = true;
$scope.detailsFetched = true;
@@ -249,7 +249,7 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.userModificationLoading = false;
$scope.acctDetailsFetched = false;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide error until we know result
$scope.couldNotConnect = true;
$scope.canotFetchDetails = true;
$scope.detailsFetched = true;
@@ -295,7 +295,7 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.userModificationLoading = true;
$scope.acctDetailsFetched = true;
$scope.userModified = false;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error on success
$scope.couldNotConnect = true;
$scope.canotFetchDetails = true;
$scope.detailsFetched = true;
@@ -312,13 +312,13 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.userModificationLoading = true;
$scope.acctDetailsFetched = false;
$scope.userModified = true;
- $scope.canotModifyUser = false;
+ $scope.canotModifyUser = true; // show modify error
$scope.couldNotConnect = true;
$scope.canotFetchDetails = true;
$scope.detailsFetched = true;
- $scope.errorMessage = response.data.error_message;
+ $scope.errorMessage = (response.data && (response.data.error_message || response.data.message || response.data.errorMessage)) || 'Unknown error';
}
@@ -1489,6 +1489,42 @@ app.controller('apiAccessCTRL', function ($scope, $http) {
/* Java script code to list table users */
+/* Show modal by id - works with Bootstrap 3 (jQuery) or Bootstrap 5 (native) */
+function showModalById(modalId) {
+ var el = document.getElementById(modalId);
+ if (!el) return;
+ if (typeof jQuery !== 'undefined' && jQuery(el).modal) {
+ jQuery(el).modal('show');
+ } else if (typeof bootstrap !== 'undefined' && bootstrap.Modal) {
+ var m = bootstrap.Modal.getOrCreateInstance(el);
+ if (m) m.show();
+ } else {
+ el.style.display = 'block';
+ el.classList.add('in');
+ if (el.getAttribute('aria-hidden') !== null) el.setAttribute('aria-hidden', 'false');
+ var backdrop = document.createElement('div');
+ backdrop.className = 'modal-backdrop fade in';
+ backdrop.setAttribute('data-modal-backdrop', modalId);
+ document.body.appendChild(backdrop);
+ }
+}
+
+function hideModalById(modalId) {
+ var el = document.getElementById(modalId);
+ if (!el) return;
+ if (typeof jQuery !== 'undefined' && jQuery(el).modal) {
+ jQuery(el).modal('hide');
+ } else if (typeof bootstrap !== 'undefined' && bootstrap.Modal) {
+ var m = bootstrap.Modal.getInstance(el);
+ if (m) m.hide();
+ } else {
+ el.style.display = 'none';
+ el.classList.remove('in');
+ if (el.getAttribute('aria-hidden') !== null) el.setAttribute('aria-hidden', 'true');
+ var backdrops = document.querySelectorAll('[data-modal-backdrop="' + modalId + '"]');
+ backdrops.forEach(function (b) { if (b.parentNode) b.parentNode.removeChild(b); });
+ }
+}
app.controller('listTableUsers', function ($scope, $http) {
@@ -1552,6 +1588,7 @@ app.controller('listTableUsers', function ($scope, $http) {
$scope.deleteUserInitial = function (name){
UserToDelete = name;
$scope.UserToDelete = name;
+ showModalById('deleteModal');
};
$scope.deleteUserFinal = function () {
@@ -1576,6 +1613,7 @@ app.controller('listTableUsers', function ($scope, $http) {
$scope.cyberpanelLoading = true;
if (response.data.deleteStatus === 1) {
$scope.populateCurrentRecords();
+ hideModalById('deleteModal');
new PNotify({
title: 'Success!',
text: 'Users successfully deleted!',
@@ -1613,6 +1651,7 @@ app.controller('listTableUsers', function ($scope, $http) {
$scope.editInitial = function (name) {
$scope.name = name;
+ showModalById('editModal');
};
@@ -1640,6 +1679,7 @@ app.controller('listTableUsers', function ($scope, $http) {
if (response.data.status === 1) {
$scope.populateCurrentRecords();
+ hideModalById('editModal');
new PNotify({
title: 'Success!',
text: 'Changes successfully applied!',
@@ -1693,6 +1733,7 @@ app.controller('listTableUsers', function ($scope, $http) {
if (response.data.status === 1) {
$scope.populateCurrentRecords();
+ hideModalById('editModal');
new PNotify({
title: 'Success!',
text: 'ACL Successfully changed.',
diff --git a/static/userManagment/userManagment.js b/static/userManagment/userManagment.js
index fdf0e7878..071dcec34 100644
--- a/static/userManagment/userManagment.js
+++ b/static/userManagment/userManagment.js
@@ -2,14 +2,65 @@
* Created by usman on 8/5/17.
*/
+/* Safe notification - use PNotify if available, else fallback to alert */
+function safePNotify(opts) {
+ if (typeof PNotify !== 'undefined') {
+ new PNotify(opts);
+ } else {
+ var msg = (opts.title || '') + (opts.text ? ': ' + opts.text : '');
+ alert(msg || JSON.stringify(opts));
+ }
+}
/* Java script code to create account */
app.controller('createUserCtr', function ($scope, $http) {
+ // Home directory functionality
+ $scope.homeDirectories = [];
+ $scope.selectedHomeDirectory = '';
+ $scope.selectedHomeDirectoryInfo = null;
+
+ // Load home directories on page load
+ $scope.loadHomeDirectories = function() {
+ var url = '/users/getUserHomeDirectories';
+ var config = {
+ headers: {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+ $http.post(url, {}, config)
+ .then(function(response) {
+ if (response.data && response.data.status === 1) {
+ $scope.homeDirectories = response.data.directories || [];
+ } else {
+ console.error('Error loading home directories:', response.data);
+ $scope.homeDirectories = [];
+ }
+ })
+ .catch(function(error) {
+ console.error('Error loading home directories:', error);
+ $scope.homeDirectories = [];
+ });
+ };
+
+ // Update home directory info when selection changes
+ $scope.updateHomeDirectoryInfo = function() {
+ if ($scope.selectedHomeDirectory) {
+ $scope.selectedHomeDirectoryInfo = $scope.homeDirectories.find(function(dir) {
+ return dir.id == $scope.selectedHomeDirectory;
+ });
+ } else {
+ $scope.selectedHomeDirectoryInfo = null;
+ }
+ };
+
+ // Initialize home directories
+ $scope.loadHomeDirectories();
+
$scope.acctsLimit = true;
$scope.webLimits = true;
$scope.userCreated = true;
- $scope.userCreationFailed = true;
+ $scope.userCreationFailed = false; // false = don't show error alert on load
$scope.couldNotConnect = true;
$scope.userCreationLoading = true;
$scope.combinedLength = true;
@@ -18,20 +69,24 @@ app.controller('createUserCtr', function ($scope, $http) {
$scope.webLimits = false;
$scope.userCreated = true;
- $scope.userCreationFailed = true;
+ $scope.userCreationFailed = false; // hide error until we know the result
$scope.couldNotConnect = true;
$scope.userCreationLoading = false;
$scope.combinedLength = true;
-
- var firstName = $scope.firstName;
- var lastName = $scope.lastName;
+ var firstName = $scope.firstName || '';
+ var lastName = $scope.lastName || '';
var email = $scope.email;
var selectedACL = $scope.selectedACL;
var websitesLimits = $scope.websitesLimits;
var userName = $scope.userName;
var password = $scope.password;
+ if (firstName.length + lastName.length > 20) {
+ $scope.combinedLength = false;
+ $scope.userCreationLoading = true;
+ return;
+ }
var url = "/users/submitUserCreation";
@@ -43,12 +98,14 @@ app.controller('createUserCtr', function ($scope, $http) {
websitesLimit: websitesLimits,
userName: userName,
password: password,
- securityLevel: $scope.securityLevel
+ securityLevel: $scope.securityLevel,
+ selectedHomeDirectory: $scope.selectedHomeDirectory || ''
};
var config = {
headers: {
- 'X-CSRFToken': getCookie('csrftoken')
+ 'X-CSRFToken': getCookie('csrftoken'),
+ 'Content-Type': 'application/json'
}
};
@@ -59,42 +116,31 @@ app.controller('createUserCtr', function ($scope, $http) {
if (response.data.createStatus == 1) {
-
- $scope.userCreated = false;
- $scope.userCreationFailed = true;
+ $scope.userCreated = false; // show success
+ $scope.userCreationFailed = false; // hide error
$scope.couldNotConnect = true;
$scope.userCreationLoading = true;
-
$scope.userName = userName;
-
-
} else {
-
$scope.acctsLimit = false;
$scope.webLimits = false;
$scope.userCreated = true;
- $scope.userCreationFailed = false;
+ $scope.userCreationFailed = true; // true = show error alert
$scope.couldNotConnect = true;
$scope.userCreationLoading = true;
-
- $scope.errorMessage = response.data.error_message;
-
-
+ $scope.errorMessage = (response.data && (response.data.error_message || response.data.message || response.data.errorMessage)) || 'Unknown error';
}
}
function cantLoadInitialDatas(response) {
-
$scope.acctsLimit = false;
$scope.webLimits = false;
$scope.userCreated = true;
- $scope.userCreationFailed = true;
- $scope.couldNotConnect = false;
+ $scope.userCreationFailed = false; // hide server error, show connection error instead
+ $scope.couldNotConnect = false; // show "Could not connect" message
$scope.userCreationLoading = true;
-
-
}
@@ -138,10 +184,10 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.acctDetailsFetched = true;
$scope.userAccountsLimit = true;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // false = don't show error alert on load
$scope.couldNotConnect = true;
- $scope.canotFetchDetails = true;
- $scope.detailsFetched = true;
+ $scope.canotFetchDetails = false; // false = don't show fetch error on load
+ $scope.detailsFetched = false; // false = don't show "details loaded" on load
$scope.accountTypeView = true;
$scope.websitesLimit = true;
$scope.qrHidden = true;
@@ -401,9 +447,9 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.userModificationLoading = true;
$scope.acctDetailsFetched = false;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error (we only fetched details)
$scope.couldNotConnect = true;
- $scope.canotFetchDetails = true;
+ $scope.canotFetchDetails = false; // hide fetch error on success
$scope.detailsFetched = false;
$scope.userAccountsLimit = true;
$scope.websitesLimit = true;
@@ -413,13 +459,13 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.acctDetailsFetched = true;
$scope.userAccountsLimit = true;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error (only fetch failed)
$scope.couldNotConnect = true;
- $scope.canotFetchDetails = false;
- $scope.detailsFetched = true;
+ $scope.canotFetchDetails = true; // show fetch error on failure
+ $scope.detailsFetched = false;
- $scope.errorMessage = response.data.error_message;
+ $scope.errorMessage = (response.data && (response.data.error_message || response.data.message || response.data.errorMessage)) || 'Unknown error';
}
@@ -433,7 +479,7 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.acctDetailsFetched = true;
$scope.userAccountsLimit = true;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error (only connection/fetch failed)
$scope.couldNotConnect = false;
$scope.canotFetchDetails = true;
$scope.detailsFetched = true;
@@ -450,7 +496,7 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.userModificationLoading = false;
$scope.acctDetailsFetched = false;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error until we know result
$scope.couldNotConnect = true;
$scope.canotFetchDetails = true;
$scope.detailsFetched = true;
@@ -506,7 +552,7 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.userModificationLoading = true;
$scope.acctDetailsFetched = true;
$scope.userModified = false;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error on success
$scope.couldNotConnect = true;
$scope.canotFetchDetails = true;
$scope.detailsFetched = true;
@@ -523,13 +569,13 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.userModificationLoading = true;
$scope.acctDetailsFetched = false;
$scope.userModified = true;
- $scope.canotModifyUser = false;
+ $scope.canotModifyUser = true; // show modify error on failure
$scope.couldNotConnect = true;
$scope.canotFetchDetails = true;
$scope.detailsFetched = true;
- $scope.errorMessage = response.data.error_message;
+ $scope.errorMessage = (response.data && (response.data.error_message || response.data.message || response.data.errorMessage)) || 'Unknown error';
}
@@ -673,7 +719,7 @@ app.controller('deleteUser', function ($scope, $http) {
app.controller('createACLCTRL', function ($scope, $http) {
$scope.aclCreated = true;
- $scope.aclCreationFailed = true;
+ $scope.aclCreationFailed = false; // false = don't show error alert on load
$scope.couldNotConnect = true;
$scope.aclLoading = true;
@@ -844,14 +890,14 @@ app.controller('createACLCTRL', function ($scope, $http) {
$scope.aclLoading = true;
if (response.data.status === 1) {
- new PNotify({
+ safePNotify({
title: 'Success!',
text: 'ACL Successfully created.',
type: 'success'
});
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.errorMessage,
type: 'error'
@@ -866,7 +912,7 @@ app.controller('createACLCTRL', function ($scope, $http) {
$scope.aclLoading = false;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
@@ -1065,14 +1111,14 @@ app.controller('deleteACTCTRL', function ($scope, $http) {
$scope.aclLoading = true;
if (response.data.status === 1) {
- new PNotify({
+ safePNotify({
title: 'Success!',
text: 'ACL Successfully deleted.',
type: 'success'
});
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.errorMessage,
type: 'error'
@@ -1084,7 +1130,7 @@ app.controller('deleteACTCTRL', function ($scope, $http) {
function cantLoadInitialDatas(response) {
$scope.aclLoading = true;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
@@ -1128,7 +1174,7 @@ app.controller('modifyACLCtrl', function ($scope, $http) {
if (response.data.status === 1) {
- new PNotify({
+ safePNotify({
title: 'Success!',
text: 'Current settings successfully fetched',
type: 'success'
@@ -1208,7 +1254,7 @@ app.controller('modifyACLCtrl', function ($scope, $http) {
$scope.mailServerSSL = Boolean(response.data.mailServerSSL);
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.errorMessage,
type: 'error'
@@ -1221,7 +1267,7 @@ app.controller('modifyACLCtrl', function ($scope, $http) {
$scope.aclLoading = false;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
@@ -1323,14 +1369,14 @@ app.controller('modifyACLCtrl', function ($scope, $http) {
$scope.aclLoading = true;
if (response.data.status === 1) {
- new PNotify({
+ safePNotify({
title: 'Success!',
text: 'ACL Successfully modified.',
type: 'success'
});
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.errorMessage,
type: 'error'
@@ -1345,7 +1391,7 @@ app.controller('modifyACLCtrl', function ($scope, $http) {
$scope.aclLoading = false;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
@@ -1537,14 +1583,14 @@ app.controller('changeUserACLCTRL', function ($scope, $http) {
$scope.aclLoading = true;
if (response.data.status === 1) {
- new PNotify({
+ safePNotify({
title: 'Success!',
text: 'ACL Successfully changed.',
type: 'success'
});
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.errorMessage,
type: 'error'
@@ -1556,7 +1602,7 @@ app.controller('changeUserACLCTRL', function ($scope, $http) {
function cantLoadInitialDatas(response) {
$scope.aclLoading = true;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
@@ -1599,14 +1645,14 @@ app.controller('resellerCenterCTRL', function ($scope, $http) {
$scope.aclLoading = true;
if (response.data.status === 1) {
- new PNotify({
+ safePNotify({
title: 'Success!',
text: 'Changes successfully applied!',
type: 'success'
});
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.errorMessage,
type: 'error'
@@ -1618,7 +1664,7 @@ app.controller('resellerCenterCTRL', function ($scope, $http) {
function cantLoadInitialDatas(response) {
$scope.aclLoading = true;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
@@ -1668,14 +1714,14 @@ app.controller('apiAccessCTRL', function ($scope, $http) {
if (response.data.status === 1) {
$scope.apiAccessDropDown = true;
- new PNotify({
+ safePNotify({
title: 'Success!',
text: 'Changes successfully applied!',
type: 'success'
});
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
@@ -1687,7 +1733,7 @@ app.controller('apiAccessCTRL', function ($scope, $http) {
function cantLoadInitialDatas(response) {
$scope.cyberpanelLoading = true;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
@@ -1728,13 +1774,13 @@ app.controller('apiUsersCTRL', function ($scope, $http) {
$scope.apiUsers = response.data.users;
$scope.filteredUsers = response.data.users;
- new PNotify({
+ safePNotify({
title: 'Success!',
text: 'API users loaded successfully',
type: 'success'
});
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
@@ -1744,7 +1790,7 @@ app.controller('apiUsersCTRL', function ($scope, $http) {
function loadAPIUsersError(response) {
$scope.apiUsersLoading = true;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not load API users. Please refresh the page.',
type: 'error'
@@ -1773,7 +1819,7 @@ app.controller('apiUsersCTRL', function ($scope, $http) {
};
$scope.viewUserDetails = function(user) {
- new PNotify({
+ safePNotify({
title: 'User Details',
text: 'Username: ' + user.userName + '
' +
'Full Name: ' + user.firstName + ' ' + user.lastName + '
' +
@@ -1816,13 +1862,13 @@ app.controller('apiUsersCTRL', function ($scope, $http) {
});
$scope.filteredUsers = $scope.apiUsers;
- new PNotify({
+ safePNotify({
title: 'Success!',
text: 'API access disabled for ' + response.data.accountUsername,
type: 'success'
});
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
@@ -1832,7 +1878,7 @@ app.controller('apiUsersCTRL', function ($scope, $http) {
function disableAPIError(response) {
$scope.apiUsersLoading = true;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not disable API access. Please try again.',
type: 'error'
@@ -1845,6 +1891,42 @@ app.controller('apiUsersCTRL', function ($scope, $http) {
/* Java script code to list table users */
+/* Show modal by id - works with Bootstrap 3 (jQuery) or Bootstrap 5 (native) */
+function showModalById(modalId) {
+ var el = document.getElementById(modalId);
+ if (!el) return;
+ if (typeof jQuery !== 'undefined' && jQuery(el).modal) {
+ jQuery(el).modal('show');
+ } else if (typeof bootstrap !== 'undefined' && bootstrap.Modal) {
+ var m = bootstrap.Modal.getOrCreateInstance(el);
+ if (m) m.show();
+ } else {
+ el.style.display = 'block';
+ el.classList.add('in');
+ if (el.getAttribute('aria-hidden') !== null) el.setAttribute('aria-hidden', 'false');
+ var backdrop = document.createElement('div');
+ backdrop.className = 'modal-backdrop fade in';
+ backdrop.setAttribute('data-modal-backdrop', modalId);
+ document.body.appendChild(backdrop);
+ }
+}
+
+function hideModalById(modalId) {
+ var el = document.getElementById(modalId);
+ if (!el) return;
+ if (typeof jQuery !== 'undefined' && jQuery(el).modal) {
+ jQuery(el).modal('hide');
+ } else if (typeof bootstrap !== 'undefined' && bootstrap.Modal) {
+ var m = bootstrap.Modal.getInstance(el);
+ if (m) m.hide();
+ } else {
+ el.style.display = 'none';
+ el.classList.remove('in');
+ if (el.getAttribute('aria-hidden') !== null) el.setAttribute('aria-hidden', 'true');
+ var backdrops = document.querySelectorAll('[data-modal-backdrop="' + modalId + '"]');
+ backdrops.forEach(function (b) { if (b.parentNode) b.parentNode.removeChild(b); });
+ }
+}
app.controller('listTableUsers', function ($scope, $http) {
@@ -1876,14 +1958,14 @@ app.controller('listTableUsers', function ($scope, $http) {
$scope.records = JSON.parse(response.data.data);
- new PNotify({
+ safePNotify({
title: 'Success!',
text: 'Users successfully fetched!',
type: 'success'
});
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
@@ -1894,7 +1976,7 @@ app.controller('listTableUsers', function ($scope, $http) {
function cantLoadInitialDatas(response) {
$scope.cyberpanelLoading = true;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
@@ -1908,7 +1990,7 @@ app.controller('listTableUsers', function ($scope, $http) {
$scope.deleteUserInitial = function (name){
UserToDelete = name;
$scope.UserToDelete = name;
- $('#deleteModal').modal('show');
+ showModalById('deleteModal');
};
$scope.deleteUserFinal = function () {
@@ -1933,8 +2015,8 @@ app.controller('listTableUsers', function ($scope, $http) {
$scope.cyberpanelLoading = true;
if (response.data.deleteStatus === 1) {
$scope.populateCurrentRecords();
- $('#deleteModal').modal('hide');
- new PNotify({
+ hideModalById('deleteModal');
+ safePNotify({
title: 'Success!',
text: 'Users successfully deleted!',
type: 'success'
@@ -1942,7 +2024,7 @@ app.controller('listTableUsers', function ($scope, $http) {
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
@@ -1956,7 +2038,7 @@ app.controller('listTableUsers', function ($scope, $http) {
function cantLoadInitialDatas(response) {
$scope.cyberpanelLoading = false;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
@@ -1970,7 +2052,7 @@ app.controller('listTableUsers', function ($scope, $http) {
$scope.editInitial = function (name) {
$scope.name = name;
- $('#editModal').modal('show');
+ showModalById('editModal');
};
$scope.saveResellerChanges = function () {
@@ -1997,15 +2079,15 @@ app.controller('listTableUsers', function ($scope, $http) {
if (response.data.status === 1) {
$scope.populateCurrentRecords();
- $('#editModal').modal('hide');
- new PNotify({
+ hideModalById('editModal');
+ safePNotify({
title: 'Success!',
text: 'Changes successfully applied!',
type: 'success'
});
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.errorMessage,
type: 'error'
@@ -2016,7 +2098,7 @@ app.controller('listTableUsers', function ($scope, $http) {
}
function cantLoadInitialDatas(response) {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
@@ -2051,15 +2133,15 @@ app.controller('listTableUsers', function ($scope, $http) {
if (response.data.status === 1) {
$scope.populateCurrentRecords();
- $('#editModal').modal('hide');
- new PNotify({
+ hideModalById('editModal');
+ safePNotify({
title: 'Success!',
text: 'ACL Successfully changed.',
type: 'success'
});
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.errorMessage,
type: 'error'
@@ -2071,7 +2153,7 @@ app.controller('listTableUsers', function ($scope, $http) {
function cantLoadInitialDatas(response) {
$scope.aclLoading = true;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
@@ -2105,7 +2187,7 @@ app.controller('listTableUsers', function ($scope, $http) {
$scope.cyberpanelLoading = true;
if (response.data.status === 1) {
$scope.populateCurrentRecords();
- new PNotify({
+ safePNotify({
title: 'Success!',
text: 'Action successfully started.',
type: 'success'
@@ -2113,7 +2195,7 @@ app.controller('listTableUsers', function ($scope, $http) {
} else {
- new PNotify({
+ safePNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
@@ -2127,7 +2209,7 @@ app.controller('listTableUsers', function ($scope, $http) {
function cantLoadInitialDatas(response) {
$scope.cyberpanelLoading = false;
- new PNotify({
+ safePNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
diff --git a/userManagment/static/userManagment/userManagment.js b/userManagment/static/userManagment/userManagment.js
index dedfd2a14..071dcec34 100644
--- a/userManagment/static/userManagment/userManagment.js
+++ b/userManagment/static/userManagment/userManagment.js
@@ -447,9 +447,9 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.userModificationLoading = true;
$scope.acctDetailsFetched = false;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error (we only fetched details)
$scope.couldNotConnect = true;
- $scope.canotFetchDetails = true;
+ $scope.canotFetchDetails = false; // hide fetch error on success
$scope.detailsFetched = false;
$scope.userAccountsLimit = true;
$scope.websitesLimit = true;
@@ -459,13 +459,13 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.acctDetailsFetched = true;
$scope.userAccountsLimit = true;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error (only fetch failed)
$scope.couldNotConnect = true;
- $scope.canotFetchDetails = false;
- $scope.detailsFetched = true;
+ $scope.canotFetchDetails = true; // show fetch error on failure
+ $scope.detailsFetched = false;
- $scope.errorMessage = response.data.error_message;
+ $scope.errorMessage = (response.data && (response.data.error_message || response.data.message || response.data.errorMessage)) || 'Unknown error';
}
@@ -479,7 +479,7 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.acctDetailsFetched = true;
$scope.userAccountsLimit = true;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error (only connection/fetch failed)
$scope.couldNotConnect = false;
$scope.canotFetchDetails = true;
$scope.detailsFetched = true;
@@ -496,7 +496,7 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.userModificationLoading = false;
$scope.acctDetailsFetched = false;
$scope.userModified = true;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error until we know result
$scope.couldNotConnect = true;
$scope.canotFetchDetails = true;
$scope.detailsFetched = true;
@@ -552,7 +552,7 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.userModificationLoading = true;
$scope.acctDetailsFetched = true;
$scope.userModified = false;
- $scope.canotModifyUser = true;
+ $scope.canotModifyUser = false; // hide modify error on success
$scope.couldNotConnect = true;
$scope.canotFetchDetails = true;
$scope.detailsFetched = true;
@@ -569,13 +569,13 @@ app.controller('modifyUser', function ($scope, $http) {
$scope.userModificationLoading = true;
$scope.acctDetailsFetched = false;
$scope.userModified = true;
- $scope.canotModifyUser = false;
+ $scope.canotModifyUser = true; // show modify error on failure
$scope.couldNotConnect = true;
$scope.canotFetchDetails = true;
$scope.detailsFetched = true;
- $scope.errorMessage = response.data.error_message;
+ $scope.errorMessage = (response.data && (response.data.error_message || response.data.message || response.data.errorMessage)) || 'Unknown error';
}
@@ -1891,6 +1891,42 @@ app.controller('apiUsersCTRL', function ($scope, $http) {
/* Java script code to list table users */
+/* Show modal by id - works with Bootstrap 3 (jQuery) or Bootstrap 5 (native) */
+function showModalById(modalId) {
+ var el = document.getElementById(modalId);
+ if (!el) return;
+ if (typeof jQuery !== 'undefined' && jQuery(el).modal) {
+ jQuery(el).modal('show');
+ } else if (typeof bootstrap !== 'undefined' && bootstrap.Modal) {
+ var m = bootstrap.Modal.getOrCreateInstance(el);
+ if (m) m.show();
+ } else {
+ el.style.display = 'block';
+ el.classList.add('in');
+ if (el.getAttribute('aria-hidden') !== null) el.setAttribute('aria-hidden', 'false');
+ var backdrop = document.createElement('div');
+ backdrop.className = 'modal-backdrop fade in';
+ backdrop.setAttribute('data-modal-backdrop', modalId);
+ document.body.appendChild(backdrop);
+ }
+}
+
+function hideModalById(modalId) {
+ var el = document.getElementById(modalId);
+ if (!el) return;
+ if (typeof jQuery !== 'undefined' && jQuery(el).modal) {
+ jQuery(el).modal('hide');
+ } else if (typeof bootstrap !== 'undefined' && bootstrap.Modal) {
+ var m = bootstrap.Modal.getInstance(el);
+ if (m) m.hide();
+ } else {
+ el.style.display = 'none';
+ el.classList.remove('in');
+ if (el.getAttribute('aria-hidden') !== null) el.setAttribute('aria-hidden', 'true');
+ var backdrops = document.querySelectorAll('[data-modal-backdrop="' + modalId + '"]');
+ backdrops.forEach(function (b) { if (b.parentNode) b.parentNode.removeChild(b); });
+ }
+}
app.controller('listTableUsers', function ($scope, $http) {
@@ -1954,7 +1990,7 @@ app.controller('listTableUsers', function ($scope, $http) {
$scope.deleteUserInitial = function (name){
UserToDelete = name;
$scope.UserToDelete = name;
- $('#deleteModal').modal('show');
+ showModalById('deleteModal');
};
$scope.deleteUserFinal = function () {
@@ -1979,7 +2015,7 @@ app.controller('listTableUsers', function ($scope, $http) {
$scope.cyberpanelLoading = true;
if (response.data.deleteStatus === 1) {
$scope.populateCurrentRecords();
- $('#deleteModal').modal('hide');
+ hideModalById('deleteModal');
safePNotify({
title: 'Success!',
text: 'Users successfully deleted!',
@@ -2016,7 +2052,7 @@ app.controller('listTableUsers', function ($scope, $http) {
$scope.editInitial = function (name) {
$scope.name = name;
- $('#editModal').modal('show');
+ showModalById('editModal');
};
$scope.saveResellerChanges = function () {
@@ -2043,7 +2079,7 @@ app.controller('listTableUsers', function ($scope, $http) {
if (response.data.status === 1) {
$scope.populateCurrentRecords();
- $('#editModal').modal('hide');
+ hideModalById('editModal');
safePNotify({
title: 'Success!',
text: 'Changes successfully applied!',
@@ -2097,7 +2133,7 @@ app.controller('listTableUsers', function ($scope, $http) {
if (response.data.status === 1) {
$scope.populateCurrentRecords();
- $('#editModal').modal('hide');
+ hideModalById('editModal');
safePNotify({
title: 'Success!',
text: 'ACL Successfully changed.',
diff --git a/userManagment/templates/userManagment/listUsers.html b/userManagment/templates/userManagment/listUsers.html
index 8443ab182..5d6579264 100644
--- a/userManagment/templates/userManagment/listUsers.html
+++ b/userManagment/templates/userManagment/listUsers.html
@@ -330,28 +330,28 @@