"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateFilePath = validateFilePath;
const path_1 = __importDefault(require("path"));
const promises_1 = __importDefault(require("fs/promises"));
/**
 * Validates that a file path is safe and within the allowed base directory
 * Prevents path traversal attacks via:
 * - Null byte injection
 * - Directory traversal sequences (../)
 * - Symlink attacks
 *
 * @param basePath - The allowed base directory (must be absolute)
 * @param relativePath - The relative path to validate
 * @returns The validated absolute path
 * @throws Error if path validation fails
 */
async function validateFilePath(basePath, relativePath) {
    // Check for null bytes
    if (relativePath.includes('\0')) {
        throw new Error('Invalid file path: contains null byte');
    }
    // Resolve to absolute path
    const fullPath = path_1.default.resolve(basePath, relativePath);
    // Verify it's still within base directory
    const resolvedBase = path_1.default.resolve(basePath);
    if (!fullPath.startsWith(resolvedBase)) {
        throw new Error('Invalid file path: directory traversal detected');
    }
    // Check for symlinks (resolve real path)
    try {
        const realPath = await promises_1.default.realpath(fullPath);
        if (!realPath.startsWith(resolvedBase)) {
            throw new Error('Invalid file path: symlink traversal detected');
        }
    }
    catch (err) {
        if (err.code === 'ENOENT') {
            // File doesn't exist yet, verify parent directory
            const parent = path_1.default.dirname(fullPath);
            try {
                const realParent = await promises_1.default.realpath(parent);
                if (!realParent.startsWith(resolvedBase)) {
                    throw new Error('Invalid file path: parent traversal detected');
                }
            }
            catch (parentErr) {
                if (parentErr.code === 'ENOENT') {
                    // Parent also doesn't exist, just verify the path is within base
                    // This is already checked above
                }
                else {
                    throw parentErr;
                }
            }
        }
        else {
            throw err;
        }
    }
    return fullPath;
}
//# sourceMappingURL=path-validator.js.map