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
4 changes: 3 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const express = require('express');
const hbs = require('hbs');

const app = express();

const {sessionConfig, loggedUser} = require("./config/sessions.config");
// ℹ️ This function is getting exported from the config folder. It runs most middlewares
require('./config')(app);

Expand All @@ -24,6 +24,8 @@ const capitalized = string => string[0].toUpperCase() + string.slice(1).toLowerC

app.locals.title = `${capitalized(projectName)}- Generated with Ironlauncher`;

app.use(sessionConfig);
app.use(loggedUser);
// 👇 Start handling routes here
const index = require('./routes/index');
app.use('/', index);
Expand Down
45 changes: 45 additions & 0 deletions config/sessions.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const User = require("../models/User.model");
const expressSession = require("express-session");
const MongoStore = require("connect-mongo");

//Periodo de vida
const MAX_AGE = 7;
module.exports.sessionConfig = expressSession({
//la clave que identifica con la cookie
secret: "super secret",
//Si quieres renocar la session y la coockiee
resave: false,
saveUninitialized: false,
cookie:{
secure: false,
httpOnly: true,
//Aqui esta en milisegundos
maxAge: 4 * 3600 * 1000 * MAX_AGE,
},
store: new MongoStore({
mongoUrl: "mongodb://127.0.0.1:27017/lab-express-basic-auth",
//Aqui esta en segundos
ttl: 4 * 3600 * MAX_AGE,
}),
});
module.exports.loggedUser = (req, res, next) =>{
const userId = req.session.userId;

if(userId){
User.findById(userId)
.then((user)=>{
console.log(user);
if (user) {
req.currentUser = user;
res.locals.currentUser = user;
console.log(user);
next();
}else{
next();
}
})
.catch((err)=>next(err))
}else{
next();
}
}
3 changes: 3 additions & 0 deletions controllers/misc.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports.getHome = (req, res, next) => {
res.render("index");
}
57 changes: 57 additions & 0 deletions controllers/user.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const User = require("../models/User.model");
module.exports.signUp = (req, res, next) => {
res.render("user/sign-up");
};
module.exports.doSignUp = (req, res, next) => {
User.create(req.body)
.then(() => {
res.render("user/login");
})
.catch((error) => {
res.render("user/sign-up", { errors: error.errors, user: req.body });
});
};
module.exports.login = (req, res, next) => {
res.render("user/login");
};
module.exports.doLogin = (req, res, next) => {
//deconstrir el body
const { username, password } = req.body;
//crear una función de errores
const renderWithErrors = () => {
res.render("user/login", {
errors: {
message: "Email or password wrong",
},
});
};

//Ahora buscamos si existe el usuario por su email
User.findOne({ username: username })
.then((user) => {
//si existe user será truty
if (user) {
return user.checkPassword(password).then((match) => {
if (match) {
//Aquí se pasa el id del usuario a la session
req.session.userId = user.id;
res.redirect("/user/profile");
} else {
renderWithErrors();
}
});
} else {
renderWithErrors();
}
})
.catch((err) => {
next(err);
});
};
module.exports.userProfile = (req, res, next) => {
res.render("user/profile");
};
module.exports.logout = (req, res, next) => {
req.session.destroy();
res.redirect("/login");
};
15 changes: 15 additions & 0 deletions middlewares/auth.middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//isAuthenticated = si estas en sesión te daja pasar al siguiente middleware
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("/user/profile");
}
}
28 changes: 26 additions & 2 deletions models/User.model.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
const { Schema, model } = require("mongoose");
const bcrypt = require("bcrypt");
const SALT_ROUNDS = 10;

// TODO: Please make sure you edit the user model to whatever makes sense in this case
const userSchema = new Schema({
username: {
type: String,
unique: true
unique: true,
required: [true, "Username is required"],
},
password: {
type: String,
required: [true, "Password is required"],
},
password: String
});

userSchema.pre("save", function (next) {
if (this.isModified("password")) {
bcrypt
.hash(this.password, SALT_ROUNDS)
.then((hash) => {
this.password = hash;
next();
})
.catch((error) => next(error));
} else{
next();
}
});

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

const User = model("User", userSchema);

module.exports = User;
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
"dev": "nodemon server.js"
},
"dependencies": {
"bcrypt": "^5.1.1",
"connect-mongo": "^5.1.0",
"cookie-parser": "^1.4.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-session": "^1.18.0",
"hbs": "^4.1.1",
"mongoose": "^6.1.2",
"morgan": "^1.10.0",
Expand Down
26 changes: 23 additions & 3 deletions routes/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
const router = require("express").Router();
const { getHome } = require("../controllers/misc.controller");
const {
signUp,
doSignUp,
login,
doLogin,
userProfile,
logout
} = require("../controllers/user.controller");
const {
isAuthenticated,
isNotAuthenticated
} = require("../middlewares/auth.middleware");

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

//Sign up
router.get("/signUp", isNotAuthenticated, signUp);
router.post("/signUp", isNotAuthenticated, doSignUp);
router.get("/login", isNotAuthenticated, login);
router.post("/login", isNotAuthenticated, doLogin);
router.get("/user/profile", isAuthenticated, userProfile)
router.get("/logout",isAuthenticated, logout);


module.exports = router;
7 changes: 7 additions & 0 deletions views/index.hbs
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
<h1>{{title}}</h1>
<p>Welcome to {{title}}</p>
{{#if currentUser}}
<h3>You´re in Session</h3>
{{else}}
<h3>Go
<a href="/login">login</a>
to start your Session</h3>
{{/if}}
38 changes: 38 additions & 0 deletions views/layout.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,52 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{title}}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<link rel="stylesheet" href="/stylesheets/style.css" />

</head>

<body>
{{#if currentUser}}
{{else}}
<ul class="nav justify-content-center">
<li class="nav-item">
<a class="nav-link" href="/signUp">Sing up</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/login">Login</a>
</ul>
{{/if}}
<nav class="navbar navbar-expand-lg navbar-light bg-light mb-3">
<div class="container-fluid">
{{#if currentUser}}
<a class="navbar-brand" href="#">Hi {{currentUser.username}}</a>
{{else}}
<a class="navbar-brand" href="#">Navbar</a>
{{/if}}
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarTogglerDemo02" aria-controls="navbarTogglerDemo02" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarTogglerDemo02">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="/">Home</a>
</li>
</ul>
{{#if currentUser}}
<div class="d-flex">
<a class="nav-link active" aria-current="page" href="/user/profile">Profile</a>
<a class="btn btn-outline-danger" href="/logout">Logout</a>
</div>
{{/if}}
</div>
</div>
</nav>

{{{body}}}

<script src="/js/script.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>

</html>
33 changes: 33 additions & 0 deletions views/user/login.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<div class="container">
<h2>Login</h2>
<form action="/login" method="POST">
<div class="row mb-3">
<label for="username" class="col-sm-2 col-form-label">Username</label>
<div class="col-sm-10">
<input
type="text"
class="form-control"
id="username"
name="username"
/>
</div>
</div>
<div class="row mb-3">
<label for="password" class="col-sm-2 col-form-label">Password</label>
<div class="col-sm-10">
<input
type="password"
class="form-control"
id="password"
name="password"
/>
</div>
</div>
<button type="submit" class="btn btn-primary">Login</button>
{{#if errors.message}}
<div class="alert alert-danger my-4" role="alert">
{{errors.message}}
</div>
{{/if}}
</form>
</div>
2 changes: 2 additions & 0 deletions views/user/profile.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<h2>Profile</h2>
{{currentUser.username}}
27 changes: 27 additions & 0 deletions views/user/sign-up.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div class="container">
<h2>Sign Up</h2>
<form action="/signUp" method="POST">
<div class="row mb-3">
<label for="username" class="col-sm-2 col-form-label">Username</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="username" name="username" value="{{user.username}}"/>
{{#if errors.username}}
<div class="alert alert-danger mt-2">{{errors.username}}</div>
{{/if}}
</div>
</div>
<div class="row mb-3">
<label
for="password"
class="col-sm-2 col-form-label"
>Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="password" name="password"/>
{{#if errors.password}}
<div class="alert alert-danger mt-2">{{errors.password}}</div>
{{/if}}
</div>
</div>
<button type="submit" class="btn btn-primary">Sign in</button>
</form>
</div>