aktueller stand
This commit is contained in:
@@ -376,6 +376,47 @@ function isSecureRequest(req) {
|
||||
}
|
||||
|
||||
const authSessions = new Map();
|
||||
const AUTH_SESSION_TABLE = 'auth_sessions';
|
||||
|
||||
function persistAuthSession(token, username, expiresAt) {
|
||||
if (!AUTH_ENABLED) {
|
||||
return;
|
||||
}
|
||||
db.prepare(`
|
||||
INSERT INTO ${AUTH_SESSION_TABLE} (token, username, expires_at)
|
||||
VALUES (?, ?, ?)
|
||||
ON CONFLICT(token) DO UPDATE SET
|
||||
username = excluded.username,
|
||||
expires_at = excluded.expires_at
|
||||
`).run(token, username, expiresAt);
|
||||
}
|
||||
|
||||
function deletePersistedAuthSession(token) {
|
||||
if (!AUTH_ENABLED) {
|
||||
return;
|
||||
}
|
||||
db.prepare(`DELETE FROM ${AUTH_SESSION_TABLE} WHERE token = ?`).run(token);
|
||||
}
|
||||
|
||||
function hydrateAuthSessions() {
|
||||
if (!AUTH_ENABLED) {
|
||||
return;
|
||||
}
|
||||
const now = Date.now();
|
||||
db.prepare(`DELETE FROM ${AUTH_SESSION_TABLE} WHERE expires_at <= ?`).run(now);
|
||||
const rows = db.prepare(`
|
||||
SELECT token, username, expires_at
|
||||
FROM ${AUTH_SESSION_TABLE}
|
||||
WHERE expires_at > ?
|
||||
`).all(now);
|
||||
|
||||
rows.forEach(row => {
|
||||
authSessions.set(row.token, {
|
||||
username: row.username,
|
||||
expiresAt: row.expires_at
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function buildAuthCookieValue(token, req) {
|
||||
const secure = isSecureRequest(req);
|
||||
@@ -425,6 +466,7 @@ function createSession(username) {
|
||||
const token = crypto.randomBytes(32).toString('hex');
|
||||
const expiresAt = Date.now() + AUTH_SESSION_MAX_AGE * 1000;
|
||||
authSessions.set(token, { username, expiresAt });
|
||||
persistAuthSession(token, username, expiresAt);
|
||||
return { token, expiresAt };
|
||||
}
|
||||
|
||||
@@ -437,17 +479,39 @@ function getSessionFromRequest(req) {
|
||||
|
||||
const session = authSessions.get(token);
|
||||
if (!session) {
|
||||
if (AUTH_ENABLED) {
|
||||
const row = db.prepare(`
|
||||
SELECT username, expires_at
|
||||
FROM ${AUTH_SESSION_TABLE}
|
||||
WHERE token = ?
|
||||
`).get(token);
|
||||
|
||||
if (!row) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (row.expires_at <= Date.now()) {
|
||||
deletePersistedAuthSession(token);
|
||||
return null;
|
||||
}
|
||||
|
||||
const hydrated = { username: row.username, expiresAt: row.expires_at };
|
||||
authSessions.set(token, hydrated);
|
||||
return { token, ...hydrated };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (session.expiresAt <= Date.now()) {
|
||||
authSessions.delete(token);
|
||||
deletePersistedAuthSession(token);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Sliding expiration
|
||||
session.expiresAt = Date.now() + AUTH_SESSION_MAX_AGE * 1000;
|
||||
authSessions.set(token, session);
|
||||
persistAuthSession(token, session.username, session.expiresAt);
|
||||
return { token, ...session };
|
||||
}
|
||||
|
||||
@@ -552,6 +616,7 @@ app.post('/api/logout', (req, res) => {
|
||||
const session = getSessionFromRequest(req);
|
||||
if (session) {
|
||||
authSessions.delete(session.token);
|
||||
deletePersistedAuthSession(session.token);
|
||||
}
|
||||
clearAuthCookie(res, req);
|
||||
res.json({ success: true });
|
||||
@@ -1384,6 +1449,15 @@ db.exec(`
|
||||
);
|
||||
`);
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS auth_sessions (
|
||||
token TEXT PRIMARY KEY,
|
||||
username TEXT NOT NULL,
|
||||
expires_at INTEGER NOT NULL
|
||||
);
|
||||
`);
|
||||
hydrateAuthSessions();
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS ai_settings (
|
||||
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||
|
||||
Reference in New Issue
Block a user