diff --git a/Server/controllers/monitorController.js b/Server/controllers/monitorController.js index 5ee6d2c5d..c56e8851b 100644 --- a/Server/controllers/monitorController.js +++ b/Server/controllers/monitorController.js @@ -3,6 +3,7 @@ import { getMonitorByIdQueryValidation, getMonitorsByTeamIdValidation, createMonitorBodyValidation, + getMonitorURLByQueryValidation, editMonitorBodyValidation, getMonitorsAndSummaryByTeamIdParamValidation, getMonitorsAndSummaryByTeamIdQueryValidation, @@ -273,6 +274,13 @@ const createMonitor = async (req, res, next) => { * @throws {Error} If there is an error during the process, especially if there is a validation error (422). */ const checkEndpointResolution = async (req, res, next) => { + try { + await getMonitorURLByQueryValidation.validateAsync(req.query); + } catch (error) { + next(handleValidationError(error, SERVICE_NAME)); + return; + } + try { let { monitorURL } = req.query; monitorURL = new URL(monitorURL); diff --git a/Server/openapi.json b/Server/openapi.json index ff13498ea..aaa10a5d3 100644 --- a/Server/openapi.json +++ b/Server/openapi.json @@ -882,6 +882,16 @@ } } }, + "422": { + "description": "Unprocessable Content", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "500": { "description": "Internal Server Error", "content": { diff --git a/Server/tests/controllers/monitorController.test.js b/Server/tests/controllers/monitorController.test.js index 690649660..bd89b3dea 100644 --- a/Server/tests/controllers/monitorController.test.js +++ b/Server/tests/controllers/monitorController.test.js @@ -480,7 +480,7 @@ describe("Monitor Controllor - checkEndpointResolution", () => { })).to.be.true; expect(next.called).to.be.false; }); - it("should return a 400 error message if DNS resolution fails", async () => { + it("should return an error if DNS resolution fails", async () => { const dnsError = new Error("DNS resolution failed"); dnsError.code = 'ENOTFOUND'; dnsResolveStub.callsFake((hostname, callback) => callback(dnsError)); @@ -491,13 +491,13 @@ describe("Monitor Controllor - checkEndpointResolution", () => { expect(errorPassedToNext.message).to.include('DNS resolution failed'); expect(errorPassedToNext.code).to.equal('ENOTFOUND'); }); - it('should call next with an error for invalid monitorURL', async () => { + it('should reject with an error if query validation fails', async () => { req.query.monitorURL = 'invalid-url'; await checkEndpointResolution(req, res, next); expect(next.calledOnce).to.be.true; const error = next.getCall(0).args[0]; - expect(error).to.be.an.instanceOf(TypeError); - expect(error.message).to.include('Invalid URL'); + expect(next.firstCall.args[0]).to.be.an("error"); + expect(next.firstCall.args[0].status).to.equal(422); }); }); diff --git a/Server/validation/joi.js b/Server/validation/joi.js index 033650a3d..090cb3211 100644 --- a/Server/validation/joi.js +++ b/Server/validation/joi.js @@ -236,12 +236,16 @@ const pauseMonitorParamValidation = joi.object({ monitorId: joi.string().required(), }); +const getMonitorURLByQueryValidation = joi.object({ + monitorURL: joi.string().uri().required(), +}); + //**************************************** // Alerts //**************************************** const createAlertParamValidation = joi.object({ - monitorId: joi.string().required(), + monitorId: joi.string().uri().required(), }); const createAlertBodyValidation = joi.object({ @@ -446,6 +450,7 @@ export { getCertificateParamValidation, editMonitorBodyValidation, pauseMonitorParamValidation, + getMonitorURLByQueryValidation, editUserParamValidation, editUserBodyValidation, createAlertParamValidation,