Files
yourpart3/backend/utils/redis.js
Torsten Schulz (local) cdaaf7e515 Änderung: Verbesserung der Redis-Integration und Aktualisierung der HTML-Metadaten
Änderungen:
- Die Redis-Client-Konfiguration wurde aktualisiert, um die Verwendung von Umgebungsvariablen für Passwort und URL zu unterstützen.
- Warnungen wurden hinzugefügt, um auf fehlende Authentifizierungsinformationen hinzuweisen.
- Die HTML-Dateien wurden um wichtige Metadaten wie Beschreibung, Open Graph- und Twitter-Tags erweitert, um die Sichtbarkeit und SEO zu verbessern.
- Eine Beta-Hinweis-Nachricht wurde in die NoLoginView.vue eingefügt, um Benutzer über den Entwicklungsstatus der Plattform zu informieren.

Diese Anpassungen erhöhen die Sicherheit der Redis-Verbindung und verbessern die Benutzererfahrung sowie die Auffindbarkeit der Anwendung.
2025-09-11 16:55:40 +02:00

129 lines
4.7 KiB
JavaScript

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;
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}`;
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
};