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 .env
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
PORT=3000
PORT=3000
SESS_SECRET=123
2 changes: 2 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ const app = express();
// ℹ️ This function is getting exported from the config folder. It runs most middlewares
require('./config')(app);

require('./config/session.config')(app);

// default value for title local
const projectName = 'lab-express-basic-auth';
const capitalized = string => string[0].toUpperCase() + string.slice(1).toLowerCase();
Expand Down
29 changes: 29 additions & 0 deletions config/session.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const session = require('express-session');
const MongoStore = require('connect-mongo');

// since we are going to USE this middleware in the app.js,
// let's export it and have it receive a parameter
module.exports = app => {
// <== app is just a placeholder here
// but will become a real "app" in the app.js
// when this file gets imported/required there

// required for the app when deployed to Heroku (in production)
app.set('trust proxy', 1);

// use session
app.use(
session({
secret: process.env.SESS_SECRET,
resave: true,
saveUninitialized: true,
store: MongoStore.create({ mongoUrl: process.env.MONGODB_URI || "mongodb://127.0.0.1:27017/basic-auth" }),
cookie: {
sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
secure: process.env.NODE_ENV === 'production',
httpOnly: true,
maxAge: 600000 // 600 * 1000 ms === 10 min
}
})
);
};
1 change: 1 addition & 0 deletions error-handling/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module.exports = (app) => {
res.status(404).render("not-found");
});


app.use((err, req, res, next) => {
// whenever you call next(err), this middleware will handle the error
// always logs the error
Expand Down
22 changes: 22 additions & 0 deletions middlewares/route-guard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// checks if the user is logged in when trying to access a specific page
const isLoggedIn = (req, res, next) => {
if (!req.session.currentUser) {
return res.redirect('/login');
}
next();
};

// if an already logged in user tries to access the login page it
// redirects the user to the home page
const isLoggedOut = (req, res, next) => {
console.log(req.session)
if (req.session.currentUser) {
return res.redirect('/');
}
next();
};

module.exports = {
isLoggedIn,
isLoggedOut
};
11 changes: 11 additions & 0 deletions models/User.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ const userSchema = new Schema({
type: String,
unique: true
},
email: {
type: String,
required: [true, 'Email is required.'],
unique: true,
lowercase: true,
trim: true
},
passwordHash: {
type: String,
required: [true, 'Password is required.']
},
password: String
});

Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
"dev": "nodemon server.js"
},
"dependencies": {
"bcrypt": "^5.1.1",
"connect-mongo": "^5.1.0",
"cookie-parser": "^1.4.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-session": "^1.18.0",
"hbs": "^4.1.1",
"mongoose": "^6.1.2",
"morgan": "^1.10.0",
Expand Down
76 changes: 76 additions & 0 deletions routes/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,84 @@
const User = require("../models/User.model");
const bcryptjs = require('bcrypt');
const saltRounds = 10;
const router = require("express").Router();
const { isLoggedIn, isLoggedOut } = require('../middlewares/route-guard.js');


/* GET home page */
router.get("/", (req, res, next) => {
res.render("index");
});
/* GET signup page */
router.get("/signup", isLoggedOut, (req, res, next) => {
console.log('req.session', req.session)
res.render("auth/signup");
});

router.post('/signup', isLoggedOut, (req, res, next) => {
// console.log("The form data: ", req.body);
const { username, email, password } = req.body;

bcryptjs
.genSalt(saltRounds)
.then(salt => bcryptjs.hash(password, salt))
.then(hashedPassword => {
return User.create({
username: username,
email: email,
passwordHash: hashedPassword
});
})
.then(userFromDB => {
res.redirect('/usersProfile');
console.log(userFromDB, `this is the new user`)
})
.catch(error => next(error));
});

router.get('/usersProfile', (req, res) => res.render('users/user-profile'));

router.get('/login', isLoggedOut, (req, res)=>{
res.render('auth/login')
})

router.post('/login', isLoggedOut, (req, res)=>{
const { email, password } = req.body;

if (email === '' || password === '') {
res.render('auth/login', {
errorMessage: 'Please enter both, email and password to login.'
});
return;
}

User.findOne({ email })
.then(user => {
console.log('user', user)
if (!user) {

console.log("Email not registered. ");
res.render('auth/login', { errorMessage: 'User not found and/or incorrect password.' });
return;
}
else if (bcryptjs.compareSync(password, user.passwordHash)) {
req.session.currentUser = user;
res.render('users/user-profile', { user });
}
else {
console.log("Incorrect password. ");
res.render('auth/login', { errorMessage: 'User not found and/or incorrect password.' });
}
})
.catch(error => next(error));
})

router.get('/main', isLoggedIn, (req, res) => {
res.render('main', { user: req.session.currentUser });
});

router.get('/private', isLoggedIn, (req, res) => {
res.render('private', { user: req.session.currentUser });
});

module.exports = router;
22 changes: 22 additions & 0 deletions views/auth/login.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

{{!-- views/auth/signup.hbs --}}

<div id="form">
<h2>Login</h2>
<form action="/login" method="POST">

<label> Email
<input type="email" name="email" placeholder="rockstar@ironhack.com" />
</label>

<label> Password
<input type="password" name="password" placeholder="********" />
</label>

<button type="submit">Log in</button>
{{#if errorMessage}}
<p class="error">{{errorMessage}}</p>
{{/if}}
{{!-- error message will be added here --}}
</form>
</div>
23 changes: 23 additions & 0 deletions views/auth/signup.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{{!-- views/auth/signup.hbs --}}

<div id="form">
<h2>Signup</h2>
<form action="/signup" method="POST">

<label> Username
<input type="text" name="username" placeholder="ironhacker" />
</label>

<label> Email
<input type="email" name="email" placeholder="rockstar@ironhack.com" />
</label>

<label> Password
<input type="password" name="password" placeholder="********" />
</label>

<button type="submit">Create account</button>

{{!-- error message will be added here --}}
</form>
</div>
14 changes: 14 additions & 0 deletions views/main.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Main Page</title>
</head>
<body>
<h1>Welcome, {{user}}!</h1>
<p>Here is a funny picture of a cat:</p>
<img src="https://placekitten.com/400/300" alt="Funny Cat">
<br>
<a href="/">Home</a>
</body>
</html>
14 changes: 14 additions & 0 deletions views/private.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Private Page</title>
</head>
<body>
<h1>This is a private page</h1>
<p>Here is my favorite gif:</p>
<img src="https://media.giphy.com/media/3o7aD2saalBwwftBIY/giphy.gif" alt="Favorite GIF">
<br>
<a href="/">Home</a>
</body>
</html>
1 change: 1 addition & 0 deletions views/users/user-profile.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>poto</h1>