Skip to content

Commit

Permalink
[issue #32] : Organizing Backend files (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
Artlfmj authored Oct 7, 2023
2 parents 1b65556 + 1ea2bbf commit 5922917
Show file tree
Hide file tree
Showing 9 changed files with 294 additions and 189 deletions.
2 changes: 1 addition & 1 deletion example.env.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
MONGODB_URL = mongodb://localhost:27017/course
MONGODB_URL = mongodb://localhost:27017/course
SECRET_KEY = YOUR_SECRET_KEY_HERE
PORT = 3000
54 changes: 46 additions & 8 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
@@ -1,6 +1,7 @@
{
"dependencies": {
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
"connect-flash": "^0.1.1",
"cookie-parser": "^1.4.6",
"csurf": "^1.11.0",
Expand Down
202 changes: 23 additions & 179 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
const express = require("express");
const mongoose = require("mongoose");

const fs = require("fs");
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const session = require("express-session");
const flash = require("connect-flash");
const morgan = require("morgan");
const bcrypt = require("bcrypt"); // Import bcrypt for password hashing
const rateLimit = require("express-rate-limit");
const csrf = require("csurf");
const bodyparser = require('body-parser')
const limiter=require("./utils/limiter")
const addCSRF = require("./middlewares/addCSRF");

const cookieParser = require("cookie-parser");
const mongoSanitize = require("express-mongo-sanitize");
const dotenv = require("dotenv");
Expand All @@ -26,33 +27,35 @@ const isAuthenticated = require("./middlewares/isAuthenticated");

const app = express();

const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // 5 requests per windowMs
message: "Too many requests from this IP, please try again later.",
});

//Views folder should be accessible from anywhere..
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
app.use(express.urlencoded({ extended: true }));

app.use(bodyparser.urlencoded({extended:true}));
// app.use(app.use(bodyparser.urlencoded({ extended: true }));
app.use(bodyparser.json());
app.use(morgan("dev"));

app.use(mongoSanitize());

const addCSRF = require("./middlewares/addCSRF");


//Regular middleware
app.use(cookieParser());
//app.use(csrf());
//app.use(addCSRF)
const csrf = require("csurf");

app.use(
session({
secret: process.env.SECRET_KEY,
secret: process.env.SECRET_KEY,
resave: false,
saveUninitialized: true,
})
);
);

app.use(csrf());
app.use(addCSRF)

app.use(flash());
// Initialize Passport and session middleware
require("./config/passportConfig");
Expand All @@ -62,180 +65,21 @@ app.use(passport.session());
const csrfProtection = csrf({ cookie: true });
app.use(csrfProtection);

app.get("/login", limiter, csrfProtection, (req, res) => {
if (req.isAuthenticated()) {
return res.redirect("/");
} else {
res.render("login", {
messages: req.flash("error"),
csrfToken: req.csrfToken(),
}); // Pass flash messages to the template
}
});

app.post("/login", limiter, csrfProtection, (req, res, next) => {
/*console.log(req.body, req.csrfToken())
if (!req.body._csrf || req.body._csrf !== req.csrfToken()) {
return res.status(403).send("CSRF token validation failed.");
}*/
passport.authenticate("local", (err, user, info) => {
if (err) {
return next(err);
}
if (!user) {
req.flash("error", "Incorrect username or password."); // Set flash message
return res.redirect("/login"); // Redirect with flash message
}
req.logIn(user, (err) => {
if (err) {
return next(err);
}
return res.redirect("/");
});
})(req, res, next);
});

app.get("/logout", limiter, (req, res) => {
req.session.destroy(function (err) {
if (err) {
console.error("Error during logout:", err);
} else {
res.redirect("/login");
}
});
});

app.get("/", isAuthenticated, (req, res) => {
// This route is protected and can only be accessed by authenticated users
res.render("home");
});

app.get("/register", (req, res) => {
if (req.isAuthenticated()) return res.redirect("/");
console.log(req.csrfToken());
res.render("register", {
messages: req.flash("error"),
csrfToken: req.csrfToken(),
});
});

app.post("/register", limiter, csrfProtection, async (req, res) => {
/*if (!req.body._csrf || req.body._csrf !== req.csrfToken()) {
return res.status(403).send("CSRF token validation failed.");
}*/
const { username, email, password, confirmPassword, fullName } = req.body;

try {
// Check if the username or email already exists in the database
const existingUser = await User.findOne({
$or: [{ username: username }, { email: email }],
});

if (existingUser) {
req.flash("error", "Username or email already in use.");
return res.redirect("/register");
}

// Check if the password and confirmPassword match
if (password !== confirmPassword) {
req.flash("error", "Passwords do not match.");
return res.redirect("/register");
}

// Hash the password before saving it
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(password, salt);

// Create a new user document and save it to the database
const newUser = new User({
username: username,
email: email,
password: hashedPassword,
fullName,
// Additional user profile fields can be added here
});

await newUser.save();

// Redirect to the login page after successful registration
res.redirect("/login");
} catch (error) {
console.error("Error during registration:", error);
req.flash("error", "Registration failed. Please try again.");
res.redirect("/register");
}
});

app.get("/profile", isAuthenticated, async (req, res) => {
res.render("profile", {
user: req.user,
messages: req.flash(),
csrfToken: req.csrfToken(),
});
});

app.post(
"/profile",
limiter,
isAuthenticated,
csrfProtection,
async (req, res) => {
/*if (!req.body._csrf || req.body._csrf !== req.csrfToken()) {
return res.status(403).send("CSRF token validation failed.");
}*/
const { fullName, avatarUrl, bio, location, website } = req.body;

try {
// Find the user by their ID (you need to have the user ID stored in the session)
const userId = req.user._id; // Assuming you have a user object in the session
const user = await User.findById(userId);

if (!user) {
// Handle the case where the user is not found
return res.status(404).send("User not found.");
}

// Update the user's profile fields
user.fullName = fullName;
user.avatarUrl = avatarUrl;
user.bio = bio;
user.location = location;
user.website = website;

// Save the updated user profile
await user.save();

// Redirect to the user's profile page or any other desired page
return res.redirect("/profile");
} catch (error) {
console.error("Error updating profile:", error);
// Handle the error, display an error message, or redirect to an error page
return res.status(500).send("Error updating profile.");
}
}
);

app.use("/courses", limiter, isAuthenticated, async function (req, res) {
const courses = await courseModel.find();
return res.render("course", { courses: courses });
});

app.post("/search-course", limiter, isAuthenticated, async function (req, res) {
const query = req.body.query;
const regexQuery = {
title: { $regex: query, $options: "i" },
};
try {
const searchCourses = await courseModel.findOne(regexQuery);
res.json(searchCourses);
} catch (err) {
console.error(err);
res.json({ message: "An error occurred while searching." });
}
});


app.use("/css", express.static("src/css"));

// user routes
const userRoutes=require("./routes/userRoutes")
app.use(userRoutes)

// Start the server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
Expand Down
3 changes: 3 additions & 0 deletions src/config/dbconfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ function dbConfig() {
});
}
module.exports = dbConfig;


//Everything
Loading

0 comments on commit 5922917

Please sign in to comment.