/**
* 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",
});
}
}
Source