import { createClient } from 'redis'; import User from '../models/community/user.js'; // dotenv wird global in server.js/app.js geladen const EXPIRATION_TIME = 30 * 60 * 1000; // Debug: Zeige alle Umgebungsvariablen console.log('[redis] DEBUG - Alle Umgebungsvariablen:'); console.log('[redis] process.env.REDIS_HOST:', process.env.REDIS_HOST); console.log('[redis] process.env.REDIS_PORT:', process.env.REDIS_PORT); console.log('[redis] process.env.REDIS_PASSWORD:', process.env.REDIS_PASSWORD ? '***gesetzt***' : 'NICHT GESETZT'); console.log('[redis] process.env.REDIS_PASS:', process.env.REDIS_PASS ? '***gesetzt***' : 'NICHT GESETZT'); console.log('[redis] process.env.REDIS_URL:', process.env.REDIS_URL); const redisHost = process.env.REDIS_HOST || '127.0.0.1'; const redisPort = process.env.REDIS_PORT || '6379'; const redisPassword = process.env.REDIS_PASSWORD || process.env.REDIS_PASS || undefined; const redisUrl = process.env.REDIS_URL || `redis://${redisHost}:${redisPort}`; console.log('[redis] Finale Redis-Konfiguration:'); console.log('[redis] redisHost:', redisHost); console.log('[redis] redisPort:', redisPort); console.log('[redis] redisPassword:', redisPassword ? '***gesetzt***' : 'NICHT GESETZT'); console.log('[redis] redisUrl:', redisUrl); if (!process.env.REDIS_HOST || !process.env.REDIS_PORT) { console.warn(`[redis] Verwende Fallback ${redisHost}:${redisPort}`); } if (!process.env.REDIS_PASSWORD && !process.env.REDIS_PASS && !process.env.REDIS_URL) { console.warn('[redis] Kein Passwort gesetzt (REDIS_PASSWORD/REDIS_PASS) und keine REDIS_URL vorhanden. Wenn der Server Auth erfordert, schlägt dies fehl.'); } const redisClient = createClient({ url: redisUrl, password: redisPassword, legacyMode: false, }); redisClient.on('error', (err) => { if (typeof err?.message === 'string' && err.message.includes('NOAUTH')) { console.error('[redis] Authentifizierungsfehler: Server verlangt Passwort. Bitte REDIS_PASSWORD/REDIS_PASS oder REDIS_URL setzen.'); } else { console.error('[redis] Fehler:', err); } }); redisClient.connect().catch(console.error); const setUserSession = async (userId, sessionData) => { try { await redisClient.sendCommand(['JSON.SET', `user:${userId}`, '.', JSON.stringify(sessionData)]); console.log(userId, sessionData); const sessionDataStr = await redisClient.sendCommand(['JSON.GET', `user:${userId}`]); console.log(sessionDataStr); } catch (error) { console.error('Fehler beim Setzen der Benutzersitzung:', error); } }; const deleteUserSession = async (userId) => { try { const result = await redisClient.del(`user:${userId}`); if (result === 1) { console.log(`Benutzersitzung für Benutzer ${userId} erfolgreich gelöscht.`); } else { console.warn(`Benutzersitzung für Benutzer ${userId} war nicht vorhanden.`); } } catch (error) { console.error('Fehler beim Löschen der Benutzersitzung:', error); } }; const convertToOriginalType = (value) => { if (value === 'true') return true; if (value === 'false') return false; if (!isNaN(value) && value.trim() !== '') return Number(value); return value; }; const getUserSession = async (userId) => { try { const sessionData = await redisClient.sendCommand(['JSON.GET', `user:${userId}`]); return JSON.parse(sessionData); } catch (error) { console.error('Fehler beim Abrufen der Benutzersitzung:', error); return null; } }; const updateUserTimestamp = async (userId) => { try { const userKey = `user:${userId}`; const userExists = await redisClient.exists(userKey); if (userExists) { const sessionDataString = await redisClient.sendCommand(['JSON.GET', `user:${userId}`]); const sessionData = JSON.parse(sessionDataString); sessionData.timestamp = Date.now(); await redisClient.sendCommand(['JSON.SET', `user:${userId}`, '.', JSON.stringify(sessionData)]); } } catch (error) { console.error('Fehler beim Aktualisieren des Zeitstempels:', error); } }; const cleanupExpiredSessions = async () => { try { const keys = await redisClient.keys('user:*'); const now = Date.now(); for (const key of keys) { try { const sessionStr = await redisClient.sendCommand(['JSON.GET', key]); if (sessionStr) { const session = JSON.parse(sessionStr); if (session.timestamp && now - parseInt(session.timestamp) > EXPIRATION_TIME) { const userId = key.split(':')[1]; await redisClient.del(key); await User.update({ authCode: '' }, { where: { hashedId: userId } }); console.log(`Abgelaufene Sitzung für Benutzer ${userId} mit RedisJSON gelöscht.`); } } } catch (error) { if (error.message.includes('WRONGTYPE')) { console.warn(`Schlüssel ${key} ist kein JSON-Objekt, wird übersprungen.`); } else { console.error(`Fehler beim Bereinigen für Schlüssel ${key}:`, error); } } } } catch (error) { console.error('Fehler beim Bereinigen abgelaufener Sitzungen mit RedisJSON:', error); } }; export { setUserSession, deleteUserSession, getUserSession, updateUserTimestamp, cleanupExpiredSessions, redisClient };