diff --git a/pages/api/file/setupcontainer.js b/pages/api/file/setupcontainer.js index ca2c5d00..01927dcc 100644 --- a/pages/api/file/setupcontainer.js +++ b/pages/api/file/setupcontainer.js @@ -1,10 +1,4 @@ -import { - createContainer, - createContainerSas, - getContainers, - getBlobs, - uploadFile -} from "../../../actions/azurestorage"; +import { createContainer } from "../../../actions/azurestorage"; import { hashAPIPath } from "../../../actions/core/hash"; import { consoleLogger } from "../../../actions/core/logger"; import { respondError, respondSuccess } from "../middleware/apiResponse"; @@ -16,8 +10,8 @@ const ApiProxy = nextConnect(); ApiProxy.use(middleware); ApiProxy.get(async (req, res) => { - var containerName = req.query.ident; - var checkHash = req.query.hash; + const containerName = req.query.ident; + const checkHash = req.query.hash; if ( typeof containerName === "undefined" || @@ -32,9 +26,19 @@ ApiProxy.get(async (req, res) => { }); } - var checkquerypath = "/api/file/setupcontainer?ident=" + containerName; + const containerNameTrimmed = containerName.trim(); - if (hashAPIPath(checkquerypath) != "&hash=" + checkHash) { + const hashCandidatePaths = [ + "/api/file/setupcontainer?ident=" + containerNameTrimmed, + "/api/file/setupcontainer?ident=" + + encodeURIComponent(containerNameTrimmed) + ]; + + const isHashValid = hashCandidatePaths.some( + (candidatePath) => hashAPIPath(candidatePath) == "&hash=" + checkHash + ); + + if (!isHashValid) { return respondError(res, { status: 400, code: "INVALID_HASH", @@ -42,18 +46,17 @@ ApiProxy.get(async (req, res) => { }); } - await createContainer(containerName) - .then((data) => { - return respondSuccess(res, { data: "success", output: data }); - }) - .catch((error) => { - consoleLogger(error); - return respondError(res, { - status: 400, - code: "SETUP_CONTAINER_FAILED", - message: "Failed to setup container" - }); + try { + const data = await createContainer(containerNameTrimmed); + return respondSuccess(res, { data: "success", output: data }); + } catch (error) { + consoleLogger(error); + return respondError(res, { + status: 400, + code: "SETUP_CONTAINER_FAILED", + message: "Failed to setup container" }); + } }); export const config = { diff --git a/tests/phase21/file-handler-contract.test.cjs b/tests/phase21/file-handler-contract.test.cjs index 6b55f036..6287299f 100644 --- a/tests/phase21/file-handler-contract.test.cjs +++ b/tests/phase21/file-handler-contract.test.cjs @@ -596,6 +596,31 @@ test("setupcontainer handler returns MISSING_REQUIRED_QUERY when ident missing", assert.strictEqual(res.state.jsonBody.error.code, "MISSING_REQUIRED_QUERY"); }); +test("setupcontainer handler accepts encoded ident hash variant", async () => { + const mod = loadModule("pages/api/file/setupcontainer.js", { + nextConnect: createNextConnectMock(), + middleware: () => {}, + hashAPIPath: (queryPath) => + queryPath.includes("ident=container%2Fname") + ? "&hash=expected" + : "&hash=other", + consoleLogger: () => {}, + respondError: respondErrorMock, + respondSuccess: respondSuccessMock, + createContainer: async () => ({ created: true }) + }); + + const req = { query: { ident: "container/name", hash: "expected" } }; + const res = createRes(); + await mod.default.handler(req, res); + + assert.strictEqual(res.state.statusCode, 200); + assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), { + data: "success", + output: { created: true } + }); +}); + test("upload handler success returns data payload with 200", async () => { const mod = loadModule("pages/api/file/upload.js", { nextConnect: createNextConnectMock(),