"use strict";
// @ts-check
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = userAuth;
const decrypt_1 = __importDefault(require("../package-shared/functions/dsql/decrypt"));
const get_auth_cookie_names_1 = __importDefault(require("../package-shared/functions/backend/cookies/get-auth-cookie-names"));
const write_auth_files_1 = require("../package-shared/functions/backend/auth/write-auth-files");
const parseCookies_1 = __importDefault(require("../package-shared/utils/backend/parseCookies"));
const minuteInMilliseconds = 60000;
const hourInMilliseconds = minuteInMilliseconds * 60;
const dayInMilliseconds = hourInMilliseconds * 24;
const weekInMilliseconds = dayInMilliseconds * 7;
const monthInMilliseconds = dayInMilliseconds * 30;
const yearInMilliseconds = dayInMilliseconds * 365;
/**
 * Authenticate User from request
 * ==============================================================================
 * @description This Function takes in a request object and returns a user object
 * with the user's data
 */
function userAuth({ request, req, encryptionKey, encryptionSalt, level, database, dsqlUserId, encryptedUserString, expiry = weekInMilliseconds, cookieString, csrfHeaderIsValue, csrfHeaderName, }) {
    try {
        const finalRequest = req || request;
        const finalEncryptionKey = encryptionKey || process.env.DSQL_ENCRYPTION_PASSWORD;
        const finalEncryptionSalt = encryptionSalt || process.env.DSQL_ENCRYPTION_SALT;
        const cookies = (0, parseCookies_1.default)({
            request: finalRequest,
            cookieString,
        });
        const keyNames = (0, get_auth_cookie_names_1.default)({
            userId: dsqlUserId || process.env.DSQL_API_USER_ID,
            database: database || process.env.DSQL_DB_NAME,
        });
        const authKeyName = keyNames.keyCookieName;
        const csrfName = keyNames.csrfCookieName;
        const key = encryptedUserString
            ? encryptedUserString
            : cookies[authKeyName];
        const csrf = cookies[csrfName];
        /**
         * Grab the payload
         *
         * @description Grab the payload
         */
        let userPayloadJSON = (0, decrypt_1.default)({
            encryptedString: key,
            encryptionKey: finalEncryptionKey,
            encryptionSalt: finalEncryptionSalt,
        });
        /**
         * Grab the payload
         *
         * @description Grab the payload
         */
        if (!userPayloadJSON) {
            return {
                success: false,
                payload: null,
                msg: "Couldn't Decrypt cookie",
            };
        }
        /**
         * Grab the payload
         *
         * @description Grab the payload
         */
        /** @type {import("../package-shared/types").DATASQUIREL_LoggedInUser} */
        let userObject = JSON.parse(userPayloadJSON);
        if (!userObject.csrf_k) {
            return {
                success: false,
                payload: null,
                msg: "No CSRF_K in decrypted payload",
            };
        }
        if (!(0, write_auth_files_1.checkAuthFile)(userObject.csrf_k)) {
            return {
                success: false,
                payload: null,
                msg: "Auth file doesn't exist",
            };
        }
        /**
         * Grab the payload
         *
         * @description Grab the payload
         */
        if ((level === null || level === void 0 ? void 0 : level.match(/deep/i)) && finalRequest) {
            if (csrfHeaderName &&
                finalRequest.headers[csrfHeaderName] !== userObject.csrf_k) {
                return {
                    success: false,
                    payload: null,
                    msg: "CSRF_K mismatch",
                };
            }
            const targetCsrfHeaderKey = Object.keys(finalRequest.headers)
                .map((k) => k.replace(/[^a-zA-Z0-9\-]/g, ""))
                .find((k) => k == userObject.csrf_k);
            if (csrfHeaderIsValue && !targetCsrfHeaderKey) {
                return {
                    success: false,
                    payload: null,
                    msg: "CSRF_K Header Key mismatch",
                };
            }
        }
        const payloadCreationDate = Number(userObject.date);
        if (Number.isNaN(payloadCreationDate) ||
            typeof payloadCreationDate !== "number") {
            return {
                success: false,
                payload: null,
                msg: "Payload Creation Date is not a number",
            };
        }
        const timeElapsed = Date.now() - payloadCreationDate;
        const finalExpiry = process.env.DSQL_SESSION_EXPIRY_TIME
            ? Number(process.env.DSQL_SESSION_EXPIRY_TIME)
            : expiry;
        if (timeElapsed > finalExpiry) {
            return {
                success: false,
                payload: null,
                msg: "Session has expired",
            };
        }
        /**
         * Return User Object
         *
         * @description Return User Object
         */
        return {
            success: true,
            payload: userObject,
        };
    }
    catch ( /** @type {any} */error) {
        /**
         * Return User Object
         *
         * @description Return User Object
         */
        return {
            success: false,
            payload: null,
            msg: error.message,
        };
    }
}