import { APIKeyEntity } from '@app/infra/entities'; import { BadRequestException, Inject, Injectable } from '@nestjs/common'; import { AuthUserDto } from '../auth'; import { ICryptoRepository } from '../crypto'; import { APIKeyCreateDto, APIKeyCreateResponseDto, APIKeyResponseDto } from './api-key.dto'; import { IKeyRepository } from './api-key.repository'; @Injectable() export class APIKeyService { constructor( @Inject(ICryptoRepository) private crypto: ICryptoRepository, @Inject(IKeyRepository) private repository: IKeyRepository, ) {} async create(authUser: AuthUserDto, dto: APIKeyCreateDto): Promise { const secret = this.crypto.randomBytes(32).toString('base64').replace(/\W/g, ''); const entity = await this.repository.create({ key: this.crypto.hashSha256(secret), name: dto.name || 'API Key', userId: authUser.id, }); return { secret, apiKey: this.map(entity) }; } async update(authUser: AuthUserDto, id: string, dto: APIKeyCreateDto): Promise { const exists = await this.repository.getById(authUser.id, id); if (!exists) { throw new BadRequestException('API Key not found'); } const key = await this.repository.update(authUser.id, id, { name: dto.name }); return this.map(key); } async delete(authUser: AuthUserDto, id: string): Promise { const exists = await this.repository.getById(authUser.id, id); if (!exists) { throw new BadRequestException('API Key not found'); } await this.repository.delete(authUser.id, id); } async getById(authUser: AuthUserDto, id: string): Promise { const key = await this.repository.getById(authUser.id, id); if (!key) { throw new BadRequestException('API Key not found'); } return this.map(key); } async getAll(authUser: AuthUserDto): Promise { const keys = await this.repository.getByUserId(authUser.id); return keys.map((key) => this.map(key)); } private map(entity: APIKeyEntity): APIKeyResponseDto { return { id: entity.id, name: entity.name, createdAt: entity.createdAt, updatedAt: entity.updatedAt, }; } }