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
71 changes: 48 additions & 23 deletions rest-express-mongo/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,88 +4,113 @@ const Note = require("./models/model");
const User = require("./models/users");
const auth = require("./authentication");
const cookieParser = require("cookie-parser");
const logger = require("./utils/logger");
const morgan = require("morgan");

const app = express();


// Middleware setup
app.use(morgan('combined', { stream: logger.stream }));
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static('public'));

//link for database connection
const db =
"mongo://localhost:27017";
// Database connection
mongoose.set('strictQuery', false);
const db = "mongodb://localhost:27017/local";

//connecting to the database
mongoose
.connect(db)
mongoose.connect(db)
.then((res) => {
app.listen(3000); //after connnecting to the database listen to this port...
app.listen(3000);
logger.info("Connected to MongoDB");
logger.info("Server listening on port 3000");
})
.catch((err) => console.log(err));
.catch((err) => logger.error("MongoDB connection error:", err));

app.set("view engine", "ejs");

//...............for signup .........................

// Routes - Maintaining your original structure with added logging
app.get("/signup", (req, res) => {
logger.debug("Rendering signup page");
res.render("signup");
});

app.post("/signup", auth.signIn);

app.get("/login", (req, res) => {
logger.debug("Rendering login page");
res.render("login");
});

app.post("/login", auth.logIn);

app.get("/logout", auth.logout);

//.....................end of signup ........................

app.get("*", auth.checkUser);

//for home page
// Home route
app.get("/", auth.showNotes);
//for posting a new note...

// Note creation
app.post("/", (req, res) => {
logger.debug("Creating new note");
const note = new Note(req.body);
note
.save()
note.save()
.then((result) => {
logger.info("Note created successfully");
res.redirect("/");
})
.catch((err) => {
console.log(err);
logger.error("Note creation error:", err);
console.log(err);
});
});

//for new note
// New note page
app.get("/note", function (req, res) {
logger.debug("New note page request");
res.render("note");
});

//get individual notes
// Individual note
app.get("/note/:id", (req, res) => {
const id = req.params.id;
logger.debug(`Fetching note with ID: ${id}`);
Note.findById(id)
.then((result) => {
logger.debug("Note found, rendering individual view");
res.render("indi", { result });
})
.catch((err) => {
console.log(err);
logger.error("Error fetching note:", err);
console.log(err);
});
});

//delete notes
// Delete note
app.delete("/:id", (req, res) => {
const id = req.params.id;
logger.debug(`Deleting note with ID: ${id}`);
Note.findByIdAndDelete(id)
.then((result) => {
logger.info("Note deleted successfully");
res.json({ redirect: "/" });
})
.catch((err) => {
console.log(err);
logger.error("Note deletion error:", err);
console.log(err); // Keeping your original error handling
});
});

//for page not found
// 404 handler
app.use((req, res) => {
logger.warn(`404 - Not Found: ${req.originalUrl}`);
res.render("error");
});

// Error handler middleware - new addition to catch any unhandled errors
app.use((err, req, res, next) => {
logger.error(`Unhandled error: ${err.stack}`);
res.status(500).render('error');
});
110 changes: 89 additions & 21 deletions rest-express-mongo/authentication.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,143 @@
const { append } = require("express/lib/response");
const jwt = require("jsonwebtoken");
const User = require("./models/users");
const Note = require("./models/model");
const logger = require("./utils/logger");

const createToken = (id) => {
logger.debug(`Creating token for user ID: ${id}`);
return jwt.sign({ id }, "MONKE", { expiresIn: 24 * 60 * 60 });
};

module.exports.createToken = createToken;

module.exports.checkUser = (req, res, next) => {
const token = req.cookies.jwt;
if (token) {
jwt.verify(token, "MONKE", async (err, decToken) => {
if (err) {
logger.warn(`Invalid JWT token: ${err.message}`);
res.locals.user = null;
next();
} else {
let user = await User.findById(decToken.id);
res.locals.user = user;
next();
logger.debug(`Valid token for user ID: ${decToken.id}`);
try {
let user = await User.findById(decToken.id);
if (!user) {
logger.warn(`User not found for ID: ${decToken.id}`);
res.locals.user = null;
} else {
logger.debug(`Authenticated user: ${user.username}`);
res.locals.user = user;
}
next();
} catch (err) {
logger.error(`User lookup error: ${err.message}`);
res.locals.user = null;
next();
}
}
});
} else {
logger.debug("No JWT token found, redirecting to signup");
res.redirect("/signup");
}
};

//to get the username of the current user........
module.exports.showNotes = (req, res) => {
const token = req.cookies.jwt;
jwt.verify(token, "MONKE", async (err, decoded) => {
if (err) {
logger.warn(`Invalid token in showNotes: ${err.message}`);
res.redirect("/login");
} else {
const user = await User.findById(decoded.id);
Note.find({ username: user.username })
.then((result) => {
res.render("index", { result });
})
.catch((err) => {
console.log(err);
});
try {
const user = await User.findById(decoded.id);
if (!user) {
logger.warn(`User not found for ID: ${decoded.id}`);
return res.redirect("/login");
}

logger.debug(`Fetching notes for user: ${user.username}`);
const notes = await Note.find({ username: user.username });

logger.debug(`Found ${notes.length} notes for user`);
res.render("index", { result: notes });
} catch (err) {
logger.error(`Error in showNotes: ${err.message}`);
res.status(500).render("error", { message: "Error loading notes" });
}
}
});
};

module.exports.signIn = async (req, res) => {
const { username, password } = req.body;
logger.debug(`Signup attempt for username: ${username}`);

try {
const user = await User.create({ username, password });
logger.info(`New user created: ${username}`);

const token = createToken(user._id);
res.cookie("jwt", token, { expiresIn: 24 * 60 * 60 * 1000 });
res.cookie("jwt", token, {
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000
});

logger.debug(`Session cookie set for user: ${username}`);
res.redirect("/");
} catch (err) {
console.log(err);
res.redirect("/signup");
logger.error(`Signup error for ${username}: ${err.message}`);

// Handle specific error cases
if (err.code === 11000) {
logger.warn(`Duplicate username attempt: ${username}`);
return res.render("signup", { error: "Username already exists" });
}

res.status(500).render("signup", {
error: "Registration failed. Please try again."
});
}
};

module.exports.logIn = async (req, res) => {
const { username, password } = req.body;
logger.debug(`Login attempt for username: ${username}`);

try {
const user = await User.login(username, password);
logger.info(`Successful login for user: ${username}`);

const token = createToken(user._id);
res.cookie("jwt", token, { expiresIn: 24 * 60 * 60 * 1000 });
res.cookie("jwt", token, {
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000
});

logger.debug(`Session cookie set for user: ${username}`);
res.redirect("/");
} catch (err) {
console.log(err);
res.sendStatus(500);
logger.warn(`Failed login attempt for ${username}: ${err.message}`);

// Differentiate between wrong password and non-existent user
const errorMessage = err.message.includes("incorrect password")
? "Incorrect password"
: "User not found";

res.status(401).render("login", {
error: errorMessage,
username: username // Return username for convenience
});
}
};

module.exports.logout = (req, res) => {
res.cookie("jwt", "", { maxAge: 1 });
logger.debug("Logout request received");
res.cookie("jwt", "", {
httpOnly: true,
maxAge: 1
});
logger.info("User logged out, session cleared");
res.redirect("/login");
};
};
Loading