diff --git a/db/db.js b/db/db.js new file mode 100644 index 0000000000000000000000000000000000000000..f70865efcbaeae828ef801239e00d6a647e95253 --- /dev/null +++ b/db/db.js @@ -0,0 +1,43 @@ +var mongoose = require('mongoose'); + +mongoose.connect('mongodb://localhost/szobatinder'); + +// Models +//------- + +const User = mongoose.model('user', { + username: String, + password: String +}) + +function createUser(username, password, callback) { + const user = new User({ username: username, password: password }); // using double ROT-13 for password encryption + user.save(err => { + console.error(err); + callback(err); + }); +} + +function doesUserExist(username) { + return new Promise((resolve, reject) => { + User.findOne({ username: username }, (err, user) => { + if (user == null) resolve(false); + else resolve(true); + }); + }); +} + +function checkUserCredentials(username, password) { + return new Promise((resolve, reject) => { + User.findOne({ username: username, password: password }, (err, user) => { + if (user == null) reject('Wrong username or password'); + else resolve('ok'); + }); + }); +} + +module.exports = { + createUser: createUser, + doesUserExist: doesUserExist, + checkUserCredentials: checkUserCredentials, +}; \ No newline at end of file diff --git a/index.js b/index.js index b6c7846fc695563c46a593478301ea27eef2098f..e3257f09968cfc02addd495aff1b2b205c62b9b3 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,10 @@ const express = require('express'); //const ejs = require('ejs'); const app = express(); +const bodyParser = require('body-parser'); +const cookieParser = require('cookie-parser'); +const session = require('express-session'); + const authMW = require('./middleware/authMW'); const loginMW = require('./middleware/loginMW'); const registerMW = require('./middleware/registerMW'); @@ -15,6 +19,9 @@ const matchlistMW = require('./middleware/matchlistMW'); const profileeditMW = require('./middleware/profileeditMW'); const renderMW = require('./middleware/renderMW'); +app.use(bodyParser.urlencoded()); +app.use(cookieParser()); +app.use(session({ secret: 'McGalagony egy cirmos cica' })); // should be read from some non-version-tracked file const objectrepository = undefined; // for now diff --git a/middleware/authMW.js b/middleware/authMW.js index 29465bb1e837949ffd5d7be9029c0ac21c7c883b..d90dd209246a6b920f561ae35867a04c91067949 100644 --- a/middleware/authMW.js +++ b/middleware/authMW.js @@ -2,6 +2,9 @@ module.exports = function () { return function (req, res, next) { // should be placed on all non-public endpoints. If the user has a valid session, sets the username on res.locals.username. Else, redirects to /login. + if (typeof req.session.username == 'undefined') return res.redirect('/login'); + + res.locals.username = req.session.username; return next(); } } \ No newline at end of file diff --git a/middleware/loginMW.js b/middleware/loginMW.js index 06a51f492f464ede148fe9069120019cf9e1fd96..90fab658e3b13de3549512a468e95bef7e8b0f26 100644 --- a/middleware/loginMW.js +++ b/middleware/loginMW.js @@ -1,7 +1,25 @@ +const db = require('../db/db.js'); module.exports = function (objectrepository) { return function (req, res, next) { - // does the login based on username and password. If the credentials are corrects, sets a session and redirects to `/`. If not, redirects to /login. - return res.redirect('/'); + // does the login based on username and password. If the credentials are correct, sets a session and redirects to `/`. If not, redirects to /login. + + username = req.body.user; + password = req.body.pass; + + if (typeof username == 'undefined' || typeof password == 'undefined') { + return res.status(400).render('login'); + } + if (username == "" || password == "") { + res.locals.error = 'Fill in all inputs!'; + return res.status(400).render('login'); + } + return db.checkUserCredentials(username, password).then(value => { + req.session.username = username; + return res.redirect('/'); + }).catch(err => { + res.locals.error = err; + return res.status(400).render('login'); + }) } } \ No newline at end of file diff --git a/middleware/logoutMW.js b/middleware/logoutMW.js index 48a83b85b7d34f8bac7968e3a035dbc5d6b5cd03..854c1f92f11ce02959ef730365b4bf6fd70ea043 100644 --- a/middleware/logoutMW.js +++ b/middleware/logoutMW.js @@ -2,6 +2,7 @@ module.exports = function (objectrepository) { return function (req, res, next) { // destroys the session and redirects to /. + req.session.username = undefined; return res.redirect('/'); } } \ No newline at end of file diff --git a/middleware/registerMW.js b/middleware/registerMW.js index 1ed81daaf4740307d4efdf07b898908256ed0fc0..1bce17145671eaf050819140cad774df66e7d461 100644 --- a/middleware/registerMW.js +++ b/middleware/registerMW.js @@ -1,7 +1,40 @@ +const db = require('../db/db.js'); module.exports = function (objectrepository) { return function (req, res, next) { - // takes a username, a password and a password-again from the registration form. If the username is not taken, and the passwords match, creates the user and creates a session and redirects to `/`. Otherwise it redirets to /register. - return next(); + // takes a username, a password and a password-again from the registration form. If the username is not taken, and the passwords match, creates the user and creates a session and redirects to `/`. Otherwise it displays an error. + + username = req.body.user; + password = req.body.pass; + password2 = req.body.pass2; + + if (typeof username == 'undefined' || typeof password == 'undefined' || typeof password2 == 'undefined') { + return res.status(400).render('register'); + } + if (username == "" || password == "" || password2 == "") { + res.locals.error = 'Fill in all inputs!'; + return res.status(400).render('register'); + } + if (password !== password2) { + res.locals.error = 'Passwords do not match!'; + return res.status(400).render('register'); + } + return db.doesUserExist(username).then(exists => { + if (exists) { + res.locals.error = 'Username already taken.'; // should also say 'User that uses this name: $username.' :D + return res.status(400).render('register'); + } + + db.createUser(username, password, err => { + if (err == null) { + req.session.username = username; + return res.redirect('/'); + } else { + res.locals.error = 'Could not create user due to a database error.' + return res.status(500).render('register'); + } + }); + + }); } } \ No newline at end of file diff --git a/package.json b/package.json index 0c5e4007db633990d57b07180a6de72d4f7ad872..14caa9e892a1b73a09b7d36ca33373f79749ff2f 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,10 @@ "author": "Schulcz Ferenc", "license": "ISC", "dependencies": { - "ejs": "^3.1.6", - "express": "^4.17.3" + "cookie-parser": "^1.4.6", + "ejs": "^3.0.2", + "express": "^4.17.3", + "express-session": "^1.17.2", + "mongoose": "^6.3.0" } } diff --git a/static/style.css b/static/style.css index b15620402d768f4b623fc969f9839852faf69c4d..f0754caf6427e9275d1ffa44b41e3171c463a46b 100644 --- a/static/style.css +++ b/static/style.css @@ -94,4 +94,10 @@ textarea { .form-helper { font-size: 11px; margin-bottom: 20px; +} + +.warning { + background-color: #fed243; + padding: 20px 20px; + border-radius: 3px; } \ No newline at end of file diff --git a/views/login.ejs b/views/login.ejs index a973fa27860e11e40d288f9c6bf61fe91cf6ba2b..0151f39233b6888113edf4a795075e8b408e238d 100644 --- a/views/login.ejs +++ b/views/login.ejs @@ -1,12 +1,21 @@ <%- include('_head', {}) %> <h1>Login</h1> - <form action="/login"> - <label for="user">User: </label> - <input type="text" id="user" name="user"><br> - <label for="pass">Password: </label> - <input type="password" id="pass" name="pass"><br> - <input type="submit" class="button" value="Login"> - </form> - - <%- include('_tail', {}) %> \ No newline at end of file + + <% if(typeof error!='undefined' ) { %> + <p class="warning"> + <%= error %> + </p> + <% } %> + + <form action="/login" method="post"> + <label for="user">User: </label> + <input type="text" id="user" name="user"><br> + <label for="pass">Password: </label> + <input type="password" id="pass" name="pass"><br> + <input type="submit" class="button" value="Login"> + </form> + + <p><a href="/register">Need to register?</a></p> + + <%- include('_tail', {}) %> \ No newline at end of file diff --git a/views/register.ejs b/views/register.ejs index e96760e9c59f49d7dcfc8629c6ece7a146141873..70feb9f874c16eaeefef715250153ba7cff65c88 100644 --- a/views/register.ejs +++ b/views/register.ejs @@ -2,4 +2,22 @@ <h1>Register</h1> - <%- include('_tail', {}) %> \ No newline at end of file + <% if(typeof error!='undefined' ) { %> + <p class="warning"> + <%= error %> + </p> + <% } %> + + <form action="/register" method="post"> + <label for="user">User: </label> + <input type="text" id="user" name="user"><br> + <label for="pass">Password: </label> + <input type="password" id="pass" name="pass"><br> + <label for="pass2">Password again: </label> + <input type="password" id="pass2" name="pass2"><br> + <input type="submit" class="button" value="Register"> + </form> + + <p><a href="/login">Already have an account?</a></p> + + <%- include('_tail', {}) %> \ No newline at end of file