feat: adiciona testes e melhorias de segurança

- Adiciona testes para auth service (createToken, createTokenPair, logout, refreshAccessToken)
- Adiciona testes para rate-limiting guard
- Adiciona testes para jwt strategy
- Remove arquivos SDK obsoletos
- Melhora validações e tratamento de erros em vários serviços
This commit is contained in:
joelson brito
2025-11-07 10:47:42 -03:00
parent a6cf4893cc
commit de4465ed60
23 changed files with 6209 additions and 4530 deletions

View File

@@ -16,20 +16,14 @@ export interface RefreshTokenData {
@Injectable()
export class RefreshTokenService {
private readonly REFRESH_TOKEN_TTL = 7 * 24 * 60 * 60; // 7 dias em segundos
private readonly MAX_REFRESH_TOKENS_PER_USER = 5; // Máximo 5 refresh tokens por usuário
private readonly REFRESH_TOKEN_TTL = 7 * 24 * 60 * 60;
private readonly MAX_REFRESH_TOKENS_PER_USER = 5;
constructor(
@Inject(RedisClientToken) private readonly redis: IRedisClient,
private readonly jwtService: JwtService,
) {}
/**
* Gera um novo refresh token para o usuário
* @param userId ID do usuário
* @param sessionId ID da sessão (opcional)
* @returns Refresh token
*/
async generateRefreshToken(userId: number, sessionId?: string): Promise<string> {
const tokenId = randomBytes(32).toString('hex');
const refreshToken = this.jwtService.sign(
@@ -48,19 +42,11 @@ export class RefreshTokenService {
const key = this.buildRefreshTokenKey(userId, tokenId);
await this.redis.set(key, tokenData, this.REFRESH_TOKEN_TTL);
/**
* Limita o número de refresh tokens por usuário
*/
await this.limitRefreshTokensPerUser(userId);
return refreshToken;
}
/**
* Valida um refresh token e retorna os dados do usuário
* @param refreshToken Token de refresh
* @returns Dados do usuário se válido
*/
async validateRefreshToken(refreshToken: string): Promise<JwtPayload> {
try {
const decoded = this.jwtService.verify(refreshToken) as any;
@@ -96,20 +82,11 @@ export class RefreshTokenService {
}
}
/**
* Revoga um refresh token específico
* @param userId ID do usuário
* @param tokenId ID do token
*/
async revokeRefreshToken(userId: number, tokenId: string): Promise<void> {
const key = this.buildRefreshTokenKey(userId, tokenId);
await this.redis.del(key);
}
/**
* Revoga todos os refresh tokens de um usuário
* @param userId ID do usuário
*/
async revokeAllRefreshTokens(userId: number): Promise<void> {
const pattern = this.buildRefreshTokenPattern(userId);
const keys = await this.redis.keys(pattern);
@@ -119,11 +96,6 @@ export class RefreshTokenService {
}
}
/**
* Lista todos os refresh tokens ativos de um usuário
* @param userId ID do usuário
* @returns Lista de tokens ativos
*/
async getActiveRefreshTokens(userId: number): Promise<RefreshTokenData[]> {
const pattern = this.buildRefreshTokenPattern(userId);
const keys = await this.redis.keys(pattern);
@@ -140,17 +112,10 @@ export class RefreshTokenService {
return tokens.sort((a, b) => b.createdAt - a.createdAt);
}
/**
* Limita o número de refresh tokens por usuário
* @param userId ID do usuário
*/
private async limitRefreshTokensPerUser(userId: number): Promise<void> {
const activeTokens = await this.getActiveRefreshTokens(userId);
if (activeTokens.length > this.MAX_REFRESH_TOKENS_PER_USER) {
/**
* Remove os tokens mais antigos
*/
const tokensToRemove = activeTokens
.slice(this.MAX_REFRESH_TOKENS_PER_USER)
.map(token => token.tokenId);
@@ -161,21 +126,10 @@ export class RefreshTokenService {
}
}
/**
* Constrói a chave para armazenar o refresh token
* @param userId ID do usuário
* @param tokenId ID do token
* @returns Chave para o Redis
*/
private buildRefreshTokenKey(userId: number, tokenId: string): string {
return `auth:refresh_tokens:${userId}:${tokenId}`;
}
/**
* Constrói o padrão para buscar refresh tokens de um usuário
* @param userId ID do usuário
* @returns Padrão para o Redis
*/
private buildRefreshTokenPattern(userId: number): string {
return `auth:refresh_tokens:${userId}:*`;
}