From b5ad962345baa98ade0f51878419d3dbfdb5e2da Mon Sep 17 00:00:00 2001 From: ReturnFI <151555003+ReturnFI@users.noreply.github.com> Date: Wed, 5 Nov 2025 20:22:26 +0000 Subject: [PATCH] feat(ui): Add client-side password validation --- core/scripts/webpanel/assets/js/users.js | 19 ++++++++++++++++++- core/scripts/webpanel/templates/users.html | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/core/scripts/webpanel/assets/js/users.js b/core/scripts/webpanel/assets/js/users.js index a0205c3..d50dee3 100644 --- a/core/scripts/webpanel/assets/js/users.js +++ b/core/scripts/webpanel/assets/js/users.js @@ -13,6 +13,7 @@ $(function () { const GET_USER_URL_TEMPLATE = contentSection.dataset.getUserUrlTemplate; const usernameRegex = /^[a-zA-Z0-9_]+$/; + const passwordRegex = /^[a-zA-Z0-9]+$/; let cachedUserData = []; function setCookie(name, value, days) { @@ -61,6 +62,18 @@ $(function () { $(errorElement).text(isValid ? "" : "Usernames can only contain letters, numbers, and underscores."); $(inputElement).closest('form').find('button[type="submit"]').prop('disabled', !isValid); } + + function validatePassword(inputElement, errorElement) { + const password = $(inputElement).val(); + // The password is valid if it's empty (no change) OR it matches the alphanumeric regex. + const isValid = password === '' || passwordRegex.test(password); + $(errorElement).text(isValid ? "" : "Password can only contain letters and numbers."); + $('#editSubmitButton').prop('disabled', !isValid); + } + + $('#editPassword').on('input', function() { + validatePassword(this, '#editPasswordError'); + }); $('#addUsername, #addBulkPrefix').on('input', function() { validateUsername(this, `#${this.id}Error`); @@ -157,6 +170,9 @@ $(function () { const trafficText = dataRow.find("td:eq(4)").text(); const expiryText = dataRow.find("td:eq(6)").text(); const note = dataRow.data('note'); + + $('#editPasswordError').text(''); + $('#editSubmitButton').prop('disabled', false); $("#originalUsername").val(user); $("#editUsername").val(user); @@ -172,6 +188,7 @@ $(function () { $.getJSON(url) .done(userData => { passwordInput.val(userData.password || ''); + validatePassword('#editPassword', '#editPasswordError'); }) .fail(() => { passwordInput.val("").attr("placeholder", "Failed to load password"); @@ -182,7 +199,7 @@ $(function () { }); $('#editUserModal').on('click', '#generatePasswordBtn', function() { - $('#editPassword').val(generatePassword()); + $('#editPassword').val(generatePassword()).trigger('input'); }); $("#editUserForm").on("submit", function (e) { diff --git a/core/scripts/webpanel/templates/users.html b/core/scripts/webpanel/templates/users.html index 632f8e2..d98a4e8 100644 --- a/core/scripts/webpanel/templates/users.html +++ b/core/scripts/webpanel/templates/users.html @@ -529,6 +529,7 @@ +