Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion server/controllers/errorController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"use strict";

const httpStatus = require("http-status-codes");
const path = require("path")


exports.logErrors = (error, req, res, next) => {
console.error(error.stack);
Expand All @@ -11,7 +13,9 @@ exports.respondNoResourceFound = (req, res) => {
let errorCode = httpStatus.NOT_FOUND;
res.status(errorCode);
// res.send(`${errorCode} | The page does not exist!`);
res.sendFile("public/html/Er404.html");
res.sendFile(path.join(__dirname, "../public/html/Er404.html"));


};

exports.respondInternalError = (error, req, res, next) => {
Expand Down
186 changes: 146 additions & 40 deletions server/controllers/usersController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
"use strict";

const User = require("../models/user");
const User = require("../models/user"),
Token = require("../models/token"),
crypto = require("crypto"),
passport = require("passport"),
nodemailer = require("nodemailer");


const getUserParams = body => {
return {
name: {
Expand Down Expand Up @@ -37,64 +43,125 @@ module.exports = {
req.flash(
"Success",
`${user.name.first}'s account created successfully!`

);
console.log(user);
res.locals.redirect = `/user/${user.name.first}`;
// Create a verification token for this user
var token = new Token({
_userId: user._id,
token: crypto.randomBytes(16).toString("hex"),
});

// Save the verification token
token.save(function (err) {
if (err) {
return res.status(500).send({ msg: err.message });
}

// Send the email
var transporter = nodemailer.createTransport({
service: "SendGrid",
auth: {
user: "apikey",
pass:
"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",
},
});
var mailOptions = {
from: "priyankrastogi14@gmail.com",
to: user.email,
subject: "Account Verification Token",
// text:
// "Hello,\n\n" +
// "Please verify your account by clicking the link \n",
html: `<p>Please verify your Smartier account by clicking the link below</p><a href=http:\/\/${req.headers.host}\/confirmation\/${token.token}>Link</a>`,
};
transporter.sendMail(mailOptions, function (err) {
if (err) {
console.log(err.stack);
res.locals.redirect = "/";
next();
}
// res.status(200).send('A verification email has been sent to Your email address.');
});
});
res.locals.redirect = `/feed`;
next();
} else {
req.flash(
"error",
`Failed to create user account because: ${error.message}.`
);
res.locals.redirect = "/";
next()
next();
}
});
},
userFeed: (req, res) => {
res.render("user", {userName:req.params.user});

res.render("feed");
},
redirectView: (req, res, next) => {
let redirectPath = res.locals.redirect;
if (redirectPath) res.redirect(redirectPath);
},
login: (req, res) => {
res.render("users/login");
},
authenticate: (req, res, next) => {
User.findOne({ email: req.body.email })
.then((user) => {
if (user) {
user.passwordComparison(req.body.password).then((passwordsMatch) => {
if (passwordsMatch) {
res.locals.redirect = `/user/${user._id}`;
req.flash("success", `${user.first}'s logged in successfully!`);
res.locals.user = user;
} else {
req.flash(
"error",
"Failed to log in user account: Incorrect Password."
);
res.locals.redirect = "/login";
}
next();
});
} else {
req.flash(
"error",
"Failed to log in user account: User account not found."
);
res.locals.redirect = "/login";
next();
}
resendToken: function (req, res, next) {
req
.sanitizeBody("email")
.normalizeEmail({
all_lowercase: true,
})
.catch((error) => {
console.log(`Error logging in user: ${error.message}`);
next(error);
});
.trim();
req.check("email", "Email is invalid").isEmail();
// Check for validation errors

var errors = req.validationErrors();
if (errors) return res.status(400).send(errors);

User.findOne({ email: req.body.email }, function (err, user) {
if (!user) return res.status(400).send({ msg: 'We were unable to find a user with that email.' });
if (user.isVerified) return res.status(400).send({ msg: 'This account has already been verified. Please log in.' });

// Create a verification token, save it, and send email
var token = new Token({ _userId: user._id, token: crypto.randomBytes(16).toString('hex') });

// Save the token
token.save(function (err) {
if (err) { return res.status(500).send({ msg: err.message }); }

// Send the email
var transporter = nodemailer.createTransport({
service: "SendGrid",
auth: {
user: "apikey",
pass:
"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",
},
});
var mailOptions = {
from: "priyankrastogi14@gmail.com",
to: user.email,
subject: "Account Verification Token",
// text:
// "Hello,\n\n" +
// "Please verify your account by clicking the link \n",
html: `<p>Please verify your Smartier account by clicking the link below</p><a href=http:\/\/${req.headers.host}\/confirmation\/${token.token}>Link</a>`,
};
transporter.sendMail(mailOptions, function (err) {
if (err) { return res.status(500).send({ msg: err.message }); }
return res.status(200).send('A verification email has been sent to ' + user.email + '.');
});
});

});
},
login: (req, res) => {
res.render("user/login");
},
authenticate: passport.authenticate("local", {
failureRedirect: "/login",
failureFlash: "Failed to login.",
successRedirect: "/feed",
successFlash: "Logged in!",
}),
validate: (req, res, next) => {
req
.sanitizeBody("email")
Expand All @@ -107,7 +174,6 @@ module.exports = {
req.check("first", "this cannot be empty").notEmpty();
req.check("last", "this cannot be empty").notEmpty();


req.getValidationResult().then((error) => {
if (!error.isEmpty()) {
let messages = error.array().map((e) => e.msg);
Expand All @@ -120,4 +186,44 @@ module.exports = {
}
});
},
/**
* POST /confirmation
*/
confirmationPost: function (req, res, next) {
console.log(req.params.token);
Token.findOne({ token: req.params.token }, function (err, token) {
if (!token)
return res
.status(400)
.send({
type: "not-verified",
msg:
"We were unable to find a valid token. Your token may have expired.",
});

// If we found a token, find a matching user
User.findOne({ _id: token._userId }, function (err, user) {
if (!user)
return res
.status(400)
.send({ msg: "We were unable to find a user for this token." });
if (user.isVerified)
return res
.status(400)
.send({
type: "already-verified",
msg: "This user has already been verified.",
});

// Verify and save the user
user.isVerified = true;
user.save(function (err) {
if (err) {
return res.status(500).send({ msg: err.message });
}
res.status(200).send("The account has been verified. Please log in.");
});
});
});
},
};
22 changes: 18 additions & 4 deletions server/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ const express = require("express"),
expressSession = require("express-session"),
cookieParser = require("cookie-parser"),
connectFlash = require("connect-flash"),
path = require("path"),
expressValidator = require("express-validator"),
passport = require("passport"),
errorController = require("./controllers/errorController"),
homeController = require("./controllers/homeController"),
// subscribersController = require("./controllers/subscribersController"),
usersController = require("./controllers/usersController"),
// coursesController = require("./controllers/coursesController"),
User = require("./models/user");
User = require("./models/user"),
Token = require("./models/token")

mongoose.Promise = global.Promise;

Expand All @@ -34,7 +36,7 @@ db.once("open", () => {
app.set("port", process.env.PORT || 3000);
app.set("view engine", "ejs");

router.use(express.static("public"));
router.use(express.static(path.join(__dirname,"public")));
router.use(layouts);
router.use(
express.urlencoded({
Expand Down Expand Up @@ -79,8 +81,20 @@ router.get("/", homeController.sendHome);
router.get("/register", usersController.new);
router.post("/user/create", usersController.validate, usersController.create, usersController.redirectView);
router.get("/login", usersController.login);
router.post("/login", usersController.authenticate, usersController.redirectView); // app.get("/:name", homeController.sendProfile); app.get("/user", usersController.index, usersController.indexView) //Middlewares
router.get("/user/:user", usersController.userFeed);
router.post("/login", usersController.authenticate); // app.get("/:name", homeController.sendProfile); app.get("/user", usersController.index, usersController.indexView) //Middlewares
router.get("/feed", usersController.userFeed);
// router.get("/user/verification", (req, res)=>{
// res
// .status(200)
// .send("A verification email has been sent to " + user.email + ".");
// })

router.get("/confirmation/:token", usersController.confirmationPost);
// app.post("/resend", usersController.resendTokenPost);
router.post("/resendToken", usersController.resendToken);



router.use(errorController.logErrors);
router.use(errorController.respondNoResourceFound);
router.use(errorController.respondInternalError);
Expand Down
12 changes: 12 additions & 0 deletions server/models/token.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const mongoose = require("mongoose");
const tokenSchema = new mongoose.Schema({
_userId: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "User",
},
token: { type: String, required: true },
createdAt: { type: Date, required: true, default: Date.now, expires: 43200 },
});

module.exports = mongoose.model("token", tokenSchema);
9 changes: 6 additions & 3 deletions server/models/user.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const mongoose = require("mongoose");
const passportLocalMongoose = require("passport-local-mongoose");
const userSchema = mongoose.Schema(
const mongoose = require("mongoose"),
passportLocalMongoose = require("passport-local-mongoose"),
bcrypt = require("bcrypt"),
passport = require("passport"),
userSchema = mongoose.Schema(
{
name: {
first: {
Expand All @@ -19,6 +21,7 @@ const userSchema = mongoose.Schema(
lowercase: true,
unique: true,
},
isVerified: { type: Boolean, default: false },
},
{
timestamps: true,
Expand Down
10 changes: 10 additions & 0 deletions server/package-lock.json

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

2 changes: 2 additions & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"dependencies": {
"connect-flash": "^0.1.1",
"cookie-parser": "^1.4.5",
"crypto": "^1.0.1",
"ejs": "^3.1.3",
"express": "^4.17.1",
"express-ejs-layouts": "^2.5.0",
Expand All @@ -35,6 +36,7 @@
"mongodb": "^3.5.9",
"mongoose": "^5.9.24",
"mongoose-type-email": "^1.0.12",
"nodemailer": "^6.4.10",
"nodemon": "^2.0.4",
"passport": "^0.4.1",
"passport-local-mongoose": "^6.0.1"
Expand Down
2 changes: 1 addition & 1 deletion server/public/html/Er404.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
<title>ERROR404</title>
</head>
<body>
<img src="../images/Er404.svg" alt="ERROR404 Not Found" style = "width: 100vw;">
<img src="/images/Er404.svg" alt="ERROR404 Not Found" style = "width: 100vw;">
</body>
</html>
11 changes: 11 additions & 0 deletions server/views/error404.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ERROR404</title>
</head>
<body>
<img src="/images/Er404.svg" alt="ERROR404 Not Found" style = "width: 100vw;">
</body>
</html>
Loading