Skip to content

Commit

Permalink
add password recovery feature
Browse files Browse the repository at this point in the history
  • Loading branch information
saras-69 committed Nov 3, 2024
1 parent c1f1c68 commit 98e8567
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 84 deletions.
53 changes: 20 additions & 33 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
if(process.env.NODE_ENV != "production"){
if (process.env.NODE_ENV != "production") {
require('dotenv').config();
}
const express = require("express");
Expand All @@ -16,43 +16,42 @@ const passport = require("passport");
const LocalStrategy = require("passport-local");
const User = require("./models/user.js");
const userRouter = require("./routes/user.js");
/* if you want to run the project and do not have .env files configured , please uncomment the next
two commented codes and comment down this code await mongoose.connect(dbUrl); You project will run succesfully*/

const MONGO_URL = "mongodb://mongo:27017/wanderlust"; // used with docker
// const MONGO_URL = "mongodb://127.0.0.1:27017/wanderlust"; // use for local db
const dbUrl =process.env.ATLASDB_URL;
const dbUrl = process.env.ATLASDB_URL;

main()
.then(() => {
console.log("connected to DB");
}).catch((err) => {
console.log(err);
});
async function main(){

async function main() {
await mongoose.connect(MONGO_URL);
// await mongoose.connect(dbUrl);
}
app.set("view engine","ejs");

app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "views"));

app.use(express.urlencoded({extended:true}));
app.use(express.urlencoded({ extended: true }));
app.use(methodOverride("_method"));
app.engine('ejs', ejsMate);
app.use(express.static(path.join(__dirname,"/public")));
app.use(express.static(path.join(__dirname, "/public")));

const sessionOptions = {
secret: "mysupersecretcode",
resave: false,
saveUninitialized: true,
cookie: {
expires: Date.now()+7*24*60*60*1000,
maxAge: 7*24*60*60*1000,
expires: Date.now() + 7 * 24 * 60 * 60 * 1000,
maxAge: 7 * 24 * 60 * 60 * 1000,
httpOnly: true,
},
};
/*app.get("/", (req,res) => {
res.send("Hi,I am root");
});*/

app.use(session(sessionOptions));
app.use(flash());
app.use(passport.initialize());
Expand All @@ -61,44 +60,32 @@ passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

app.use((req,res,next) =>{
app.use((req, res, next) => {
res.locals.success = req.flash("success");
res.locals.error = req.flash("error");
res.locals.currUser = req.user;
//console.log(success);
next();
});

app.use("/listings",listingRouter);
app.use("/listings/:id/reviews",reviewRouter);
app.use("/",userRouter);
app.use("/listings", listingRouter);
app.use("/listings/:id/reviews", reviewRouter);
app.use("/", userRouter);

app.get('/privacy', (req, res) => {
res.render('privacy'); // This should be placed before the app.all("*") block
res.render('privacy');
});

// Catch-all route for undefined paths
app.all("*", (req, res, next) => {
next(new ExpressError(404, "Page Not Found!"));
});


//if any of the incomming request does not match then throw this error
app.all("*",(req,res,next) =>{
next(new ExpressError(404,"Page Not Found!"));
});
//error handling is done by middleware
app.use((err,req,res,next) =>{
let {statusCode=500,message="Something went wrong!"}=err;
res.status(statusCode).render("error.ejs",{message});
//res.status(statusCode).send(message);
});

// Error handling middleware
app.use((err, req, res, next) => {
console.log(err); // Log the full error to see what’s causing the issue
let { statusCode = 500, message = "Something went wrong!" } = err;
res.status(statusCode).render("error.ejs", { message });
});

app.listen(8080,()=>{
app.listen(8080, () => {
console.log("Server is listening to port 8080");
});
19 changes: 16 additions & 3 deletions controllers/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const renderSignupForm = (req, res) => {
res.render("users/signup.ejs");
};

const signup = async (req, res) => {
const signup = async (req, res, next) => {
try {
// Check for validation errors
const errors = validationResult(req);
Expand Down Expand Up @@ -53,10 +53,23 @@ const logout = (req, res, next) => {
});
};

// Render the password recovery form
const renderForgotPasswordForm = (req, res) => {
res.render('users/forgot.ejs');
};

// Handle the password recovery form submission
const forgotPassword = (req, res) => {
req.flash('info', 'If an account with that email exists, you will receive an email with instructions to reset your password.');
res.redirect('/forgot');
};

module.exports = {
renderSignupForm,
signup,
renderLoginForm,
login,
logout
};
logout,
renderForgotPasswordForm,
forgotPassword
};
7 changes: 6 additions & 1 deletion routes/user.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const express = require("express");
const router = express.Router();
const User = require("../models/user.js");
const wrapAsync = require("../utils/wrapAsync.js");
const passport = require("passport");
const { saveRedirectUrl } = require("../middleware.js");
Expand Down Expand Up @@ -30,4 +29,10 @@ router

router.get("/logout", saveRedirectUrl, userController.logout);

// Add routes for forgot password
router
.route("/forgot")
.get(userController.renderForgotPasswordForm)
.post(wrapAsync(userController.forgotPassword));

module.exports = router;
51 changes: 51 additions & 0 deletions views/users/forgot.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<% layout("/layouts/boilerplate") -%>
<div class="row justify-content-center my-5">
<div class="col-md-6 col-lg-5">
<div class="card shadow-lg border-0 rounded">
<div class="card-body p-4">
<h1 class="text-center mb-4 display-6" style="color: black; font-weight: bold;">Forgot Password</h1>
<form action="/forgot" method="POST" class="needs-validation" novalidate>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input name="email" id="email" placeholder="Enter your email" type="email"
class="form-control form-control-lg rounded-pill" required>
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Please enter a valid email.
</div>
</div>

<button type="submit" class="btn btn-success w-100 btn-lg rounded-pill mt-3">Reset
Password</button>
</form>
<div class="text-center mt-3">
<a href="/login" class="text-decoration-none" style="color: black; font-weight: bold;">Back to
Login</a>
</div>
<p class="text-center mt-4">
Don't have an account? <a href="/signup" class="text-decoration-none">Sign Up</a>
</p>
</div>
</div>
</div>
</div>

<!-- Bootstrap form validation -->
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function () {
'use strict'
var forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms).forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>
99 changes: 52 additions & 47 deletions views/users/login.ejs
Original file line number Diff line number Diff line change
@@ -1,56 +1,61 @@
<% layout("/layouts/boilerplate") -%>
<div class="row justify-content-center my-5">
<div class="col-md-6 col-lg-5">
<div class="card shadow-lg border-0 rounded">
<div class="card-body p-4">
<h1 class="text-center mb-4 display-6" style="color: black; font-weight: bold;">Log In</h1>
<form action="/login" method="POST" class="needs-validation" novalidate>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input name="email" id="email" placeholder="Enter your email" type="email" class="form-control form-control-lg rounded-pill" required>
<div class="valid-feedback">
Looks good!
<div class="row justify-content-center my-5">
<div class="col-md-6 col-lg-5">
<div class="card shadow-lg border-0 rounded">
<div class="card-body p-4">
<h1 class="text-center mb-4 display-6" style="color: black; font-weight: bold;">Log In</h1>
<form action="/login" method="POST" class="needs-validation" novalidate>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input name="email" id="email" placeholder="Enter your email" type="email"
class="form-control form-control-lg rounded-pill" required>
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Please enter a valid email.
</div>
</div>
<div class="invalid-feedback">
Please enter a valid email.
</div>
</div>

<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input name="password" id="password" placeholder="Enter your password" type="password" class="form-control form-control-lg rounded-pill" required>
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Please enter a valid password.
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input name="password" id="password" placeholder="Enter your password" type="password"
class="form-control form-control-lg rounded-pill" required>
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Please enter a valid password.
</div>
</div>
</div>

<button type="submit" class="btn btn-success w-100 btn-lg rounded-pill mt-3">Log In</button>
</form>
<p class="text-center mt-4">
Don't have an account? <a href="/signup" class="text-decoration-none">Sign Up</a>
</p>
<button type="submit" class="btn btn-success w-100 btn-lg rounded-pill mt-3">Log In</button>
</form>
<div class="text-center mt-3">
<a href="/forgot" class="text-decoration-none" style="color: black; font-weight: bold;">Forgot Password?</a>
</div>
<p class="text-center mt-4">
Don't have an account? <a href="/signup" class="text-decoration-none">Sign Up</a>
</p>
</div>
</div>
</div>
</div>
</div>

<!-- Bootstrap form validation -->
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function () {
'use strict'
var forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms).forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>
<!-- Bootstrap form validation -->
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function () {
'use strict'
var forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms).forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>

0 comments on commit 98e8567

Please sign in to comment.