Skip to content

Commit

Permalink
Merge pull request #32 from Skill-Sync/SS-1.2-Medhat
Browse files Browse the repository at this point in the history
Ss 1.2 medhat
  • Loading branch information
MOHAMMED1MEDHAT authored Sep 10, 2023
2 parents b442624 + 7e32588 commit 8ca9e7e
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 93 deletions.
91 changes: 29 additions & 62 deletions src/controllers/auth.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ const AppError = require('../utils/appErrorsClass');
const catchAsyncError = require('../utils/catchAsyncErrors');

async function sendTokens(user, userType, statusCode, res) {
user.password = undefined;
user.pass = undefined;
let session;
try {
session = await Session.createSession(user._id);
} catch (err) {
return next(new AppError('Error creating session', 500));
}

// console.log(user.role);

if (userType.toLowerCase() === 'user') {
userType = user.role;
}
Expand All @@ -43,38 +45,15 @@ async function sendTokens(user, userType, statusCode, res) {
res.cookie('refreshJWT', refreshToken, cookieOptions);
res.cookie('accessJWT', accessToken, cookieOptions);

let responseObject =
userType.toLowerCase() === 'mentor'
? {
name: user.name,
email: user.email,
about: user.about,
experience: user.experience,
identityCard: user.identityCard,
courses: user.courses,
onboarding_completed: user.onboarding_completed
}
: {
name: user.name,
email: user.email,
photo: user.photo,
about: user.about,
isEmployed: user.isEmployed,
skillsToLearn: user.skillsToLearn,
onboarding_completed: user.onboarding_completed,
skillsLearned: user.skillsLearned
};

res.status(statusCode).json({
status: 'success',
accessJWT: accessToken,
refreshJWT: refreshToken,
data: { responseObject }
data: user
});
}

exports.signup = catchAsyncError(async (req, res, next) => {
const { type } = req.body;
const signUpData = filterObj(
req.body,
'name',
Expand All @@ -83,57 +62,36 @@ exports.signup = catchAsyncError(async (req, res, next) => {
'passConfirm'
);

// Create a new user based on the 'type' (Mentor or User)
const newUser = await (type.toLowerCase() === 'mentor'
//TODO:only the new users and the users with non active accounts can signup
//TODO:what if the 10m are gone and the user didn't confirm his email -> if login without confirming email -> send email again

const newUser = await (req.body.type.toLowerCase() === 'mentor'
? Mentor
: User
).create(signUpData);

// Create email confirmation token and confirmation URL
//send Activation Mail to User

//1-create email confirmation token
const emailConfirmationToken = signEmailConfirmationToken(
newUser._id,
type
req.body.type
);
//2-send email
const emailConfirmationURL = `${req.protocol}://${req.get(
'host'
)}/api/v1/auth/confirmEmail/${emailConfirmationToken}`;

// Send email with the confirmation link
sendEmail(
newUser.email,
'Confirm your Email (valid for 10 min)',
{
name: newUser.name,
link: emailConfirmationURL
},
{ name: newUser.name, link: emailConfirmationURL },
'./templates/mailConfirmation.handlebars'
);

let responseObject =
type.toLowerCase() === 'mentor'
? {
name: newUser.name,
email: newUser.email,
about: newUser.about,
experience: newUser.experience,
identityCard: newUser.identityCard,
courses: newUser.courses,
onboarding_completed: newUser.onboarding_completed
}
: {
name: newUser.name,
email: newUser.email,
photo: newUser.photo,
about: newUser.about,
isEmployed: newUser.isEmployed,
skillsToLearn: newUser.skillsToLearn,
onboarding_completed: newUser.onboarding_completed,
skillsLearned: newUser.skillsLearned
};

res.status(200).json({
status: 'success',
data: responseObject
data: { newUser }
});
});

Expand All @@ -148,13 +106,11 @@ exports.confirmEmail = catchAsyncError(async (req, res, next) => {
const user = await (authenticationToken.userType.toLowerCase() === 'mentor'
? Mentor
: User
).findByIdAndUpdate(authenticationToken.id, {
active: true
});
).findById(authenticationToken.id);

//update user status
// user.active = true;
// await user.save({ validateBeforeSave: false });
user.active = true;
await user.save({ validateBeforeSave: false });

//send welcome email
sendEmail(
Expand All @@ -173,6 +129,7 @@ exports.confirmEmail = catchAsyncError(async (req, res, next) => {

exports.login = catchAsyncError(async (req, res, next) => {
const { email, pass, type } = req.body;

if (!email || !pass)
return next(new AppError('Please provide email and password', 400));

Expand All @@ -192,10 +149,13 @@ exports.login = catchAsyncError(async (req, res, next) => {
});

exports.logout = catchAsyncError(async (req, res, next) => {
//1- from the token get the user id
const { refreshSession } = await verifyToken(
req.headers.authorization?.split(' ')[2],
process.env.JWT_REFRESH_SECRET
);
// console.log(refreshSession);
//2- delete the session from the database
await Session.invalidateSession(refreshSession);
//3- delete the cookie
res.status(res.locals.statusCode || 200).json({
Expand All @@ -205,13 +165,17 @@ exports.logout = catchAsyncError(async (req, res, next) => {
});

exports.forgotPassword = catchAsyncError(async (req, res, next) => {
//1- get user based on email
const user = await (req.body.type.toLowerCase() === 'mentor'
? Mentor
: User
).findOne({ email: req.body.email });

//2- generate random token
const resetToken = user.createPasswordResetToken();
//3- send it to user's email
const resetURL = `${process.env.CLIENT_URL}/resetPass/${resetToken}`;

sendEmail(
user.email,
'Reset your password (valid for 5 min)',
Expand All @@ -223,6 +187,7 @@ exports.forgotPassword = catchAsyncError(async (req, res, next) => {
exports.resetPassword = catchAsyncError(async (req, res, next) => {
const { token, type } = req.params;

//1- get user based on token
const user = await (type.toLowerCase() === 'mentor'
? Mentor
: User
Expand All @@ -234,12 +199,14 @@ exports.resetPassword = catchAsyncError(async (req, res, next) => {
if (!user) {
return next(new AppError('The token is invalid or has expired', 404));
}
//2- if token has not expired and there is user, set new password
user.pass = req.body.pass;
user.passConfirm = req.body.passConfirm;
//3- update changedPassAt property for the user
// user.chancgedPassAt = Date.now() - 1000;
await user.save({ validateBeforeSave: false });

//4-Invalidate all user sessions
await Session.InvalidateAllUserSessions(user_id);

//TODO:Redirect to login page
Expand Down
6 changes: 2 additions & 4 deletions src/controllers/mentor.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ exports.UpdateMe = catchAsyncError(async (req, res, next) => {
'about',
'experience',
'identityCard',
'skillsToLearn',
'skillsLearned',
'courses'
);

Expand All @@ -42,7 +40,7 @@ exports.UpdateMe = catchAsyncError(async (req, res, next) => {
});
await updatedUser.save({ runValidators: true });

res.status(res.locals.statusCode || 200).json({
res.status(res.locals.statusCode || 200).json({
status: 'success',
data: {
user: updatedUser
Expand Down Expand Up @@ -86,7 +84,7 @@ exports.getMentorsReq = catchAsyncError(async (req, res, next) => {
onboarding_completed: true
});

res.status(res.locals.statusCode || 200).json({
res.status(res.locals.statusCode || 200).json({
status: 'success',
results: mentors.length,
data: {
Expand Down
10 changes: 10 additions & 0 deletions src/models/user.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ usersSchema.pre(/^find/, function(next) {
this.select(
'photo name email isEmployed skillsToLearn skillsLearned about onboarding_completed active role'
);
this.populate({
path: 'skillsToLearn',
select: 'name'
}).populate({
path: 'skillsLearned',
populate: {
path: 'skill',
select: 'name'
}
});
// this.find({ active: { $ne: false } });
next();
});
Expand Down
54 changes: 27 additions & 27 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,41 @@ dotenv.config({ path: path.join(__dirname, '..', 'config.env') });
const port = process.env.PORT || 3000;
const server = http.createServer(app);
const socketServer = new Server(server, {
cors: {
origin: '*',
methods: ['GET', 'POST']
}
cors: {
origin: '*',
methods: ['GET', 'POST']
}
});

(async function startServer() {
await mongoConnect();
// Start the server
server.listen(port, () =>
console.log(
`Server listening on port ${port} in the ${process.env.NODE_ENV} mode`
)
);
// Start Socket Listener
sockets.listen(socketServer);
await mongoConnect();
// Start the server
server.listen(port, () =>
console.log(
`Server listening on port ${port} in the ${process.env.NODE_ENV} mode`
)
);
// Start Socket Listener
sockets.listen(socketServer);
})();

//----------Exception Handling-------------//
process.on('uncaughtException', err => {
console.log('UNCAUGHT EXCEPTION! πŸ’₯ Shutting down...');
console.log(err.name, err.message);
process.exit(1);
console.log('UNCAUGHT EXCEPTION! πŸ’₯ Shutting down...');
console.log(err.name, err.message);
process.exit(1);
});
//--------------Rejection Handling------------//
process.on('unhandledRejection', err => {
console.log('UNHANDLED REJECTION! πŸ’₯ Shutting down...');
console.log(err.name, err.message);
server.close(() => {
process.exit(1);
});
});
process.on('SIGTERM', () => {
console.log('πŸ‘‹ SIGTERM RECEIVED. Shutting down gracefully');
server.close(() => {
console.log('πŸ’₯ Process terminated!');
});
console.log('UNHANDLED REJECTION! πŸ’₯ Shutting down...');
console.log(err.name, err.message);
server.close(() => {
process.exit(1);
});
});
// process.on('SIGTERM', () => {
// console.log('πŸ‘‹ SIGTERM RECEIVED. Shutting down gracefully');
// server.close(() => {
// console.log('πŸ’₯ Process terminated!');
// });
// });

0 comments on commit 8ca9e7e

Please sign in to comment.