import { eq } from 'drizzle-orm'; import { db } from '../db'; import { userSessions } from '@shared/schema'; /** * Проверка отзыва сессии (user_sessions.is_revoked) для access-токенов с claim sid. * In-memory кэш ~30 сек: неизменный ответ не дёргает БД на каждый запрос, * отозванная сессия умирает в течение ~30 секунд на всех инстансах приложения. */ const CACHE_TTL_MS = 30_000; const cache = new Map(); export async function isSessionRevoked(sid: number): Promise { const hit = cache.get(sid); if (hit && Date.now() - hit.ts < CACHE_TTL_MS) return hit.revoked; const [row] = await db .select({ isRevoked: userSessions.isRevoked }) .from(userSessions) .where(eq(userSessions.id, sid)); // Неизвестная/удалённая сессия считается отозванной const revoked = row ? row.isRevoked : true; cache.set(sid, { revoked, ts: Date.now() }); return revoked; } /** Сброс кэша после явного отзыва (logout, отзыв устройства, смена пароля) */ export function invalidateSessionRevocationCache(sid?: number): void { if (sid === undefined) cache.clear(); else cache.delete(sid); }