feat(auth): access 24ч, jti против гонок ротации, транзакционная ротация, отзыв сессий по sid
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type { Request, Response, NextFunction } from 'express';
|
||||
import { verifyAccessToken, verifyBotServiceToken, verifySuperAdminToken } from '../utils/jwt';
|
||||
import { isSessionRevoked } from '../utils/sessionRevocation';
|
||||
import { storage } from '../storage';
|
||||
import { withTenant, openTenantCtx, openSuperAdminCtx, _tenantCtx } from '../db';
|
||||
import { eq } from 'drizzle-orm';
|
||||
@@ -70,6 +71,15 @@ export const authenticateToken = async (
|
||||
if (decoded.appRole === 'bot' || (typeof payloadType === 'string' && payloadType.startsWith('bot'))) {
|
||||
return res.status(401).json({ error: 'Токены ботов не принимаются на этом ресурсе' });
|
||||
}
|
||||
// Отзыв устройства: сессия из claim sid отозвана → токен недействителен
|
||||
// (проверка с кэшем ~30 сек, см. utils/sessionRevocation)
|
||||
if (decoded.sid && await isSessionRevoked(decoded.sid)) {
|
||||
return res.status(401).json({ error: 'Сессия отозвана' });
|
||||
}
|
||||
// sid сессии — для пометки «текущее устройство» в списке сессий
|
||||
if (decoded.sid) {
|
||||
(req as any).sessionId = decoded.sid;
|
||||
}
|
||||
// Use JWT organizationId to set tenant context for the users table lookup,
|
||||
// preventing auth failure when FORCE RLS is active on the users table.
|
||||
const user = await withTenant(decoded.organizationId, () =>
|
||||
|
||||
Reference in New Issue
Block a user