Files
2026-05-19 02:46:51 +02:00

75 lines
1.9 KiB
JavaScript

function qs(id) {
return document.getElementById(id);
}
async function getSettings() {
const { authToken, apiBaseUrl } = await browser.storage.local.get(['authToken', 'apiBaseUrl']);
return {
authToken: authToken || '',
apiBaseUrl: apiBaseUrl || 'https://mal.mkelvers.tech',
};
}
async function setSettings(patch) {
await browser.storage.local.set(patch);
}
function show(el, on) {
el.hidden = !on;
}
async function render() {
const settings = await getSettings();
document.body.dataset.state = settings.authToken ? 'in' : 'out';
const logoutBtn = qs('logoutBtn');
logoutBtn.addEventListener('click', async () => {
await setSettings({ authToken: '' });
await render();
});
const hasToken = !!settings.authToken;
show(logoutBtn, hasToken);
show(qs('login'), !hasToken);
show(qs('loggedIn'), hasToken);
if (!hasToken) {
setupLogin();
return;
}
}
function setupLogin() {
const loginErr = qs('loginErr');
show(loginErr, false);
qs('loginBtn').onclick = async () => {
show(loginErr, false);
const username = qs('username').value.trim();
const password = qs('password').value;
if (!username || !password) {
loginErr.textContent = 'Missing username or password';
show(loginErr, true);
return;
}
try {
const { apiBaseUrl } = await getSettings();
const res = await fetch(apiBaseUrl.replace(/\/+$/, '') + '/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password, name: 'Firefox extension' }),
});
if (!res.ok) throw new Error('Invalid username or password');
const data = await res.json();
await setSettings({ authToken: data.token });
await render();
} catch (e) {
loginErr.textContent = e.message || 'Login failed';
show(loginErr, true);
}
};
}
render();