-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
132 lines (108 loc) · 4.6 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
if (process.env.NODE_ENV != "production") {
require("dotenv").config();
}
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const multer = require("multer");
const upload = multer({ dest: "uploads/" });
const path = require("path"); // PATH module for working with file and directory paths
const methodOverride = require("method-override"); // For overriding HTTP methods (e.g., PUT/DELETE in forms)
const ejsMate = require("ejs-mate"); // For EJS templating with layout support (Boilerplate HTML)
const db_url = process.env.ATLASDB_URl;
// Custom error class for handling specific Express errors
const ExpressError = require("./utils/ExpressError.js"); // Defined in /utils
// Importing route handlers for modularized routing
const ListingRouter = require("./routes/listing.js");
const ReviewRouter = require("./routes/review.js");
const UserRouter = require("./routes/user.js");
// Middleware for managing sessions and flash messages
const session = require("express-session");
const MongoStore = require("connect-mongo");
const flash = require("connect-flash");
// Passport.js for for username/password authentication
const passport = require("passport");
const LocalStrategy = require("passport-local");
// User model for MongoDB, used with Passport for authentication
const User = require("./models/user.js");
// Port number on which the server will listen
const port = 8080;
// App settings and middleware configuration
app.set("view engine", "ejs"); // Set the view engine to EJS for rendering templates
app.set("views", path.join(__dirname, "views")); // Set the views directory for EJS files
app.engine("ejs", ejsMate); // Use EJS-Mate for templating with boilerplates
// Middleware to parse incoming request bodies
app.use(express.urlencoded({ extended: true })); // Parses URL-encoded bodies (from forms)
app.use(express.json()); // Parses JSON bodies (from APIs)
// Serve static files (like CSS, JS, images) from the "public" directory
app.use(express.static(path.join(__dirname, "public")));
// Enable method-override for HTTP methods like PUT and DELETE in forms
app.use(methodOverride("_method"));
const store = MongoStore.create({
mongoUrl: db_url,
crypto: {
secret: process.env.SECRET,
},
touchAfter: 24 * 60 * 60,
});
store.on("error", () => {
console.log("error in mongo session store", err);
});
// Session configuration options
const sessionOptions = {
store,
secret: process.env.SECRET, // Secret for signing the session ID
resave: false, // Prevent resaving unchanged sessions
saveUninitialized: true, // Save new sessions even if they're unmodified
cookie: {
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7), // Cookie expiration (1 week)
maxAge: 1000 * 60 * 60 * 24 * 7, // Maximum cookie age
httpOnly: true, // Prevent client-side JavaScript access for added security
},
};
async function main() {
await mongoose.connect(db_url); // Database connection URI
}
// Connect to MongoDB using Mongoose
main()
.then(() => {
console.log("Connection Is Successful");
})
.catch((err) => {
console.log("Connection Is Failed");
});
// Apply session & Flash messages middleware
app.use(session(sessionOptions));
app.use(flash());
// Initialize Passport and manage sessions
app.use(passport.initialize());
app.use(passport.session());
// Configure Passport with the local strategy and User model methods
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
// Middleware to set variables available in all templates
app.use((req, res, next) => {
res.locals.success = req.flash("success");
res.locals.error = req.flash("error");
res.locals.currUser = req.user; // Set current logged-in user
next();
});
// Define routes using modularized route files
app.use("/listings", ListingRouter); // Routes for listing-related actions
app.use("/listings/:id/reviews", ReviewRouter); // Routes for review-related actions
app.use("/", UserRouter); // Routes for user-related actions
// Catch-all route for undefined paths (404 error handling)
app.all("*", (req, res, next) => {
next(new ExpressError(404, "Page Not Found !")); // Pass a custom 404 error to the error handler
});
// Global error handling middleware
app.use((err, req, res, next) => {
console.log("Error Message Received.....");
let { status = 500, message = "Some Error Occurred !" } = err;
res.status(status).render("error.ejs", { err }); // Render error template with the error details
});
// Start the Express server
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});