From 39c3bf054c56a5e6f57cdc26bc00e8491afc9d40 Mon Sep 17 00:00:00 2001 From: HisokaHX Date: Thu, 1 Feb 2024 18:14:40 +0100 Subject: [PATCH] [MAD-PT-WD092023]Luca Tobiello --- .env | 2 +- app.js | 9 +++ config/session.config.js | 21 +++++++ controllers/users.controller.js | 101 ++++++++++++++++++++++++++++++++ db/index.js | 2 + middlewares/auth.middlewares.js | 25 ++++++++ models/User.model.js | 38 ++++++++++-- package.json | 3 + routes/index.js | 16 ++++- views/layout.hbs | 26 ++++---- views/partials/navbar.hbs | 44 ++++++++++++++ views/users/login.hbs | 20 +++++++ views/users/profile.hbs | 4 ++ views/users/register.hbs | 32 ++++++++++ 14 files changed, 325 insertions(+), 18 deletions(-) create mode 100644 config/session.config.js create mode 100644 controllers/users.controller.js create mode 100644 middlewares/auth.middlewares.js create mode 100644 views/partials/navbar.hbs create mode 100644 views/users/login.hbs create mode 100644 views/users/profile.hbs create mode 100644 views/users/register.hbs diff --git a/.env b/.env index c0c68b1ca0..a43d6bb1e4 100644 --- a/.env +++ b/.env @@ -1 +1 @@ -PORT=3000 \ No newline at end of file +PORT=3001 \ No newline at end of file diff --git a/app.js b/app.js index 2ecc9f2220..4438afaa45 100644 --- a/app.js +++ b/app.js @@ -24,6 +24,15 @@ const capitalized = string => string[0].toUpperCase() + string.slice(1).toLowerC app.locals.title = `${capitalized(projectName)}- Generated with Ironlauncher`; +hbs.registerPartials(__dirname + "/views/partials"); + +const { sessionConfig } = require("./config/session.config"); +app.use(sessionConfig); +app.use((req, res, next) => { + res.locals.currentUser = req.session.currentUser; + next(); +}); + // 👇 Start handling routes here const index = require('./routes/index'); app.use('/', index); diff --git a/config/session.config.js b/config/session.config.js new file mode 100644 index 0000000000..865146a435 --- /dev/null +++ b/config/session.config.js @@ -0,0 +1,21 @@ +const User = require("../models/User.model"); +const expressSession = require("express-session"); +const MongoStore = require("connect-mongo"); +const mongoose = require("mongoose"); + +const MAX_AGE = 7; + +module.exports.sessionConfig = expressSession({ + secret: process.env.COOKIE_SECRET || "super-secret", + resave: false, + saveUninitialized: false, + cookie: { + secure: false, + httpOnly: true, + maxAge: 24 * 3600 * 1000 * MAX_AGE, + }, + store: new MongoStore({ + mongoUrl: mongoose.connection._connectionString, + ttl: 24 * 3600 * MAX_AGE, + }), +}); \ No newline at end of file diff --git a/controllers/users.controller.js b/controllers/users.controller.js new file mode 100644 index 0000000000..638f7479d3 --- /dev/null +++ b/controllers/users.controller.js @@ -0,0 +1,101 @@ +const User = require("../models/User.model"); +const mongoose = require("mongoose"); + +module.exports.register = (req, res, next) => { + res.render("users/register"); +}; + +module.exports.doRegister = (req, res, next) => { + const { email } = req.body; + + User.findOne({ email }).then((dbUser) => { + if (dbUser) { + res.render("users/register", { + user: { + email, + }, + errors: { + email: "Este email ya esta en uso!", + }, + }); + } else { + + User.create(req.body) + .then(() => { + + + res.redirect("/login"); + }) + .catch((err) => { + console.error("Error al crear usuario:", err); + + if (err instanceof mongoose.Error.ValidationError) { + res.render("users/register", { + user: { + email, + }, + errors: err.errors, // { EMAIL: 'lo que sea', PASSWOR: ''} + }); + } else { + next(err); + } + }); + } + }); +}; + +module.exports.login = (req, res, next) => { + res.render("users/login", { errors: false }); +}; + +module.exports.profile = (req, res, next) => { + res.render("users/profile"); +} + +module.exports.player = (req, res, next) => { + res.render("users/listPlayer"); +} + +module.exports.doLogin = (req, res, next) => { + const { email, password } = req.body; + + const renderWithErrors = (msg) => { + res.render('users/login', { + email, + errors: { + msg: msg || 'Email or password are incorrect', + }, + }); + }; + + if (!email || !password) { + renderWithErrors(); + } else { + User.findOne({ email }) + .then((dbUser) => { + if (!dbUser) { + renderWithErrors(); + } else { + dbUser + .checkPassword(password) + .then((match) => { + if (!match) { + renderWithErrors(); + } else { + req.session.currentUser = dbUser; + res.redirect('/profile'); + + } + }) + .catch((err) => next(err)); + } + }) + .catch((err) => next(err)); + } +}; + +module.exports.logout = (req, res, next) => { + req.session.destroy(); + res.clearCookie('connect.sid'); + res.redirect('/login'); +}; \ No newline at end of file diff --git a/db/index.js b/db/index.js index 5da532b6ee..b392206dca 100644 --- a/db/index.js +++ b/db/index.js @@ -2,6 +2,8 @@ // https://www.npmjs.com/package/mongoose const mongoose = require("mongoose"); + +mongoose.set('strictQuery', false); // â„šī¸ Sets the MongoDB URI for our app to have access to it. // If no env has been set, we dynamically set it to whatever the folder name was upon the creation of the app diff --git a/middlewares/auth.middlewares.js b/middlewares/auth.middlewares.js new file mode 100644 index 0000000000..23aac07c7e --- /dev/null +++ b/middlewares/auth.middlewares.js @@ -0,0 +1,25 @@ +module.exports.isAuthenticated = (req, res, next) => { + if (req.session.currentUser) { + next(); + } else { + res.redirect("/login"); + } +}; + +module.exports.isNotAuthenticated = (req, res, next) => { + if (!req.session.currentUser) { + next() + } else { + res.redirect("/profile"); + } +}; + +module.exports.isAdmin = (req, res, next) => { + if (req.currentUser.isAdmin) { + next() + } else { + res.render("error", { + error: "you aren't admin" + }); + } +}; \ No newline at end of file diff --git a/models/User.model.js b/models/User.model.js index 9cdd3a3ce4..9d4a021a44 100644 --- a/models/User.model.js +++ b/models/User.model.js @@ -1,14 +1,42 @@ const { Schema, model } = require("mongoose"); +const mongoose = require("mongoose"); +const bcrypt = require("bcryptjs"); + +const SALT_WORK_FACTOR = 10; +const EMAIL_PATTERN = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; // TODO: Please make sure you edit the user model to whatever makes sense in this case -const userSchema = new Schema({ - username: { +const userSchema = mongoose.Schema({ + email: { type: String, - unique: true + unique: true, + required: true, }, - password: String + password: { + type: String, + required: true, + minLength: 3, + } }); -const User = model("User", userSchema); +userSchema.pre("save", function (next) { + if (this.isModified("password")) { + bcrypt + .hash(this.password, SALT_WORK_FACTOR) + .then((hash) => { + this.password = hash; + next(); + }) + .catch((error) => next(error)); + } else { + next(); + } +}); + +userSchema.methods.checkPassword = function (passwordToCheck) { + return bcrypt.compare(passwordToCheck, this.password); +}; + +const User = mongoose.model("User", userSchema); module.exports = User; diff --git a/package.json b/package.json index 19489d9695..787f92d140 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,12 @@ "dev": "nodemon server.js" }, "dependencies": { + "bcryptjs": "^2.4.3", + "connect-mongo": "^5.1.0", "cookie-parser": "^1.4.5", "dotenv": "^8.2.0", "express": "^4.17.1", + "express-session": "^1.17.3", "hbs": "^4.1.1", "mongoose": "^6.1.2", "morgan": "^1.10.0", diff --git a/routes/index.js b/routes/index.js index 81c2396ceb..7d565c296e 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,8 +1,22 @@ const router = require("express").Router(); +const usersController = require("../controllers/users.controller"); +const authMiddleware = require("../middlewares/auth.middlewares"); + /* GET home page */ router.get("/", (req, res, next) => { res.render("index"); }); -module.exports = router; +router.get("/register", authMiddleware.isNotAuthenticated, usersController.register); +router.post("/register", authMiddleware.isNotAuthenticated, usersController.doRegister); +router.get("/login", authMiddleware.isNotAuthenticated, usersController.login); +router.post("/login", authMiddleware.isNotAuthenticated, usersController.doLogin); +router.get("/logout", authMiddleware.isAuthenticated, usersController.logout); +router.get("/listPlayer", authMiddleware.isAuthenticated, usersController.player); + + +router.get("/profile", authMiddleware.isAuthenticated, usersController.profile); + + +module.exports = router; \ No newline at end of file diff --git a/views/layout.hbs b/views/layout.hbs index 73199c166b..2467c1c886 100644 --- a/views/layout.hbs +++ b/views/layout.hbs @@ -1,19 +1,23 @@ - - - - - {{title}} - - + + + + + {{title}} + + + - + + {{> navbar}} +
{{{body}}} - - - +
+ + \ No newline at end of file diff --git a/views/partials/navbar.hbs b/views/partials/navbar.hbs new file mode 100644 index 0000000000..987133ede6 --- /dev/null +++ b/views/partials/navbar.hbs @@ -0,0 +1,44 @@ + \ No newline at end of file diff --git a/views/users/login.hbs b/views/users/login.hbs new file mode 100644 index 0000000000..39a2287fb2 --- /dev/null +++ b/views/users/login.hbs @@ -0,0 +1,20 @@ +
+

login

+
+ + + + + + + + + +
+
\ No newline at end of file diff --git a/views/users/profile.hbs b/views/users/profile.hbs new file mode 100644 index 0000000000..f320d49dd3 --- /dev/null +++ b/views/users/profile.hbs @@ -0,0 +1,4 @@ +

User's profile

+ +

Username: {{user.username}}

+

Email: {{user.email}}

\ No newline at end of file diff --git a/views/users/register.hbs b/views/users/register.hbs new file mode 100644 index 0000000000..0abfac7028 --- /dev/null +++ b/views/users/register.hbs @@ -0,0 +1,32 @@ +

User register

+ + + +
+
+ + +
We'll never share your email with anyone else.
+
+
+ + +
+
+ + +
+
+ + +
+ +
\ No newline at end of file