diff --git a/app.js b/app.js index 4c4fe56e37..2950993e07 100644 --- a/app.js +++ b/app.js @@ -1,19 +1,28 @@ -const createError = require('http-errors'); -const express = require('express'); -const path = require('path'); +const createError = require('http-errors'); +const express = require('express'); +const path = require('path'); const cookieParser = require('cookie-parser'); -const logger = require('morgan'); -const mongoose = require('mongoose'); +const logger = require('morgan'); +const mongoose = require('mongoose'); +const session = require('express-session'); +const MongoStore = require('connect-mongo')(session); -const indexRouter = require('./routes/index'); +const indexRouter = require('./routes/index'); +const usersRouter = require('./routes/users'); +const privateRouter = require('./routes/private'); const app = express(); -mongoose.connect('mongodb://localhost/basic-auth', { +// Connect to database +const app_name = require('./package.json').name; +mongoose.connect(`mongodb://localhost/${app_name}`, { keepAlive: true, useNewUrlParser: true, + useUnifiedTopology: true, reconnectTries: Number.MAX_VALUE -}); +}).then(data => {console.log(`Connected to Mongo!: ${data.connections[0].name}`) +}).catch(error => {console.log(error)}); + // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'hbs'); @@ -24,9 +33,23 @@ app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); +// Session handler +app.use(session({ + secret: app_name + "-secret", + cookie: {maxAge: 60000}, + resave: true, + saveUninitialized: true, + store: new MongoStore({ + mongooseConnection: mongoose.connection, + ttl: 24*60*60 + }) +})); + app.use('/', indexRouter); +app.use('/users', usersRouter); +app.use('/private', privateRouter); -// -- 404 and error handler +/* 404 and error handlers */ // NOTE: requires a views/not-found.ejs template app.use((req, res, next) => { @@ -36,10 +59,10 @@ app.use((req, res, next) => { // NOTE: requires a views/error.ejs template app.use((err, req, res, next) => { - // always log the error - console.error('ERROR', req.method, req.path, err); + // Always log the error + console.error('Error: ', req.method, req.path, err); - // only render if the error ocurred before sending the response + // Only render if the error ocurred before sending the response if (!res.headersSent) { res.status(500); res.render('error'); diff --git a/bin/www b/bin/www index cf4e2d5da3..3c1a570b1c 100755 --- a/bin/www +++ b/bin/www @@ -86,5 +86,5 @@ function onListening() { var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; - debug('Listening on ' + bind); + console.log('Listening on ' + bind); } diff --git a/models/User.js b/models/User.js new file mode 100644 index 0000000000..545215aecd --- /dev/null +++ b/models/User.js @@ -0,0 +1,13 @@ +const mongoose = require("mongoose"); +const Schema = mongoose.Schema; + +const userSchema = new Schema({ + username: String, + password: String +}, { + timestamps: true +}); + +const User = mongoose.model("User", userSchema); + +module.exports = User; \ No newline at end of file diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 9453385b99..9be7430694 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -1,8 +1,37 @@ body { - padding: 50px; - font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; + padding: 0px; + margin: 0px; + font: 16px "Lucida Grande", Helvetica, Arial, sans-serif; } -a { - color: #00B7FF; +.body-container { + display: flex; } + +nav { + padding: 5px 20px 0px 5px; + width: 20%; + text-align: right; +} + +nav a { + text-decoration: none; + color: darkslategray; +} + +.nav-bar { + list-style-type: none; +} + +.index { + display: flex; + flex-direction: column; + padding: 30px; +} + +.btn { + border: 0px; + background-color: darkslateblue; + color: white; + padding: 8px 15px; +} \ No newline at end of file diff --git a/routes/index.js b/routes/index.js index f2d4e52ad3..84592d2225 100644 --- a/routes/index.js +++ b/routes/index.js @@ -3,7 +3,7 @@ const router = express.Router(); /* GET home page. */ router.get('/', (req, res, next) => { - res.render('index', { title: 'Express' }); + res.render('index'); }); module.exports = router; diff --git a/routes/private.js b/routes/private.js new file mode 100644 index 0000000000..dc44591bb7 --- /dev/null +++ b/routes/private.js @@ -0,0 +1,24 @@ +const express = require('express'); +const router = express.Router(); + +router.use((req, res, next) => { + if (req.session.currentUser) { // <== if there's user in the session (user is logged in) + next(); // ==> go to the next route + } else { + res.redirect("../users/signin"); + } +}); + +// GET Main page. +router.get('/main', (req, res, next) => { + const {username} = req.session.currentUser; + res.render('private/main', {username}); +}); + +// GET Private page. +router.get('/private', (req, res, next) => { + const {username} = req.session.currentUser; + res.render('private/private', {username}); +}); + +module.exports = router; \ No newline at end of file diff --git a/routes/users.js b/routes/users.js new file mode 100644 index 0000000000..a4bcb29cfd --- /dev/null +++ b/routes/users.js @@ -0,0 +1,67 @@ +const express = require('express'); +const router = express.Router(); +const User = require('../models/User'); +const bcrypt = require('bcrypt'); +const bcryptSalt = 10; + +// GET signup page. +router.get('/signup', (req, res, next) => { + res.render('users/signup'); +}); + +// POST signup form +router.post('/signup', (req, res, next) => { + const {username, password} = req.body; + const salt = bcrypt.genSaltSync(bcryptSalt); + const hashPass = bcrypt.hashSync(password, salt); + User.findOne({'username': username}) + .then(user => { + if (user !== null) { + res.render('users/signup', {error: 'Username taken'}); + return; + } + if (username === "" || password === "") { + res.render('users/signup', {error: 'Enter a username and password'}); + return; + } + User.create({username, password: hashPass}) + .then(() => {res.redirect('/')}) + .catch(error => {console.log(error)}); + }) + .catch(error => {console.log(error)}); +}); + +// GET signin page +router.get('/signin', (req, res, next) => { + res.render('users/signin'); +}); + +// POST signin form +router.post('/signin', (req, res, next) => { + const {username, password} = req.body; + if (username === "" || password === "") { + res.render('users/signin', {error: 'You must enter a username and password' }); + return; + } + User.findOne({'username': username}) + .then(user => { + if (!user) { + res.render('users/signin', {error: "That username doesn't exist"}) + return; + } + if (bcrypt.compareSync(password, user.password)) { + req.session.currentUser = user; + res.redirect('/'); + } else { + res.render('users/signin', {error: "Incorrect password"}) + } + }) + .catch(error => {console.log(error)}); +}) + +// GET Signout page +router.get("/signout", (req, res, next) => { + req.session.destroy((error) => {res.redirect("/users/signin")}); +}); + +module.exports = router; \ No newline at end of file diff --git a/views/index.hbs b/views/index.hbs index 1f308fdb35..1626cc4be9 100644 --- a/views/index.hbs +++ b/views/index.hbs @@ -1,2 +1,4 @@ -

{{title}}

-

Welcome to {{title}}

+
+

INDEX

+

Welcome

+
\ No newline at end of file diff --git a/views/layout.hbs b/views/layout.hbs index f503bd75f1..6d56f036f0 100644 --- a/views/layout.hbs +++ b/views/layout.hbs @@ -7,7 +7,18 @@ {{title}} - + + + {{{body}}} diff --git a/views/private/main.hbs b/views/private/main.hbs new file mode 100644 index 0000000000..10c2b79897 --- /dev/null +++ b/views/private/main.hbs @@ -0,0 +1,5 @@ +
+

MAIN

+

Hello {{username}}

+ Picture of a cat +
\ No newline at end of file diff --git a/views/private/private.hbs b/views/private/private.hbs new file mode 100644 index 0000000000..2143feb825 --- /dev/null +++ b/views/private/private.hbs @@ -0,0 +1,5 @@ +
+

PRIVATE

+

Hello {{username}}

+ Gif +
\ No newline at end of file diff --git a/views/users/signin.hbs b/views/users/signin.hbs new file mode 100644 index 0000000000..3108d0c5e0 --- /dev/null +++ b/views/users/signin.hbs @@ -0,0 +1,13 @@ +
+

SIGN IN

+
+ + + + + +
+
+
+

{{error}}

+
diff --git a/views/users/signup.hbs b/views/users/signup.hbs new file mode 100644 index 0000000000..9b8ee6176c --- /dev/null +++ b/views/users/signup.hbs @@ -0,0 +1,13 @@ +
+

SIGN UP

+
+ + + + + +
+
+
+

{{error}}

+
\ No newline at end of file