"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleLogin = handleLogin;
exports.handleChangePassword = handleChangePassword;
const axios_1 = __importDefault(require("axios"));
const map_1 = __importDefault(require("lodash/map"));
const reduce_1 = __importDefault(require("lodash/reduce"));
const constants_1 = require("../../shared/constants");
const requestsSetup_1 = require("../components/requestsSetup");
const utils_1 = require("../utils");
const crypto_1 = __importDefault(require("crypto"));
// @ts-ignore
const javascript_wrapper_1 = __importDefault(require("@ytsaurus/javascript-wrapper"));
const cluster_queries_1 = require("../components/cluster-queries");
const yt = (0, javascript_wrapper_1.default)();
async function handleLogin(req, res) {
    try {
        const { ytAuthCluster } = req.params;
        const { username, password } = JSON.parse(req.body) || {};
        if (!username || !password) {
            throw new Error('Username and password must not be empty');
        }
        const { proxyBaseUrl } = (0, requestsSetup_1.getYTApiClusterSetup)(ytAuthCluster);
        const requestUrl = `${proxyBaseUrl}/login`;
        const basicAuth = Buffer.from(`${username}:${password}`).toString('base64');
        await axios_1.default
            .request({
            url: requestUrl,
            method: req.method,
            headers: { ...req.ctx.getMetadata(), Authorization: `Basic ${basicAuth}` },
            timeout: 10000,
            responseType: 'stream',
        })
            .then(async (response) => {
            const pipedSize = await (0, utils_1.pipeAxiosResponse)(req.ctx, res, response, undefined, (headers) => {
                if (headers['set-cookie']) {
                    headers['set-cookie'] = headers['set-cookie'].reduce((ret, item) => {
                        ret.push(item);
                        if (item.startsWith(constants_1.YT_CYPRESS_COOKIE_NAME)) {
                            ret.push(item.replace(constants_1.YT_CYPRESS_COOKIE_NAME, (0, utils_1.makeAuthClusterCookieName)(ytAuthCluster)));
                        }
                        return ret;
                    }, []);
                }
                return removeSecureFlagIfOriginInsecure(req, headers);
            });
            if (!pipedSize) {
                throw new Error(utils_1.UNEXPECTED_PIPE_AXIOS_RESPONSE);
            }
        });
    }
    catch (e) {
        if (e?.response?.status === 401) {
            // To avoid redirecting to login page when checking user password
            e.response.status = 400;
        }
        (0, utils_1.sendAndLogError)(req.ctx, res, 500, e);
    }
}
function removeSecureFlagIfOriginInsecure(req, headers) {
    const { ytAuthAllowInsecure } = req.ctx.config;
    const { origin } = req.headers;
    if (!ytAuthAllowInsecure || 'string' !== typeof origin || !origin.startsWith('http://')) {
        return headers;
    }
    return (0, reduce_1.default)(headers, (acc, v, k) => {
        if (k !== 'set-cookie') {
            acc[k] = v;
        }
        else {
            const tmp = (0, map_1.default)(v, (item) => {
                if (item.includes(constants_1.YT_CYPRESS_COOKIE_NAME)) {
                    return item.replace(/\s*Secure;/, '');
                }
                return item;
            });
            acc[k] = tmp;
        }
        return acc;
    }, {});
}
async function handleChangePassword(req, res) {
    try {
        const ytAuthCluster = req.params.ytAuthCluster;
        if (!ytAuthCluster) {
            throw new Error('You have to define ytAuthCluster.');
        }
        const { newPassword, currentPassword } = JSON.parse(req.body) || {};
        if (!newPassword || !currentPassword) {
            throw new Error('New and current password must not be empty');
        }
        const new_password_sha256 = crypto_1.default.createHash('sha256').update(newPassword).digest('hex');
        const current_password_sha256 = crypto_1.default
            .createHash('sha256')
            .update(currentPassword)
            .digest('hex');
        let cfg;
        try {
            cfg = (0, requestsSetup_1.getUserYTApiSetup)(ytAuthCluster, req);
        }
        catch (e) {
            (0, utils_1.sendAndLogError)(req.ctx, res, 400, e);
            return;
        }
        const { setup } = cfg;
        const { login, csrf_token } = await (0, cluster_queries_1.getXSRFToken)(req, cfg);
        yt.setup.createOption('requestHeaders', 'object', {
            'X-Csrf-Token': csrf_token,
        });
        await yt.v4
            .setUserPassword({
            setup,
            parameters: { user: login, new_password_sha256, current_password_sha256 },
        })
            .then((result) => {
            res.status(200).send({ result });
        })
            .catch((err) => {
            (0, utils_1.sendAndLogError)(req.ctx, res, 500, err);
        });
    }
    catch (e) {
        (0, utils_1.sendAndLogError)(req.ctx, res, 500, e);
    }
}
