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
23 changes: 23 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,25 @@ const express = require('express');
// Handles the handlebars
// https://www.npmjs.com/package/hbs
const hbs = require('hbs');
const MongoStore = require('connect-mongo')(session);
const mongoose = require('mongoose');

const app = express();

app.use(express.static('public'));

const authMiddleware = require('./routes/middleware');

// Import routes and other setup code

app.get('/main', authMiddleware, (req, res) => {
res.render('main'); // Render the main view
});

app.get('/private', authMiddleware, (req, res) => {
res.render('private'); // Render the private view
});

// ℹ️ This function is getting exported from the config folder. It runs most middlewares
require('./config')(app);

Expand All @@ -31,5 +47,12 @@ app.use('/', index);
// ❗ To handle errors. Routes that don't exist or errors that you handle in specific routes
require('./error-handling')(app);

app.use(session({
secret: 'your-secret-key',
resave: false,
saveUninitialized: true,
store: new MongoStore({ mongooseConnection: mongoose.connection })
}));

module.exports = app;

16 changes: 13 additions & 3 deletions models/User.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@ const { Schema, model } = require("mongoose");

// TODO: Please make sure you edit the user model to whatever makes sense in this case
const userSchema = new Schema({
username: {

email: {
type: String,
unique: true
required: [true, 'Email is required.'],
// this match will disqualify all the emails with accidental empty spaces, missing dots in front of (.)com and the ones with no domain at all
match: [/^\S+@\S+\.\S+$/, 'Please use a valid email address.'],
unique: true,
lowercase: true,
trim: true
},
password: String
passwordHash: {
type: String,
required: [true, 'Password is required.']
}

});

const User = model("User", userSchema);
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
"dev": "nodemon server.js"
},
"dependencies": {
"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
114 changes: 114 additions & 0 deletions routes/auth.routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// routes/auth.routes.js

const { Router } = require('express');
const router = new Router();




const User = require('../models/User.model');


// auth.routes.js
const mongoose = require('mongoose'); // <== has to be added
// ... other imports and get route stay untouched



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

// POST route ==> to process form data
//router.post('/signup', (req, res, next) => {
// console.log('The form data: ', req.body);
//});



// the get route skipped
const bcryptjs = require('bcryptjs');
const saltRounds = 10;
// POST route ==> to process form data
router.post('/signup', (req, res, next) => {
// console.log("The form data: ", req.body);

const { username, email, password } = req.body;

const regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}/;

if (!regex.test(password)) {
res
.status(500)
.render('auth/signup', { errorMessage: 'Password needs to have at least 6 chars and must contain at least one number, one lowercase and one uppercase letter.' });
return;
}

bcryptjs
.genSalt(saltRounds)
.then(salt => bcryptjs.hash(password, salt))
.then(hashedPassword => {
return User.create({
// username: username
username,
email,
// passwordHash => this is the key from the User model
// ^
// | |--> this is placeholder (how we named returning value from the previous method (.hash()))
passwordHash: hashedPassword
});
})
.then(userFromDB => {
console.log('Newly created user is: ', userFromDB);
})
.then(userFromDB => {
// console.log('Newly created user is: ', userFromDB);
res.redirect('/userProfile');
})

.catch(error => {
if (error instanceof mongoose.Error.ValidationError) {
res.status(500).render('auth/signup', { errorMessage: error.message });
} else if (error.code === 11000) {

console.log(" Username and email need to be unique. Either username or email is already used. ");

res.status(500).render('auth/signup', {
errorMessage: 'User not found and/or incorrect password.'
});
} else {
next(error);
}
});
});

// routes/auth.routes.js
// ... imports and get route stay untouched

// POST route ==> to process form data
router.post('/signup', (req, res, next) => {
const { username, email, password } = req.body;

// make sure users fill all mandatory fields:
if (!username || !email || !password) {
res.render('auth/signup', { errorMessage: 'All fields are mandatory. Please provide your username, email and password.' });
return;
}

// ... the rest of the code stays unchanged
});


app.get('/login', (req, res) => {
res.render('login'); // Render your login form view
});

// Handle login form submission
app.post('/login', async (req, res) => {
const { email, password } = req.body;
// Check credentials and authenticate user
// If authentication successful, store user information in session
req.session.user = { email }; // Example: Storing email in session
res.redirect('/dashboard'); // Redirect to dashboard or any other authenticated route
});

module.exports = router;
11 changes: 11 additions & 0 deletions routes/middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const authMiddleware = (req, res, next) => {
if (req.session.user) {
// User is authenticated, allow access to the next middleware
next();
} else {
// User is not authenticated, redirect to login page
res.redirect('/login');
}
};

module.exports = authMiddleware;
7 changes: 7 additions & 0 deletions views/login.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<form action="/login" method="post">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
<button type="submit">Login</button>
</form>
3 changes: 3 additions & 0 deletions views/main.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<h1>Main Page</h1>
<img src="/images/cat.jpg" alt="Funny Cat Picture">
<a href="/">Back to Home</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>Private Page</h1>
<img src="/images/favorite.gif" alt="Favorite Gif">