import { createRepCompleteMessage } from "../../../actions/azurestorage"; import { hashAPIPath } from "../../../actions/core/hash"; import { consoleLogger } from "../../../actions/core/logger"; import { respondError, respondSuccess } from "../middleware/apiResponse"; import { getSession } from "next-auth/react"; const forbidden = (res) => respondError(res, { status: 403, code: "FORBIDDEN", message: "Request not permitted" }); const isValidContainer = (value) => typeof value === "string" && value.length >= 3 && value.length <= 63 && /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(value); const isValidPathSegment = (value) => typeof value === "string" && value.length > 0 && value.length <= 255 && value === value.trim() && value !== "." && value !== ".." && !/[\\/\u0000-\u001f\u007f]/.test(value); export default async function handler(req, res) { res.setHeader("Allow", "GET"); if (req.method !== "GET") { return respondError(res, { status: 405, code: "METHOD_NOT_ALLOWED", message: "Method not allowed" }); } const containerName = req.query.container; const tempCaseRef = req.query.tempcaseref; const filename = req.query.repid; const checkHash = req.query.hash; if ( typeof containerName === "undefined" || containerName === "" || typeof tempCaseRef === "undefined" || tempCaseRef === "" || typeof filename === "undefined" || filename === "" || typeof checkHash === "undefined" || checkHash === "" ) { return respondError(res, { status: 400, code: "MISSING_REQUIRED_QUERY", message: "container, tempcaseref, repid and hash are required" }); } if ( !isValidContainer(containerName) || !isValidPathSegment(tempCaseRef) || !isValidPathSegment(filename) || typeof checkHash !== "string" ) { return respondError(res, { status: 400, code: "INVALID_REQUEST", message: "Invalid request" }); } const session = await getSession({ req }); if ( typeof session?.user?.id !== "string" || session.user.id.length === 0 || session.user.id !== containerName ) { return forbidden(res); } const hashCandidatePaths = [ "/api/file/createrepcompletemessage_api?container=" + containerName + "&tempcaseref=" + tempCaseRef + "&repid=" + filename, "/api/file/createrepcompletemessage_api?container=" + encodeURIComponent(containerName) + "&tempcaseref=" + encodeURIComponent(tempCaseRef) + "&repid=" + encodeURIComponent(filename) ]; const isHashValid = hashCandidatePaths.some( (candidatePath) => hashAPIPath(candidatePath) == "&hash=" + checkHash ); if (!isHashValid) { return respondError(res, { status: 400, code: "INVALID_HASH", message: "Invalid hash" }); } try { const data = await createRepCompleteMessage( containerName, tempCaseRef, filename ); return respondSuccess(res, data); } catch (error) { consoleLogger(error); return respondError(res, { status: 400, code: "CREATE_REP_COMPLETE_MESSAGE_FAILED", message: "Failed to create representation complete message" }); } } export const config = { api: { bodyParser: false } };