-
Notifications
You must be signed in to change notification settings - Fork 0
/
serverdelilah.js
313 lines (288 loc) · 9.91 KB
/
serverdelilah.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
const express = require("express");
const app = express();
//librería para encriptar y validar contraseñas
const hashing = require("password-hash");
const mysql = require("mysql2");
const Sequelize = require("sequelize");
//Para conectar con la base de datos
const sequelize = new Sequelize("mysql://root:@localhost:3306/delilah");
const jwt = require("jsonwebtoken");
//Contraseña para firmar los tokens
const passwordJwt = "MafcxI9nlw";
app.use(express.json());
//Validar usuario y contraseña, guarda en el token si el usuario es admin o no
function validarUsuario(req, res, next) {
let nombreusuario = req.body.nombreusuario;
let password = req.body.password;
if (typeof nombreusuario != undefined && typeof password != undefined) {
sequelize
.query("SELECT * FROM usuarios WHERE nombre_usuario= ?", {
replacements: [nombreusuario],
type: sequelize.QueryTypes.SELECT
})
.then(resultados => {
let usuario = resultados[0];
if (usuario == undefined) {
res.status(400).json("Usuario inexistente");
} else {
if (hashing.verify(password, usuario.password)) {
usuario_token = {
id_usuario: usuario.id,
nombreusuario: nombreusuario,
admin: usuario.admin
};
const token = jwt.sign({ usuario_token }, passwordJwt);
req.locals = token;
return next();
} else {
res.status(400).json("Contraseña incorrecta");
}
}
})
.catch(err => {
res.status(400).json("Ha ocurrido un error autenticando");
});
}
}
//Dado un token, se fija si corresponde a un admin o no
function validarAdmin(req, res, next) {
const token = req.headers.authorization;
if (!token) {
res.status(401).json("Primero debes iniciar sesión");
} else {
const verificado = jwt.verify(token, passwordJwt);
let usuario = verificado.usuario_token;
if (usuario.admin == 1) {
return next();
} else {
res.status(403).json("Acceso denegado. Sólo administradores");
}
}
}
//Chequea que se haya iniciado sesión para poder interactuar
function darAcceso(req, res, next) {
const token = req.headers.authorization;
if (!token) {
res.status(401).json("Primero debes iniciar sesión");
} else {
const verificado = jwt.verify(token, passwordJwt);
let usuario = verificado.usuario_token;
if (usuario != undefined) {
req.locals = usuario;
return next();
} else {
res.status(403).json("Token inválido");
}
}
}
//Calcula el total de un pedido realizado
async function calcularPrecioTotal(req, res, next) {
let productos = req.body.productos;
let cantidades = req.body.cantidades;
let total = 0;
for (var i = 0; i < productos.length; i++) {
let cantidad = cantidades[i];
await sequelize
.query("SELECT precio FROM productos WHERE id = ?", {
replacements: [productos[i]],
type: sequelize.QueryTypes.SELECT
})
.then(resultados => {
let precio = resultados[0].precio;
total = total + precio * cantidad;
})
.catch(error => res.status(400).json("Algo salió mal"));
}
res.locals = total;
return next();
}
//Endpoint para crear usuario, acceso libre
app.post("/usuarios", (req, res) => {
nombreusuario = req.body.nombreusuario;
password = req.body.password;
passwordEncriptada = hashing.generate(password);
nombre = req.body.nombre;
apellido = req.body.apellido;
email = req.body.email;
telefono = req.body.telefono;
if (
!nombreusuario ||
!password ||
!nombre ||
!apellido ||
!email ||
!telefono
) {
res.status(400).json("Hay campos obligatorios vacíos");
} else {
sequelize
.query("SELECT id FROM usuarios WHERE nombre_usuario=?", {
replacements: [nombreusuario],
type: sequelize.QueryTypes.SELECT
})
.then(resultados => {
if (resultados.length == 0) {
sequelize
.query(
"INSERT INTO usuarios (nombre_usuario, password, nombre, apellido, mail, telefono,admin) VALUES (?,?,?,?,?,?,?)",
{
replacements: [
nombreusuario,
passwordEncriptada,
nombre,
apellido,
email,
telefono,
0
]
}
)
.then(resultados => {
res.status(201).json("El usuario ha sido creado con éxito");
});
} else {
res.status(400).json("El nombre de usuario no está disponible");
}
});
}
});
//Trae todos los usuarios, sólo administrador
app.get("/usuarios", validarAdmin, (req, res) => {
sequelize
.query("SELECT nombre_usuario, nombre, apellido, mail, telefono,admin FROM usuarios", { type: sequelize.QueryTypes.SELECT })
.then(resultados => {
res.status(200).json(resultados);
});
});
//Endpoint para iniciar sesión, acceso libre
app.post("/login", validarUsuario, (req, res) => {
const token = req.locals;
res.status(200).json({"token": token});
});
//Endpoint para crear productos, sólo administrador
app.post("/productos", validarAdmin, (req, res) => {
nombre = req.body.nombre;
precio = req.body.precio;
sequelize
.query("INSERT INTO productos (nombre, precio) VALUES (?,?)", {
replacements: [nombre, precio]
})
.then(resultados => {
res
.status(201)
.json("Se ha agregado el nuevo producto a la base de datos");
});
});
//Endpoint para eliminar productos, sólo administrador
app.delete("/productos/:id", validarAdmin, (req, res) => {
const producto_id = req.params.id;
sequelize
.query("DELETE FROM productos WHERE id = ?", {
replacements: [producto_id]
})
.then(resultados => {
res.status(200).json("Se ha eliminado el producto");
});
});
//Endpoint para editar productos, sólo administrador
app.patch("/productos/:id", validarAdmin, (req, res) => {
let id_producto = req.params.id;
let nuevo_nombre = req.body.nuevo_nombre;
let nuevo_precio = req.body.nuevo_precio;
if (nuevo_nombre != undefined && nuevo_precio != undefined) {
sequelize
.query("UPDATE productos SET nombre = ?, precio = ? WHERE id = ?", {
replacements: [nuevo_nombre, nuevo_precio, id_producto]
})
.then(resultados => {
res.status(200).json("Se realizaron los cambios");
});
} else if (nuevo_nombre != undefined) {
sequelize
.query("UPDATE productos SET nombre = ? WHERE id = ?", {
replacements: [nuevo_nombre, id_producto]
})
.then(resultados => {
res.status(200).json("El nombre del producto ha sido actualizado");
});
} else if (nuevo_precio != undefined) {
sequelize
.query("UPDATE productos SET precio = ? WHERE id = ?", {
replacements: [nuevo_precio, id_producto]
})
.then(resultados => {
res.status(200).json("El precio del producto ha sido actualizado");
});
}
});
//Endpoint para consultar todos los productos disponibles, sólo usuarios autenticados y admin
app.get("/productos", darAcceso, (req, res) => {
sequelize
.query("SELECT * FROM productos", { type: sequelize.QueryTypes.SELECT })
.then(resultados => {
res.status(200).json(resultados);
});
});
//Endpoint para realizar un nuevo pedido, usuarios autenticados
app.post("/pedidos", darAcceso, calcularPrecioTotal, (req, res) => {
let usuario_id = req.locals.id_usuario;
let direccion = req.body.direccion;
let total = res.locals;
let metodo_pago = req.body.metodo_pago;
let productos = req.body.productos;
let cantidades = req.body.cantidades;
sequelize
.query(
"INSERT INTO pedidos (usuario_id, direccion, total, metodo_pago) VALUES (?,?,?,?)",
{
replacements: [usuario_id, direccion, total, metodo_pago]
}
)
.then(resultados => {
//Este query es para saber el id que va a tener este nuevo pedido
sequelize
.query("SELECT id FROM pedidos ORDER BY id DESC LIMIT 1", {
type: sequelize.QueryTypes.SELECT
})
.then(resultados => {
let pedido_id = resultados[0].id;
for (var i = 0; i < productos.length; i++) {
let producto = productos[i];
let cantidad = cantidades[i];
sequelize.query(
"INSERT INTO pedidos_productos (pedido_id, producto_id, cantidad) VALUES (?,?,?)",
{
replacements: [pedido_id, producto, cantidad]
}
);
}
res.status(200).json("El pedido fue realizado con éxito");
});
});
});
//Trae todos los pedidos, sólo administrador
app.get("/pedidos", validarAdmin, (req, res) => {
sequelize
.query(
"SELECT pedidos.*, productos.nombre AS nombre_producto, pedidos_productos.cantidad FROM pedidos JOIN pedidos_productos ON pedidos_productos.pedido_id = pedidos.id JOIN productos ON pedidos_productos.producto_id = productos.id",
{ type: sequelize.QueryTypes.SELECT }
)
.then(resultados => {
res.status(200).json(resultados);
});
});
//Endpoint para actualizar el estado de un pedido, sólo administradores
app.patch("/pedidos/:id", validarAdmin, (req, res) => {
let id_pedido = req.params.id;
let nuevo_estado = req.body.nuevo_estado;
sequelize
.query("UPDATE pedidos SET estado = ? WHERE id = ?", {
replacements: [nuevo_estado, id_pedido]
})
.then(resultados => {
res.status(200).json("El estado del pedido fue modificado");
});
});
app.listen(3000, function() {
console.log("Servidor iniciado en puerto 3000...");
});