Files
memegoat/backend/src/api-keys/api-keys.service.ts
Mathis HERRIOT 514bd354bf feat: add modular services and repositories for improved code organization
Introduce repository pattern across multiple services, including `favorites`, `tags`, `sessions`, `reports`, `auth`, and more. Decouple crypto functionalities into modular services like `HashingService`, `JwtService`, and `EncryptionService`. Improve testability and maintainability by simplifying dependencies and consolidating utility logic.
2026-01-14 12:11:39 +01:00

64 lines
1.6 KiB
TypeScript

import { randomBytes } from "node:crypto";
import { Injectable, Logger } from "@nestjs/common";
import { HashingService } from "../crypto/services/hashing.service";
import { ApiKeysRepository } from "./repositories/api-keys.repository";
@Injectable()
export class ApiKeysService {
private readonly logger = new Logger(ApiKeysService.name);
constructor(
private readonly apiKeysRepository: ApiKeysRepository,
private readonly hashingService: HashingService,
) {}
async create(userId: string, name: string, expiresAt?: Date) {
this.logger.log(`Creating API key for user ${userId}: ${name}`);
const prefix = "mg_live_";
const randomPart = randomBytes(24).toString("hex");
const key = `${prefix}${randomPart}`;
const keyHash = await this.hashingService.hashSha256(key);
await this.apiKeysRepository.create({
userId,
name,
prefix: prefix.substring(0, 8),
keyHash,
expiresAt,
});
return {
name,
key, // Retourné une seule fois à la création
expiresAt,
};
}
async findAll(userId: string) {
return await this.apiKeysRepository.findAll(userId);
}
async revoke(userId: string, keyId: string) {
this.logger.log(`Revoking API key ${keyId} for user ${userId}`);
return await this.apiKeysRepository.revoke(userId, keyId);
}
async validateKey(key: string) {
const keyHash = await this.hashingService.hashSha256(key);
const apiKey = await this.apiKeysRepository.findActiveByKeyHash(keyHash);
if (!apiKey) return null;
if (apiKey.expiresAt && apiKey.expiresAt < new Date()) {
return null;
}
// Update last used at
await this.apiKeysRepository.updateLastUsed(apiKey.id);
return apiKey;
}
}