From 68c10b4f2ea3a93d5a10aa1f5d93374b079bb761 Mon Sep 17 00:00:00 2001
From: Martin Lehoux <martin@lehoux.net>
Date: Tue, 12 Feb 2019 21:58:04 +0100
Subject: [PATCH] divide src in folders

---
 index.js                    | 105 ++++++------------------------------
 middlewares/loginChecker.js |   7 +++
 middlewares/userLoader.js   |  13 +++++
 routes/auth.js              |  45 ++++++++++++++++
 utils/notifications.js      |  12 +++++
 utils/render.js             |  24 +++++++++
 views/base.pug              |   4 +-
 views/signup.pug            |   2 +-
 8 files changed, 119 insertions(+), 93 deletions(-)
 create mode 100644 middlewares/loginChecker.js
 create mode 100644 middlewares/userLoader.js
 create mode 100644 routes/auth.js
 create mode 100644 utils/notifications.js
 create mode 100644 utils/render.js

diff --git a/index.js b/index.js
index b6be466..655fcde 100644
--- a/index.js
+++ b/index.js
@@ -6,43 +6,19 @@ const bcrypt = require('bcrypt');
 const morgan = require('morgan');
 const mongoDBStore = require('connect-mongodb-session')(session);
 
+// Config
 const config = require('./config.json');
-
+// Middlewares
+const userLoader = require('./middlewares/userLoader');
+const loginChecker = require('./middlewares/loginChecker');
+// Utils
+const render = require('./utils/render');
+const { warn, error } = require('./utils/notifications');
+// Models
 const User = require('./models/user');
 const Notification = require('./models/notification');
-
-// Utils
-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
-}
+// Routes
+const authRouter = require('./routes/auth');
 
 // Configuration
 const app = express();
@@ -63,66 +39,15 @@ app.use(session({
 }));
 
 // Middlewares
-app.use(bodyParser.urlencoded({
-  extended: false,
-}));
-app.use((req, res, next) => {
-  if (req.session.user || ['/', '/signup', '/login'].includes(req.url)) {
-    next();
-  } else {
-    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.use(bodyParser.urlencoded({ extended: false }));
+app.use(userLoader);
+app.use(loginChecker);
 
+// Routes
 app.get('/', (req, res) => {
   return render(req, res, 'home');
 });
-app.get('/signup', (req, res) => {
-  return render(req, res, 'signup');
-});
-app.post('/signup', (req, res) => {
-  const passwordHash = bcrypt.hashSync(req.body.password, config.cryptRounds);
-  User.create(req.body, (err, user) => {
-    err ? error(req, res, 'Error creating user', err) : null;
-    user.passwordHash = passwordHash;
-    user.save();
-    req.session.user = user;
-    return res.redirect('/');
-  });
-});
-app.post('/login', (req, res) => {
-  if (!req.body.username || !req.body.password) {
-    return res.redirect('/signup');
-  } else if (req.session.user) {
-    error(req, res, 'User already logged in', 'You must logout before log in.')
-  } else {
-    User.findOne({ username: req.body.username }, (err, user) => {
-      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 {
-        error(req, res, 'Bad credentials')
-        return res.redirect('/signup');
-      }
-    });
-  }
-});
-app.post('/logout', (req, res) => {
-  req.session.destroy();
-  return res.redirect('/');
-})
+app.use('/auth', authRouter);
 
 mongoose.connect('mongodb://localhost/rolegame', err => {
   if (err) {
diff --git a/middlewares/loginChecker.js b/middlewares/loginChecker.js
new file mode 100644
index 0000000..7c59919
--- /dev/null
+++ b/middlewares/loginChecker.js
@@ -0,0 +1,7 @@
+module.exports = (req, res, next) => {
+  if (req.session.user || ['/', '/auth/signup', '/auth/login'].includes(req.url)) {
+    next();
+  } else {
+    return res.redirect('/auth/signup');
+  }
+};
\ No newline at end of file
diff --git a/middlewares/userLoader.js b/middlewares/userLoader.js
new file mode 100644
index 0000000..d72167f
--- /dev/null
+++ b/middlewares/userLoader.js
@@ -0,0 +1,13 @@
+const User = require('../models/user');
+
+module.exports = (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();
+  }
+};
diff --git a/routes/auth.js b/routes/auth.js
new file mode 100644
index 0000000..c590daf
--- /dev/null
+++ b/routes/auth.js
@@ -0,0 +1,45 @@
+const express = require('express');
+const bcrypt = require('bcrypt');
+const User = require('../models/user');
+const router = express.Router();
+
+router.get('/signup', (req, res) => {
+  return render(req, res, 'signup');
+});
+
+router.post('/signup', (req, res) => {
+  const passwordHash = bcrypt.hashSync(req.body.password, config.cryptRounds);
+  User.create(req.body, (err, user) => {
+    err ? error(req, res, 'Error creating user', err) : null;
+    user.passwordHash = passwordHash;
+    user.save();
+    req.session.user = user;
+    return res.redirect('/');
+  });
+});
+
+router.post('/login', (req, res) => {
+  if (!req.body.username || !req.body.password) {
+    return res.redirect('/auth/signup');
+  } else if (req.session.user) {
+    error(req, res, 'User already logged in', 'You must logout before log in.')
+  } else {
+    User.findOne({ username: req.body.username }, (err, user) => {
+      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 {
+        error(req, res, 'Bad credentials')
+        return res.redirect('/auth/signup');
+      }
+    });
+  }
+});
+
+router.post('/logout', (req, res) => {
+  req.session.destroy();
+  return res.redirect('/');
+});
+
+module.exports = router;
\ No newline at end of file
diff --git a/utils/notifications.js b/utils/notifications.js
new file mode 100644
index 0000000..0ff1738
--- /dev/null
+++ b/utils/notifications.js
@@ -0,0 +1,12 @@
+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
+};
+
+module.exports = { warn, error };
\ No newline at end of file
diff --git a/utils/render.js b/utils/render.js
new file mode 100644
index 0000000..3ebc535
--- /dev/null
+++ b/utils/render.js
@@ -0,0 +1,24 @@
+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: []
+    });
+  }
+};
+
+module.exports = render;
\ No newline at end of file
diff --git a/views/base.pug b/views/base.pug
index 6be4787..27a4a50 100644
--- a/views/base.pug
+++ b/views/base.pug
@@ -11,7 +11,7 @@ html(lang="en")
     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")
+        form.ui.form(action="/auth/login", method="post")
           .ui.pointing.menu
             .right.menu
               .item
@@ -24,7 +24,7 @@ html(lang="en")
                 .ui.transparent.input
                   input.ui.button(type="submit" value="Se connecter")
       else
-        form.ui.form(action="/logout", method="post")
+        form.ui.form(action="/auth/logout", method="post")
           .ui.pointing.menu
             .right.menu
               .item #{user.firstName} #{user.lastName}
diff --git a/views/signup.pug b/views/signup.pug
index afcd907..5de4a9c 100644
--- a/views/signup.pug
+++ b/views/signup.pug
@@ -1,7 +1,7 @@
 extends base.pug
 
 block main
-  form.ui.form(action="/signup" method="post")
+  form.ui.form(action="/auth/signup" method="post")
     .two.fields
       .field
         label(for="firstName") Prénom
-- 
GitLab