Wenn aktiviert, bekommt der JWT-Token statt der üblichen 7 Tage eine Lebensdauer von 180 Tagen. Der Token liegt wie bisher in localStorage, bleibt also bis zum manuellen Löschen / Cookie-Reset gültig. - backend/routers/auth_router.py: LoginRequest.remember_me, längere expires_delta beim Token-Erstellen - index.html: Checkbox unter dem 2FA-Feld - api.js: login() reicht remember_me als 4. Parameter durch - app.js: Wert aus #login-remember lesen und mitschicken - Version v5 → v6
73 lines
2.2 KiB
JavaScript
73 lines
2.2 KiB
JavaScript
import { t } from './i18n.js';
|
|
const BASE = '/api';
|
|
|
|
async function request(method, path, body = null, formEncoded = false) {
|
|
const token = localStorage.getItem('token');
|
|
const headers = {};
|
|
|
|
if (token) headers['Authorization'] = `Bearer ${token}`;
|
|
|
|
let bodyStr = null;
|
|
if (body !== null) {
|
|
if (formEncoded) {
|
|
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
bodyStr = new URLSearchParams(body).toString();
|
|
} else {
|
|
headers['Content-Type'] = 'application/json';
|
|
bodyStr = JSON.stringify(body);
|
|
}
|
|
}
|
|
|
|
const res = await fetch(`${BASE}${path}`, { method, headers, body: bodyStr });
|
|
|
|
if (res.status === 401 && !path.startsWith('/auth/login')) {
|
|
localStorage.removeItem('token');
|
|
localStorage.removeItem('user');
|
|
window.location.reload();
|
|
return null;
|
|
}
|
|
|
|
if (!res.ok) {
|
|
const err = await res.json().catch(() => ({ detail: t('unknown_error') }));
|
|
throw new Error(err.detail || `HTTP ${res.status}`);
|
|
}
|
|
|
|
if (res.status === 204) return null;
|
|
return res.json();
|
|
}
|
|
|
|
async function uploadRequest(path, formData) {
|
|
const token = localStorage.getItem('token');
|
|
const headers = {};
|
|
if (token) headers['Authorization'] = `Bearer ${token}`;
|
|
|
|
const res = await fetch(`${BASE}${path}`, { method: 'POST', headers, body: formData });
|
|
|
|
if (res.status === 401) {
|
|
localStorage.removeItem('token');
|
|
localStorage.removeItem('user');
|
|
window.location.reload();
|
|
return null;
|
|
}
|
|
if (!res.ok) {
|
|
const err = await res.json().catch(() => ({ detail: t('unknown_error') }));
|
|
throw new Error(err.detail || `HTTP ${res.status}`);
|
|
}
|
|
if (res.status === 204) return null;
|
|
return res.json();
|
|
}
|
|
|
|
export const api = {
|
|
get: (path) => request('GET', path),
|
|
post: (path, body) => request('POST', path, body),
|
|
put: (path, body) => request('PUT', path, body),
|
|
delete: (path) => request('DELETE', path),
|
|
upload: (path, form) => uploadRequest(path, form),
|
|
|
|
login: (username, password, totp_code = null, remember_me = false) =>
|
|
request('POST', '/auth/login', { username, password, totp_code, remember_me }),
|
|
|
|
setupRequired: () => request('GET', '/auth/setup-required'),
|
|
setup: (data) => request('POST', '/auth/setup', data),
|
|
};
|