Ratan1870/code-execution
0
1// ─── Input Validation Middleware ──────────────2// Uses Joi for strict request validation3 4const Joi = require("joi");5const config = require("../config");6 7const supportedLanguages = Object.keys(config.LANGUAGES);8 9// ─── Schema: POST /api/execute ───10const executeSchema = Joi.object({11 language: Joi.string()12 .valid(...supportedLanguages)13 .required()14 .messages({15 "any.only": `Language must be one of: ${supportedLanguages.join(", ")}`,16 "any.required": "Language is required",17 }),18 code: Joi.string()19 .min(1)20 .max(config.MAX_CODE_SIZE)21 .required()22 .messages({23 "string.max": `Code exceeds maximum size of ${config.MAX_CODE_SIZE} bytes`,24 "string.empty": "Code cannot be empty",25 "any.required": "Code is required",26 }),27 input: Joi.string().max(config.MAX_INPUT_SIZE).allow("").default(""),28 timeLimit: Joi.number()29 .integer()30 .min(1)31 .max(config.MAX_TIME_LIMIT)32 .default(config.DEFAULT_TIME_LIMIT)33 .messages({34 "number.max": `Time limit cannot exceed ${config.MAX_TIME_LIMIT} seconds`,35 }),36 memoryLimit: Joi.number()37 .integer()38 .min(16)39 .max(config.MAX_MEMORY_LIMIT)40 .default(config.DEFAULT_MEMORY_LIMIT)41 .messages({42 "number.max": `Memory limit cannot exceed ${config.MAX_MEMORY_LIMIT} MB`,43 }),44});45 46// ─── Schema: Test case ───47const testCaseSchema = Joi.object({48 input: Joi.string().max(config.MAX_INPUT_SIZE).allow("").required(),49 expectedOutput: Joi.string().max(config.MAX_INPUT_SIZE).required(),50});51 52// ─── Schema: POST /api/judge ───53const judgeSchema = Joi.object({54 language: Joi.string()55 .valid(...supportedLanguages)56 .required()57 .messages({58 "any.only": `Language must be one of: ${supportedLanguages.join(", ")}`,59 }),60 code: Joi.string()61 .min(1)62 .max(config.MAX_CODE_SIZE)63 .required()64 .messages({65 "string.max": `Code exceeds maximum size of ${config.MAX_CODE_SIZE} bytes`,66 }),67 testCases: Joi.array()68 .items(testCaseSchema)69 .min(1)70 .max(50)71 .required()72 .messages({73 "array.min": "At least 1 test case is required",74 "array.max": "Maximum 50 test cases allowed",75 }),76 timeLimit: Joi.number()77 .integer()78 .min(1)79 .max(config.MAX_TIME_LIMIT)80 .default(config.DEFAULT_TIME_LIMIT),81 memoryLimit: Joi.number()82 .integer()83 .min(16)84 .max(config.MAX_MEMORY_LIMIT)85 .default(config.DEFAULT_MEMORY_LIMIT),86});87 88// ─── Middleware: Validate execute request ───89function validateExecution(req, res, next) {90 const { error, value } = executeSchema.validate(req.body, {91 abortEarly: false,92 });93 if (error) {94 return res.status(400).json({95 success: false,96 error: "Validation Error",97 details: error.details.map((d) => d.message),98 });99 }100 req.body = value;101 next();102}103 104// ─── Middleware: Validate judge request ───105function validateJudge(req, res, next) {106 const { error, value } = judgeSchema.validate(req.body, {107 abortEarly: false,108 });109 if (error) {110 return res.status(400).json({111 success: false,112 error: "Validation Error",113 details: error.details.map((d) => d.message),114 });115 }116 req.body = value;117 next();118}119 120module.exports = { validateExecution, validateJudge };121 