feat(ui): Add client-side password validation

This commit is contained in:
ReturnFI
2025-11-05 20:22:26 +00:00
parent b898db944e
commit b5ad962345
2 changed files with 19 additions and 1 deletions

View File

@ -13,6 +13,7 @@ $(function () {
const GET_USER_URL_TEMPLATE = contentSection.dataset.getUserUrlTemplate; const GET_USER_URL_TEMPLATE = contentSection.dataset.getUserUrlTemplate;
const usernameRegex = /^[a-zA-Z0-9_]+$/; const usernameRegex = /^[a-zA-Z0-9_]+$/;
const passwordRegex = /^[a-zA-Z0-9]+$/;
let cachedUserData = []; let cachedUserData = [];
function setCookie(name, value, days) { function setCookie(name, value, days) {
@ -62,6 +63,18 @@ $(function () {
$(inputElement).closest('form').find('button[type="submit"]').prop('disabled', !isValid); $(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() { $('#addUsername, #addBulkPrefix').on('input', function() {
validateUsername(this, `#${this.id}Error`); validateUsername(this, `#${this.id}Error`);
}); });
@ -158,6 +171,9 @@ $(function () {
const expiryText = dataRow.find("td:eq(6)").text(); const expiryText = dataRow.find("td:eq(6)").text();
const note = dataRow.data('note'); const note = dataRow.data('note');
$('#editPasswordError').text('');
$('#editSubmitButton').prop('disabled', false);
$("#originalUsername").val(user); $("#originalUsername").val(user);
$("#editUsername").val(user); $("#editUsername").val(user);
$("#editTrafficLimit").val(parseFloat(trafficText.split('/')[1]) || 0); $("#editTrafficLimit").val(parseFloat(trafficText.split('/')[1]) || 0);
@ -172,6 +188,7 @@ $(function () {
$.getJSON(url) $.getJSON(url)
.done(userData => { .done(userData => {
passwordInput.val(userData.password || ''); passwordInput.val(userData.password || '');
validatePassword('#editPassword', '#editPasswordError');
}) })
.fail(() => { .fail(() => {
passwordInput.val("").attr("placeholder", "Failed to load password"); passwordInput.val("").attr("placeholder", "Failed to load password");
@ -182,7 +199,7 @@ $(function () {
}); });
$('#editUserModal').on('click', '#generatePasswordBtn', function() { $('#editUserModal').on('click', '#generatePasswordBtn', function() {
$('#editPassword').val(generatePassword()); $('#editPassword').val(generatePassword()).trigger('input');
}); });
$("#editUserForm").on("submit", function (e) { $("#editUserForm").on("submit", function (e) {

View File

@ -529,6 +529,7 @@
<button class="btn btn-outline-secondary" type="button" id="generatePasswordBtn"><i class="fas fa-sync-alt"></i></button> <button class="btn btn-outline-secondary" type="button" id="generatePasswordBtn"><i class="fas fa-sync-alt"></i></button>
</div> </div>
</div> </div>
<small class="form-text text-danger" id="editPasswordError"></small>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="editTrafficLimit">Traffic Limit (GB)</label> <label for="editTrafficLimit">Traffic Limit (GB)</label>