| import { initAccessibility } from './a11y.js'; |
|
|
| |
| |
| |
| let csrfToken = ''; |
| let discreetLogin = false; |
|
|
| |
| |
| |
| |
| async function getCsrfToken() { |
| const response = await fetch('/csrf-token'); |
| const data = await response.json(); |
| return data.token; |
| } |
|
|
| |
| |
| |
| |
| async function getUserList() { |
| const response = await fetch('/api/users/list', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| 'X-CSRF-Token': csrfToken, |
| }, |
| }); |
|
|
| if (!response.ok) { |
| const errorData = await response.json(); |
| return displayError(errorData.error || 'An error occurred'); |
| } |
|
|
| if (response.status === 204) { |
| discreetLogin = true; |
| return []; |
| } |
|
|
| const userListObj = await response.json(); |
| console.log(userListObj); |
| return userListObj; |
| } |
|
|
| |
| |
| |
| |
| |
| async function sendRecoveryPart1(handle) { |
| const response = await fetch('/api/users/recover-step1', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| 'X-CSRF-Token': csrfToken, |
| }, |
| body: JSON.stringify({ handle }), |
| }); |
|
|
| if (!response.ok) { |
| const errorData = await response.json(); |
| return displayError(errorData.error || 'An error occurred'); |
| } |
|
|
| showRecoveryBlock(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| async function sendRecoveryPart2(handle, code, newPassword) { |
| const recoveryData = { |
| handle, |
| code, |
| newPassword, |
| }; |
|
|
| const response = await fetch('/api/users/recover-step2', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| 'X-CSRF-Token': csrfToken, |
| }, |
| body: JSON.stringify(recoveryData), |
| }); |
|
|
| if (!response.ok) { |
| const errorData = await response.json(); |
| return displayError(errorData.error || 'An error occurred'); |
| } |
|
|
| console.log(`Successfully recovered password for ${handle}!`); |
| await performLogin(handle, newPassword); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| async function performLogin(handle, password) { |
| const userInfo = { |
| handle: handle, |
| password: password, |
| }; |
|
|
| try { |
| const response = await fetch('/api/users/login', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| 'X-CSRF-Token': csrfToken, |
| }, |
| body: JSON.stringify(userInfo), |
| }); |
|
|
| if (!response.ok) { |
| const errorData = await response.json(); |
| return displayError(errorData.error || 'An error occurred'); |
| } |
|
|
| const data = await response.json(); |
|
|
| if (data.handle) { |
| console.log(`Successfully logged in as ${handle}!`); |
| redirectToHome(); |
| } |
| } catch (error) { |
| console.error('Error logging in:', error); |
| displayError(String(error)); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| async function onUserSelected(user) { |
| |
| if (!user.password) { |
| return await performLogin(user.handle, ''); |
| } |
|
|
| $('#passwordRecoveryBlock').hide(); |
| $('#passwordEntryBlock').show(); |
| $('#loginButton').off('click').on('click', async () => { |
| const password = String($('#userPassword').val()); |
| await performLogin(user.handle, password); |
| }); |
|
|
| $('#recoverPassword').off('click').on('click', async () => { |
| await sendRecoveryPart1(user.handle); |
| }); |
|
|
| $('#sendRecovery').off('click').on('click', async () => { |
| const code = String($('#recoveryCode').val()); |
| const newPassword = String($('#newPassword').val()); |
| await sendRecoveryPart2(user.handle, code, newPassword); |
| }); |
|
|
| displayError(''); |
| } |
|
|
| |
| |
| |
| |
| function displayError(message) { |
| $('#errorMessage').text(message); |
| } |
|
|
| |
| |
| |
| |
| function redirectToHome() { |
| |
| const currentUrl = new URL(window.location.href); |
|
|
| |
| |
| currentUrl.searchParams.delete('noauto'); |
|
|
| |
| currentUrl.pathname = '/'; |
|
|
| |
| window.location.href = currentUrl.toString(); |
| } |
|
|
| |
| |
| |
| function showRecoveryBlock() { |
| $('#passwordEntryBlock').hide(); |
| $('#passwordRecoveryBlock').show(); |
| displayError(''); |
| } |
|
|
| |
| |
| |
| function onCancelRecoveryClick() { |
| $('#passwordRecoveryBlock').hide(); |
| $('#passwordEntryBlock').show(); |
| displayError(''); |
| } |
|
|
| |
| |
| |
| |
| function configureNormalLogin(userList) { |
| console.log('Discreet login is disabled'); |
| $('#handleEntryBlock').hide(); |
| $('#normalLoginPrompt').show(); |
| $('#discreetLoginPrompt').hide(); |
| console.log(userList); |
| for (const user of userList) { |
| const userBlock = $('<div></div>').addClass('userSelect'); |
| const avatarBlock = $('<div></div>').addClass('avatar'); |
| avatarBlock.append($('<img>').attr('src', user.avatar)); |
| userBlock.append(avatarBlock); |
| userBlock.append($('<span></span>').addClass('userName').text(user.name)); |
| userBlock.append($('<small></small>').addClass('userHandle').text(user.handle)); |
| userBlock.on('click', () => onUserSelected(user)); |
| $('#userList').append(userBlock); |
| } |
| } |
|
|
| |
| |
| |
| function configureDiscreetLogin() { |
| console.log('Discreet login is enabled'); |
| $('#handleEntryBlock').show(); |
| $('#normalLoginPrompt').hide(); |
| $('#discreetLoginPrompt').show(); |
| $('#userList').hide(); |
| $('#passwordRecoveryBlock').hide(); |
| $('#passwordEntryBlock').show(); |
| $('#loginButton').off('click').on('click', async () => { |
| const handle = String($('#userHandle').val()); |
| const password = String($('#userPassword').val()); |
| await performLogin(handle, password); |
| }); |
|
|
| $('#recoverPassword').off('click').on('click', async () => { |
| const handle = String($('#userHandle').val()); |
| await sendRecoveryPart1(handle); |
| }); |
|
|
| $('#sendRecovery').off('click').on('click', async () => { |
| const handle = String($('#userHandle').val()); |
| const code = String($('#recoveryCode').val()); |
| const newPassword = String($('#newPassword').val()); |
| await sendRecoveryPart2(handle, code, newPassword); |
| }); |
| } |
|
|
| (async function () { |
| initAccessibility(); |
|
|
| csrfToken = await getCsrfToken(); |
| const userList = await getUserList(); |
|
|
| if (discreetLogin) { |
| configureDiscreetLogin(); |
| } else { |
| configureNormalLogin(userList); |
| } |
| document.getElementById('shadow_popup').style.opacity = ''; |
| $('#cancelRecovery').on('click', onCancelRecoveryClick); |
| $(document).on('keydown', (evt) => { |
| if (evt.key === 'Enter' && document.activeElement.tagName === 'INPUT') { |
| if ($('#passwordRecoveryBlock').is(':visible')) { |
| $('#sendRecovery').trigger('click'); |
| } else { |
| $('#loginButton').trigger('click'); |
| } |
| } |
| }); |
| })(); |
|
|