login/register aria

This commit is contained in:
Barış Soner Uşaklı
2024-02-12 11:54:15 -05:00
parent ad18c93901
commit 6cb9f60d2b
2 changed files with 84 additions and 80 deletions

View File

@@ -15,85 +15,79 @@ define('forum/login', ['hooks', 'translator', 'jquery-form'], function (hooks, t
e.preventDefault();
const username = $('#username').val();
const password = $('#password').val();
errorEl.addClass('hidden').find('p').text('');
if (!username || !password) {
errorEl.find('p').translateText('[[error:invalid-username-or-password]]');
errorEl.show();
} else {
errorEl.hide();
errorEl.removeClass('hidden');
return;
}
if (submitEl.hasClass('disabled')) {
return;
}
if (submitEl.hasClass('disabled')) {
return;
}
submitEl.addClass('disabled');
submitEl.addClass('disabled');
try {
const hookData = await hooks.fire('filter:app.login', {
username,
password,
cancel: false,
});
if (hookData.cancel) {
submitEl.removeClass('disabled');
return;
}
} catch (err) {
errorEl.find('p').translateText(err.message);
errorEl.show();
try {
const hookData = await hooks.fire('filter:app.login', {
username,
password,
cancel: false,
});
if (hookData.cancel) {
submitEl.removeClass('disabled');
return;
}
hooks.fire('action:app.login');
formEl.ajaxSubmit({
headers: {
'x-csrf-token': config.csrf_token,
},
beforeSend: function () {
app.flags._login = true;
},
success: function (data) {
hooks.fire('action:app.loggedIn', data);
const pathname = utils.urlToLocation(data.next).pathname;
const params = utils.params({ url: data.next });
params.loggedin = true;
delete params.register; // clear register message incase it exists
const qs = decodeURIComponent($.param(params));
window.location.href = pathname + '?' + qs;
},
error: function (data) {
let message = data.responseText;
const errInfo = data.responseJSON;
if (data.status === 403 && data.responseText === 'Forbidden') {
window.location.href = config.relative_path + '/login?error=csrf-invalid';
} else if (errInfo && errInfo.hasOwnProperty('banned_until')) {
message = errInfo.banned_until ?
translator.compile('error:user-banned-reason-until', (new Date(errInfo.banned_until).toLocaleString()), errInfo.reason) :
'[[error:user-banned-reason, ' + errInfo.reason + ']]';
}
errorEl.find('p').translateText(message);
errorEl.show();
submitEl.removeClass('disabled');
// Select the entire password if that field has focus
if ($('#password:focus').length) {
$('#password').select();
}
},
});
} catch (err) {
errorEl.find('p').translateText(err.message);
errorEl.removeClass('hidden');
submitEl.removeClass('disabled');
return;
}
hooks.fire('action:app.login');
formEl.ajaxSubmit({
headers: {
'x-csrf-token': config.csrf_token,
},
beforeSend: function () {
app.flags._login = true;
},
success: function (data) {
hooks.fire('action:app.loggedIn', data);
const pathname = utils.urlToLocation(data.next).pathname;
const params = utils.params({ url: data.next });
params.loggedin = true;
delete params.register; // clear register message incase it exists
const qs = decodeURIComponent($.param(params));
window.location.href = pathname + '?' + qs;
},
error: function (data) {
let message = data.responseText;
const errInfo = data.responseJSON;
if (data.status === 403 && data.responseText === 'Forbidden') {
window.location.href = config.relative_path + '/login?error=csrf-invalid';
} else if (errInfo && errInfo.hasOwnProperty('banned_until')) {
message = errInfo.banned_until ?
translator.compile('error:user-banned-reason-until', (new Date(errInfo.banned_until).toLocaleString()), errInfo.reason) :
'[[error:user-banned-reason, ' + errInfo.reason + ']]';
}
errorEl.find('p').translateText(message);
errorEl.removeClass('hidden');
submitEl.removeClass('disabled');
// Select the entire password if that field has focus
if ($('#password:focus').length) {
$('#password').select();
}
},
});
});
// Guard against caps lock
Login.capsLockCheck(document.querySelector('#password'), document.querySelector('#caps-lock-warning'));
$('#login-error-notify button').on('click', function (e) {
e.preventDefault();
errorEl.hide();
return false;
});
if ($('#content #username').val()) {
$('#content #password').val('').focus();
} else {

View File

@@ -48,6 +48,8 @@ define('forum/register', [
function validateForm(callback) {
validationError = false;
$('[aria-invalid="true"]').removeAttr('aria-invalid');
validatePassword(password.val(), password_confirm.val());
validatePasswordConfirm(password.val(), password_confirm.val());
validateUsername(username.val(), callback);
@@ -59,6 +61,7 @@ define('forum/register', [
register.on('click', function (e) {
const registerBtn = $(this);
const errorEl = $('#register-error-notify');
errorEl.addClass('hidden');
e.preventDefault();
validateForm(function () {
@@ -108,29 +111,31 @@ define('forum/register', [
});
// Set initial focus
$('#username').focus();
$('#username').trigger('focus');
};
function validateUsername(username, callback) {
callback = callback || function () {};
const username_notify = $('#username-notify');
username_notify.text('');
const usernameInput = $('#username');
const userslug = slugify(username);
if (username.length < ajaxify.data.minimumUsernameLength || userslug.length < ajaxify.data.minimumUsernameLength) {
showError(username_notify, '[[error:username-too-short]]');
showError(usernameInput, username_notify, '[[error:username-too-short]]');
} else if (username.length > ajaxify.data.maximumUsernameLength) {
showError(username_notify, '[[error:username-too-long]]');
showError(usernameInput, username_notify, '[[error:username-too-long]]');
} else if (!utils.isUserNameValid(username) || !userslug) {
showError(username_notify, '[[error:invalid-username]]');
showError(usernameInput, username_notify, '[[error:invalid-username]]');
} else {
Promise.allSettled([
api.head(`/users/bySlug/${userslug}`, {}),
api.head(`/groups/${username}`, {}),
]).then((results) => {
if (results.every(obj => obj.status === 'rejected')) {
showSuccess(username_notify, successIcon);
showSuccess(usernameInput, username_notify, successIcon);
} else {
showError(username_notify, '[[error:username-taken]]');
showError(usernameInput, username_notify, '[[error:username-taken]]');
}
callback();
@@ -139,9 +144,11 @@ define('forum/register', [
}
function validatePassword(password, password_confirm) {
const passwordInput = $('#password');
const password_notify = $('#password-notify');
const password_confirm_notify = $('#password-confirm-notify');
password_notify.text('');
password_confirm_notify.text('');
try {
utils.assertPasswordValidity(password, zxcvbn);
@@ -149,33 +156,35 @@ define('forum/register', [
throw new Error('[[user:password-same-as-username]]');
}
showSuccess(password_notify, successIcon);
showSuccess(passwordInput, password_notify, successIcon);
} catch (err) {
showError(password_notify, err.message);
showError(passwordInput, password_notify, err.message);
}
if (password !== password_confirm && password_confirm !== '') {
showError(password_confirm_notify, '[[user:change-password-error-match]]');
showError(passwordInput, password_confirm_notify, '[[user:change-password-error-match]]');
}
}
function validatePasswordConfirm(password, password_confirm) {
const passwordConfirmInput = $('#password-confirm');
const password_notify = $('#password-notify');
const password_confirm_notify = $('#password-confirm-notify');
password_confirm_notify.text('');
if (!password || password_notify.hasClass('alert-error')) {
return;
}
if (password !== password_confirm) {
showError(password_confirm_notify, '[[user:change-password-error-match]]');
showError(passwordConfirmInput, password_confirm_notify, '[[user:change-password-error-match]]');
} else {
showSuccess(password_confirm_notify, successIcon);
showSuccess(passwordConfirmInput, password_confirm_notify, successIcon);
}
}
function showError(element, msg) {
function showError(input, element, msg) {
translator.translate(msg, function (msg) {
input.attr('aria-invalid', 'true');
element.html(msg);
element.parent()
.removeClass('register-success')
@@ -185,8 +194,9 @@ define('forum/register', [
validationError = true;
}
function showSuccess(element, msg) {
function showSuccess(input, element, msg) {
translator.translate(msg, function (msg) {
input.removeAttr('aria-invalid');
element.html(msg);
element.parent()
.removeClass('register-danger')