Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions Controllers/auth.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
const User = require("../models/User.model");
const mongoose = require("mongoose");

// signup
module.exports.signup = (req, res, next) => {
res.render("auth/signup"); // Correct path FINALLYYYYYY
};


// doSignup
module.exports.doSignup = (req, res, next) => {
User.create(req.body)
.then((user) => {
res.redirect("/login");
})
.catch((err) => {
if (err instanceof mongoose.Error.ValidationError) {
// Handle validation errors
res.render("auth/signup", {
user: {
email: req.body.email,
},
errors: err.errors,
});
} else if (err.code === 11000) {
// Handle duplicate key error
res.render("auth/signup", {
user: {
email: req.body.email,
},
errors:{
password:"This email is already registered. Please use a different one."
}

});
} else {
// Handle any other errors
next(err);
}
});
}


// Render login form
module.exports.login = (req, res, next) => {
res.render("auth/login"); // Correct view path
};

// Handle login submission
module.exports.doLogin = (req, res, next) => {
const { email, password } = req.body;

const renderWithErrors = () => {
res.render("auth/login", {
email,
error: "Email o contraseña incorrectos", // Incorrect email or password
});
};

// The juicy part we did in class
User.findOne({ email })
.then((user) => {
if (user) {
return user.checkPassword(password).then((match) => {
if (match) {
req.session.userId = user.id; // Save user ID in session (cookie magic!)
res.redirect("/profile");
} else {
console.log("Contraseña incorrecta");
renderWithErrors();
}
});
} else {
console.log("No existe usuario con ese email");
renderWithErrors();
}
})
.catch((err) => next(err));
};

// How you logout
module.exports.logout = (req, res, next) => {
req.session.destroy();
res.clearCookie("express-cookie");
res.redirect("/login");
};


// Add the main


// Add the private
13 changes: 13 additions & 0 deletions Controllers/misc.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const User = require("../models/User.model");

module.exports.home = (req, res, next) => {
res.render("index");
};

module.exports.panel = (req, res, next) => {
User.find({ _id: { $ne: req.currentUser.id } }) // Excluir el usuario actual
.then((users) => {
res.render("control/panel", { users });
})
.catch((err) => next(err));
};
14 changes: 14 additions & 0 deletions Controllers/users.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const User = require("../models/User.model");

module.exports.profile = (req, res, next) => {
console.log(req.currentUser);
res.render("user/profile");
};

module.exports.delete = (req, res, next) => {
User.findByIdAndDelete(req.params.id)
.then(() => {
res.redirect("/panel");
})
.catch((err) => next(err));
};
7 changes: 5 additions & 2 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ const express = require('express');
// Handles the handlebars
// https://www.npmjs.com/package/hbs
const hbs = require('hbs');
hbs.registerPartials(__dirname + "/views/partials");

const app = express();
const { sessionConfig, loggedUser } = require("./config/session.config");

// ℹ️ This function is getting exported from the config folder. It runs most middlewares
require('./config')(app);
app.use(sessionConfig);
app.use(loggedUser);

// default value for title local
const projectName = 'lab-express-basic-auth';
Expand All @@ -31,5 +35,4 @@ app.use('/', index);
// ❗ To handle errors. Routes that don't exist or errors that you handle in specific routes
require('./error-handling')(app);

module.exports = app;

module.exports = app;
2 changes: 1 addition & 1 deletion config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ module.exports = (app) => {

// Handles access to the favicon
app.use(favicon(path.join(__dirname, "..", "public", "images", "favicon.ico")));
};
};
42 changes: 42 additions & 0 deletions config/session.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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({
name: "express-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,
}),
});

module.exports.loggedUser = (req, res, next) => {
const userId = req.session.userId;

if (userId) {
User.findById(userId)
.then((userFromDB) => {
if (userFromDB) {
req.currentUser = userFromDB; // todos los middlewares ya tienen acceso a currentUser
res.locals.currentUser = userFromDB; // res.locals es el objeto donde se manda informacion a todas las vistas (hbs)
next();
} else {
next();
}
})
.catch((err) => next(err));
} else {
next();
}
};
9 changes: 9 additions & 0 deletions middlewares/admin.middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports.isAdmin = (req, res, next) => {
if (req.currentUser.isAdmin) {
next();
} else {
res.render("error", {
error: "No eres admin",
});
}
};
15 changes: 15 additions & 0 deletions middlewares/auth.middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports.isAuthenticated = (req, res, next) => {
if (req.currentUser) {
next();
} else {
res.redirect("/login");
}
};

module.exports.isNotAuthenticated = (req, res, next) => {
if (!req.currentUser) {
next();
} else {
res.redirect("/profile");
}
};
48 changes: 40 additions & 8 deletions models/User.model.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,46 @@
const { Schema, model } = require("mongoose");
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");

// TODO: Please make sure you edit the user model to whatever makes sense in this case
const userSchema = new Schema({
username: {
const EMAIL_PATTERN =
/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;

const UserSchema = new mongoose.Schema({
name: {
type: String,
trim: true,
},
email: {
type: String,
required: [true, "Email is required"],
unique: true,
match: [EMAIL_PATTERN, "Email is invalid"],
trim: true,
lowercase: true,
},
password: {
type: String,
unique: true
required: true,
minLength: [8, "Password must be 8 characters or longer"],
},
password: String
});

const User = model("User", userSchema);
UserSchema.pre("save", function (next) {
const user = this;

if (user.isModified("password")) {
bcrypt.hash(user.password, 10).then((hash) => {
user.password = hash;
next();
});
} else {
next();
}
});

UserSchema.methods.checkPassword = function (password) {
return bcrypt.compare(password, this.password);
};

const User = mongoose.model("User", UserSchema);

module.exports = User;
module.exports = User;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"dev": "nodemon server.js"
},
"dependencies": {
"bcrypt": "^5.1.1",
"cookie-parser": "^1.4.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
Expand Down
46 changes: 46 additions & 0 deletions routes/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,54 @@
const router = require("express").Router();

//Define the controllers
const authController = require("../Controllers/auth.controller")
const miscController = require("../Controllers/misc.controller");
const usersController = require("../Controllers/users.controller");

//Define the middlewares
const authMiddlewares = require("../middlewares/auth.middleware");
const adminMiddlewares = require("../middlewares/admin.middleware");

/* GET home page */
router.get("/", (req, res, next) => {
res.render("index");
});


router.get("/", miscController.home);
router.get("/panel", adminMiddlewares.isAdmin, miscController.panel);


// Signup routes
router.get("/signup", authMiddlewares.isNotAuthenticated, authController.signup);
router.post("/signup", authMiddlewares.isNotAuthenticated, authController.doSignup);

// Login routes
router.get("/login", authMiddlewares.isNotAuthenticated, authController.login);
router.post("/login", authMiddlewares.isNotAuthenticated, authController.doLogin);

// Now the Logout part
router.get("/logout", authController.logout);

// Delete your profile
router.post("/users/delete/:id", adminMiddlewares.isAdmin, usersController.delete);

// and aha, this is the Profillleeee
router.get("/profile", authMiddlewares.isAuthenticated, usersController.profile);

// The main (protected)
router.get("/main", authMiddlewares.isAuthenticated, (req, res, next) => {
res.render("user/main");
});

// Private (protected)
router.get("/private", authMiddlewares.isAuthenticated, (req, res, next) => {
res.render("user/private");
});

module.exports = router;





14 changes: 14 additions & 0 deletions views/auth/login.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<h1>Log in</h1>
{{#if error}}
<p style="color: red;">{{error}}</p>
{{/if}}

<form action="/login" method="POST">
<label for="email">Email:</label>
<input type="email" id="email" name="email" value="{{email}}" required>

<label for="password">Password:</label>
<input type="password" id="password" name="password" required>

<button type="submit">Log In</button>
</form>
Loading