"use strict";
const backend_common_1 = require("@n8n/backend-common");
const db_1 = require("@n8n/db");
const di_1 = require("@n8n/di");
const permissions_1 = require("@n8n/permissions");
const zod_1 = require("zod");
const credential_types_1 = require("../../../../credential-types");
const credentials_service_ee_1 = require("../../../../credentials/credentials.service.ee");
const credentials_helper_1 = require("../../../../credentials-helper");
const response_error_1 = require("../../../../errors/response-errors/abstract/response.error");
const credentials_middleware_1 = require("./credentials.middleware");
const credentials_service_1 = require("./credentials.service");
const global_middleware_1 = require("../../shared/middlewares/global.middleware");
const pagination_service_1 = require("../../shared/services/pagination.service");
module.exports = {
    getCredentials: [
        (0, global_middleware_1.apiKeyHasScopeWithGlobalScopeFallback)({ scope: 'credential:list' }),
        global_middleware_1.validCursor,
        async (req, res) => {
            const offset = Number(req.query.offset) || 0;
            const limit = Math.min(Number(req.query.limit) || 100, 250);
            const repo = di_1.Container.get(db_1.CredentialsRepository);
            const [credentials, count] = await repo.findAndCount({
                take: limit,
                skip: offset,
                select: ['id', 'name', 'type', 'createdAt', 'updatedAt'],
                relations: ['shared', 'shared.project'],
                order: { createdAt: 'DESC' },
            });
            const data = credentials.map((credential) => {
                const shared = (0, credentials_service_1.buildSharedForCredential)(credential);
                return {
                    id: credential.id,
                    name: credential.name,
                    type: credential.type,
                    createdAt: credential.createdAt,
                    updatedAt: credential.updatedAt,
                    shared,
                };
            });
            return res.json({
                data,
                nextCursor: (0, pagination_service_1.encodeNextCursor)({
                    offset,
                    limit,
                    numberOfTotalRecords: count,
                }),
            });
        },
    ],
    createCredential: [
        credentials_middleware_1.validCredentialType,
        credentials_middleware_1.validCredentialsProperties,
        (0, global_middleware_1.publicApiScope)('credential:create'),
        async (req, res) => {
            const savedCredential = await (0, credentials_service_1.saveCredential)(req.body, req.user);
            return res.json((0, credentials_service_1.sanitizeCredentials)(savedCredential));
        },
    ],
    updateCredential: [
        credentials_middleware_1.validCredentialTypeForUpdate,
        credentials_middleware_1.validCredentialsPropertiesForUpdate,
        (0, global_middleware_1.publicApiScope)('credential:update'),
        (0, global_middleware_1.projectScope)('credential:update', 'credential'),
        async (req, res) => {
            const { id: credentialId } = req.params;
            const existingCredential = await (0, credentials_service_1.getCredential)(credentialId);
            if (!existingCredential) {
                return res.status(404).json({ message: 'Credential not found' });
            }
            if (req.body.isGlobal !== undefined && req.body.isGlobal !== existingCredential.isGlobal) {
                if (!di_1.Container.get(backend_common_1.LicenseState).isSharingLicensed()) {
                    return res.status(403).json({ message: 'You are not licensed for sharing credentials' });
                }
                const canShareGlobally = (0, permissions_1.hasGlobalScope)(req.user, 'credential:shareGlobally');
                if (!canShareGlobally) {
                    return res.status(403).json({
                        message: 'You do not have permission to change global sharing for credentials',
                    });
                }
            }
            try {
                const updatedCredential = await (0, credentials_service_1.updateCredential)(existingCredential, req.user, req.body);
                return res.json((0, credentials_service_1.sanitizeCredentials)(updatedCredential));
            }
            catch (error) {
                if (error instanceof credentials_service_1.CredentialsIsNotUpdatableError) {
                    return res.status(400).json({ message: error.message });
                }
                if (error instanceof response_error_1.ResponseError) {
                    return res.status(error.httpStatusCode).json({ message: error.message });
                }
                const message = error instanceof Error ? error.message : 'Unknown error';
                return res.status(500).json({ message });
            }
        },
    ],
    transferCredential: [
        (0, global_middleware_1.publicApiScope)('credential:move'),
        (0, global_middleware_1.projectScope)('credential:move', 'credential'),
        async (req, res) => {
            const body = zod_1.z.object({ destinationProjectId: zod_1.z.string() }).parse(req.body);
            await di_1.Container.get(credentials_service_ee_1.EnterpriseCredentialsService).transferOne(req.user, req.params.id, body.destinationProjectId);
            res.status(204).send();
        },
    ],
    deleteCredential: [
        (0, global_middleware_1.publicApiScope)('credential:delete'),
        (0, global_middleware_1.projectScope)('credential:delete', 'credential'),
        async (req, res) => {
            const { id: credentialId } = req.params;
            let credential;
            if (!['global:owner', 'global:admin'].includes(req.user.role.slug)) {
                const shared = await (0, credentials_service_1.getSharedCredentials)(req.user.id, credentialId);
                if (shared?.role === 'credential:owner') {
                    credential = shared.credentials;
                }
            }
            else {
                credential = (await (0, credentials_service_1.getCredential)(credentialId));
            }
            if (!credential) {
                return res.status(404).json({ message: 'Not Found' });
            }
            await (0, credentials_service_1.removeCredential)(req.user, credential);
            return res.json((0, credentials_service_1.sanitizeCredentials)(credential));
        },
    ],
    getCredentialType: [
        async (req, res) => {
            const { credentialTypeName } = req.params;
            try {
                di_1.Container.get(credential_types_1.CredentialTypes).getByName(credentialTypeName);
            }
            catch (error) {
                return res.status(404).json({ message: 'Not Found' });
            }
            const schema = di_1.Container.get(credentials_helper_1.CredentialsHelper)
                .getCredentialsProperties(credentialTypeName)
                .filter((property) => property.type !== 'hidden');
            return res.json((0, credentials_service_1.toJsonSchema)(schema));
        },
    ],
};
//# sourceMappingURL=credentials.handler.js.map