Skip to content

Commit 6bbe852

Browse files
author
bgonzalez
committed
se agrego el jwt y validaciones en endpoints, y helpers
1 parent 8ebf352 commit 6bbe852

15 files changed

+340
-45
lines changed

controller/auth.controller.js

+28-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,38 @@
11
const { response, request } = require('express');
22
const { log } = require('../helpers/log');
3+
const { generate_jwt } = require('../helpers/jeisonguebtoken');
4+
const { compare_pass } = require('../helpers/encrypt');
5+
const user_model = require('../models/user');
36

47
const login = async (req = request, res = response) => {
58
try {
69
const { username = '', password = '' } = req.body;
7-
if (!username || !password) {
8-
throw new Error('[ERROR] Username and Password required');
9-
}
10+
const user_db = await user_model.findOne({ email: username }) || await user_model.findOne({ username });
1011

11-
const token = '';
12+
// verify user <email> or <username> exist
13+
if (!!!user_db) {
14+
return res.status(400).json({
15+
message: '[ERROR] - Invalid <username> / <password> ',
16+
error: 'invalid <username>'
17+
});
18+
}
19+
// vevrify user <status> --> active
20+
if (!!!user_db.active) {
21+
return res.status(400).json({
22+
message: '[ERROR] - Invalid <status>',
23+
error: 'user <status> inactive'
24+
});
25+
}
26+
// verify password correct
27+
if (!!!compare_pass(password, user_db.password)) {
28+
return res.status(400).json({
29+
message: '[ERROR] - Invalid <username> / <password> ',
30+
error: 'invalid <password>'
31+
});
32+
}
33+
// generate token
34+
const { token } = await generate_jwt(user_db.id);
35+
1236
res.json({
1337
message: '[SUCCESS] - LOGIN SUCCESS',
1438
token

controller/user.controller.js

+28-17
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,8 @@ const post_user = async (req = request, res = response) => {
6464
image,
6565
google
6666
});
67-
6867
// encrypyt password
6968
new_user.password = encrypt_pass(password);
70-
7169
// save db
7270
await new_user.save();
7371

@@ -129,6 +127,34 @@ const put_user = async (req = request, res = response) => {
129127
});
130128
}
131129

130+
}
131+
/**
132+
* Handles a PATCH request for updating a user
133+
* and returns a JSON response with a success message and an empty data object.
134+
* @param [req] - The `req` parameter represents the request object, which contains information about
135+
* the incoming HTTP request such as headers, query parameters, and request body.
136+
* @param [res] - The `res` parameter is the response object that is used to send a response back to
137+
* the client. It contains methods and properties that allow you to control the response, such as
138+
* `json()` which is used to send a JSON response.
139+
*/
140+
const patch_user = async (req = reques, res = response) => {
141+
try {
142+
const { _uid, ...user } = req.body;
143+
const user_db = await user_model.findByIdAndUpdate({ id: _uid}, user);
144+
145+
log(user, user_db);
146+
res.json({
147+
message: '[SUCCESS] - PATCH USER SUCCESS',
148+
data: user_db
149+
});
150+
} catch (error) {
151+
log(error);
152+
res.status(500).json({
153+
message: '[ERROR] - PATCH USER ERROR',
154+
error
155+
});
156+
}
157+
132158
}
133159
/**
134160
* Handles a DELETE request for deleting a
@@ -158,21 +184,6 @@ const delete_user = async (req = request, res = response) => {
158184
});
159185
}
160186
}
161-
/**
162-
* Handles a PATCH request for updating a user
163-
* and returns a JSON response with a success message and an empty data object.
164-
* @param [req] - The `req` parameter represents the request object, which contains information about
165-
* the incoming HTTP request such as headers, query parameters, and request body.
166-
* @param [res] - The `res` parameter is the response object that is used to send a response back to
167-
* the client. It contains methods and properties that allow you to control the response, such as
168-
* `json()` which is used to send a JSON response.
169-
*/
170-
const patch_user = (req = reques, res = response) => {
171-
res.json({
172-
message: 'PATCH - USER SUCCESS',
173-
data: {}
174-
});
175-
}
176187

177188
module.exports = {
178189
get_users,

helpers/db-validators.js

+10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
const Role = require("../models/role");
22

3+
/**
4+
* Checks if a given role exists in the database and throws an error if it
5+
* does not.
6+
* @param [role] - The `role` parameter is a string that represents the role that needs to be
7+
* validated.
8+
*/
39
const validate_rol = async (role = '') => {
410
const if_exist = await Role.findOne({ role });
511
if (!if_exist) {
612
throw new Error(`${role} is not register`);
713
}
814
}
15+
/**
16+
* Checks if a user with a given ID exists and throws an error if not.
17+
* @param [id] - The `id` parameter is the user ID that needs to be validated.
18+
*/
919
const validate_user_id = async (id = '') => {
1020
const if_exist = await Role.findById({ id });
1121
if (!!!if_exist) {

helpers/encrypt.js

+22-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
11
const bcrypt = require('bcryptjs');
22

3+
/**
4+
* Takes a password as input and returns the encrypted version of the
5+
* password using bcrypt.
6+
* @param [password] - The `password` parameter is the plain text password that you want to encrypt.
7+
* @returns The encrypted password is being returned.
8+
*/
9+
const encrypt_pass = (password = '') => {
10+
const salt = bcrypt.genSaltSync();
11+
const encrypted_password = bcrypt.hashSync(password, salt);
12+
return encrypted_password;
13+
};
14+
/**
15+
* Compares a plain text password with an encrypted password using bcrypt.
16+
* @param [password] - The password parameter is the plain text password that you want to compare with
17+
* the encrypted password.
18+
* @param [encrypted_pass] - The `encrypted_pass` parameter is the encrypted version of the password.
19+
* It is typically stored in a database or some other form of persistent storage.
20+
*/
21+
const compare_pass = (password = '', encrypted_pass = '') => bcrypt.compareSync(password, encrypted_pass);
22+
323
module.exports = {
4-
encrypt_pass: (password = '') => {
5-
const salt = bcrypt.genSaltSync();
6-
const encrypted_password = bcrypt.hashSync(password, salt);
7-
return encrypted_password;
8-
}
24+
encrypt_pass,
25+
compare_pass
926
}

helpers/jeisonguebtoken.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const jwt = require("jsonwebtoken");
2+
const { log } = require('../helpers/log');
3+
const { JWTSECRET } = process.env;
4+
const TOKEN_TIME = 10000;
5+
6+
/**
7+
* Generates a JSON Web Token (JWT) using a given payload and returns a
8+
* promise that resolves to an object containing the token.
9+
* @param [payload] - The payload parameter is the data that you want to include in the JSON Web Token
10+
* (JWT). It can be any valid JSON object that you want to encode and include in the token.
11+
* @returns The function `generate_jwt` returns a Promise that resolves to an object with a `token`
12+
* property.
13+
*/
14+
const generate_jwt = (payload = '') => {
15+
if (!!!payload) return new Error('<payload> required');
16+
return new Promise((resolve, reject) => {
17+
const cb = (err, t) => {
18+
if (err) {
19+
log(err);
20+
reject('[ERROR] - Can t generate token');
21+
} else resolve({ token: t });
22+
}
23+
jwt.sign({ __uid: payload }, JWTSECRET, { expiresIn: TOKEN_TIME}, cb);
24+
});
25+
}
26+
27+
module.exports = {
28+
generate_jwt
29+
}

helpers/parse-jwt.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11

2+
/**
3+
* Takes a JWT token as input and returns the decoded payload as a JavaScript
4+
* object.
5+
* @param [token] - The `token` parameter is a string representing a JSON Web Token (JWT).
6+
* @returns the parsed JSON object from the decoded base64 string.
7+
*/
28
const parse_jwt = function(token = '') {
39
let url_encrypted = token.split('.')[0];
410
b64 = url_encrypted.replace('-', '+').replace('_', '/');
5-
return JSON.parse(window.atob(b64));
11+
return JSON.parse(window?.atob(b64));
612
}
713

814
module.exports = {

middelwares/email_validator.js middlewares/email_validator.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ const user_model = require('../models/user');
1919
*/
2020
const validate_fields = (req, res, next) => {
2121
const error = validationResult(req);
22-
if (!!error.isEmpty()) {
22+
if (!!!error.isEmpty()) {
2323
return res.status(400).json({
24-
message: 'ERROR',
25-
data: {},
24+
message: '[ERROR] -<validate-fields>',
2625
error
2726
});
2827
}

middlewares/jwt.middleware.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const { response } = require('express');
2+
const { log } = require('../helpers/log');
3+
const jwt = require('jsonwebtoken');
4+
const { JWTSECRET } = process.env;
5+
const user_model = require('../models/user');
6+
7+
/**
8+
* Validate a JSON Web Token (JWT) in the `x-token` header of a
9+
* request, and if valid, allows the request to proceed to the next middleware or route handler.
10+
* @param req - The `req` parameter is the request object that contains information about the incoming
11+
* HTTP request, such as headers, body, and query parameters. It is typically provided by the web
12+
* framework or server handling the request.
13+
* @param [res] - The `res` parameter is the response object that is used to send the response back to
14+
* the client. It is an instance of the `response` object from the Express framework.
15+
* @param next - The `next` parameter is a function that is used to pass control to the next middleware
16+
* function in the request-response cycle. It is typically used to move to the next middleware function
17+
* or to the route handler after the current middleware function has completed its task.
18+
* @returns a middleware function that takes in three parameters: `req`, `res`, and `next`.
19+
*/
20+
const validate_jwt = async (req , res = response, next) => {
21+
const { 'x-token': auth } = req.headers;
22+
if (!!!auth) return res.status(400).json({
23+
message: '[ERROR] - Invalid <header>',
24+
error: 'header <x-token> undefined'
25+
});
26+
// validate true jwt
27+
try {
28+
const { _uid } = jwt.verify(auth, JWTSECRET);
29+
const user_loged = await user_model.findById({ _id: _uid });
30+
if (!!user_loged) req.user = user_loged;
31+
req.uid = _uid;
32+
next();
33+
} catch (error) {
34+
log(error);
35+
res.status(401).json({
36+
message: '[ERROR] - Invalid token',
37+
error: 'Invalid <token>'
38+
});
39+
}
40+
}
41+
42+
module.exports = {
43+
validate_jwt
44+
}

middlewares/role.middleware.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const { response } = require('express');
2+
const { log } = require('../helpers/log');
3+
const ADMIN_ROLE = 'ADMIN_ROLE';
4+
5+
const validate_admin_role = (req, res = response, next) => {
6+
try {
7+
const { role = '' } = req.body;
8+
9+
if (!!!role.includes(ADMIN_ROLE)) {
10+
return res.status(400).json({
11+
message: '[ERROR] - Inavlid <role> name',
12+
error: 'invalid <role> only admin'
13+
});
14+
}
15+
next();
16+
17+
} catch (error) {
18+
log(error);
19+
res.status(500).json({
20+
message: '[ERROR]- Internal Server Error',
21+
error
22+
});
23+
}
24+
}
25+
26+
module.exports = {
27+
validate_admin_role
28+
}

models/server.js

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const express = require('express');
22
const { log } = require('../helpers/log');
33
const cors = require('cors');
44
const { connection_mongodb } = require('../database/config');
5+
const { validate_jwt } = require('../middlewares/jwt.middleware');
56
const { ROOT_PATH_API } = process?.env;
67

78
class Server {

models/user.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ const user_schema = new Schema({
3131
});
3232

3333
user_schema.methods.toJSON = function () {
34-
const { password, __v,...user } = this.toObject();
35-
return user;
34+
const { password, __v, _id,...user } = this.toObject();
35+
return { ...user, _uid: _id };
3636
}
3737

3838
module.exports = model('User', user_schema);

0 commit comments

Comments
 (0)