Merge pull request #390 from bluewave-labs/feat/user-invitation
Feat/user invitation
This commit is contained in:
6 files changed
+93
-1875
No files matched your search
Generated
+11
-1872
File diff suppressed because it is too large.
Load diff
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user