77 lines
2.4 KiB
JavaScript
77 lines
2.4 KiB
JavaScript
(function (root, factory) {
|
|
if (typeof module === 'object' && module.exports) module.exports = factory;
|
|
else root.createLoginController = factory;
|
|
}(typeof self !== 'undefined' ? self : this, function createLoginController(options) {
|
|
const form = options.form;
|
|
const status = options.status;
|
|
const button = options.button;
|
|
const fetchImpl = options.fetchImpl;
|
|
const location = options.location;
|
|
const setIntervalImpl = options.setIntervalImpl || setInterval;
|
|
const clearIntervalImpl = options.clearIntervalImpl || clearInterval;
|
|
let timer = null;
|
|
|
|
function showRetryCountdown(seconds) {
|
|
let remaining = Math.max(1, Number.parseInt(seconds, 10) || 1);
|
|
button.disabled = true;
|
|
status.textContent = `Too many attempts. Try again in ${remaining} seconds.`;
|
|
timer = setIntervalImpl(() => {
|
|
remaining -= 1;
|
|
if (remaining <= 0) {
|
|
clearIntervalImpl(timer);
|
|
timer = null;
|
|
button.disabled = false;
|
|
status.textContent = 'You can try signing in again.';
|
|
return;
|
|
}
|
|
status.textContent = `Too many attempts. Try again in ${remaining} seconds.`;
|
|
}, 1000);
|
|
}
|
|
|
|
async function submit(accessToken) {
|
|
status.textContent = 'Signing in…';
|
|
let response;
|
|
try {
|
|
response = await fetchImpl('api/v1/session', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ access_token: accessToken }),
|
|
});
|
|
} catch (_error) {
|
|
form.reset();
|
|
status.textContent = 'Sign-in failed. Check your connection and try again.';
|
|
return;
|
|
}
|
|
form.reset();
|
|
if (response.ok) {
|
|
location.replace('./');
|
|
return;
|
|
}
|
|
if (response.status === 429) {
|
|
showRetryCountdown(response.headers.get('Retry-After'));
|
|
return;
|
|
}
|
|
status.textContent = 'Sign-in failed. Check the token and try again.';
|
|
}
|
|
|
|
return { submit };
|
|
}));
|
|
|
|
if (typeof document !== 'undefined') {
|
|
const form = document.getElementById('sign-in');
|
|
const status = document.getElementById('status');
|
|
const button = document.getElementById('submit-sign-in');
|
|
const controller = createLoginController({
|
|
form,
|
|
status,
|
|
button,
|
|
fetchImpl: fetch.bind(window),
|
|
location: window.location,
|
|
});
|
|
form.addEventListener('submit', event => {
|
|
event.preventDefault();
|
|
const accessToken = new FormData(form).get('access_token');
|
|
controller.submit(accessToken);
|
|
});
|
|
}
|