"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;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AccessKeyService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const access_key_entity_1 = require("../entities/access-key.entity");
const user_entity_1 = require("../entities/user.entity");
const event_emitter_1 = require("@nestjs/event-emitter");
const crypto_1 = require("crypto");
const auth_constants_1 = require("../../auth.constants");
let AccessKeyService = class AccessKeyService {
    accessKeyRepository;
    userRepository;
    eventEmitter;
    constructor(accessKeyRepository, userRepository, eventEmitter) {
        this.accessKeyRepository = accessKeyRepository;
        this.userRepository = userRepository;
        this.eventEmitter = eventEmitter;
    }
    generateKeyPair() {
        const privateKey = (0, crypto_1.randomBytes)(32).toString('hex');
        const publicKey = (0, crypto_1.createHash)('sha256').update(privateKey).digest('hex');
        return { publicKey, privateKey };
    }
    async createAccessKey(userId, name) {
        const user = await this.userRepository.findOne({ where: { id: userId } });
        if (!user) {
            throw new common_1.NotFoundException({
                message: `User with ID ${userId} not found`,
                code: 'USER_NOT_FOUND'
            });
        }
        const { publicKey, privateKey } = this.generateKeyPair();
        const accessKey = this.accessKeyRepository.create({
            name,
            publicKey,
            privateKey,
            userId,
        });
        const savedKey = await this.accessKeyRepository.save(accessKey);
        await this.eventEmitter.emitAsync(auth_constants_1.NestAuthEvents.ACCESS_KEY_CREATED, {
            accessKey: savedKey,
            userId
        });
        return savedKey;
    }
    async getAccessKey(publicKey) {
        const accessKey = await this.accessKeyRepository.findOne({
            where: { publicKey },
            relations: ['user']
        });
        if (!accessKey) {
            throw new common_1.NotFoundException({
                message: 'Invalid access key',
                code: 'INVALID_ACCESS_KEY'
            });
        }
        if (!accessKey.isActive) {
            throw new common_1.BadRequestException({
                message: 'Access key is inactive',
                code: 'INACTIVE_ACCESS_KEY'
            });
        }
        if (accessKey.expiresAt && accessKey.expiresAt < new Date()) {
            throw new common_1.BadRequestException({
                message: 'Access key has expired',
                code: 'EXPIRED_ACCESS_KEY'
            });
        }
        return accessKey;
    }
    async validateAccessKey(publicKey, privateKey) {
        const accessKey = await this.getAccessKey(publicKey);
        return accessKey.privateKey === privateKey;
    }
    async getUserAccessKeys(userId) {
        return this.accessKeyRepository.find({
            where: { userId },
            order: { createdAt: 'DESC' }
        });
    }
    async deactivateAccessKey(publicKey) {
        const accessKey = await this.getAccessKey(publicKey);
        accessKey.isActive = false;
        const updatedKey = await this.accessKeyRepository.save(accessKey);
        await this.eventEmitter.emitAsync(auth_constants_1.NestAuthEvents.ACCESS_KEY_DEACTIVATED, {
            accessKey: updatedKey,
            userId: updatedKey.userId
        });
        return updatedKey;
    }
    async updateAccessKeyLastUsed(publicKey) {
        const accessKey = await this.getAccessKey(publicKey);
        accessKey.lastUsedAt = new Date();
        await this.accessKeyRepository.save(accessKey);
    }
    async setAccessKeyExpiry(publicKey, expiresAt) {
        const accessKey = await this.getAccessKey(publicKey);
        accessKey.expiresAt = expiresAt;
        return this.accessKeyRepository.save(accessKey);
    }
    async deleteAccessKey(publicKey) {
        const accessKey = await this.getAccessKey(publicKey);
        await this.eventEmitter.emitAsync(auth_constants_1.NestAuthEvents.ACCESS_KEY_DELETED, {
            accessKey,
            userId: accessKey.userId
        });
        await this.accessKeyRepository.remove(accessKey);
    }
};
exports.AccessKeyService = AccessKeyService;
exports.AccessKeyService = AccessKeyService = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(access_key_entity_1.NestAuthAccessKey)),
    __param(1, (0, typeorm_1.InjectRepository)(user_entity_1.NestAuthUser)),
    __metadata("design:paramtypes", [typeorm_2.Repository,
        typeorm_2.Repository,
        event_emitter_1.EventEmitter2])
], AccessKeyService);
//# sourceMappingURL=access-key.service.js.map