Skip to content
Open
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
.env
.vscode
.vscode
config.env
3 changes: 3 additions & 0 deletions config/database.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const mongoose = require("mongoose");

//connecting to the DataBase
const connectDB = async () => {
try {
//connect to the database using the connection string
const conn = await mongoose.connect(process.env.DB_STRING, {
useNewUrlParser: true,
useUnifiedTopology: true,
Expand All @@ -11,6 +13,7 @@ const connectDB = async () => {

console.log(`MongoDB Connected: ${conn.connection.host}`);
} catch (err) {
//log the error if there are any
console.error(err);
process.exit(1);
}
Expand Down
7 changes: 7 additions & 0 deletions config/passport.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,33 @@ const User = require("../models/User");
module.exports = function (passport) {
passport.use(
new LocalStrategy({ usernameField: "email" }, (email, password, done) => {
//finds the data about the email
User.findOne({ email: email.toLowerCase() }, (err, user) => {
if (err) {
return done(err);
}
//chcks if there is no user
if (!user) {
return done(null, false, { msg: `Email ${email} not found.` });
}
//checks if there is no password
if (!user.password) {
return done(null, false, {
msg:
"Your account was registered using a sign-in provider. To enable password login, sign in using a provider, and then set a password under your user profile.",
});
}
//checks if the password is correct
user.comparePassword(password, (err, isMatch) => {
//checks if there is an error
if (err) {
return done(err);
}
//checks if it is a match
if (isMatch) {
return done(null, user);
}
//if not error or match it notifies of invalid inputs
return done(null, false, { msg: "Invalid email or password." });
});
});
Expand Down
26 changes: 23 additions & 3 deletions controllers/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ const passport = require("passport");
const validator = require("validator");
const User = require("../models/User");

//export for getLogin
exports.getLogin = (req, res) => {
//checks if there is a user and routes to the profile page of user
if (req.user) {
return res.redirect("/profile");
}
Expand All @@ -11,13 +13,16 @@ exports.getLogin = (req, res) => {
});
};

//export for updating/creating login
exports.postLogin = (req, res, next) => {
const validationErrors = [];
//checking email
if (!validator.isEmail(req.body.email))
validationErrors.push({ msg: "Please enter a valid email address." });
//checking password
if (validator.isEmpty(req.body.password))
validationErrors.push({ msg: "Password cannot be blank." });

//checking for errors
if (validationErrors.length) {
req.flash("errors", validationErrors);
return res.redirect("/login");
Expand All @@ -27,9 +32,11 @@ exports.postLogin = (req, res, next) => {
});

passport.authenticate("local", (err, user, info) => {
//checking the errors
if (err) {
return next(err);
}
//checking for user
if (!user) {
req.flash("errors", info);
return res.redirect("/login");
Expand All @@ -44,38 +51,48 @@ exports.postLogin = (req, res, next) => {
})(req, res, next);
};

//export for logging out
exports.logout = (req, res) => {
req.logout(() => {
console.log('User has logged out.')
})
//ends the session
req.session.destroy((err) => {
if (err)
console.log("Error : Failed to destroy the session during logout.", err);
req.user = null;
//sends back to home page once logged out
res.redirect("/");
});
};

//export for Sign Up
exports.getSignup = (req, res) => {
//if there is a user got to the profile page
if (req.user) {
return res.redirect("/profile");
}
//if there is no user route them to sign up
res.render("signup", {
title: "Create Account",
});
};

//export to update a sign up request
exports.postSignup = (req, res, next) => {
const validationErrors = [];
//checking email adress
if (!validator.isEmail(req.body.email))
validationErrors.push({ msg: "Please enter a valid email address." });
//checking password
if (!validator.isLength(req.body.password, { min: 8 }))
validationErrors.push({
msg: "Password must be at least 8 characters long",
});
if (req.body.password !== req.body.confirmPassword)
//checking that passwords match
if (req.body.password !== req.body.confirmPassword)
validationErrors.push({ msg: "Passwords do not match" });

//hcecking if there are any validation errors
if (validationErrors.length) {
req.flash("errors", validationErrors);
return res.redirect("../signup");
Expand All @@ -84,18 +101,21 @@ exports.postSignup = (req, res, next) => {
gmail_remove_dots: false,
});

//create new user with userName, email, and password
const user = new User({
userName: req.body.userName,
email: req.body.email,
password: req.body.password,
});

//finding if there is a user that matches the email and userName
User.findOne(
{ $or: [{ email: req.body.email }, { userName: req.body.userName }] },
(err, existingUser) => {
if (err) {
return next(err);
}
//notifies there is already a user name
if (existingUser) {
req.flash("errors", {
msg: "Account with that email address or username already exists.",
Expand Down
52 changes: 52 additions & 0 deletions controllers/comments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const cloudinary = require("../middleware/cloudinary");
const Post = require("../models/Post");
const Comment = require("../models/Comment");

//export for multiple functions
module.exports = {
createComment: async (req, res) => {
try {
// Upload image to cloudinary
const result = await cloudinary.uploader.upload(req.file.path);
//creates post with image
await Post.create({
comment: req.body.comment,
likes: 0,
post: req.params.id,
});
console.log("Post has been added!");
res.redirect("/profile");
} catch (err) {
console.log(err);
}
},
likePost: async (req, res) => {
try {
//gets the post based off the id and udpates likes
await Post.findOneAndUpdate(
{ _id: req.params.id },
{
$inc: { likes: 1 },
}
);
console.log("Likes +1");
res.redirect(`/post/${req.params.id}`);
} catch (err) {
console.log(err);
}
},
deletePost: async (req, res) => {
try {
// Find post by id
let post = await Post.findById({ _id: req.params.id });
// Delete image from cloudinary
await cloudinary.uploader.destroy(post.cloudinaryId);
// Delete post from db
await Post.remove({ _id: req.params.id });
console.log("Deleted Post");
res.redirect("/profile");
} catch (err) {
res.redirect("/profile");
}
},
};
1 change: 1 addition & 0 deletions controllers/home.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//export to render index.ejs for the home page
module.exports = {
getIndex: (req, res) => {
res.render("index.ejs");
Expand Down
14 changes: 12 additions & 2 deletions controllers/posts.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
const cloudinary = require("../middleware/cloudinary");
const Post = require("../models/Post");
const Comment = require("../models/Comment");

//export for multiple functions
module.exports = {
//method for getting profile
getProfile: async (req, res) => {
try {
//finds all posts
const posts = await Post.find({ user: req.user.id });
//renders all posts
res.render("profile.ejs", { posts: posts, user: req.user });
} catch (err) {
console.log(err);
}
},
//method for getting feed
getFeed: async (req, res) => {
try {
//gets all posts and sorts them by recent
const posts = await Post.find().sort({ createdAt: "desc" }).lean();
res.render("feed.ejs", { posts: posts });
} catch (err) {
Expand All @@ -20,8 +27,10 @@ module.exports = {
},
getPost: async (req, res) => {
try {
//gets specific post by ID
const post = await Post.findById(req.params.id);
res.render("post.ejs", { post: post, user: req.user });
const comments = await Comment.find({post: req.post.id}).sort({ createdAt: "desc" }).lean();
res.render("post.ejs", { post: post, user: req.user, commments: comments });
} catch (err) {
console.log(err);
}
Expand All @@ -30,7 +39,7 @@ module.exports = {
try {
// Upload image to cloudinary
const result = await cloudinary.uploader.upload(req.file.path);

//creates post with image
await Post.create({
title: req.body.title,
image: result.secure_url,
Expand All @@ -47,6 +56,7 @@ module.exports = {
},
likePost: async (req, res) => {
try {
//gets the post based off the id and udpates likes
await Post.findOneAndUpdate(
{ _id: req.params.id },
{
Expand Down
2 changes: 2 additions & 0 deletions middleware/auth.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
module.exports = {
//checking if the user is logged in
ensureAuth: function (req, res, next) {
if (req.isAuthenticated()) {
return next();
} else {
res.redirect("/");
}
},
//checking if the user has a login
ensureGuest: function (req, res, next) {
if (!req.isAuthenticated()) {
return next();
Expand Down
2 changes: 2 additions & 0 deletions middleware/cloudinary.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const cloudinary = require("cloudinary").v2;

//gets the connection path for the cloudinary
require("dotenv").config({ path: "./config/.env" });

//configures connection to the cloudinary based on the inputs from the env
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.API_KEY,
Expand Down
2 changes: 2 additions & 0 deletions middleware/multer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ const multer = require("multer");
const path = require("path");

module.exports = multer({
//gets storage
storage: multer.diskStorage({}),
//filters based on if the file is supported or not
fileFilter: (req, file, cb) => {
let ext = path.extname(file.originalname);
if (ext !== ".jpg" && ext !== ".jpeg" && ext !== ".png") {
Expand Down
22 changes: 22 additions & 0 deletions models/Comment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const mongoose = require("mongoose");

const CommentSchema = new mongoose.Schema({
comment: {
type: String,
required: true,
},
likes: {
type: Number,
required: true,
},
post: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
createdAt: {
type: Date,
default: Date.now,
},
});

module.exports = mongoose.model("Comment", CommentSchema);
1 change: 1 addition & 0 deletions models/Post.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const mongoose = require("mongoose");

//Create schema for MongoDB for posts
const PostSchema = new mongoose.Schema({
title: {
type: String,
Expand Down
6 changes: 5 additions & 1 deletion models/User.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const bcrypt = require("bcrypt");
const mongoose = require("mongoose");

//create MongoDB schema for users
const UserSchema = new mongoose.Schema({
userName: { type: String, unique: true },
email: { type: String, unique: true },
Expand All @@ -11,9 +12,11 @@ const UserSchema = new mongoose.Schema({

UserSchema.pre("save", function save(next) {
const user = this;
//checking that the password is not modified
if (!user.isModified("password")) {
return next();
}
//encryption magic
bcrypt.genSalt(10, (err, salt) => {
if (err) {
return next(err);
Expand All @@ -33,7 +36,8 @@ UserSchema.pre("save", function save(next) {
UserSchema.methods.comparePassword = function comparePassword(
candidatePassword,
cb
) {
) //validation of user inputs
{
bcrypt.compare(candidatePassword, this.password, (err, isMatch) => {
cb(err, isMatch);
});
Expand Down
Loading