"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CreateClientCredentialsHandler = void 0;
const node_crypto_1 = require("node:crypto");
const yup_1 = require("yup");
const global_logger_factory_1 = require("global-logger-factory");
const BadRequestHttpError_1 = require("../../../util/errors/BadRequestHttpError");
const StringUtil_1 = require("../../../util/StringUtil");
const AccountUtil_1 = require("../account/util/AccountUtil");
const JsonInteractionHandler_1 = require("../JsonInteractionHandler");
const YupUtil_1 = require("../YupUtil");
const inSchema = (0, yup_1.object)({
    name: (0, yup_1.string)().trim().optional(),
    webId: (0, yup_1.string)().trim().required(),
});
/**
 * Handles the creation of client credential tokens.
 */
class CreateClientCredentialsHandler extends JsonInteractionHandler_1.JsonInteractionHandler {
    logger = (0, global_logger_factory_1.getLoggerFor)(this);
    webIdStore;
    clientCredentialsStore;
    clientCredentialsRoute;
    constructor(webIdStore, clientCredentialsStore, clientCredentialsRoute) {
        super();
        this.webIdStore = webIdStore;
        this.clientCredentialsStore = clientCredentialsStore;
        this.clientCredentialsRoute = clientCredentialsRoute;
    }
    async getView({ accountId }) {
        (0, AccountUtil_1.assertAccountId)(accountId);
        const clientCredentials = {};
        for (const { id, label } of await this.clientCredentialsStore.findByAccount(accountId)) {
            clientCredentials[label] = this.clientCredentialsRoute.getPath({ accountId, clientCredentialsId: id });
        }
        return { json: { ...(0, YupUtil_1.parseSchema)(inSchema), clientCredentials } };
    }
    async handle({ accountId, json }) {
        (0, AccountUtil_1.assertAccountId)(accountId);
        const { name, webId } = await (0, YupUtil_1.validateWithError)(inSchema, json);
        if (!await this.webIdStore.isLinked(webId, accountId)) {
            this.logger.warn(`Trying to create token for ${webId} which does not belong to account ${accountId}`);
            throw new BadRequestHttpError_1.BadRequestHttpError('WebID does not belong to this account.');
        }
        const cleanedName = name ? (0, StringUtil_1.sanitizeUrlPart)(name.trim()) : '';
        const label = `${cleanedName}_${(0, node_crypto_1.randomUUID)()}`;
        const { secret, id } = await this.clientCredentialsStore.create(label, webId, accountId);
        const resource = this.clientCredentialsRoute.getPath({ accountId, clientCredentialsId: id });
        // Exposing the field as `id` as that is how we originally defined the client credentials API
        // and is more consistent with how the field names are explained in other places
        return { json: { id: label, secret, resource } };
    }
}
exports.CreateClientCredentialsHandler = CreateClientCredentialsHandler;
//# sourceMappingURL=CreateClientCredentialsHandler.js.map