diff --git a/Client/src/Pages/Monitors/Details/index.jsx b/Client/src/Pages/Monitors/Details/index.jsx index 918077a91..e2c0eb91b 100644 --- a/Client/src/Pages/Monitors/Details/index.jsx +++ b/Client/src/Pages/Monitors/Details/index.jsx @@ -113,6 +113,7 @@ const DetailsPage = () => { const { monitorId } = useParams(); const { authToken } = useSelector((state) => state.auth); const [dateRange, setDateRange] = useState("day"); + const [certificateExpiry, setCertificateExpiry] = useState("N/A"); const navigate = useNavigate(); const fetchMonitor = useCallback(async () => { @@ -136,10 +137,23 @@ const DetailsPage = () => { fetchMonitor(); }, [fetchMonitor]); + useEffect(() => { + const fetchCertificate = async () => { + const res = await axiosInstance.get( + `/monitors/certificate/${monitorId}`, + { + headers: { + Authorization: `Bearer ${authToken}`, + }, + } + ); + setCertificateExpiry(res.data.data.certificateDate); + }; + fetchCertificate(); + }, [authToken, monitorId]); + const theme = useTheme(); - let loading = Object.keys(monitor).length === 0; - return ( {loading ? ( @@ -222,6 +236,35 @@ const DetailsPage = () => { value={`${formatDuration(monitor?.lastChecked)} ago`} /> + + + + + + + { - + diff --git a/Client/src/Pages/PageSpeed/Details/index.jsx b/Client/src/Pages/PageSpeed/Details/index.jsx index 04e08d122..963b0b31f 100644 --- a/Client/src/Pages/PageSpeed/Details/index.jsx +++ b/Client/src/Pages/PageSpeed/Details/index.jsx @@ -6,11 +6,9 @@ import { useTheme } from "@emotion/react"; import { useNavigate, useParams } from "react-router-dom"; import { useSelector } from "react-redux"; import { - formatDate, formatDuration, formatDurationRounded, } from "../../../Utils/timeUtils"; -import { getLastChecked } from "../../../Utils/monitorUtils"; import axiosInstance from "../../../Utils/axiosConfig"; import Button from "../../../Components/Button"; import WestRoundedIcon from "@mui/icons-material/WestRounded"; diff --git a/Server/controllers/monitorController.js b/Server/controllers/monitorController.js index b8aa24c25..28c33caeb 100644 --- a/Server/controllers/monitorController.js +++ b/Server/controllers/monitorController.js @@ -7,6 +7,7 @@ const { getMonitorsByUserIdQueryValidation, } = require("../validation/joi"); +const sslChecker = require("ssl-checker"); const SERVICE_NAME = "monitorController"; const { errorMessages, successMessages } = require("../utils/messages"); const { runInNewContext } = require("vm"); @@ -65,6 +66,41 @@ const getMonitorStatsById = async (req, res, next) => { } }; +const getMonitorCertificate = async (req, res, next) => { + try { + //validation + } catch (error) { + error.status = 422; + error.message = + error.details?.[0]?.message || error.message || "Validation Error"; + next(error); + } + + try { + const monitor = await req.db.getMonitorById(req, res); + const monitorUrl = new URL(monitor.url); + const certificate = await sslChecker(monitorUrl.hostname); + if (certificate && certificate.validTo) { + return res.json({ + success: true, + msg: successMessages.MONITOR_CERTIFICATE, + data: { + certificateDate: new Date(certificate.validTo).toLocaleDateString(), + }, + }); + } else { + return res.json({ + success: true, + msg: successMessages.MONITOR_CERTIFICATE, + data: { certificateDate: "N/A" }, + }); + } + } catch (error) { + error.service = SERVICE_NAME; + next(error); + } +}; + /** * Returns monitor with matching ID * @async @@ -302,6 +338,7 @@ const editMonitor = async (req, res, next) => { module.exports = { getAllMonitors, getMonitorStatsById, + getMonitorCertificate, getMonitorById, getMonitorsByUserId, createMonitor, diff --git a/Server/models/Check.js b/Server/models/Check.js index aeb4f4849..66984d545 100644 --- a/Server/models/Check.js +++ b/Server/models/Check.js @@ -57,6 +57,7 @@ const CheckSchema = mongoose.Schema( * * @type {Date} */ + expiry: { type: Date, default: Date.now, diff --git a/Server/package-lock.json b/Server/package-lock.json index 916c66648..6f11e3a2e 100644 --- a/Server/package-lock.json +++ b/Server/package-lock.json @@ -27,6 +27,7 @@ "nodemailer": "^6.9.14", "ping": "0.4.4", "sharp": "0.33.4", + "ssl-checker": "2.0.10", "winston": "^3.13.0" }, "devDependencies": { @@ -983,9 +984,10 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", + "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -5026,6 +5028,12 @@ "memory-pager": "^1.0.2" } }, + "node_modules/ssl-checker": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/ssl-checker/-/ssl-checker-2.0.10.tgz", + "integrity": "sha512-SS6rrZocToJWHM1p6iVNb583ybB3UqT1fymCHSWuEdXDUqKA6O1D5Fb8KJVmhj3XKXE82IEWcr+idJrc4jUzFQ==", + "license": "MIT" + }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", diff --git a/Server/package.json b/Server/package.json index ad0936654..6c383ce73 100644 --- a/Server/package.json +++ b/Server/package.json @@ -29,6 +29,7 @@ "nodemailer": "^6.9.14", "ping": "0.4.4", "sharp": "0.33.4", + "ssl-checker": "2.0.10", "winston": "^3.13.0" }, "devDependencies": { diff --git a/Server/routes/monitorRoute.js b/Server/routes/monitorRoute.js index ba585affb..847b2b25d 100644 --- a/Server/routes/monitorRoute.js +++ b/Server/routes/monitorRoute.js @@ -5,6 +5,7 @@ const Monitor = require("../models/Monitor"); router.get("/", monitorController.getAllMonitors); router.get("/stats/:monitorId", monitorController.getMonitorStatsById); +router.get("/certificate/:monitorId", monitorController.getMonitorCertificate); router.get("/:monitorId", monitorController.getMonitorById); router.get("/user/:userId", monitorController.getMonitorsByUserId); diff --git a/Server/utils/messages.js b/Server/utils/messages.js index 4e56ec5b7..92f568605 100644 --- a/Server/utils/messages.js +++ b/Server/utils/messages.js @@ -77,6 +77,7 @@ const successMessages = { MONITOR_CREATE: "Monitor created successfully", MONITOR_DELETE: "Monitor deleted successfully", MONITOR_EDIT: "Monitor edited successfully", + MONITOR_CERTIFICATE: "Got monitor certificate successfully", //Job Queue JOB_QUEUE_DELETE_JOB: "Job removed successfully",