Merge pull request #390 from bluewave-labs/feat/user-invitation

Feat/user invitation
This commit is contained in:
Alexander Holliday authored and GitHub committed 2024-07-19 15:10:13 -07:00
commit 6ada5e08fe
6 files changed
+93 -1875

No files matched your search

+11 -1872
View File
File diff suppressed because it is too large. Load diff
-1
View File
@@ -25,7 +25,6 @@
"dayjs": "1.11.11",
"joi": "17.13.1",
"jwt-decode": "^4.0.0",
"mjml-react": "^2.0.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "9.1.2",
+18
View File
@@ -8,6 +8,8 @@ const {
recoveryTokenValidation,
newPasswordValidation,
deleteUserParamValidation,
inviteRoleValidation,
inviteBodyValidation,
} = require("../validation/joi");
const logger = require("../utils/logger");
require("dotenv").config();
@@ -214,6 +216,21 @@ const userEditController = async (req, res, next) => {
}
};
const inviteController = async (req, res, next) => {
try {
// Only admins can invite
const token = getTokenFromHeaders(req.headers);
const { role } = jwt.decode(token);
await inviteRoleValidation.validateAsync({ roles: role });
await inviteBodyValidation.validateAsync(req.body);
return res.status(200).json({ success: true, msg: "Invite sent" });
} catch (error) {
error.service = SERVICE_NAME;
next(error);
return;
}
};
/**
* Checks to see if an admin account exists
* @async
@@ -404,6 +421,7 @@ module.exports = {
registerController,
loginController,
userEditController,
inviteController,
checkAdminController,
recoveryRequestController,
validateRecoveryTokenController,
+25
View File
@@ -0,0 +1,25 @@
const mongoose = require("mongoose");
const InviteTokenSchema = mongoose.Schema(
{
email: {
type: String,
required: true,
unique: true,
},
token: {
type: String,
required: true,
},
expiry: {
type: Date,
default: Date.now,
expires: 3600,
},
},
{
timestamps: true,
}
);
module.exports = mongoose.model("InviteToken", InviteTokenSchema);
+10 -2
View File
@@ -13,7 +13,8 @@ const {
validateRecoveryTokenController,
resetPasswordController,
checkAdminController,
deleteUserController
deleteUserController,
inviteController,
} = require("../controllers/authController");
//Auth routes
@@ -26,7 +27,14 @@ router.post(
userEditController
);
router.get("/users/admin", checkAdminController);
router.delete("/user/:userId", verifyJWT, verifyOwnership(User, "userId") , deleteUserController);
router.delete(
"/user/:userId",
verifyJWT,
verifyOwnership(User, "userId"),
deleteUserController
);
router.post("/invite", verifyJWT, inviteController);
//Recovery routes
router.post("/recovery/request", recoveryRequestController);
+29
View File
@@ -1,5 +1,17 @@
const joi = require("joi");
//****************************************
// Custom Validators
//****************************************
const roleValidatior = (role) => (value, helpers) => {
console.log(role);
if (!value.includes(role)) {
throw new joi.ValidationError(`You do not have ${role} authorization`);
}
return value;
};
//****************************************
// Auth
//****************************************
@@ -87,6 +99,20 @@ const deleteUserParamValidation = joi.object({
email: joi.string().email().required(),
});
const inviteRoleValidation = joi.object({
roles: joi.custom(roleValidatior("admin")).required(),
});
const inviteBodyValidation = joi.object({
email: joi.string().trim().email().required().messages({
"string.empty": "Email is required",
"string.email": "Must be a valid email address",
}),
role: joi.string().required().messages({
"string.empty": "Role is required",
}),
});
//****************************************
// Monitors
//****************************************
@@ -206,11 +232,14 @@ const deletePageSpeedCheckParamValidation = joi.object({
});
module.exports = {
roleValidatior,
loginValidation,
registerValidation,
recoveryValidation,
recoveryTokenValidation,
newPasswordValidation,
inviteRoleValidation,
inviteBodyValidation,
getMonitorByIdValidation,
getMonitorsByUserIdValidation,
monitorValidation,