Added recovery Request route, controller, and DB operations

This commit is contained in:
Alex Holliday
2024-06-10 15:54:45 -07:00
parent 5064450e8b
commit 276dadab66
5 changed files with 91 additions and 13 deletions
+28 -6
View File
@@ -13,6 +13,7 @@ const { sendEmail } = require("../utils/sendEmail");
const {
registerTemplate,
} = require("../utils/emailTemplates/registerTemplate");
const RecoveryToken = require("../models/RecoveryToken");
/**
* Creates and returns JWT token with an arbitrary payload
@@ -97,10 +98,6 @@ const loginController = async (req, res, next) => {
// Check if user exists
const user = await req.db.getUserByEmail(req, res);
// If user not found, throw an error
if (!user) {
throw new Error("User not found!");
}
// Compare password
const match = await user.comparePassword(req.body.password);
if (!match) {
@@ -145,7 +142,7 @@ const userEditController = async (req, res, next) => {
try {
const updatedUser = await req.db.updateUser(req, res);
res
return res
.status(200)
.json({ success: true, msg: "User updated", data: updatedUser });
} catch (error) {
@@ -155,4 +152,29 @@ const userEditController = async (req, res, next) => {
}
};
module.exports = { registerController, loginController, userEditController };
const recoveryRequestController = async (req, res, next) => {
const email = req.body.email;
try {
const user = await req.db.getUserByEmail(req, res);
// TODO Email token to user
if (user) {
const recoveryToken = await req.db.requestRecoveryToken(req, res);
console.log(recoveryToken);
return res.status(200).json({
success: true,
msg: "Created recovery token",
data: recoveryToken.token,
});
}
} catch (error) {
error.service = SERVICE_NAME;
next(error);
return;
}
};
module.exports = {
registerController,
loginController,
userEditController,
recoveryRequestController,
};
+33 -6
View File
@@ -3,10 +3,8 @@ const mongoose = require("mongoose");
const UserModel = require("../models/user");
const Check = require("../models/Check");
const Alert = require("../models/Alert");
const verifyId = (userId, monitorId) => {
return userId.toString() === monitorId.toString();
};
const RecoveyToken = require("../models/RecoveryToken");
const crypto = require("crypto");
const connect = async () => {
try {
@@ -44,6 +42,7 @@ const insertUser = async (req, res) => {
* Get User by Email
* Gets a user by Email. Not sure if we'll ever need this except for login.
* If not needed except for login, we can move password comparison here
* Throws error if user not found
* @async
* @param {Express.Request} req
* @param {Express.Response} res
@@ -52,10 +51,14 @@ const insertUser = async (req, res) => {
*/
const getUserByEmail = async (req, res) => {
try {
// Returns null if no user is found
// Need the password to be able to compare, removed .select()
// We can strip the hash before returing the user
return await UserModel.findOne({ email: req.body.email });
const user = await UserModel.findOne({ email: req.body.email });
if (user) {
return user;
} else {
throw new Error("User not found");
}
} catch (error) {
throw error;
}
@@ -86,6 +89,29 @@ const updateUser = async (req, res) => {
}
};
/**
* Request a recovery token
* @async
* @param {Express.Request} req
* @param {Express.Response} res
* @returns {Promise<UserModel>}
* @throws {Error}
*/
const requestRecoveryToken = async (req, res) => {
try {
// Delete any existing tokens
await RecoveyToken.deleteMany({ email: req.body.email });
let recoveryToken = new RecoveyToken({
email: req.body.email,
token: crypto.randomBytes(32).toString("hex"),
});
await recoveryToken.save();
return recoveryToken;
} catch (error) {
throw error;
}
};
//****************************************
// Monitors
//****************************************
@@ -393,6 +419,7 @@ module.exports = {
insertUser,
getUserByEmail,
updateUser,
requestRecoveryToken,
getAllMonitors,
getMonitorById,
getMonitorsByUserId,
+25
View File
@@ -0,0 +1,25 @@
const mongoose = require("mongoose");
const RecoveryTokenSchema = mongoose.Schema(
{
email: {
type: String,
required: true,
unique: true,
},
token: {
type: String,
required: true,
},
expiry: {
type: Date,
default: Date.now,
expires: 600,
},
},
{
timestamps: true,
}
);
module.exports = mongoose.model("RecoveryToken", RecoveryTokenSchema);
+5
View File
@@ -5,10 +5,15 @@ const {
registerController,
loginController,
userEditController,
recoveryRequestController,
} = require("../controllers/authController");
router.post("/register", registerController);
router.post("/login", loginController);
router.post("/user/:userId", verifyJWT, userEditController);
//Recovery routes
router.post("/recovery/request", recoveryRequestController);
module.exports = router;
-1
View File
@@ -14,7 +14,6 @@ class JobQueue {
* @throws {Error}
*/
constructor() {
console.log(process.env.REDIS_PORT);
this.queue = new Queue(QUEUE_NAME, {
connection,
});