Source

middlewares/validateFileSize.js

/**
 * Middleware to validate file size for base64 encoded file uploads
 * @module middlewares/validateFileSize
 */
import { env } from "@config/env";
import { getLogger } from "@utils/asyncLocalStorage";
/**
 * Calculate the size of a base64 encoded string in bytes
 * @param {string} base64String - The base64 encoded string
 * @returns {number} Size in bytes
 */
function getBase64Size(base64String) {
    // Remove data URL prefix if present (e.g., "data:image/png;base64,")
    const base64Data = base64String.split(",")[1] || base64String;
    // Calculate actual size: (length * 3) / 4, accounting for padding
    const padding = (base64Data.match(/=/g) || []).length;
    return base64Data.length * 0.75 - padding;
}
/**
 * Middleware to validate file size for uploaded files
 * Checks if the base64 encoded file in the request body exceeds the maximum allowed size
 * Uses OBJECT_IMAGE_MAX_SIZE_MB configuration to ensure consistency with image processing
 * @param {Request} req - Express request object
 * @param {Response} res - Express response object
 * @param {NextFunction} next - Express next function
 * @category Middleware
 */
export function validateFileSize(req, res, next) {
    const logger = getLogger();
    const maxFileSizeBytes = env.OBJECT_IMAGE_MAX_SIZE_MB * 1024 * 1024;
    try {
        // Check if photo exists in request body
        const body = req.body;
        if (body && typeof body.photo === "string") {
            const photoSize = getBase64Size(body.photo);
            if (photoSize > maxFileSizeBytes) {
                logger.warn({
                    fileSize: photoSize,
                    maxSize: maxFileSizeBytes,
                    path: req.path,
                }, "File size exceeds maximum allowed size");
                res.status(413).json({
                    error: "File size exceeds maximum allowed size",
                    maxSize: `${env.OBJECT_IMAGE_MAX_SIZE_MB}MB`,
                    receivedSize: `${(photoSize / (1024 * 1024)).toFixed(2)}MB`,
                });
                return;
            }
            logger.debug({
                fileSize: photoSize,
                maxSize: maxFileSizeBytes,
            }, "File size validation passed");
        }
        next();
    }
    catch (error) {
        logger.error({ error }, "Error validating file size");
        res.status(400).json({
            error: "Invalid file data",
        });
    }
}