All checks were successful
Build AppImage / build (push) Has been skipped
Backend (pwa/server/): - Express + WebSocket API-Server auf Port 3100 - Claude Agent SDK Bridge mit Streaming - Bearer-Token Authentifizierung - REST: /api/status, /api/models, /api/sessions, /api/stop - WebSocket: /ws mit Live-Text-Streaming - Dockerfile für Container-Deployment Frontend (pwa/client/): - SvelteKit 5 PWA mit Dark Theme - Mobil-optimierter Chat (WhatsApp/Telegram-Feeling) - Message-Bubbles mit Markdown + Live-Streaming - Session-Drawer (Swipe von links) - Settings-Modal (Server/Token/Modell) - Service Worker für Auto-Updates - PWA-Manifest für "Add to Homescreen" - Safe-Area-Insets für Notch-Handys Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
52 lines
1.5 KiB
JavaScript
52 lines
1.5 KiB
JavaScript
// Claude Chat API — Authentifizierung
|
|
// Einfache Bearer-Token-Middleware fuer Express + WebSocket
|
|
|
|
import { randomBytes } from 'node:crypto';
|
|
|
|
// Token aus ENV oder zufaellig generiert
|
|
let API_TOKEN = process.env.CHAT_API_TOKEN;
|
|
|
|
if (!API_TOKEN) {
|
|
API_TOKEN = randomBytes(32).toString('hex');
|
|
console.log('========================================');
|
|
console.log('Kein CHAT_API_TOKEN gesetzt — zufaelliges Token generiert:');
|
|
console.log(` ${API_TOKEN}`);
|
|
console.log('Setze CHAT_API_TOKEN als ENV-Variable fuer einen festen Wert.');
|
|
console.log('========================================');
|
|
}
|
|
|
|
/**
|
|
* Express-Middleware: prueft Authorization-Header
|
|
* Erwartet: Authorization: Bearer <token>
|
|
*/
|
|
export function authMiddleware(req, res, next) {
|
|
const authHeader = req.headers.authorization;
|
|
|
|
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
return res.status(401).json({ error: 'Authorization-Header fehlt oder ungueltig' });
|
|
}
|
|
|
|
const token = authHeader.slice(7); // "Bearer " abschneiden
|
|
if (token !== API_TOKEN) {
|
|
return res.status(403).json({ error: 'Ungueltiges Token' });
|
|
}
|
|
|
|
next();
|
|
}
|
|
|
|
/**
|
|
* WebSocket-Upgrade: prueft Token als Query-Parameter ?token=xxx
|
|
* Gibt true zurueck wenn authentifiziert, sonst false
|
|
*/
|
|
export function verifyWsToken(url) {
|
|
try {
|
|
// URL kann relativ sein (/ws?token=xxx), daher Basis-URL ergaenzen
|
|
const parsed = new URL(url, 'http://localhost');
|
|
const token = parsed.searchParams.get('token');
|
|
return token === API_TOKEN;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export { API_TOKEN };
|