Skip to content

Commit

Permalink
rewrite monitor resolution check, update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ajhollid committed Nov 20, 2024
1 parent cb02716 commit 58be0c0
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 21 deletions.
18 changes: 8 additions & 10 deletions Server/controllers/monitorController.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import jwt from "jsonwebtoken";
import { getTokenFromHeaders } from "../utils/utils.js";
import logger from "../utils/logger.js";
import { handleError, handleValidationError } from "./controllerUtils.js";
import dns from "dns";
import axios from "axios";

const SERVICE_NAME = "monitorController";

Expand Down Expand Up @@ -288,18 +288,16 @@ const checkEndpointResolution = async (req, res, next) => {
}

try {
let { monitorURL } = req.query;
monitorURL = new URL(monitorURL);
await new Promise((resolve, reject) => {
dns.resolve(monitorURL.hostname, (error) => {
if (error) {
reject(error);
}
resolve();
});
const { monitorURL } = req.query;
const parsedUrl = new URL(monitorURL);
const response = await axios.get(parsedUrl, {
timeout: 5000,
validateStatus: () => true,
});

Check failure

Code scanning / CodeQL

Server-side request forgery Critical

The
URL
of this request depends on a
user-provided value
.
return res.status(200).json({
success: true,
code: response.status,
statusText: response.statusText,
msg: `URL resolved successfully`,
});
} catch (error) {
Expand Down
24 changes: 13 additions & 11 deletions Server/tests/controllers/monitorController.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import jwt from "jsonwebtoken";
import sinon from "sinon";
import { successMessages } from "../../utils/messages.js";
import logger from "../../utils/logger.js";
import dns from "dns";
import axios from "axios";
const SERVICE_NAME = "monitorController";

describe("Monitor Controller - getAllMonitors", () => {
Expand Down Expand Up @@ -476,38 +476,40 @@ describe("Monitor Controller - createMonitor", () => {
});
});

describe("Monitor Controllor - checkEndpointResolution", () => {
let req, res, next, dnsResolveStub;
describe("Monitor Controller - checkEndpointResolution", () => {
let req, res, next, axiosGetStub;
beforeEach(() => {
req = { query: { monitorURL: "https://example.com" } };
res = { status: sinon.stub().returnsThis(), json: sinon.stub() };
next = sinon.stub();
dnsResolveStub = sinon.stub(dns, "resolve");
axiosGetStub = sinon.stub(axios, "get");
});
afterEach(() => {
dnsResolveStub.restore();
sinon.restore();
});
it("should resolve the URL successfully", async () => {
dnsResolveStub.callsFake((hostname, callback) => callback(null));
axiosGetStub.resolves({ status: 200, statusText: "OK" });
await checkEndpointResolution(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
expect(
res.json.calledWith({
success: true,
code: 200,
statusText: "OK",
msg: "URL resolved successfully",
})
).to.be.true;
expect(next.called).to.be.false;
});
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));
it("should return an error if endpoint resolution fails", async () => {
const axiosError = new Error("resolution failed");
axiosError.code = "ENOTFOUND";
axiosGetStub.rejects(axiosError);
await checkEndpointResolution(req, res, next);
expect(next.calledOnce).to.be.true;
const errorPassedToNext = next.getCall(0).args[0];
expect(errorPassedToNext).to.be.an.instanceOf(Error);
expect(errorPassedToNext.message).to.include("DNS resolution failed");
expect(errorPassedToNext.message).to.include("resolution failed");
expect(errorPassedToNext.code).to.equal("ENOTFOUND");
expect(errorPassedToNext.status).to.equal(500);
});
Expand Down

0 comments on commit 58be0c0

Please sign in to comment.