mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-05-20 08:28:48 -05:00
Merge pull request #3108 from bluewave-labs/feat/monitor-controller
monitor controller -> ts
This commit is contained in:
@@ -28,12 +28,7 @@ export const initializeControllers = (services) => {
|
||||
userService: services.userService,
|
||||
});
|
||||
|
||||
controllers.monitorController = new MonitorController(commonDependencies, {
|
||||
settingsService: services.settingsService,
|
||||
jobQueue: services.jobQueue,
|
||||
emailService: services.emailService,
|
||||
monitorService: services.monitorService,
|
||||
});
|
||||
controllers.monitorController = new MonitorController(services.monitorService);
|
||||
|
||||
controllers.settingsController = new SettingsController(commonDependencies, {
|
||||
settingsService: services.settingsService,
|
||||
|
||||
@@ -1,493 +0,0 @@
|
||||
import {
|
||||
getMonitorByIdParamValidation,
|
||||
getMonitorByIdQueryValidation,
|
||||
getMonitorsByTeamIdParamValidation,
|
||||
getMonitorsByTeamIdQueryValidation,
|
||||
createMonitorBodyValidation,
|
||||
editMonitorBodyValidation,
|
||||
pauseMonitorParamValidation,
|
||||
getMonitorStatsByIdParamValidation,
|
||||
getMonitorStatsByIdQueryValidation,
|
||||
getCertificateParamValidation,
|
||||
getHardwareDetailsByIdParamValidation,
|
||||
getHardwareDetailsByIdQueryValidation,
|
||||
} from "../../validation/joi.js";
|
||||
import sslChecker from "ssl-checker";
|
||||
import { fetchMonitorCertificate } from "./controllerUtils.js";
|
||||
import BaseController from "./baseController.js";
|
||||
|
||||
const SERVICE_NAME = "monitorController";
|
||||
class MonitorController extends BaseController {
|
||||
static SERVICE_NAME = SERVICE_NAME;
|
||||
constructor(commonDependencies, { settingsService, jobQueue, emailService, monitorService }) {
|
||||
super(commonDependencies);
|
||||
this.settingsService = settingsService;
|
||||
this.jobQueue = jobQueue;
|
||||
this.emailService = emailService;
|
||||
this.monitorService = monitorService;
|
||||
}
|
||||
|
||||
get serviceName() {
|
||||
return MonitorController.SERVICE_NAME;
|
||||
}
|
||||
|
||||
async verifyTeamAccess(teamId, monitorId) {
|
||||
const monitor = await this.db.monitorModule.getMonitorById(monitorId);
|
||||
if (!monitor.teamId.equals(teamId)) {
|
||||
throw this.errorService.createAuthorizationError();
|
||||
}
|
||||
}
|
||||
|
||||
getAllMonitors = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
const monitors = await this.monitorService.getAllMonitors();
|
||||
return res.success({
|
||||
msg: this.stringService.monitorGetAll,
|
||||
data: monitors,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"getAllMonitors"
|
||||
);
|
||||
|
||||
getUptimeDetailsById = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
const monitorId = req?.params?.monitorId;
|
||||
const dateRange = req?.query?.dateRange;
|
||||
const normalize = req?.query?.normalize;
|
||||
|
||||
const teamId = req?.user?.teamId;
|
||||
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const data = await this.monitorService.getUptimeDetailsById({
|
||||
teamId,
|
||||
monitorId,
|
||||
dateRange,
|
||||
normalize,
|
||||
});
|
||||
return res.success({
|
||||
msg: this.stringService.monitorGetByIdSuccess,
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"getUptimeDetailsById"
|
||||
);
|
||||
|
||||
getMonitorStatsById = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
await getMonitorStatsByIdParamValidation.validateAsync(req.params);
|
||||
await getMonitorStatsByIdQueryValidation.validateAsync(req.query);
|
||||
|
||||
let { limit, sortOrder, dateRange, numToDisplay, normalize } = req.query;
|
||||
const monitorId = req?.params?.monitorId;
|
||||
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const monitorStats = await this.monitorService.getMonitorStatsById({
|
||||
teamId,
|
||||
monitorId,
|
||||
limit,
|
||||
sortOrder,
|
||||
dateRange,
|
||||
numToDisplay,
|
||||
normalize,
|
||||
});
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.monitorStatsById,
|
||||
data: monitorStats,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"getMonitorStatsById"
|
||||
);
|
||||
|
||||
/**
|
||||
* Get hardware details for a specific monitor by ID
|
||||
* @async
|
||||
* @param {Express.Request} req - Express request object containing monitorId in params
|
||||
* @param {Express.Response} res - Express response object
|
||||
* @param {Express.NextFunction} next - Express next middleware function
|
||||
* @returns {Promise<Express.Response>}
|
||||
* @throws {Error} - Throws error if monitor not found or other database errors
|
||||
*/
|
||||
getHardwareDetailsById = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
await getHardwareDetailsByIdParamValidation.validateAsync(req.params);
|
||||
await getHardwareDetailsByIdQueryValidation.validateAsync(req.query);
|
||||
|
||||
const monitorId = req?.params?.monitorId;
|
||||
const dateRange = req?.query?.dateRange;
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const monitor = await this.monitorService.getHardwareDetailsById({
|
||||
teamId,
|
||||
monitorId,
|
||||
dateRange,
|
||||
});
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.monitorGetByIdSuccess,
|
||||
data: monitor,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"getHardwareDetailsById"
|
||||
);
|
||||
|
||||
getMonitorCertificate = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
await getCertificateParamValidation.validateAsync(req.params);
|
||||
|
||||
const { monitorId } = req.params;
|
||||
const monitor = await this.db.monitorModule.getMonitorById(monitorId);
|
||||
const certificate = await fetchMonitorCertificate(sslChecker, monitor);
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.monitorCertificate,
|
||||
data: {
|
||||
certificateDate: new Date(certificate.validTo),
|
||||
},
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"getMonitorCertificate"
|
||||
);
|
||||
|
||||
getMonitorById = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
await getMonitorByIdParamValidation.validateAsync(req.params);
|
||||
await getMonitorByIdQueryValidation.validateAsync(req.query);
|
||||
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const monitor = await this.monitorService.getMonitorById({ teamId, monitorId: req?.params?.monitorId });
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.monitorGetByIdSuccess,
|
||||
data: monitor,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"getMonitorById"
|
||||
);
|
||||
|
||||
createMonitor = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
await createMonitorBodyValidation.validateAsync(req.body);
|
||||
|
||||
const userId = req?.user?._id;
|
||||
const teamId = req?.user?.teamId;
|
||||
|
||||
const monitor = await this.monitorService.createMonitor({ teamId, userId, body: req.body });
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.monitorCreate,
|
||||
data: monitor,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"createMonitor"
|
||||
);
|
||||
|
||||
createBulkMonitors = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
if (!req.file) {
|
||||
throw this.errorService.createBadRequestError("No file uploaded");
|
||||
}
|
||||
|
||||
if (!req.file.mimetype.includes("csv")) {
|
||||
throw this.errorService.createBadRequestError("File is not a CSV");
|
||||
}
|
||||
|
||||
if (req.file.size === 0) {
|
||||
throw this.errorService.createBadRequestError("File is empty");
|
||||
}
|
||||
|
||||
const userId = req?.user?._id;
|
||||
const teamId = req?.user?.teamId;
|
||||
|
||||
if (!userId || !teamId) {
|
||||
throw this.errorService.createBadRequestError("Missing userId or teamId");
|
||||
}
|
||||
|
||||
const fileData = req?.file?.buffer?.toString("utf-8");
|
||||
if (!fileData) {
|
||||
throw this.errorService.createBadRequestError("Cannot get file from buffer");
|
||||
}
|
||||
|
||||
const monitors = await this.monitorService.createBulkMonitors({ fileData, userId, teamId });
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.bulkMonitorsCreate,
|
||||
data: monitors,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"createBulkMonitors"
|
||||
);
|
||||
|
||||
deleteMonitor = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
await getMonitorByIdParamValidation.validateAsync(req.params);
|
||||
const monitorId = req.params.monitorId;
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const deletedMonitor = await this.monitorService.deleteMonitor({ teamId, monitorId });
|
||||
|
||||
return res.success({ msg: this.stringService.monitorDelete, data: deletedMonitor });
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"deleteMonitor"
|
||||
);
|
||||
|
||||
deleteAllMonitors = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const deletedCount = await this.monitorService.deleteAllMonitors({ teamId });
|
||||
|
||||
return res.success({ msg: `Deleted ${deletedCount} monitors` });
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"deleteAllMonitors"
|
||||
);
|
||||
|
||||
editMonitor = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
await getMonitorByIdParamValidation.validateAsync(req.params);
|
||||
await editMonitorBodyValidation.validateAsync(req.body);
|
||||
const monitorId = req?.params?.monitorId;
|
||||
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const editedMonitor = await this.monitorService.editMonitor({ teamId, monitorId, body: req.body });
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.monitorEdit,
|
||||
data: editedMonitor,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"editMonitor"
|
||||
);
|
||||
|
||||
pauseMonitor = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
await pauseMonitorParamValidation.validateAsync(req.params);
|
||||
|
||||
const monitorId = req.params.monitorId;
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const monitor = await this.monitorService.pauseMonitor({ teamId, monitorId });
|
||||
|
||||
return res.success({
|
||||
msg: monitor.isActive ? this.stringService.monitorResume : this.stringService.monitorPause,
|
||||
data: monitor,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"pauseMonitor"
|
||||
);
|
||||
|
||||
addDemoMonitors = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
const { _id, teamId } = req.user;
|
||||
const demoMonitors = await this.monitorService.addDemoMonitors({ userId: _id, teamId });
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.monitorDemoAdded,
|
||||
data: demoMonitors?.length ?? 0,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"addDemoMonitors"
|
||||
);
|
||||
|
||||
sendTestEmail = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
const { to } = req.body;
|
||||
if (!to || typeof to !== "string") {
|
||||
throw this.errorService.createBadRequestError(this.stringService.errorForValidEmailAddress);
|
||||
}
|
||||
|
||||
const messageId = await this.monitorService.sendTestEmail({ to });
|
||||
return res.success({
|
||||
msg: this.stringService.sendTestEmail,
|
||||
data: { messageId },
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"sendTestEmail"
|
||||
);
|
||||
|
||||
getMonitorsByTeamId = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
await getMonitorsByTeamIdParamValidation.validateAsync(req.params);
|
||||
await getMonitorsByTeamIdQueryValidation.validateAsync(req.query);
|
||||
|
||||
let { limit, type, page, rowsPerPage, filter, field, order } = req.query;
|
||||
const teamId = req?.user?.teamId;
|
||||
|
||||
const monitors = await this.monitorService.getMonitorsByTeamId({ teamId, limit, type, page, rowsPerPage, filter, field, order });
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.monitorGetByTeamId,
|
||||
data: monitors,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"getMonitorsByTeamId"
|
||||
);
|
||||
|
||||
getMonitorsAndSummaryByTeamId = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
await getMonitorsByTeamIdParamValidation.validateAsync(req.params);
|
||||
await getMonitorsByTeamIdQueryValidation.validateAsync(req.query);
|
||||
|
||||
const explain = req?.query?.explain;
|
||||
const type = req?.query?.type;
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const result = await this.monitorService.getMonitorsAndSummaryByTeamId({ teamId, type, explain });
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.monitorSummaryByTeamId,
|
||||
data: result,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"getMonitorsAndSummaryByTeamId"
|
||||
);
|
||||
|
||||
getMonitorsWithChecksByTeamId = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
await getMonitorsByTeamIdParamValidation.validateAsync(req.params);
|
||||
await getMonitorsByTeamIdQueryValidation.validateAsync(req.query);
|
||||
|
||||
const explain = req?.query?.explain;
|
||||
let { limit, type, page, rowsPerPage, filter, field, order } = req.query;
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const monitors = await this.monitorService.getMonitorsWithChecksByTeamId({
|
||||
teamId,
|
||||
limit,
|
||||
type,
|
||||
page,
|
||||
rowsPerPage,
|
||||
filter,
|
||||
field,
|
||||
order,
|
||||
explain,
|
||||
});
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.monitorGetByTeamId,
|
||||
data: monitors,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"getMonitorsWithChecksByTeamId"
|
||||
);
|
||||
|
||||
exportMonitorsToCSV = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const csv = await this.monitorService.exportMonitorsToCSV({ teamId });
|
||||
|
||||
return res.file({
|
||||
data: csv,
|
||||
headers: {
|
||||
"Content-Type": "text/csv",
|
||||
"Content-Disposition": "attachment; filename=monitors.csv",
|
||||
},
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"exportMonitorsToCSV"
|
||||
);
|
||||
|
||||
exportMonitorsToJSON = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const json = await this.monitorService.exportMonitorsToJSON({ teamId });
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.monitorExportSuccess,
|
||||
data: json,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"exportMonitorsToJSON"
|
||||
);
|
||||
|
||||
getAllGames = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
return res.success({
|
||||
msg: this.stringService.gameListSuccess,
|
||||
data: this.monitorService.getAllGames(),
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"getAllGames"
|
||||
);
|
||||
|
||||
getGroupsByTeamId = this.asyncHandler(
|
||||
async (req, res) => {
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw this.errorService.createBadRequestError("Team ID is required");
|
||||
}
|
||||
|
||||
const groups = await this.monitorService.getGroupsByTeamId({ teamId });
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.groupsByTeamId,
|
||||
data: groups,
|
||||
});
|
||||
},
|
||||
SERVICE_NAME,
|
||||
"getGroupsByTeamId"
|
||||
);
|
||||
}
|
||||
|
||||
export default MonitorController;
|
||||
@@ -0,0 +1,505 @@
|
||||
import { Request, Response, NextFunction } from "express";
|
||||
|
||||
import {
|
||||
getMonitorByIdParamValidation,
|
||||
getMonitorByIdQueryValidation,
|
||||
getMonitorsByTeamIdParamValidation,
|
||||
getMonitorsByTeamIdQueryValidation,
|
||||
createMonitorBodyValidation,
|
||||
editMonitorBodyValidation,
|
||||
pauseMonitorParamValidation,
|
||||
getMonitorStatsByIdParamValidation,
|
||||
getMonitorStatsByIdQueryValidation,
|
||||
getCertificateParamValidation,
|
||||
getHardwareDetailsByIdParamValidation,
|
||||
getHardwareDetailsByIdQueryValidation,
|
||||
} from "../../validation/joi.js";
|
||||
import sslChecker from "ssl-checker";
|
||||
import { fetchMonitorCertificate } from "./controllerUtils.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
|
||||
const SERVICE_NAME = "monitorController";
|
||||
class MonitorController {
|
||||
static SERVICE_NAME = SERVICE_NAME;
|
||||
|
||||
private monitorService: any;
|
||||
|
||||
constructor(monitorService: any) {
|
||||
this.monitorService = monitorService;
|
||||
}
|
||||
|
||||
get serviceName() {
|
||||
return MonitorController.SERVICE_NAME;
|
||||
}
|
||||
|
||||
async verifyTeamAccess(teamId: string, monitorId: string) {
|
||||
const monitor = await this.monitorService.getMonitorById(monitorId);
|
||||
if (!monitor.teamId.equals(teamId)) {
|
||||
throw new AppError({ message: "Access denied", status: 403 });
|
||||
}
|
||||
}
|
||||
|
||||
getAllMonitors = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const monitors = await this.monitorService.getAllMonitors();
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Retrieved all monitors successfully",
|
||||
data: monitors,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
getMonitorCertificate = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
await getCertificateParamValidation.validateAsync(req.params);
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
const { monitorId } = req.params;
|
||||
const monitor = await this.monitorService.getMonitorById({ teamId, monitorId });
|
||||
const certificate = await fetchMonitorCertificate(sslChecker, monitor);
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "SSL certificate retrieved successfully",
|
||||
data: {
|
||||
certificateDate: new Date(certificate.validTo),
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
getUptimeDetailsById = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const monitorId = req?.params?.monitorId;
|
||||
const dateRange = req?.query?.dateRange;
|
||||
const normalize = req?.query?.normalize;
|
||||
|
||||
const teamId = req?.user?.teamId;
|
||||
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const data = await this.monitorService.getUptimeDetailsById({
|
||||
teamId,
|
||||
monitorId,
|
||||
dateRange,
|
||||
normalize,
|
||||
});
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Uptime details retrieved successfully",
|
||||
data: data,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
getMonitorStatsById = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
await getMonitorStatsByIdParamValidation.validateAsync(req.params);
|
||||
await getMonitorStatsByIdQueryValidation.validateAsync(req.query);
|
||||
|
||||
let { limit, sortOrder, dateRange, numToDisplay, normalize } = req.query;
|
||||
const monitorId = req?.params?.monitorId;
|
||||
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const monitorStats = await this.monitorService.getMonitorStatsById({
|
||||
teamId,
|
||||
monitorId,
|
||||
limit,
|
||||
sortOrder,
|
||||
dateRange,
|
||||
numToDisplay,
|
||||
normalize,
|
||||
});
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Monitor stats retrieved successfully",
|
||||
data: monitorStats,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
getHardwareDetailsById = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
await getHardwareDetailsByIdParamValidation.validateAsync(req.params);
|
||||
await getHardwareDetailsByIdQueryValidation.validateAsync(req.query);
|
||||
|
||||
const monitorId = req?.params?.monitorId;
|
||||
const dateRange = req?.query?.dateRange;
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const monitor = await this.monitorService.getHardwareDetailsById({
|
||||
teamId,
|
||||
monitorId,
|
||||
dateRange,
|
||||
});
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Hardware details retrieved successfully",
|
||||
data: monitor,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
getMonitorById = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
await getMonitorByIdParamValidation.validateAsync(req.params);
|
||||
await getMonitorByIdQueryValidation.validateAsync(req.query);
|
||||
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const monitor = await this.monitorService.getMonitorById({ teamId, monitorId: req?.params?.monitorId });
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Monitor retrieved successfully",
|
||||
data: monitor,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
createMonitor = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
await createMonitorBodyValidation.validateAsync(req.body);
|
||||
|
||||
const userId = req?.user?._id;
|
||||
const teamId = req?.user?.teamId;
|
||||
|
||||
const monitor = await this.monitorService.createMonitor({ teamId, userId, body: req.body });
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Monitor created successfully",
|
||||
data: monitor,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
createBulkMonitors = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (!req.file) {
|
||||
throw new AppError({ message: "No file uploaded", status: 400 });
|
||||
}
|
||||
|
||||
if (!req.file.mimetype.includes("csv")) {
|
||||
throw new AppError({ message: "File is not a CSV", status: 400 });
|
||||
}
|
||||
|
||||
if (req.file.size === 0) {
|
||||
throw new AppError({ message: "File is empty", status: 400 });
|
||||
}
|
||||
|
||||
const userId = req?.user?._id;
|
||||
const teamId = req?.user?.teamId;
|
||||
|
||||
if (!userId || !teamId) {
|
||||
throw new AppError({ message: "Missing userId or teamId", status: 400 });
|
||||
}
|
||||
|
||||
const fileData = req?.file?.buffer?.toString("utf-8");
|
||||
if (!fileData) {
|
||||
throw new AppError({ message: "Cannot get file from buffer", status: 400 });
|
||||
}
|
||||
|
||||
const monitors = await this.monitorService.createBulkMonitors({ fileData, userId, teamId });
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Bulk monitors created successfully",
|
||||
data: monitors,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
deleteMonitor = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
await getMonitorByIdParamValidation.validateAsync(req.params);
|
||||
const monitorId = req.params.monitorId;
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const deletedMonitor = await this.monitorService.deleteMonitor({ teamId, monitorId });
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Monitor deleted successfully",
|
||||
data: deletedMonitor,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
deleteAllMonitors = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const deletedCount = await this.monitorService.deleteAllMonitors({ teamId });
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: `Deleted ${deletedCount} monitors`,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
editMonitor = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
await getMonitorByIdParamValidation.validateAsync(req.params);
|
||||
await editMonitorBodyValidation.validateAsync(req.body);
|
||||
const monitorId = req?.params?.monitorId;
|
||||
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const editedMonitor = await this.monitorService.editMonitor({ teamId, monitorId, body: req.body });
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Monitor edited successfully",
|
||||
data: editedMonitor,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
pauseMonitor = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
await pauseMonitorParamValidation.validateAsync(req.params);
|
||||
|
||||
const monitorId = req.params.monitorId;
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const monitor = await this.monitorService.pauseMonitor({ teamId, monitorId });
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: monitor.isActive ? "Monitor resumed successfully" : "Monitor paused successfully",
|
||||
data: monitor,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
addDemoMonitors = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const { _id, teamId } = req.user;
|
||||
const demoMonitors = await this.monitorService.addDemoMonitors({ userId: _id, teamId });
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Demo monitors added successfully",
|
||||
data: demoMonitors?.length ?? 0,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
sendTestEmail = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const { to } = req.body;
|
||||
if (!to || typeof to !== "string") {
|
||||
throw new AppError({ message: "Invalid 'to' email address", status: 400 });
|
||||
}
|
||||
|
||||
const messageId = await this.monitorService.sendTestEmail({ to });
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Test email sent successfully",
|
||||
data: { messageId },
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
getMonitorsByTeamId = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
await getMonitorsByTeamIdParamValidation.validateAsync(req.params);
|
||||
await getMonitorsByTeamIdQueryValidation.validateAsync(req.query);
|
||||
|
||||
let { limit, type, page, rowsPerPage, filter, field, order } = req.query;
|
||||
const teamId = req?.user?.teamId;
|
||||
|
||||
const monitors = await this.monitorService.getMonitorsByTeamId({ teamId, limit, type, page, rowsPerPage, filter, field, order });
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Monitors retrieved successfully",
|
||||
data: monitors,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
getMonitorsAndSummaryByTeamId = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
await getMonitorsByTeamIdParamValidation.validateAsync(req.params);
|
||||
await getMonitorsByTeamIdQueryValidation.validateAsync(req.query);
|
||||
|
||||
const explain = req?.query?.explain;
|
||||
const type = req?.query?.type;
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const result = await this.monitorService.getMonitorsAndSummaryByTeamId({ teamId, type, explain });
|
||||
|
||||
return res.status(200).json({
|
||||
msg: "Monitors and summary retrieved successfully",
|
||||
data: result,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
getMonitorsWithChecksByTeamId = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
await getMonitorsByTeamIdParamValidation.validateAsync(req.params);
|
||||
await getMonitorsByTeamIdQueryValidation.validateAsync(req.query);
|
||||
|
||||
const explain = req?.query?.explain;
|
||||
let { limit, type, page, rowsPerPage, filter, field, order } = req.query;
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const monitors = await this.monitorService.getMonitorsWithChecksByTeamId({
|
||||
teamId,
|
||||
limit,
|
||||
type,
|
||||
page,
|
||||
rowsPerPage,
|
||||
filter,
|
||||
field,
|
||||
order,
|
||||
explain,
|
||||
});
|
||||
|
||||
return res.status(200).json({
|
||||
msg: "Monitors retrieved successfully",
|
||||
data: monitors,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
exportMonitorsToCSV = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const csv = await this.monitorService.exportMonitorsToCSV({ teamId });
|
||||
res.setHeader("Content-Type", "text/csv");
|
||||
res.setHeader("Content-Disposition", "attachment; filename=monitors.csv");
|
||||
return res.send(csv);
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
exportMonitorsToJSON = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const json = await this.monitorService.exportMonitorsToJSON({ teamId });
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Monitors exported successfully",
|
||||
data: json,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
getAllGames = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const games = this.monitorService.getAllGames();
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Supported games retrieved successfully",
|
||||
data: games,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
getGroupsByTeamId = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const teamId = req?.user?.teamId;
|
||||
if (!teamId) {
|
||||
throw new AppError({ message: "Team ID is required", status: 400 });
|
||||
}
|
||||
|
||||
const groups = await this.monitorService.getGroupsByTeamId({ teamId });
|
||||
|
||||
return res.status(200).json({
|
||||
msg: "Groups retrieved successfully",
|
||||
data: groups,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default MonitorController;
|
||||
@@ -1,83 +0,0 @@
|
||||
import { Typography, Select } from "@mui/material";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import type { SelectProps } from "@mui/material/Select";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
||||
|
||||
export const SelectInput: React.FC<SelectProps> = ({ ...props }) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<Select
|
||||
{...props}
|
||||
sx={{
|
||||
height: "34px",
|
||||
"& .MuiOutlinedInput-notchedOutline": {
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
borderColor: theme.palette.primary.lowContrast,
|
||||
},
|
||||
"&:hover .MuiOutlinedInput-notchedOutline": {
|
||||
borderColor: theme.palette.primary.lowContrast,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
type ItemTypes = string | number;
|
||||
interface SelectItem {
|
||||
_id: ItemTypes;
|
||||
name: string;
|
||||
}
|
||||
export type CustomSelectProps = SelectProps & {
|
||||
items: SelectItem[];
|
||||
placeholder?: string;
|
||||
isHidden?: boolean;
|
||||
hasError?: boolean;
|
||||
};
|
||||
|
||||
export const SelectFromItems: React.FC<CustomSelectProps> = (
|
||||
{ items, placeholder, isHidden = false, hasError = false, ...props }
|
||||
) => {
|
||||
return (
|
||||
<SelectInput
|
||||
error={hasError}
|
||||
IconComponent={KeyboardArrowDownIcon}
|
||||
displayEmpty
|
||||
MenuProps={{ disableScrollLock: true }}
|
||||
renderValue={(selected) => {
|
||||
if (!selected) {
|
||||
return (
|
||||
<Typography
|
||||
noWrap
|
||||
color="text.secondary"
|
||||
>
|
||||
{placeholder ?? ""}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
const selectedItem = items.find((item) => item._id === selected);
|
||||
const displayName = selectedItem ? selectedItem.name : placeholder;
|
||||
return (
|
||||
<Typography
|
||||
noWrap
|
||||
title={displayName}
|
||||
>
|
||||
{displayName}
|
||||
</Typography>
|
||||
);
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{items.map((item) => (
|
||||
<MenuItem
|
||||
key={item._id}
|
||||
value={item._id}
|
||||
>
|
||||
{item.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</SelectInput>
|
||||
);
|
||||
}
|
||||
|
||||
SelectInput.displayName = "SelectInput";
|
||||
@@ -1,9 +1,12 @@
|
||||
import { config } from "@/config/index.js";
|
||||
|
||||
const SERVICE_NAME = "BufferService";
|
||||
|
||||
class BufferService {
|
||||
static SERVICE_NAME = SERVICE_NAME;
|
||||
constructor({ db, logger, envSettings, incidentService }) {
|
||||
this.BUFFER_TIMEOUT = envSettings.nodeEnv === "development" ? 1000 : 1000 * 60 * 1; // 1 minute
|
||||
console.log(envSettings);
|
||||
this.BUFFER_TIMEOUT = config.NODE_ENV === "development" ? 10 : 1000 * 60 * 1; // 1 minute
|
||||
this.db = db;
|
||||
this.logger = logger;
|
||||
this.incidentService = incidentService;
|
||||
|
||||
Vendored
+1
@@ -3,6 +3,7 @@ import { ITokenizedUser } from "../db/models/index.ts";
|
||||
declare global {
|
||||
namespace Express {
|
||||
interface Request {
|
||||
file?: Multer.File;
|
||||
user?: ITokenizedUser;
|
||||
resource?: any;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
export interface AppErrorConfig {
|
||||
message: string;
|
||||
status?: number;
|
||||
service?: string | null;
|
||||
method?: string | null;
|
||||
details?: any;
|
||||
}
|
||||
|
||||
export class AppError extends Error {
|
||||
private status: number;
|
||||
private service: string | null;
|
||||
private method: string | null;
|
||||
private details: any;
|
||||
|
||||
constructor({ message, status = 500, service = null, method = null, details = null }: AppErrorConfig) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
this.service = service;
|
||||
this.method = method;
|
||||
this.details = details;
|
||||
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user