Skip to content
Snippets Groups Projects
Commit 92a8b007 authored by Kagamino's avatar Kagamino
Browse files

add notifications

parent 8422e15c
Branches
Tags
1 merge request!2Release 0.2: Notifications & Errors
......@@ -10,16 +10,12 @@
* `mongoose`: Mongoose MongoDB ODM
* `body-parser`: Node.js body parsing middleware
* `morgan`: HTTP request logger middleware for node.js
* `connect-mongodb-session`: MongoDB session store for connect/express built by MongoDB
### To use
* `joi`: Object schema description language and validator for JavaScript objects.
## Release
### Next: v0.1.0
* [ ] Authentication and session
### TODO
* [ ] Validate mongoose models
* [ ] Make mongoose unique index work
### Next: v0.2.0
* [ ] Message handler
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');
const User = require('./models/user');
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const morgan = require('morgan');
const mongoDBStore = require('connect-mongodb-session')(session);
const config = require('./config.json');
const User = require('./models/user');
const Notification = require('./models/notification');
// Utils
const render = (req, res, view, options) => res.render(view, {
const render = (req, res, view, options) => {
// Load notifications
if (req.session.user) {
res.render(view, {
...options,
user: req.session.user,
nextUrl: req.url,
notifications: req.session.user.notifications
});
req.session.user.notifications
.filter(notification => !notification.persistant)
.forEach(notification => notification.remove());
req.session.user.save();
} else {
return res.render(view, {
...options,
user: req.session.user,
nextUrl: req.url,
notifications: []
});
}
};
const warn = (req, res, title, content) => {
req.session.user.notifications.push({ title, content, color: "warning" });
req.session.user.save();
};
const error = (req, res, title, content) => {
req.session.user.notifications.push({ title, content, color: "error" });
req.user.session.save();
return res.redirect('/'); // TODO redirect to error route or previous
}
// Configuration
const app = express();
const store = new mongoDBStore({
uri: 'mongodb://localhost/rolegame',
collection: 'sessions'
});
store.on('error', function(error) {
console.error(error);
});
app.set('view engine', 'pug');
app.use(morgan('tiny'));
app.use(session({
secret: config.secret,
resave: false,
saveUninitialized: false
saveUninitialized: false,
store
}));
// Middlewares
......@@ -36,6 +73,17 @@ app.use((req, res, next) => {
return res.redirect('/signup');
}
});
app.use((req, res, next) => {
if (req.session.user) {
User.findById(req.session.user._id, (err, user) => {
err ? error(req, res, 'Error fetching user', err) : null;
req.session.user = user;
next();
});
} else {
next();
}
})
app.get('/', (req, res) => {
return render(req, res, 'home');
......@@ -46,7 +94,7 @@ app.get('/signup', (req, res) => {
app.post('/signup', (req, res) => {
const passwordHash = bcrypt.hashSync(req.body.password, config.cryptRounds);
User.create(req.body, (err, user) => {
err ? console.error(err) : null;
err ? error(req, res, 'Error creating user', err) : null;
user.passwordHash = passwordHash;
user.save();
req.session.user = user;
......@@ -54,13 +102,16 @@ app.post('/signup', (req, res) => {
});
});
app.post('/login', (req, res) => {
if (!req.body.username || !req.body.password) {
return res.redirect('/signup');
}
User.findOne({ username: req.body.username }, (err, user) => {
err ? console.error(err) : null;
err ? error(req, res, 'Error fetching user', err) : null;
if (bcrypt.compareSync(req.body.password, user.passwordHash)) {
req.session.user = user;
return res.redirect(req.query.nextUrl || '/');
} else {
console.error("Bad authentication");
error(req, res, 'Bad credentials')
return res.redirect('/signup');
}
});
......
const mongoose = require('mongoose');
const Notification = new mongoose.Schema({
title: {
type: String,
required: true,
},
content: {
type: String,
},
persistant: {
type: Boolean,
default: false,
},
color: {
type: String,
default: ""
}
});
module.exports = Notification;
\ No newline at end of file
const mongoose = require('mongoose');
const Notification = require('./notification');
const User = new mongoose.Schema({
firstName: {
......@@ -7,11 +8,12 @@ const User = new mongoose.Schema({
},
lastName: {
type: String,
required: true,
},
username: {
unique: true,
type: String,
lowercase: true
lowercase: true,
},
email: {
type: String,
......@@ -20,6 +22,7 @@ const User = new mongoose.Schema({
passwordHash: {
type: String,
},
notifications: [Notification],
});
module.exports = mongoose.model('User', User);
\ No newline at end of file
......@@ -7,6 +7,8 @@ html(lang="en")
link(rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css" integrity="sha256-9mbkOfVho3ZPXfM7W8sV2SndrGDuh7wuyLjtsWeTI1Q=" crossorigin="anonymous")
title RoleGame
body
script(src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E=" crossorigin="anonymous")
script(src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js" integrity="sha256-t8GepnyPmw9t+foMh3mKNvcorqNHamSKtKRxxpUEgFI=" crossorigin="anonymous")
block navbar
if !user
form.ui.form(action="/login", method="post")
......@@ -29,8 +31,8 @@ html(lang="en")
.item
button.ui.icon.button.basic(type="submit")
i.power.off.icon
.ui.container
.ui.grid
.thirteen.wide.column
block main
block script
script(src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E=" crossorigin="anonymous")
script(src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js" integrity="sha256-t8GepnyPmw9t+foMh3mKNvcorqNHamSKtKRxxpUEgFI=" crossorigin="anonymous")
\ No newline at end of file
.three.wide.column
include notifications.pug
each notification in notifications
.ui.message.tiny(class=notification.color)
i.close.icon
.header= notification.title
p= notification.content
script
| $('.message .close').on('click', function() {
| $(this).closest('.message').transition('fade');
| });
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment