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.
64 lines
1.6 KiB
TypeScript
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;
|
|
}
|
|
}
|