Skip to content

Commit

Permalink
Merge pull request #43 from MoaidHashem3/master
Browse files Browse the repository at this point in the history
Ezzz
  • Loading branch information
ezzbakry authored Oct 15, 2024
2 parents 1e0071f + d7dbc5a commit 4dcc016
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 17 deletions.
4 changes: 3 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
CONNECTION_STRING = 'mongodb+srv://mophoeniiiix:ZK6AdzDw6PbK8YoN@cluster0.ob8d1.mongodb.net/ums?retryWrites=true&w=majority'
secret="this_is_my_jwt_secret"
PORT=3000
PORT=3000
MAILJET_API_KEY='3509b8424511b49f7f77c97af1e74044'
MAILJET_API_SECRET='1d3be59ab9ebf2d3c9900fd19d5f13d4'
1 change: 0 additions & 1 deletion controllers/handelCourse.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ const enrollInCourse = async (req, res)=>{
// Enroll the student in the course
course.students.push(studentId);
await course.save();

// Add the course to the student's enrolled courses
student.enrolledCourses.push(courseId);
await student.save();
Expand Down
132 changes: 125 additions & 7 deletions controllers/handelUser.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
var jwt = module.require('jsonwebtoken');
const bcrypt = module.require('bcrypt');
const usermodel = module.require("../models/usersModel")
const crypto = require('crypto');
const nodemailer = require('nodemailer');


const getall = async (req, res) => {
Expand Down Expand Up @@ -35,21 +37,19 @@ const getByid = async (req, res) => {
const updateOne = async (req, res) => {
try {
const { id } = req.params;
const { password, ...newUpdate } = req.body; // Extract other fields from req.body
const { newPassword, ...newUpdate } = req.body; // Extract other fields from req.body
const updateData = { ...newUpdate };

console.log(req.body)
// Handle password hashing if provided
if (password) {
const hashedPassword = await bcrypt.hash(password, 10);
if (newPassword) {
const hashedPassword = await bcrypt.hash(newPassword, 10);
updateData.password = hashedPassword;
}

// If an image is provided, handle file upload
if (req.file) {
updateData.image = req.file.path; // Set image path from multer file upload
}

// Find the user and update
const updatedUser = await usermodel.findByIdAndUpdate(id, updateData, { new: true });

if (!updatedUser) {
Expand All @@ -63,6 +63,7 @@ const updateOne = async (req, res) => {
};



const createone = async (req, res) => {
try {
// Extract user data from the request body
Expand Down Expand Up @@ -199,4 +200,121 @@ const uploadImage = async (req, res) => {
res.status(500).send(err.message);
}
};
module.exports = { getall, getByid, updateOne,createone,deleteOne,deleteall,login, uploadImage,getAllProfessors }

const forgotPassword = async (req, res) => {
const { email } = req.body;

if (!email) {
return res.status(400).json({ message: "Email is required" });
}

try {
const user = await usermodel.findOne({ email });

if (!user) {
return res.status(404).json({ message: "User not found" });
}

const token = crypto.randomBytes(20).toString('hex');

user.resetPasswordToken = token;
user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
await user.save();

const transporter = nodemailer.createTransport({
host: 'in.mailjet.com',
port: 587,
auth: {
user: process.env.MAILJET_API_KEY,
pass: process.env.MAILJET_API_SECRET,
},
});

const resetUrl = `http://localhost:5173/reset-password/${token}`;
const mailOptions = {
to: user.email,
from: 'gamestorrent2015@gmail.com',
subject: 'UMS Password Reset',
html: `
<div style="font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px; border-radius: 8px;">
<div style="max-width: 600px; margin: auto; background-color: #ffffff; padding: 30px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);">
<h1 style="color:#808080;">UMS</h1>
<h2 style="color: #333333;">Password Reset Request [Valid for 1 hour]</h2>
<p style="color: #555555;">Dear ${user.name},</p>
<p style="color: #555555;">
You are receiving this email because we received a request to reset the password for your account.
</p>
<p style="color: #555555;">
To complete the process, please click on the link below or copy and paste it into your browser:
</p>
<p>
<a href="${resetUrl}" style="color: #008A90; text-decoration: none; font-weight: bold;">${resetUrl}</a>
</p>
<p style="color: #555555;">
If you did not request this change, please ignore this email. Your password will remain unchanged.
</p>
<p style="color: #555555;">Thank you,</p>
<p style="color: #008A90; font-weight: bold;">UMS Team</p>
</div>
</div>
`
};

transporter.sendMail(mailOptions, (err) => {
if (err) {
return res.status(500).json({ message: "Error sending email", error: err.message });
}
res.status(200).json({ message: "Password reset link sent!" });
});

} catch (error) {
res.status(500).json({ message: "Server error, please try again later" });
}

};
const resetPassword = async (req, res) => {
const { token } = req.params;
const { password } = req.body;
if (!password) {
return res.status(400).json({ message: "Password is required" });
}

try {
const user = await usermodel.findOne({
resetPasswordToken: token,
resetPasswordExpires: { $gt: Date.now() },
});

if (!user) {
return res.status(400).json({ message: "Invalid or expired token" });
}


user.password = password;
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;

await user.save();

res.status(200).json({ message: "Password successfully reset!" });
} catch (error) {
res.status(500).json({ message: "Server error, please try again later" });
}
};
const verifyPassword = async (req, res) => {
const { password } = req.body;
console.log("password is",password)
try {
const user = await usermodel.findById(req.params.id);
if (!user) return res.status(404).send('User not found');

const isValid = await bcrypt.compare(password, user.password);
if (!isValid) return res.status(401).send('passord is not valid');

res.send( isValid);
} catch (err) {
res.status(500).send(err.message);
}
}

module.exports = { getall, getByid, updateOne,createone,deleteOne,deleteall,login, uploadImage,getAllProfessors, forgotPassword, resetPassword,verifyPassword }
2 changes: 2 additions & 0 deletions models/usersModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ const userSchema = new mongoose.Schema({
totalScore: { type: Number, default: 0 },
},
],
resetPasswordToken: { type: String },
resetPasswordExpires: { type: Date },
});

userSchema.pre("save", async function (next) {
Expand Down
24 changes: 17 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"mongoose": "^8.6.1",
"multer": "^1.4.4",
"multer-gridfs-storage": "^5.0.2",
"nodemailer": "^6.9.15",
"nodemon": "^3.1.4",
"uuid": "^10.0.0",
"validator": "^13.12.0"
Expand Down
6 changes: 5 additions & 1 deletion routes/userRoute.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const upload = require('../Middlewares/uploadConfig');

const { getall, getByid, updateOne,createone,deleteOne,deleteall,login,uploadImage, getAllProfessors} = module.require("../controllers/handelUser");
const { getall, getByid, updateOne,createone,deleteOne,deleteall,login,uploadImage, getAllProfessors, forgotPassword, resetPassword,verifyPassword} = module.require("../controllers/handelUser");

const express = module.require('express')
const router=express.Router();
Expand All @@ -16,4 +16,8 @@ router.delete('/:id',deleteOne)
router.delete('/',auth,restrict("admin"),deleteall)
router.post('/login',login)
router.post('/uploadUserImage/:id',upload.single('image'),uploadImage);
router.post('/forgot-password', forgotPassword);
router.post('/reset-password/:token', resetPassword);
router.post('/verify/:id',verifyPassword);

module.exports=router;

0 comments on commit 4dcc016

Please sign in to comment.