diff --git a/Client/src/App.jsx b/Client/src/App.jsx
index d6fca146f..09fcfcf5f 100644
--- a/Client/src/App.jsx
+++ b/Client/src/App.jsx
@@ -83,14 +83,14 @@ function App() {
path="integrations"
element={}
/>
- }
- />
- */}
+ {/* }
- />
+ /> */}
}
diff --git a/Client/src/Components/Sidebar/index.jsx b/Client/src/Components/Sidebar/index.jsx
index 145b6f02e..1333b6f67 100644
--- a/Client/src/Components/Sidebar/index.jsx
+++ b/Client/src/Components/Sidebar/index.jsx
@@ -55,7 +55,7 @@ const menu = [
},
{ name: "Incidents", path: "incidents", icon: },
// { name: "Status pages", path: "status", icon: },
- { name: "Maintenance", path: "maintenance", icon: },
+ // { name: "Maintenance", path: "maintenance", icon: },
// { name: "Integrations", path: "integrations", icon: },
{
name: "Account",
diff --git a/Client/src/Components/TabPanels/Account/TeamPanel.jsx b/Client/src/Components/TabPanels/Account/TeamPanel.jsx
index 07d209fc1..ac55cd5b1 100644
--- a/Client/src/Components/TabPanels/Account/TeamPanel.jsx
+++ b/Client/src/Components/TabPanels/Account/TeamPanel.jsx
@@ -55,7 +55,9 @@ const TeamPanel = () => {
useEffect(() => {
const fetchTeam = async () => {
try {
- const response = await networkService.getAllUsers(authToken);
+ const response = await networkService.getAllUsers({
+ authToken: authToken,
+ });
setMembers(response.data.data);
} catch (error) {
createToast({
@@ -187,11 +189,11 @@ const TeamPanel = () => {
}
try {
- await networkService.requestInvitationToken(
- authToken,
- toInvite.email,
- toInvite.role
- );
+ await networkService.requestInvitationToken({
+ authToken: authToken,
+ email: toInvite.email,
+ role: toInvite.role,
+ });
closeInviteModal();
createToast({
body: "Member invited. They will receive an email with details on how to create their account.",
diff --git a/Client/src/Features/Auth/authSlice.js b/Client/src/Features/Auth/authSlice.js
index f6d40c38a..7c8588b52 100644
--- a/Client/src/Features/Auth/authSlice.js
+++ b/Client/src/Features/Auth/authSlice.js
@@ -66,8 +66,11 @@ export const update = createAsyncThunk(
form.deleteProfileImage &&
fd.append("deleteProfileImage", form.deleteProfileImage);
- const res = await networkService.updateUser(token, user._id, fd);
- console.log(res);
+ const res = await networkService.updateUser({
+ authToken: token,
+ userId: user._id,
+ form: fd,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -88,7 +91,10 @@ export const deleteUser = createAsyncThunk(
const user = jwtDecode(data);
try {
- const res = await networkService.deleteUser(data, user._id);
+ const res = await networkService.deleteUser({
+ authToken: data,
+ userId: user._id,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -127,8 +133,11 @@ export const setNewPassword = createAsyncThunk(
async (data, thunkApi) => {
const { token, form } = data;
try {
- await networkService.validateRecoveryToken(token);
- const res = await networkService.setNewPassword(token, form);
+ await networkService.validateRecoveryToken({ recoveryToken: token });
+ const res = await networkService.setNewPassword({
+ recoveryToken: token,
+ form: form,
+ });
return res.data;
} catch (error) {
if (error.response.data) {
diff --git a/Client/src/Features/PageSpeedMonitor/pageSpeedMonitorSlice.js b/Client/src/Features/PageSpeedMonitor/pageSpeedMonitorSlice.js
index 2e107e7e7..0322a5143 100644
--- a/Client/src/Features/PageSpeedMonitor/pageSpeedMonitorSlice.js
+++ b/Client/src/Features/PageSpeedMonitor/pageSpeedMonitorSlice.js
@@ -13,7 +13,10 @@ export const createPageSpeed = createAsyncThunk(
async (data, thunkApi) => {
try {
const { authToken, monitor } = data;
- const res = await networkService.createMonitor(authToken, monitor);
+ const res = await networkService.createMonitor({
+ authToken: authToken,
+ monitor: monitor,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -33,7 +36,10 @@ export const getPagespeedMonitorById = createAsyncThunk(
async (data, thunkApi) => {
try {
const { authToken, monitorId } = data;
- const res = await networkService.getMonitorByid(authToken, monitorId);
+ const res = await networkService.getMonitorById({
+ authToken: authToken,
+ monitorId: monitorId,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -53,11 +59,11 @@ export const getPageSpeedByTeamId = createAsyncThunk(
async (token, thunkApi) => {
const user = jwtDecode(token);
try {
- const res = await networkService.getMonitorsAndSummaryByTeamId(
- token,
- user.teamId,
- ["pagespeed"]
- );
+ const res = await networkService.getMonitorsAndSummaryByTeamId({
+ authToken: token,
+ teamId: user.teamId,
+ types: ["pagespeed"],
+ });
return res.data;
} catch (error) {
@@ -84,11 +90,11 @@ export const updatePageSpeed = createAsyncThunk(
interval: monitor.interval,
// notifications: monitor.notifications,
};
- const res = await networkService.updateMonitor(
- authToken,
- monitor._id,
- updatedFields
- );
+ const res = await networkService.updateMonitor({
+ authToken: authToken,
+ monitorId: monitor._id,
+ updatedFields: updatedFields,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -108,10 +114,10 @@ export const deletePageSpeed = createAsyncThunk(
async (data, thunkApi) => {
try {
const { authToken, monitor } = data;
- const res = await networkService.deleteMonitorById(
- authToken,
- monitor._id
- );
+ const res = await networkService.deleteMonitorById({
+ authToken: authToken,
+ monitorId: monitor._id,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -130,7 +136,10 @@ export const pausePageSpeed = createAsyncThunk(
async (data, thunkApi) => {
try {
const { authToken, monitorId } = data;
- const res = await networkService.pauseMonitorById(authToken, monitorId);
+ const res = await networkService.pauseMonitorById({
+ authToken: authToken,
+ monitorId: monitorId,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
diff --git a/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js b/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js
index a8b1ea737..f6c3cb10a 100644
--- a/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js
+++ b/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js
@@ -13,7 +13,10 @@ export const createUptimeMonitor = createAsyncThunk(
async (data, thunkApi) => {
try {
const { authToken, monitor } = data;
- const res = await networkService.createMonitor(authToken, monitor);
+ const res = await networkService.createMonitor({
+ authToken: authToken,
+ monitor: monitor,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -33,7 +36,10 @@ export const getUptimeMonitorById = createAsyncThunk(
async (data, thunkApi) => {
try {
const { authToken, monitorId } = data;
- const res = await networkService.getMonitorByid(authToken, monitorId);
+ const res = await networkService.getMonitorById({
+ authToken: authToken,
+ monitorId: monitorId,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -53,11 +59,11 @@ export const getUptimeMonitorsByTeamId = createAsyncThunk(
async (token, thunkApi) => {
const user = jwtDecode(token);
try {
- const res = await networkService.getMonitorsAndSummaryByTeamId(
- token,
- user.teamId,
- ["http", "ping"]
- );
+ const res = await networkService.getMonitorsAndSummaryByTeamId({
+ authToken: token,
+ teamId: user.teamId,
+ types: ["http", "ping"],
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -83,11 +89,11 @@ export const updateUptimeMonitor = createAsyncThunk(
interval: monitor.interval,
notifications: monitor.notifications,
};
- const res = await networkService.updateMonitor(
- authToken,
- monitor._id,
- updatedFields
- );
+ const res = await networkService.updateMonitor({
+ authToken: authToken,
+ monitorId: monitor._id,
+ updatedFields: updatedFields,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -107,10 +113,10 @@ export const deleteUptimeMonitor = createAsyncThunk(
async (data, thunkApi) => {
try {
const { authToken, monitor } = data;
- const res = await networkService.deleteMonitorById(
- authToken,
- monitor._id
- );
+ const res = await networkService.deleteMonitorById({
+ authToken: authToken,
+ monitorId: monitor._id,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -130,7 +136,10 @@ export const pauseUptimeMonitor = createAsyncThunk(
async (data, thunkApi) => {
try {
const { authToken, monitorId } = data;
- const res = await networkService.pauseMonitorById(authToken, monitorId);
+ const res = await networkService.pauseMonitorById({
+ authToken: authToken,
+ monitorId: monitorId,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -150,7 +159,10 @@ export const deleteMonitorChecksByTeamId = createAsyncThunk(
async (data, thunkApi) => {
try {
const { authToken, teamId } = data;
- const res = await networkService.deleteChecksByTeamId(authToken, teamId);
+ const res = await networkService.deleteChecksByTeamId({
+ authToken: authToken,
+ teamId: teamId,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -169,7 +181,9 @@ export const addDemoMonitors = createAsyncThunk(
async (data, thunkApi) => {
try {
const { authToken } = data;
- const res = await networkService.addDemoMonitors(authToken);
+ const res = await networkService.addDemoMonitors({
+ authToken: authToken,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
@@ -188,7 +202,9 @@ export const deleteAllMonitors = createAsyncThunk(
async (data, thunkApi) => {
try {
const { authToken } = data;
- const res = await networkService.deleteAllMonitors(authToken);
+ const res = await networkService.deleteAllMonitors({
+ authToken: authToken,
+ });
return res.data;
} catch (error) {
if (error.response && error.response.data) {
diff --git a/Client/src/Pages/Incidents/IncidentTable/index.jsx b/Client/src/Pages/Incidents/IncidentTable/index.jsx
index 6ca18a1e9..f47ad0cf0 100644
--- a/Client/src/Pages/Incidents/IncidentTable/index.jsx
+++ b/Client/src/Pages/Incidents/IncidentTable/index.jsx
@@ -53,27 +53,27 @@ const IncidentTable = ({ monitors, selectedMonitor, filter }) => {
try {
let res;
if (selectedMonitor === "0") {
- res = await networkService.getChecksByTeam(
- authToken,
- user.teamId,
- "desc",
- null,
- null,
- filter,
- paginationController.page,
- paginationController.rowsPerPage
- );
+ res = await networkService.getChecksByTeam({
+ authToken: authToken,
+ userId: user.teamId,
+ sortOrder: "desc",
+ limit: null,
+ dateRange: null,
+ filter: filter,
+ page: paginationController.page,
+ rowsPerPage: paginationController.rowsPerPage,
+ });
} else {
- res = await networkService.getChecksByMonitor(
- authToken,
- selectedMonitor,
- "desc",
- null,
- null,
- filter,
- paginationController.page,
- paginationController.rowsPerPage
- );
+ res = await networkService.getChecksByMonitor({
+ authToken: authToken,
+ monitorId: selectedMonitor,
+ sortOrder: "desc",
+ limit: null,
+ dateRange: null,
+ sitler: filter,
+ page: paginationController.page,
+ rowsPerPage: paginationController.rowsPerPage,
+ });
}
setChecks(res.data.data.checks);
setChecksCount(res.data.data.checksCount);
diff --git a/Client/src/Pages/Monitors/Details/PaginationTable/index.jsx b/Client/src/Pages/Monitors/Details/PaginationTable/index.jsx
index b438f104b..8538ac169 100644
--- a/Client/src/Pages/Monitors/Details/PaginationTable/index.jsx
+++ b/Client/src/Pages/Monitors/Details/PaginationTable/index.jsx
@@ -40,16 +40,16 @@ const PaginationTable = ({ monitorId, dateRange }) => {
useEffect(() => {
const fetchPage = async () => {
try {
- const res = await networkService.getChecksByMonitor(
- authToken,
- monitorId,
- "desc",
- null,
- dateRange,
- null,
- paginationController.page,
- paginationController.rowsPerPage
- );
+ const res = await networkService.getChecksByMonitor({
+ authToken: authToken,
+ monitoirId: monitorId,
+ sortOrder: "desc",
+ limit: null,
+ dateRange: dateRange,
+ filter: null,
+ page: paginationController.page,
+ rowsPerPage: paginationController.rowsPerPage,
+ });
setChecks(res.data.data.checks);
setChecksCount(res.data.data.checksCount);
} catch (error) {
diff --git a/Client/src/Pages/Monitors/Details/index.jsx b/Client/src/Pages/Monitors/Details/index.jsx
index 50ae8f558..31029fb45 100644
--- a/Client/src/Pages/Monitors/Details/index.jsx
+++ b/Client/src/Pages/Monitors/Details/index.jsx
@@ -63,15 +63,15 @@ const DetailsPage = ({ isAdmin }) => {
const fetchMonitor = useCallback(async () => {
try {
- const res = await networkService.getStatsByMonitorId(
- authToken,
- monitorId,
- null,
- null,
- dateRange,
- 50,
- true
- );
+ const res = await networkService.getStatsByMonitorId({
+ authToken: authToken,
+ monitorId: monitorId,
+ sortOrder: null,
+ limit: null,
+ dateRange: dateRange,
+ numToDisplay: 50,
+ normalize: true,
+ });
setMonitor(res?.data?.data ?? {});
} catch (error) {
logger.error(error);
@@ -89,10 +89,10 @@ const DetailsPage = ({ isAdmin }) => {
return;
}
try {
- const res = await networkService.getCertificateExpiry(
- authToken,
- monitorId
- );
+ const res = await networkService.getCertificateExpiry({
+ authToken: authToken,
+ monitorId: monitorId,
+ });
if (res?.data?.data?.certificateDate) {
let [month, day, year] = res.data.data.certificateDate.split("/");
diff --git a/Client/src/Pages/Monitors/Home/MonitorTable/index.jsx b/Client/src/Pages/Monitors/Home/MonitorTable/index.jsx
index b7e50a499..b86a739e0 100644
--- a/Client/src/Pages/Monitors/Home/MonitorTable/index.jsx
+++ b/Client/src/Pages/Monitors/Home/MonitorTable/index.jsx
@@ -17,7 +17,7 @@ import ArrowDownwardRoundedIcon from "@mui/icons-material/ArrowDownwardRounded";
import ArrowUpwardRoundedIcon from "@mui/icons-material/ArrowUpwardRounded";
import { setRowsPerPage } from "../../../../Features/UI/uiSlice";
-import { useState, useEffect, memo } from "react";
+import { useState, useEffect, memo, useCallback, useRef } from "react";
import { useNavigate } from "react-router";
import { logger } from "../../../../Utils/Logger";
import Host from "../host";
@@ -49,7 +49,6 @@ import useUtils from "../../utils";
*/
const TablePaginationActions = (props) => {
const { count, page, rowsPerPage, onPageChange } = props;
-
const handleFirstPageButtonClick = (event) => {
onPageChange(event, 0);
};
@@ -108,7 +107,7 @@ TablePaginationActions.propTypes = {
onPageChange: PropTypes.func.isRequired,
};
-const MonitorTable = ({ isAdmin, filter }) => {
+const MonitorTable = ({ isAdmin, filter, setLoading }) => {
const theme = useTheme();
const navigate = useNavigate();
const dispatch = useDispatch();
@@ -121,6 +120,7 @@ const MonitorTable = ({ isAdmin, filter }) => {
const authState = useSelector((state) => state.auth);
const [updateTrigger, setUpdateTrigger] = useState(false);
const [sort, setSort] = useState({});
+ const prevFilter = useRef(filter);
const handleActionMenuDelete = () => {
setUpdateTrigger((prev) => !prev);
@@ -140,33 +140,53 @@ const MonitorTable = ({ isAdmin, filter }) => {
setPage(0);
};
+ const fetchPage = useCallback(async () => {
+ try {
+ const { authToken } = authState;
+ const user = jwtDecode(authToken);
+ const res = await networkService.getMonitorsByTeamId({
+ authToken,
+ teamId: user.teamId,
+ limit: 25,
+ types: ["http", "ping"],
+ status: null,
+ checkOrder: "desc",
+ normalize: true,
+ page: page,
+ rowsPerPage: rowsPerPage,
+ filter: filter,
+ field: sort.field,
+ order: sort.order,
+ });
+ setMonitors(res?.data?.data?.monitors ?? []);
+ setMonitorCount(res?.data?.data?.monitorCount ?? 0);
+ setLoading(false);
+ } catch (error) {
+ logger.error(error);
+ }
+ }, [authState, page, rowsPerPage, filter, sort, setLoading]);
+
useEffect(() => {
- const fetchPage = async () => {
- try {
- const { authToken } = authState;
- const user = jwtDecode(authToken);
- const res = await networkService.getMonitorsByTeamId({
- authToken,
- teamId: user.teamId,
- limit: 25,
- types: ["http", "ping"],
- status: null,
- checkOrder: "desc",
- normalize: true,
- page: page,
- rowsPerPage: rowsPerPage,
- filter: filter,
- field: sort.field,
- order: sort.order,
- });
- setMonitors(res?.data?.data?.monitors ?? []);
- setMonitorCount(res?.data?.data?.monitorCount ?? 0);
- } catch (error) {
- logger.error(error);
- }
- };
fetchPage();
- }, [updateTrigger, authState, page, rowsPerPage, filter, sort]);
+ }, [
+ updateTrigger,
+ authState,
+ page,
+ rowsPerPage,
+ filter,
+ sort,
+ setLoading,
+ fetchPage,
+ ]);
+
+ // Listen for changes in filter, if new value reset the page
+ useEffect(() => {
+ if (prevFilter.current !== filter) {
+ setPage(0);
+ fetchPage();
+ }
+ prevFilter.current = filter;
+ }, [filter, fetchPage]);
/**
* Helper function to calculate the range of displayed rows.
@@ -407,6 +427,7 @@ const MonitorTable = ({ isAdmin, filter }) => {
MonitorTable.propTypes = {
isAdmin: PropTypes.bool,
filter: PropTypes.string,
+ setLoading: PropTypes.func,
};
const MemoizedMonitorTable = memo(MonitorTable);
diff --git a/Client/src/Pages/Monitors/Home/index.jsx b/Client/src/Pages/Monitors/Home/index.jsx
index 9db0cbf9a..c2a532bb9 100644
--- a/Client/src/Pages/Monitors/Home/index.jsx
+++ b/Client/src/Pages/Monitors/Home/index.jsx
@@ -4,7 +4,13 @@ import { useSelector, useDispatch } from "react-redux";
import { getUptimeMonitorsByTeamId } from "../../../Features/UptimeMonitors/uptimeMonitorsSlice";
import { useNavigate } from "react-router-dom";
import { useTheme } from "@emotion/react";
-import { Box, Button, Stack, Typography } from "@mui/material";
+import {
+ Box,
+ Button,
+ CircularProgress,
+ Stack,
+ Typography,
+} from "@mui/material";
import PropTypes from "prop-types";
import SkeletonLayout from "./skeleton";
import Fallback from "./fallback";
@@ -21,12 +27,19 @@ const Monitors = ({ isAdmin }) => {
const monitorState = useSelector((state) => state.uptimeMonitors);
const authState = useSelector((state) => state.auth);
const [search, setSearch] = useState("");
+ const [isSearching, setIsSearching] = useState(false);
const dispatch = useDispatch({});
const debouncedFilter = useDebounce(search, 500);
+ const handleSearch = (value) => {
+ setIsSearching(true);
+ setSearch(value);
+ };
+
useEffect(() => {
dispatch(getUptimeMonitorsByTeamId(authState.authToken));
}, [authState.authToken, dispatch]);
+
let loading =
monitorState?.isLoading &&
monitorState?.monitorsSummary?.monitors?.length === 0;
@@ -124,11 +137,47 @@ const Monitors = ({ isAdmin }) => {
options={monitorState?.monitorsSummary.monitors}
filteredBy="name"
value={search}
- handleInputChange={setSearch}
+ handleInputChange={handleSearch}
/>
-
+
+ {isSearching && (
+ <>
+
+
+
+
+ >
+ )}
+
+
>
)}
diff --git a/Client/src/Pages/PageSpeed/Details/index.jsx b/Client/src/Pages/PageSpeed/Details/index.jsx
index 48d8aa86a..8fc137223 100644
--- a/Client/src/Pages/PageSpeed/Details/index.jsx
+++ b/Client/src/Pages/PageSpeed/Details/index.jsx
@@ -44,15 +44,15 @@ const PageSpeedDetails = () => {
useEffect(() => {
const fetchMonitor = async () => {
try {
- const res = await networkService.getStatsByMonitorId(
- authToken,
- monitorId,
- "desc",
- 50,
- "day",
- null,
- null
- );
+ const res = await networkService.getStatsByMonitorId({
+ authToken: authToken,
+ monitorId: monitorId,
+ sortOrder: "desc",
+ limit: 50,
+ dateRange: "day",
+ numToDisplay: null,
+ normalize: null,
+ });
setMonitor(res?.data?.data ?? {});
setAudits(res?.data?.data?.checks?.[0]?.audits ?? []);
} catch (error) {
diff --git a/Client/src/Pages/Settings/index.jsx b/Client/src/Pages/Settings/index.jsx
index ac25c480d..806f29e75 100644
--- a/Client/src/Pages/Settings/index.jsx
+++ b/Client/src/Pages/Settings/index.jsx
@@ -69,7 +69,10 @@ const Settings = ({ isAdmin }) => {
const handleSave = async () => {
try {
setChecksIsLoading(true);
- await networkService.updateChecksTTL(authToken, form.ttl);
+ await networkService.updateChecksTTL({
+ authToken: authToken,
+ ttl: form.ttl,
+ });
const updatedUser = { ...user, checkTTL: form.ttl };
const action = await dispatch(
update({ authToken, localData: updatedUser })
diff --git a/Client/src/Utils/NetworkService.js b/Client/src/Utils/NetworkService.js
index 63323d5a8..c087fb73a 100644
--- a/Client/src/Utils/NetworkService.js
+++ b/Client/src/Utils/NetworkService.js
@@ -24,15 +24,16 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {string} monitorId - The monitor ID to be sent in the param.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.monitorId - The monitor ID to be sent in the param.
* @returns {Promise} The response from the axios GET request.
*/
- async getMonitorByid(authToken, monitorId) {
- return this.axiosInstance.get(`/monitors/${monitorId}`, {
+ async getMonitorById(config) {
+ return this.axiosInstance.get(`/monitors/${config.monitorId}`, {
headers: {
- Authorization: `Bearer ${authToken}`,
+ Authorization: `Bearer ${config.authToken}`,
"Content-Type": "application/json",
},
});
@@ -45,32 +46,46 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {Object} monitor - The monitor object to be sent in the request body.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {Object} config.monitor - The monitor object to be sent in the request body.
* @returns {Promise} The response from the axios POST request.
*/
- async createMonitor(authToken, monitor) {
- return this.axiosInstance.post(`/monitors`, monitor, {
+ async createMonitor(config) {
+ return this.axiosInstance.post(`/monitors`, config.monitor, {
headers: {
- Authorization: `Bearer ${authToken}`,
+ Authorization: `Bearer ${config.authToken}`,
"Content-Type": "application/json",
},
});
}
- async getMonitorsAndSummaryByTeamId(authToken, teamId, types) {
+ /**
+ *
+ * ************************************
+ * Gets monitors and summary of stats by TeamID
+ * ************************************
+ *
+ * @async
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.teamId - Team ID
+ * @param {Array} config.types - Array of monitor types
+ * @returns {Promise} The response from the axios POST request.
+ */
+ async getMonitorsAndSummaryByTeamId(config) {
const params = new URLSearchParams();
- if (types) {
- types.forEach((type) => {
+ if (config.types) {
+ config.types.forEach((type) => {
params.append("type", type);
});
}
return this.axiosInstance.get(
- `/monitors/team/summary/${teamId}?${params.toString()}`,
+ `/monitors/team/summary/${config.teamId}?${params.toString()}`,
{
headers: {
- Authorization: `Bearer ${authToken}`,
+ Authorization: `Bearer ${config.authToken}`,
"Content-Type": "application/json",
},
}
@@ -148,61 +163,29 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {string} monitorId - The ID of the monitor whose statistics are to be retrieved.
- * @param {string} [sortOrder] - The order in which to sort the retrieved statistics.
- * @param {number} [limit] - The maximum number of statistics to retrieve.
- * @param {string} [dateRange] - The date range for which to retrieve statistics.
- * @param {number} [numToDisplay] - The number of checks to display.
- * @param {boolean} [normalize] - Whether to normalize the retrieved statistics.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.monitorId - The ID of the monitor whose statistics are to be retrieved.
+ * @param {string} config.sortOrder - The order in which to sort the retrieved statistics.
+ * @param {number} config.limit - The maximum number of statistics to retrieve.
+ * @param {string} config.dateRange - The date range for which to retrieve statistics.
+ * @param {number} config.numToDisplay - The number of checks to display.
+ * @param {boolean} config.normalize - Whether to normalize the retrieved statistics.
* @returns {Promise} The response from the axios GET request.
*/
- async getStatsByMonitorId(
- authToken,
- monitorId,
- sortOrder,
- limit,
- dateRange,
- numToDisplay,
- normalize
- ) {
+ async getStatsByMonitorId(config) {
const params = new URLSearchParams();
- if (sortOrder) params.append("sortOrder", sortOrder);
- if (limit) params.append("limit", limit);
- if (dateRange) params.append("dateRange", dateRange);
- if (numToDisplay) params.append("numToDisplay", numToDisplay);
- if (normalize) params.append("normalize", normalize);
+ if (config.sortOrder) params.append("sortOrder", config.sortOrder);
+ if (config.limit) params.append("limit", config.limit);
+ if (config.dateRange) params.append("dateRange", config.dateRange);
+ if (config.numToDisplay) params.append("numToDisplay", config.numToDisplay);
+ if (config.normalize) params.append("normalize", config.normalize);
return this.axiosInstance.get(
- `/monitors/stats/${monitorId}?${params.toString()}`,
+ `/monitors/stats/${config.monitorId}?${params.toString()}`,
{
headers: {
- Authorization: `Bearer ${authToken}`,
- },
- }
- );
- }
-
- /**
- * ************************************
- * Gets aggregate stats by monitor ID
- * ************************************
- *
- * @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {string} monitorId - The ID of the monitor whose certificate expiry is to be retrieved.
- * @returns {Promise} The response from the axios GET request.
- *
- */
- async getAggregateStatsById(authToken, monitorId, dateRange) {
- const params = new URLSearchParams();
- if (dateRange) params.append("dateRange", dateRange);
-
- return this.axiosInstance.get(
- `/monitors/aggregate/${monitorId}?${params.toString()}`,
- {
- headers: {
- Authorization: `Bearer ${authToken}`,
+ Authorization: `Bearer ${config.authToken}`,
},
}
);
@@ -214,18 +197,23 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {string} monitorId - The ID of the monitor to be updated.
- * @param {Object} updatedFields - The fields to be updated for the monitor.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.monitorId - The ID of the monitor to be updated.
+ * @param {Object} config.updatedFields - The fields to be updated for the monitor.
* @returns {Promise} The response from the axios PUT request.
*/
- async updateMonitor(authToken, monitorId, updatedFields) {
- return this.axiosInstance.put(`/monitors/${monitorId}`, updatedFields, {
- headers: {
- Authorization: `Bearer ${authToken}`,
- "Content-Type": "application/json",
- },
- });
+ async updateMonitor(config) {
+ return this.axiosInstance.put(
+ `/monitors/${config.monitorId}`,
+ config.updatedFields,
+ {
+ headers: {
+ Authorization: `Bearer ${config.authToken}`,
+ "Content-Type": "application/json",
+ },
+ }
+ );
}
/**
@@ -234,14 +222,15 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {string} monitorId - The ID of the monitor to be deleted.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.monitorId - The ID of the monitor to be deleted.
* @returns {Promise} The response from the axios DELETE request.
*/
- async deleteMonitorById(authToken, monitorId) {
- return this.axiosInstance.delete(`/monitors/${monitorId}`, {
+ async deleteMonitorById(config) {
+ return this.axiosInstance.delete(`/monitors/${config.monitorId}`, {
headers: {
- Authorization: `Bearer ${authToken}`,
+ Authorization: `Bearer ${config.authToken}`,
"Content-Type": "application/json",
},
});
@@ -253,14 +242,15 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {string} monitorId - The ID of the monitor to be deleted.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.teamId - The team ID of the monitors to be deleted.
* @returns {Promise} The response from the axios DELETE request.
*/
- async deleteChecksByTeamId(authToken, teamId) {
- return this.axiosInstance.delete(`/checks/team/${teamId}`, {
+ async deleteChecksByTeamId(config) {
+ return this.axiosInstance.delete(`/checks/team/${config.teamId}`, {
headers: {
- Authorization: `Bearer ${authToken}`,
+ Authorization: `Bearer ${config.authToken}`,
"Content-Type": "application/json",
},
});
@@ -271,17 +261,18 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {string} monitorId - The ID of the monitor to be paused.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.monitorId - The ID of the monitor to be paused.
* @returns {Promise} The response from the axios POST request.
*/
- async pauseMonitorById(authToken, monitorId) {
+ async pauseMonitorById(config) {
return this.axiosInstance.post(
- `/monitors/pause/${monitorId}`,
+ `/monitors/pause/${config.monitorId}`,
{},
{
headers: {
- Authorization: `Bearer ${authToken}`,
+ Authorization: `Bearer ${config.authToken}`,
"Content-Type": "application/json",
},
}
@@ -294,16 +285,17 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
* @returns {Promise} The response from the axios POST request.
*/
- async addDemoMonitors(authToken) {
+ async addDemoMonitors(config) {
return this.axiosInstance.post(
`/monitors/demo`,
{},
{
headers: {
- Authorization: `Bearer ${authToken}`,
+ Authorization: `Bearer ${config.authToken}`,
"Content-Type": "application/json",
},
}
@@ -316,13 +308,14 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
* @returns {Promise} The response from the axios DELETE request.
*/
- async deleteAllMonitors(authToken) {
+ async deleteAllMonitors(config) {
return this.axiosInstance.delete(`/monitors/`, {
headers: {
- Authorization: `Bearer ${authToken}`,
+ Authorization: `Bearer ${config.authToken}`,
"Content-Type": "application/json",
},
});
@@ -334,15 +327,16 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {string} monitorId - The ID of the monitor whose certificate expiry is to be retrieved.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.monitorId - The ID of the monitor whose certificate expiry is to be retrieved.
* @returns {Promise} The response from the axios GET request.
*
*/
- async getCertificateExpiry(authToken, monitorId) {
- return this.axiosInstance.get(`/monitors/certificate/${monitorId}`, {
+ async getCertificateExpiry(config) {
+ return this.axiosInstance.get(`/monitors/certificate/${config.monitorId}`, {
headers: {
- Authorization: `Bearer ${authToken}`,
+ Authorization: `Bearer ${config.authToken}`,
},
});
}
@@ -380,23 +374,35 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {string} userId - The ID of the user to be updated.
- * @param {Object} form - The form data for the user to be updated.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.userId - The ID of the user to be updated.
+ * @param {Object} config.form - The form data for the user to be updated.
* @returns {Promise} The response from the axios PUT request.
*
*/
- async updateUser(authToken, userId, form) {
- return this.axiosInstance.put(`/auth/user/${userId}`, form, {
+ async updateUser(config) {
+ return this.axiosInstance.put(`/auth/user/${config.userId}`, config.form, {
headers: {
- Authorization: `Bearer ${authToken}`,
+ Authorization: `Bearer ${config.authToken}`,
},
});
}
- async deleteUser(authToken, userId) {
- return this.axiosInstance.delete(`/auth/user/${userId}`, {
- headers: { Authorization: `Bearer ${authToken}` },
+ /**
+ * ************************************
+ * Deletes a user
+ * ************************************
+ *
+ * @async
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.userId - The ID of the user to be deleted.
+ *
+ **/
+ async deleteUser(config) {
+ return this.axiosInstance.delete(`/auth/user/${config.userId}`, {
+ headers: { Authorization: `Bearer ${config.authToken}` },
});
}
@@ -420,13 +426,14 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} recoveryToken - The recovery token to be validated.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.recoveryToken - The recovery token to be validated.
* @returns {Promise} The response from the axios POST request.
*
*/
- async validateRecoveryToken(recoveryToken) {
+ async validateRecoveryToken(config) {
return this.axiosInstance.post("/auth/recovery/validate", {
- recoveryToken,
+ recoveryToken: config.recoveryToken,
});
}
@@ -436,14 +443,16 @@ class NetworkService {
* ************************************
*
* @async
- * @param {Object} form - The form data for the password recovery request.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.recoveryToken - The token for recovery request.
+ * @param {Object} config.form - The form data for the password recovery request.
* @returns {Promise} The response from the axios POST request.
*
*/
- async setNewPassword(recoveryToken, form) {
+ async setNewPassword(config) {
return this.axiosInstance.post("/auth/recovery/reset", {
- ...form,
- recoveryToken,
+ ...config.form,
+ recoveryToken: config.recoveryToken,
});
}
@@ -466,13 +475,14 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
* @returns {Promise} The response from the axios GET request.
*
*/
- async getAllUsers(authToken) {
+ async getAllUsers(config) {
return this.axiosInstance.get("/auth/users", {
- headers: { Authorization: `Bearer ${authToken}` },
+ headers: { Authorization: `Bearer ${config.authToken}` },
});
}
@@ -482,18 +492,19 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {string} email - The email of the user to be invited.
- * @param {string} role - The role of the user to be invited.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.email - The email of the user to be invited.
+ * @param {string} config.role - The role of the user to be invited.
* @returns {Promise} The response from the axios POST request.
*
*/
- async requestInvitationToken(authToken, email, role) {
+ async requestInvitationToken(config) {
return this.axiosInstance.post(
`/invite`,
- { email, role },
+ { email: config.email, role: config.role },
{
- headers: { Authorization: `Bearer ${authToken}` },
+ headers: { Authorization: `Bearer ${config.authToken}` },
}
);
}
@@ -520,39 +531,34 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {string} monitorId - The ID of the monitor.
- * @param {string} sortOrder - The order in which to sort the checks.
- * @param {number} limit - The maximum number of checks to retrieve.
- * @param {string} dateRange - The range of dates for which to retrieve checks.
- * @param {string} filter - The filter to apply to the checks.
- * @param {number} page - The page number to retrieve in a paginated list.
- * @param {number} rowsPerPage - The number of rows per page in a paginated list.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.monitorId - The ID of the monitor.
+ * @param {string} config.sortOrder - The order in which to sort the checks.
+ * @param {number} config.limit - The maximum number of checks to retrieve.
+ * @param {string} config.dateRange - The range of dates for which to retrieve checks.
+ * @param {string} config.filter - The filter to apply to the checks.
+ * @param {number} config.page - The page number to retrieve in a paginated list.
+ * @param {number} config.rowsPerPage - The number of rows per page in a paginated list.
* @returns {Promise} The response from the axios GET request.
*
*/
- async getChecksByMonitor(
- authToken,
- monitorId,
- sortOrder,
- limit,
- dateRange,
- filter,
- page,
- rowsPerPage
- ) {
+ async getChecksByMonitor(config) {
const params = new URLSearchParams();
- if (sortOrder) params.append("sortOrder", sortOrder);
- if (limit) params.append("limit", limit);
- if (dateRange) params.append("dateRange", dateRange);
- if (filter) params.append("filter", filter);
- if (page) params.append("page", page);
- if (rowsPerPage) params.append("rowsPerPage", rowsPerPage);
+ if (config.sortOrder) params.append("sortOrder", config.sortOrder);
+ if (config.limit) params.append("limit", config.limit);
+ if (config.dateRange) params.append("dateRange", config.dateRange);
+ if (config.filter) params.append("filter", config.filter);
+ if (config.page) params.append("page", config.page);
+ if (config.rowsPerPage) params.append("rowsPerPage", config.rowsPerPage);
- return this.axiosInstance.get(`/checks/${monitorId}?${params.toString()}`, {
- headers: { Authorization: `Bearer ${authToken}` },
- });
+ return this.axiosInstance.get(
+ `/checks/${config.monitorId}?${params.toString()}`,
+ {
+ headers: { Authorization: `Bearer ${config.authToken}` },
+ }
+ );
}
/**
@@ -561,49 +567,53 @@ class NetworkService {
* ************************************
*
* @async
- * @param {string} authToken - The authorization token to be used in the request header.
- * @param {string} userId - The ID of the user.
- * @param {string} sortOrder - The order in which to sort the checks.
- * @param {number} limit - The maximum number of checks to retrieve.
- * @param {string} dateRange - The range of dates for which to retrieve checks.
- * @param {string} filter - The filter to apply to the checks.
- * @param {number} page - The page number to retrieve in a paginated list.
- * @param {number} rowsPerPage - The number of rows per page in a paginated list.
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {string} config.userId - The ID of the user.
+ * @param {string} config.sortOrder - The order in which to sort the checks.
+ * @param {number} config.limit - The maximum number of checks to retrieve.
+ * @param {string} config.dateRange - The range of dates for which to retrieve checks.
+ * @param {string} config.filter - The filter to apply to the checks.
+ * @param {number} config.page - The page number to retrieve in a paginated list.
+ * @param {number} config.rowsPerPage - The number of rows per page in a paginated list.
* @returns {Promise} The response from the axios GET request.
*
*/
- async getChecksByTeam(
- authToken,
- teamId,
- sortOrder,
- limit,
- dateRange,
- filter,
- page,
- rowsPerPage
- ) {
+ async getChecksByTeam(config) {
const params = new URLSearchParams();
- if (sortOrder) params.append("sortOrder", sortOrder);
- if (limit) params.append("limit", limit);
- if (dateRange) params.append("dateRange", dateRange);
- if (filter) params.append("filter", filter);
- if (page) params.append("page", page);
- if (rowsPerPage) params.append("rowsPerPage", rowsPerPage);
+ if (config.sortOrder) params.append("sortOrder", config.sortOrder);
+ if (config.limit) params.append("limit", config.limit);
+ if (config.dateRange) params.append("dateRange", config.dateRange);
+ if (config.filter) params.append("filter", config.filter);
+ if (config.page) params.append("page", config.page);
+ if (config.rowsPerPage) params.append("rowsPerPage", config.rowsPerPage);
return this.axiosInstance.get(
- `/checks/team/${teamId}?${params.toString()}`,
+ `/checks/team/${config.teamId}?${params.toString()}`,
{
- headers: { Authorization: `Bearer ${authToken}` },
+ headers: { Authorization: `Bearer ${config.authToken}` },
}
);
}
- async updateChecksTTL(authToken, ttl) {
+ /**
+ * ************************************
+ * Get all checks for a given user
+ * ************************************
+ *
+ * @async
+ * @param {Object} config - The configuration object.
+ * @param {string} config.authToken - The authorization token to be used in the request header.
+ * @param {number} config.ttl - TTL for checks
+ * @returns {Promise} The response from the axios GET request.
+ *
+ */
+ async updateChecksTTL(config) {
return this.axiosInstance.put(
`/checks/ttl`,
- { ttl },
+ { ttl: config.ttl },
{
headers: {
- Authorization: `Bearer ${authToken}`,
+ Authorization: `Bearer ${config.authToken}`,
"Content-Type": "application/json",
},
}
diff --git a/Docker/.gitignore b/Docker/.gitignore
index 89aa6bfac..3035bcf7a 100644
--- a/Docker/.gitignore
+++ b/Docker/.gitignore
@@ -1,4 +1,5 @@
*.sh
+!quickstart.sh
!build_images.sh
mongo/data/*
redis/data/*
diff --git a/Docker/mongoDB.Dockerfile b/Docker/mongoDB.Dockerfile
index 969a320c2..19fc6e358 100644
--- a/Docker/mongoDB.Dockerfile
+++ b/Docker/mongoDB.Dockerfile
@@ -1,3 +1,4 @@
FROM mongo
+COPY ./Docker/mongo/init/create_users.js /docker-entrypoint-initdb.d/
EXPOSE 27017
CMD ["mongod"]
diff --git a/Docker/quickstart/docker-compose.yaml b/Docker/quickstart/docker-compose.yaml
new file mode 100644
index 000000000..e2c6e0bae
--- /dev/null
+++ b/Docker/quickstart/docker-compose.yaml
@@ -0,0 +1,34 @@
+services:
+ client:
+ image: bluewaveuptime/uptime_client:latest
+ ports:
+ - "80:80"
+ - "443:443"
+ depends_on:
+ - server
+ volumes:
+ - ./nginx/conf.d:/etc/nginx/conf.d/:ro
+ server:
+ image: bluewaveuptime/uptime_server:latest
+ ports:
+ - "5000:5000"
+ env_file:
+ - server.env
+ depends_on:
+ - redis
+ - mongodb
+ redis:
+ image: bluewaveuptime/uptime_redis:latest
+ ports:
+ - "6379:6379"
+ volumes:
+ - ./redis/data:/data
+ mongodb:
+ image: bluewaveuptime/uptime_database_mongo:latest
+ command: ["mongod", "--quiet", "--auth"]
+ ports:
+ - "27017:27017"
+ volumes:
+ - ./mongo/data:/data/db
+ env_file:
+ - mongo.env
diff --git a/Docker/quickstart/quickstart.sh b/Docker/quickstart/quickstart.sh
new file mode 100755
index 000000000..b460daaad
--- /dev/null
+++ b/Docker/quickstart/quickstart.sh
@@ -0,0 +1,123 @@
+default_server_base_url="http://localhost:5000/api/v1"
+default_client_host="http://localhost"
+default_jwt_secret="my_secret"
+default_db_type="MongoDB"
+default_redis_host="redis"
+default_redis_port=6379
+default_token_ttl="99d"
+
+default_db_username="uptime_user"
+default_db_password="uptime_password"
+
+default_system_email_host="smtp.gmail.com"
+default_system_email_port=465
+
+
+echo "Welcome to the Uptime Monitor Setup Script! \n"
+echo
+
+echo "Configuring server"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' '*'
+echo
+
+db_type=$default_db_type
+redis_host=$default_redis_host
+redis_port=$default_redis_port
+jwt_secret=$default_jwt_secret
+
+
+read -p "Enter a username for your database [$default_db_username]: " db_username
+db_username="${db_username:-$default_db_username}"
+
+read -p "Enter a password for your database [$default_db_password]: " db_password
+db_password="${db_password:-$default_db_password}"
+
+read -p "Enter your system email host [$default_system_email_host]: " system_email_host
+system_email_host="${system_email_host:-$default_system_email_host}"
+echo "System email host: $system_email_host"
+echo
+
+read -p "Enter your DB connection string [$default_db_connection_string]: " db_connection_string
+db_connection_string="mongodb://${db_username}:${db_password}@mongodb:27017/uptime_db"
+echo "DB connection string: $db_connection_string"
+echo
+
+read -p "Enter your system email port [$default_system_email_port]: " system_email_port
+system_email_port="${system_email_port:-$default_system_email_port}"
+echo "System email port: $system_email_port"
+echo
+
+
+read -p "Enter your system email address: " system_email_address
+echo "System email address: $system_email_address"
+echo
+
+read -p "Enter your system email password: " system_email_password
+echo "System email password: $system_email_password"
+echo
+
+read -p "Enter your Token TTL [$default_token_ttl]: " token_ttl
+token_ttl="${token_ttl:-$default_token_ttl}"
+echo "Token TTL: $token_ttl"
+echo
+
+read -p "Enter your Pagespeed API key: " pagespeed_api_key
+echo "Pagespeed API key: $pagespeed_api_key"
+echo
+
+echo "Writing to ./server.env"
+echo
+
+{
+ echo "CLIENT_HOST=\"$client_host\""
+ echo "JWT_SECRET=\"$jwt_secret\""
+ echo "DB_TYPE=\"$db_type\""
+ echo "DB_CONNECTION_STRING=\"$db_connection_string\""
+ echo "REDIS_HOST=\"$redis_host\""
+ echo "REDIS_PORT=$redis_port"
+ echo "SYSTEM_EMAIL_HOST=\"$system_email_host\""
+ echo "SYSTEM_EMAIL_PORT=$system_email_port"
+ echo "SYSTEM_EMAIL_ADDRESS=\"$system_email_address\""
+ echo "SYSTEM_EMAIL_PASSWORD=\"$system_email_password\""
+ echo "TOKEN_TTL=\"$token_ttl\""
+ echo "PAGESPEED_API_KEY=\"$pagespeed_api_key\""
+} > ./server.env
+
+
+echo
+{
+ echo USERNAME_ENV_VAR=${db_username}
+ echo PASSWORD_ENV_VAR=${db_password}
+} > ./mongo.env
+
+mkdir -p ./nginx/conf.d/
+
+
+cat < ./nginx/conf.d/default.conf
+server {
+ listen 80;
+ listen [::]:80;
+
+ server_name uptime-demo.bluewavelabs.ca;
+ server_tokens off;
+
+ location /.well-known/acme-challenge/ {
+ root /var/www/certbot;
+ }
+
+ location / {
+ root /usr/share/nginx/html;
+ index index.html index.htm;
+ try_files \$uri \$uri/ /index.html;
+ }
+
+ location /api/ {
+ proxy_pass http://server:5000/api/;
+ proxy_http_version 1.1;
+ proxy_set_header Host \$host;
+ proxy_set_header X-Real-IP \$remote_addr;
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto \$scheme;
+ }
+}
+EOL
\ No newline at end of file
diff --git a/README.md b/README.md
index 92ee37e35..3c96a0af4 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,10 @@
BlueWave Uptime is an open source server monitoring application used to track the operational status and performance of servers and websites. It regularly checks whether a server/website is accessible and performs optimally, providing real-time alerts and reports on the monitored services' availability, downtime, and response time.
+## Demo
+
+See [BlueWave Uptime](https://uptime-demo.bluewavelabs.ca/) in action. The username is uptimedemo@demo.com and the password is Demouser1!
+
## Features
- [x] Completely open source, deployable on your servers
@@ -74,6 +78,7 @@ Also check other developer and contributor-friendly projects of BlueWave:
- Clone this repository to your local machine
+1. [Quickstart for Users](#user-quickstart)
1. [Quickstart for Developers](#dev-quickstart)
1. [Docker Compose](#docker-compose)
1. [Installation (Client)](#client)
@@ -129,6 +134,15 @@ Also check other developer and contributor-friendly projects of BlueWave:
---
+#### Quickstart for Users
+
+1. Download our [Docker Compose File](/Docker/quickstart/docker-compose.yaml)
+2. Download our [Quickstart script](/Docker/quickstart/quickstart.sh)
+3. Place these files in a directory of your choice
+4. Run `quickstart.sh` and generate config files
+5. Run `docker compose up` to start the application
+6. Application is running at `http://localhost`
+
#### Quickstart for Developers
MAKE SURE YOU CD TO THE SPECIFIED DIRECTORIES AS PATHS IN COMMANDS ARE RELATIVE
diff --git a/Server/routes/inviteRoute.js b/Server/routes/inviteRoute.js
index 54e74b0fa..17744bf82 100644
--- a/Server/routes/inviteRoute.js
+++ b/Server/routes/inviteRoute.js
@@ -13,10 +13,6 @@ router.post(
verifyJWT,
inviteController
);
-router.post(
- "/verify",
- isAllowed(["admin", "superadmin"]),
- inviteVerifyController
-);
+router.post("/verify", inviteVerifyController);
module.exports = router;