Datenbank bereinigt / Gitea-Integration gefixt
Dieser Commit ist enthalten in:
committet von
Server Deploy
Ursprung
395598c2b0
Commit
c21be47428
@ -8,7 +8,7 @@ const express = require('express');
|
||||
const router = express.Router();
|
||||
const bcrypt = require('bcryptjs');
|
||||
const { getDb } = require('../database');
|
||||
const { generateToken, authenticateToken } = require('../middleware/auth');
|
||||
const { generateToken, generateRefreshToken, refreshAccessToken, revokeAllRefreshTokens, authenticateToken } = require('../middleware/auth');
|
||||
const { getTokenForUser } = require('../middleware/csrf');
|
||||
const { validatePassword } = require('../middleware/validation');
|
||||
const logger = require('../utils/logger');
|
||||
@ -37,13 +37,8 @@ router.post('/login', async (req, res) => {
|
||||
|
||||
// Benutzer suchen: Zuerst nach Username "admin", dann nach E-Mail
|
||||
let user;
|
||||
if (username.toLowerCase() === 'admin') {
|
||||
// Admin-User per Username suchen
|
||||
user = db.prepare('SELECT * FROM users WHERE username = ?').get('admin');
|
||||
} else {
|
||||
// Normale User per E-Mail suchen
|
||||
user = db.prepare('SELECT * FROM users WHERE email = ?').get(username);
|
||||
}
|
||||
// User per Username suchen (kann E-Mail-Adresse oder admin sein)
|
||||
user = db.prepare('SELECT * FROM users WHERE username = ?').get(username);
|
||||
|
||||
// Audit-Log Eintrag vorbereiten
|
||||
const logAttempt = (userId, success) => {
|
||||
@ -111,8 +106,11 @@ router.post('/login', async (req, res) => {
|
||||
|
||||
logAttempt(user.id, true);
|
||||
|
||||
// JWT-Token generieren
|
||||
const token = generateToken(user);
|
||||
// JWT Access-Token generieren (kurze Lebensdauer)
|
||||
const accessToken = generateToken(user);
|
||||
|
||||
// Refresh-Token generieren (lange Lebensdauer)
|
||||
const refreshToken = generateRefreshToken(user.id, ip, userAgent);
|
||||
|
||||
// CSRF-Token generieren
|
||||
const csrfToken = getTokenForUser(user.id);
|
||||
@ -128,7 +126,8 @@ router.post('/login', async (req, res) => {
|
||||
}
|
||||
|
||||
res.json({
|
||||
token,
|
||||
token: accessToken,
|
||||
refreshToken,
|
||||
csrfToken,
|
||||
user: {
|
||||
id: user.id,
|
||||
@ -147,13 +146,19 @@ router.post('/login', async (req, res) => {
|
||||
|
||||
/**
|
||||
* POST /api/auth/logout
|
||||
* Benutzer abmelden
|
||||
* Benutzer abmelden und Refresh-Tokens widerrufen
|
||||
*/
|
||||
router.post('/logout', authenticateToken, (req, res) => {
|
||||
// Bei JWT gibt es serverseitig nichts zu tun
|
||||
// Client muss Token löschen
|
||||
logger.info(`Logout: ${req.user.username}`);
|
||||
res.json({ message: 'Erfolgreich abgemeldet' });
|
||||
try {
|
||||
// Alle Refresh-Tokens des Benutzers löschen
|
||||
revokeAllRefreshTokens(req.user.id);
|
||||
|
||||
logger.info(`Logout: ${req.user.username}`);
|
||||
res.json({ message: 'Erfolgreich abgemeldet' });
|
||||
} catch (error) {
|
||||
logger.error('Logout-Fehler:', { error: error.message });
|
||||
res.status(500).json({ error: 'Logout fehlgeschlagen' });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
@ -200,27 +205,68 @@ router.get('/me', authenticateToken, (req, res) => {
|
||||
|
||||
/**
|
||||
* POST /api/auth/refresh
|
||||
* Token erneuern
|
||||
* Token mit Refresh-Token erneuern
|
||||
*/
|
||||
router.post('/refresh', authenticateToken, (req, res) => {
|
||||
router.post('/refresh', async (req, res) => {
|
||||
try {
|
||||
const db = getDb();
|
||||
const user = db.prepare('SELECT * FROM users WHERE id = ?').get(req.user.id);
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({ error: 'Benutzer nicht gefunden' });
|
||||
const { refreshToken } = req.body;
|
||||
const ip = req.ip || req.connection.remoteAddress;
|
||||
const userAgent = req.headers['user-agent'];
|
||||
|
||||
if (!refreshToken) {
|
||||
// Fallback für alte Clients - mit Access Token authentifizieren
|
||||
if (req.headers.authorization) {
|
||||
return legacyRefresh(req, res);
|
||||
}
|
||||
return res.status(400).json({ error: 'Refresh-Token erforderlich' });
|
||||
}
|
||||
|
||||
const token = generateToken(user);
|
||||
const csrfToken = getTokenForUser(user.id);
|
||||
// Neuen Access-Token mit Refresh-Token generieren
|
||||
const accessToken = await refreshAccessToken(refreshToken, ip, userAgent);
|
||||
const db = getDb();
|
||||
|
||||
// User-Daten für CSRF-Token abrufen
|
||||
const decoded = require('jsonwebtoken').decode(accessToken);
|
||||
const csrfToken = getTokenForUser(decoded.id);
|
||||
|
||||
res.json({ token, csrfToken });
|
||||
res.json({
|
||||
token: accessToken,
|
||||
csrfToken
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Token-Refresh Fehler:', { error: error.message });
|
||||
res.status(500).json({ error: 'Interner Serverfehler' });
|
||||
res.status(401).json({ error: 'Token-Erneuerung fehlgeschlagen' });
|
||||
}
|
||||
});
|
||||
|
||||
// Legacy Refresh für Rückwärtskompatibilität
|
||||
function legacyRefresh(req, res) {
|
||||
// Prüfe Authorization Header
|
||||
const authHeader = req.headers['authorization'];
|
||||
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
||||
return res.status(401).json({ error: 'Nicht authentifiziert' });
|
||||
}
|
||||
|
||||
const token = authHeader.substring(7);
|
||||
const user = require('../middleware/auth').verifyToken(token);
|
||||
|
||||
if (!user) {
|
||||
return res.status(401).json({ error: 'Token ungültig' });
|
||||
}
|
||||
|
||||
const db = getDb();
|
||||
const dbUser = db.prepare('SELECT * FROM users WHERE id = ?').get(user.id);
|
||||
|
||||
if (!dbUser) {
|
||||
return res.status(404).json({ error: 'Benutzer nicht gefunden' });
|
||||
}
|
||||
|
||||
const newToken = generateToken(dbUser);
|
||||
const csrfToken = getTokenForUser(dbUser.id);
|
||||
|
||||
res.json({ token: newToken, csrfToken });
|
||||
}
|
||||
|
||||
/**
|
||||
* PUT /api/auth/password
|
||||
* Passwort ändern
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren