"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiKeyService = void 0;
const common_1 = require("@nestjs/common");
const base_service_1 = require("./base.service");
const access_1 = require("../utils/access");
let ApiKeyService = class ApiKeyService extends base_service_1.BaseService {
    async create(auth, dto) {
        const token = this.cryptoRepository.randomBytesAsText(32);
        const hashed = this.cryptoRepository.hashSha256(token);
        if (auth.apiKey && !(0, access_1.isGranted)({ requested: dto.permissions, current: auth.apiKey.permissions })) {
            throw new common_1.BadRequestException('Cannot grant permissions you do not have');
        }
        const entity = await this.apiKeyRepository.create({
            key: hashed,
            name: dto.name || 'API Key',
            userId: auth.user.id,
            permissions: dto.permissions,
        });
        return { secret: token, apiKey: this.map(entity) };
    }
    async update(auth, id, dto) {
        const exists = await this.apiKeyRepository.getById(auth.user.id, id);
        if (!exists) {
            throw new common_1.BadRequestException('API Key not found');
        }
        if (auth.apiKey &&
            dto.permissions &&
            !(0, access_1.isGranted)({ requested: dto.permissions, current: auth.apiKey.permissions })) {
            throw new common_1.BadRequestException('Cannot grant permissions you do not have');
        }
        const key = await this.apiKeyRepository.update(auth.user.id, id, { name: dto.name, permissions: dto.permissions });
        return this.map(key);
    }
    async delete(auth, id) {
        const exists = await this.apiKeyRepository.getById(auth.user.id, id);
        if (!exists) {
            throw new common_1.BadRequestException('API Key not found');
        }
        await this.apiKeyRepository.delete(auth.user.id, id);
    }
    async getMine(auth) {
        if (!auth.apiKey) {
            throw new common_1.ForbiddenException('Not authenticated with an API Key');
        }
        const key = await this.apiKeyRepository.getById(auth.user.id, auth.apiKey.id);
        if (!key) {
            throw new common_1.BadRequestException('API Key not found');
        }
        return this.map(key);
    }
    async getById(auth, id) {
        const key = await this.apiKeyRepository.getById(auth.user.id, id);
        if (!key) {
            throw new common_1.BadRequestException('API Key not found');
        }
        return this.map(key);
    }
    async getAll(auth) {
        const keys = await this.apiKeyRepository.getByUserId(auth.user.id);
        return keys.map((key) => this.map(key));
    }
    map(entity) {
        return {
            id: entity.id,
            name: entity.name,
            createdAt: entity.createdAt,
            updatedAt: entity.updatedAt,
            permissions: entity.permissions,
        };
    }
};
exports.ApiKeyService = ApiKeyService;
exports.ApiKeyService = ApiKeyService = __decorate([
    (0, common_1.Injectable)()
], ApiKeyService);
//# sourceMappingURL=api-key.service.js.map