Einstellungen-Seite: .env-Werte in DB (app_state), keine .env mehr

Neue /einstellungen-Seite (Zahnrad im Header) mit allen bisherigen .env-Werten
(Ollama, E-Mail, CalDAV, REST-API), gespeichert in SQLite (app_state, cfg:-Prefix).
Libs lesen per lib/config.js zur Laufzeit statt beim Start -> Aenderungen
wirken sofort, kein Neustart. Bestehende .env wird beim ersten Start einmalig
migriert.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-13 20:57:31 +02:00
co-authored by Claude
parent 41887dd56c
commit 97b48f9841
12 changed files with 410 additions and 72 deletions
+13 -6
View File
@@ -1,9 +1,10 @@
// Third-party REST API (v1) for the Bewerbungs-Tracker.
//
// Mounted under /api/v1 in server.js. All endpoints except /health require an
// API key (env API_TOKEN) sent in the X-API-Key header. Reuses the server's
// existing DB helpers, sanitizer, duplicate guard, generation runner and
// attachment directories so behaviour stays consistent with the web UI.
// API key (API_TOKEN, editable via /einstellungen) sent in the X-API-Key
// header. Reuses the server's existing DB helpers, sanitizer, duplicate guard,
// generation runner and attachment directories so behaviour stays consistent
// with the web UI.
const express = require('express');
const path = require('path');
@@ -41,16 +42,22 @@ function createExternalApi(deps) {
const router = express.Router();
// `apiToken` may be a string (static) or a function () => string (dynamic,
// read from the DB on each request so an edit on /einstellungen takes effect
// without a restart).
const resolveToken = () => (typeof apiToken === 'function' ? apiToken() : apiToken);
// --- API key auth --------------------------------------------------
// /health is public so monitoring tools can probe availability; everything
// else returns 401 when the header is missing/wrong or the token isn't set.
router.use((req, res, next) => {
if (req.path === '/health') return next();
if (!apiToken) {
return res.status(503).json({ error: 'API-Token nicht konfiguriert (API_TOKEN-Umgebungsvariable fehlt).' });
const token = resolveToken();
if (!token) {
return res.status(503).json({ error: 'API-Token nicht konfiguriert (in den Einstellungen setzen).' });
}
const provided = req.get('X-API-Key');
if (!provided || provided !== apiToken) {
if (!provided || provided !== token) {
return res.status(401).json({ error: 'Ungültiger oder fehlender API-Key (Header: X-API-Key).' });
}
next();