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 = 'super session secret'
1 change: 1 addition & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ 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';
Expand Down
40 changes: 40 additions & 0 deletions config/session.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// require session
const session = require('express-session');

// require mongostore
const MongoStore = require('connect-mongo');

// require mongoose
const mongoose = require('mongoose');

// 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: false,
cookie: {
sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
secure: process.env.NODE_ENV === 'production',
httpOnly: true,
maxAge: 60000 // 60 * 1000 ms === 1 min
}, // storing in db
store: MongoStore.create({
mongoUrl: process.env.MONGODB_URI || 'mongodb://127.0.0.1:27017/basic-auth'

// ttl => time to live
// ttl: 60 * 60 * 24 // 60sec * 60min * 24h => 1 day
})
})
);
};
22 changes: 22 additions & 0 deletions middleware/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) => {
if (req.session.currentUser) {
return res.redirect('/');
}
next();
};

module.exports = {
isLoggedIn,
isLoggedOut
};

13 changes: 13 additions & 0 deletions models/User.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,21 @@ const { Schema, model } = require("mongoose");
const userSchema = new Schema({
username: {
type: String,
trim: true,
required: [true, 'Username is required.'],
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": {
"bcryptjs": "^2.4.3",
"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
Binary file added public/images/funnycat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
81 changes: 81 additions & 0 deletions routes/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,89 @@
const router = require("express").Router();
const bcryptjs = require("bcryptjs")
const saltRounds = 10
const User = require('../models/User.model');

// require auth middleware
const { isLoggedIn, isLoggedOut } = require('../middleware/route-guard.js');

/* GET home page */
router.get("/", (req, res, next) => {
res.render("index");
});

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

/* POST signup page */
router.post('/signup', isLoggedOut, (req, res, next) => {
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('/userProfile/' + userFromDB.username);
})
.catch(error => next(error));
});

router.get('/userProfile', isLoggedIn, (req, res) => {
res.render('users/user-profile', { userInSession: req.session.currentUser });
});

// GET route ==> to display the login form to users
router.get('/login', isLoggedOut, (req, res) => res.render('auth/login'));

// POST login route ==> to process form data
router.post('/login', isLoggedOut, (req, res, next) => {
console.log('SESSION =====> ', req.session);
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 => {
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)) {
// when we introduce session, the following line gets replaced with what follows:
// res.render('users/user-profile', { user });

//******* SAVE THE USER IN THE SESSION ********//
req.session.currentUser = user;
res.redirect('/userProfile');
} else {
console.log("Incorrect password. ");
res.render('auth/login', { errorMessage: 'User not found and/or incorrect password.' });
}
})
.catch(error => next(error));
});

router.post('/logout', isLoggedIn, (req, res, next) => {
req.session.destroy(err => {
if (err) next(err);
res.redirect('/');
});
});

router.get('/main', isLoggedIn, (req, res) => res.render('main'));
router.get('/private', isLoggedIn, (req, res) => res.render('private'));

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/login.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">Login</button>

{{#if errorMessage}}
<p class="error">{{errorMessage}}</p>
{{/if}}
</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>
16 changes: 16 additions & 0 deletions views/layout.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@

<body>

<nav>
<ul>
<li id="to-left">
<p><a href="/"> Users - demo </a></p>
</li>
<li id="to-right">
<a href="/signup">Signup</a> <span> | </span>
<a href="/login">Login</a>
<form id="logout-form" action="/logout" method="POST">
<button>Logout</button>
</form>
<a href="/userProfile">Profile</a>
</li>
</ul>
</nav>

{{{body}}}

<script src="/js/script.js"></script>
Expand Down
3 changes: 3 additions & 0 deletions views/main.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<p>a funny picture of a cat</p>
<img src="/images/funnycat.png">
<a href="/">Back to homepage</a>
2 changes: 2 additions & 0 deletions views/private.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<h1>This page is private</h1>
<iframe src="https://giphy.com/embed/1OalRHPW2IIOhMCwOk" width="480" height="271" style="" frameBorder="0" class="giphy-embed" allowFullScreen></iframe><p><a href="https://giphy.com/gifs/survivorcbs-survivor-44-season-1OalRHPW2IIOhMCwOk">via GIPHY</a></p>
13 changes: 13 additions & 0 deletions views/users/user-profile.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{!-- the new version, with the session: --}}

{{#if userInSession}}
<h2>Welcome, {{ userInSession.username }}!</h2>
<p>This is your profile page my friend!</p>
<button>
<a href="/userProfile">Reload the page</a>
</button>
{{else}}

<br><p>Still no logged in user, sorry!</p>

{{/if}}