Simplifica start:prod e ajusta consultas de ofertas para 10x (codplpagmax=42), com melhorias de sanitização e imports.
75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
import { Injectable, Inject } from '@nestjs/common';
|
|
import { RedisClientToken } from '../../core/configs/cache/redis-client.adapter.provider';
|
|
import { IRedisClient } from '../../core/configs/cache/IRedisClient';
|
|
import { JwtService } from '@nestjs/jwt';
|
|
import { JwtPayload } from '../models/jwt-payload.model';
|
|
import * as crypto from 'crypto';
|
|
|
|
@Injectable()
|
|
export class TokenBlacklistService {
|
|
constructor(
|
|
@Inject(RedisClientToken) private readonly redis: IRedisClient,
|
|
private readonly jwtService: JwtService,
|
|
) {}
|
|
|
|
async addToBlacklist(token: string, expiresIn?: number): Promise<void> {
|
|
try {
|
|
const decoded = this.jwtService.decode(token) as JwtPayload;
|
|
if (!decoded) {
|
|
throw new Error('Token inválido');
|
|
}
|
|
|
|
const blacklistKey = this.buildBlacklistKey(token);
|
|
const ttl = expiresIn || this.calculateTokenTTL(decoded);
|
|
|
|
await this.redis.set(blacklistKey, 'blacklisted', ttl);
|
|
} catch (error) {
|
|
throw new Error(`Erro ao adicionar token à blacklist: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
async isBlacklisted(token: string): Promise<boolean> {
|
|
try {
|
|
const blacklistKey = this.buildBlacklistKey(token);
|
|
const result = await this.redis.get(blacklistKey);
|
|
return result === 'blacklisted';
|
|
} catch (_error) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async removeFromBlacklist(token: string): Promise<void> {
|
|
const blacklistKey = this.buildBlacklistKey(token);
|
|
await this.redis.del(blacklistKey);
|
|
}
|
|
|
|
async clearUserBlacklist(userId: number): Promise<void> {
|
|
const pattern = `auth:blacklist:${userId}:*`;
|
|
const keys = await this.redis.keys(pattern);
|
|
|
|
if (keys.length > 0) {
|
|
await this.redis.del(...keys);
|
|
}
|
|
}
|
|
|
|
private buildBlacklistKey(token: string): string {
|
|
const decoded = this.jwtService.decode(token) as JwtPayload;
|
|
const tokenHash = this.hashToken(token);
|
|
return `auth:blacklist:${decoded.id}:${tokenHash}`;
|
|
}
|
|
|
|
private calculateTokenTTL(payload: JwtPayload): number {
|
|
const now = Math.floor(Date.now() / 1000);
|
|
const exp = payload.exp || now + 8 * 60 * 60;
|
|
return Math.max(0, exp - now);
|
|
}
|
|
|
|
private hashToken(token: string): string {
|
|
return crypto
|
|
.createHash('sha256')
|
|
.update(token)
|
|
.digest('hex')
|
|
.substring(0, 16);
|
|
}
|
|
}
|