diff --git a/Client/src/Pages/Auth/Register/Register.jsx b/Client/src/Pages/Auth/Register/Register.jsx index a5db76373..662729eac 100644 --- a/Client/src/Pages/Auth/Register/Register.jsx +++ b/Client/src/Pages/Auth/Register/Register.jsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import { useTheme } from "@emotion/react"; import { Stack, Typography } from "@mui/material"; @@ -15,13 +15,13 @@ import { createToast } from "../../../Utils/toastUtils"; import Field from "../../../Components/Inputs/Field"; import { register } from "../../../Features/Auth/authSlice"; import { useParams } from "react-router-dom"; +import axiosInstance from "../../../Utils/axiosConfig"; const Register = ({ isAdmin }) => { const dispatch = useDispatch(); const navigate = useNavigate(); const { token } = useParams(); const theme = useTheme(); - // TODO If possible, change the IDs of these fields to match the backend const idMap = { "register-firstname-input": "firstName", @@ -41,6 +41,23 @@ const Register = ({ isAdmin }) => { }); const [errors, setErrors] = useState({}); + useEffect(() => { + const fetchInvite = async () => { + if (token !== undefined) { + try { + const res = await axiosInstance.post(`/auth/invite/verify`, { + token, + }); + const { role, email } = res.data.data; + setForm({ ...form, email, role }); + } catch (error) { + console.log(error); + } + } + }; + fetchInvite(); + }, [token]); + const handleSubmit = async (e) => { e.preventDefault(); diff --git a/Client/src/Validation/validation.js b/Client/src/Validation/validation.js index 00d5a1d49..a60259234 100644 --- a/Client/src/Validation/validation.js +++ b/Client/src/Validation/validation.js @@ -68,7 +68,7 @@ const credentials = joi.object({ } return value; }), - role: joi.array().required(), + role: joi.array(), }); const monitorValidation = joi.object({ diff --git a/Server/controllers/authController.js b/Server/controllers/authController.js index 28126c0a2..cec65eecd 100644 --- a/Server/controllers/authController.js +++ b/Server/controllers/authController.js @@ -10,6 +10,7 @@ const { deleteUserParamValidation, inviteRoleValidation, inviteBodyValidation, + inviteVerifciationBodyValidation, } = require("../validation/joi"); const logger = require("../utils/logger"); require("dotenv").config(); @@ -237,6 +238,21 @@ const inviteController = async (req, res, next) => { } }; +const inviteVerifyController = async (req, res, next) => { + try { + await inviteVerifciationBodyValidation.validateAsync(req.body); + const invite = await req.db.getInviteToken(req, res); + + res + .status(200) + .json({ status: "success", msg: "Invite verified", data: invite }); + } catch (error) { + error.service = SERVICE_NAME; + next(error); + return; + } +}; + /** * Checks to see if an admin account exists * @async @@ -445,6 +461,7 @@ module.exports = { loginController, userEditController, inviteController, + inviteVerifyController, checkAdminController, recoveryRequestController, validateRecoveryTokenController, diff --git a/Server/db/MongoDB.js b/Server/db/MongoDB.js index 438c7c306..05b7ca4ab 100644 --- a/Server/db/MongoDB.js +++ b/Server/db/MongoDB.js @@ -185,6 +185,21 @@ const requestInviteToken = async (req, res) => { } }; +const getInviteToken = async (req, res) => { + try { + console.log(req.body.token); + const invite = await InviteToken.findOneAndDelete({ + token: req.body.token, + }); + if (invite === null) { + throw new Error(errorMessages.AUTH_INVITE_NOT_FOUND); + } + return invite; + } catch (error) { + throw error; + } +}; + /** * Request a recovery token * @async @@ -695,6 +710,7 @@ module.exports = { deleteUser, getAllUsers, requestInviteToken, + getInviteToken, requestRecoveryToken, validateRecoveryToken, resetPassword, diff --git a/Server/routes/authRoute.js b/Server/routes/authRoute.js index 02a1a67dd..137434b7a 100644 --- a/Server/routes/authRoute.js +++ b/Server/routes/authRoute.js @@ -17,6 +17,7 @@ const { getAllUsersController, deleteUserController, inviteController, + inviteVerifyController, } = require("../controllers/authController"); //Auth routes @@ -38,6 +39,7 @@ router.delete( ); router.post("/invite", verifyJWT, inviteController); +router.post("/invite/verify", inviteVerifyController); //Recovery routes router.post("/recovery/request", recoveryRequestController); diff --git a/Server/utils/messages.js b/Server/utils/messages.js index 9ef5c6938..19d9929ab 100644 --- a/Server/utils/messages.js +++ b/Server/utils/messages.js @@ -6,6 +6,7 @@ const errorMessages = { // Auth Controller UNAUTHORIZED: "Unauthorized access", AUTH_ADMIN_EXISTS: "Admin already exists", + AUTH_INVITE_NOT_FOUND: "Invite not found", //Error handling middleware UNKNOWN_SERVICE: "Unknown service", diff --git a/Server/validation/joi.js b/Server/validation/joi.js index ec773632c..eb298bb28 100644 --- a/Server/validation/joi.js +++ b/Server/validation/joi.js @@ -112,6 +112,10 @@ const inviteBodyValidation = joi.object({ }), }); +const inviteVerifciationBodyValidation = joi.object({ + token: joi.string().required(), +}); + //**************************************** // Monitors //**************************************** @@ -239,6 +243,7 @@ module.exports = { newPasswordValidation, inviteRoleValidation, inviteBodyValidation, + inviteVerifciationBodyValidation, getMonitorByIdValidation, getMonitorsByUserIdValidation, monitorValidation,