Untitled
unknown
javascript
7 months ago
14 kB
3
Indexable
Never
var express = require('express'); var router = express.Router(); const modeloPiscina = require("../models/piscina") const jwt = require("jsonwebtoken"); const crypto = require("crypto"); const { check, validationResult, body } = require('express-validator'); var usuario = "paco" var clave = "falsa" var tokenfalso = "mentira" /** * se utiliza un array de piscinas para almacenar los recusos * no es el objetivo del módulo el trabajar con base de datos */ var piscinas = new Array(); var contador = 0; function init(){ let tempopiscina= new modeloPiscina.Piscina("Torre Stark", "Iron Man", new Date().toISOString().slice(0, 10)) piscinas.push(tempopiscina); contador++; tempopiscina.Id = contador; tempopiscina= new modeloPiscina.Piscina("C/Titan", "Thanos", new Date().toISOString().slice(0, 10)) piscinas.push(tempopiscina); contador++; tempopiscina.Id = contador; tempopiscina=new modeloPiscina.Piscina("Avda Dimensión Espejo", "Doctor Strange", new Date().toISOString().slice(0, 10)) piscinas.push(tempopiscina); contador++; tempopiscina.Id = contador; } /** * Añadir el código necesario para validar los campos de entrada y generar * un token */ //! ====== HECHO ====== function validate() { if (usuario === "paco" || clave === "falsa") { console.log("¡Bienvenido " + usuario + "!"); return true; }else { console.log("Por favor ingrese usuario y contraseña"); return false; } } // Token con JWT const payload = { usuario: "paco", clave: "falsa" }; const secret = "mi_clave_secreta"; const tokenJWT = jwt.sign(payload, secret); console.log(tokenJWT); router.post("/login", (req, res) => { return res.json(validate() + " || " + tokenJWT); }) /** * Alta de una nueva piscina, validar que se tiene permisos (enviar el token), comprobar los parámetros y desinfectar los mismos */ //! ====== HECHO ====== //? Se utiliza la librería express-validator para validar los parámetros y xss para desinfectarlos //? Explicación: //? Se importan las librerías express-validator y xss. //? En el middleware de la ruta se utiliza body de express-validator para validar que los campos direccion y propietario no estén vacíos y se les aplica el método trim para quitar espacios en blanco al principio y al final, y escape para escapar caracteres especiales. //? Se verifica si existen errores de validación utilizando validationResult de express-validator y se devuelve un error 400 con los errores si es el caso. //? Se utiliza xss para desinfectar los valores de direccion y propietario. //? Se crea la nueva instancia de Piscina utilizando los valores validados y desinfectados. //? Se incrementa el contador y se asigna el nuevo id a la instancia de Piscina. //? Se envía la respuesta con la nueva instancia de Piscina y el token. const { body, validationResult } = require('express-validator'); const xss = require('xss'); router.post( '/piscina', [ body('direccion').notEmpty().trim().escape(), body('propietario').notEmpty().trim().escape(), ], (req, res) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } const direccion = xss(req.body.direccion); const propietario = xss(req.body.propietario); const fechaCreacion = new Date().toISOString().slice(0, 10); const piscina = new modeloPiscina.Piscina(direccion, propietario, fechaCreacion); piscinas.push(piscina); contador++; piscina.Id = contador; res.json({ piscina, token: tokenJWT }); } ); /** * * Borrar una piscina, validar que se tiene permisos (enviar el token), comprobar los parámetros y desinfectar los mismos */ //! ====== HECHO ====== //? Se utiliza la librería jsonwebtoken para verificar el token y express-validator para validar los parámetros y xss para desinfectarlos //? Explicación: //? Se importan las librerías jsonwebtoken, express-validator y xss. //? En el middleware de la ruta se utiliza param de express-validator para validar que el parámetro id sea un número entero. //? Se verifica si existen errores de validación utilizando validationResult de express-validator y se devuelve un error 400 con los errores si es el caso. //? Se recupera el token de autenticación del encabezado Authorization de la solicitud HTTP y se verifica utilizando jsonwebtoken. //? Se comprueba si el usuario tiene permisos para realizar la acción. En este caso, se verifica si el campo role del token decodificado es "admin". //? Se recupera el valor del parámetro id y se busca el índice de la piscina correspondiente en el arreglo piscinas. //? Si no se encuentra la piscina, se devuelve un error 404 con un mensaje. //? Si se encuentra la piscina, se elimina del arreglo piscinas. //? Se envía una respuesta JSON que incluye el número de elementos eliminados del arreglo. const jwt = require('jsonwebtoken'); const { param, validationResult } = require('express-validator'); const xss = require('xss'); router.delete( '/piscina/:id', [ param('id').isInt().toInt(), ], (req, res) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } const token = req.headers.authorization; if (!token) { return res.status(401).json({ message: 'No se ha proporcionado un token de autenticación' }); } try { const decoded = jwt.verify(token, 'mi_clave_secreta'); if (decoded.role !== 'admin') { return res.status(403).json({ message: 'No tiene permisos para realizar esta acción' }); } } catch (err) { return res.status(401).json({ message: 'Token inválido o expirado' }); } const id = req.params.id; const index = piscinas.findIndex(piscina => piscina.Id === id); if (index === -1) { return res.status(404).json({ message: 'No se encontró la piscina con el id especificado' }); } const length_antes = piscinas.length; piscinas.splice(index, 1); const length_despues = piscinas.length; res.json({ deleted: length_antes - length_despues }); } ); /** * Datos de todas las piscinas, comprobar si se tiene permisos. * */ //! ====== HECHO ====== //? Se utiliza la librería jsonwebtoken para verificar el token //? Explicación: //? Se importa la librería jsonwebtoken. //? Se define la ruta GET /piscina. //? Se recupera el token de autenticación del encabezado Authorization de la solicitud HTTP y se verifica utilizando jsonwebtoken. //? Se comprueba si el usuario tiene permisos para realizar la acción. En este caso, se verifica si el campo role del token decodificado es "admin". //? Se envía una respuesta JSON que incluye el arreglo piscinas. const jwt = require('jsonwebtoken'); router.get('/piscina', (req, res) => { const token = req.headers.authorization; if (!token) { return res.status(401).json({ message: 'No se ha proporcionado un token de autenticación' }); } try { const decoded = jwt.verify(token, 'mi_clave_secreta'); if (decoded.role !== 'admin') { return res.status(403).json({ message: 'No tiene permisos para realizar esta acción' }); } } catch (err) { return res.status(401).json({ message: 'Token inválido o expirado' }); } res.json(piscinas); }); /** * Datos de una piscina concreta, Comprobar si se tiene permisos y el parámetro es correcto. * */ //! ====== HECHO ====== //? Se utiliza la librería jsonwebtoken para verificar el token: //? Explicación: //? Se importa la librería jsonwebtoken. //? Se define la ruta GET /piscina/:id. //? Se recupera el token de autenticación del encabezado Authorization de la solicitud HTTP y se verifica utilizando jsonwebtoken. //? Se comprueba si el usuario tiene permisos para realizar la acción. En este caso, se verifica si el campo role del token decodificado es "admin". //? Se comprueba si el parámetro id es un número entero válido. Si no lo es, se envía una respuesta de error. //? Se busca la piscina correspondiente al id proporcionado en el arreglo piscinas. Si no se encuentra, se envía una respuesta de error. //? Se envía una respuesta JSON que incluye los datos de la piscina correspondiente. const jwt = require('jsonwebtoken'); router.get('/piscina/:id', (req, res) => { const token = req.headers.authorization; if (!token) { return res.status(401).json({ message: 'No se ha proporcionado un token de autenticación' }); } try { const decoded = jwt.verify(token, 'mi_clave_secreta'); if (decoded.role !== 'admin') { return res.status(403).json({ message: 'No tiene permisos para realizar esta acción' }); } } catch (err) { return res.status(401).json({ message: 'Token inválido o expirado' }); } const id = parseInt(req.params.id); if (isNaN(id)) { return res.status(400).json({ message: 'El parámetro ID debe ser un número entero' }); } const piscina = piscinas.find(element => element.Id === id); if (!piscina) { return res.status(404).json({ message: 'No existe la piscina con el ID proporcionado' }); } res.json(piscina); }); /** * Alta de una nueva medición a una piscina, validar que se tiene permisos (enviar el token), comprobar los parámetros y desinfectar los mismos */ //! ====== HECHO ====== //? Se utiliza la librería jsonwebtoken para verificar el token y se comprueban los parámetros antes de crear la medición: //? Explicación: //? Se importa la librería jsonwebtoken. //? Se define la ruta POST /piscina/:id/medicion. //? Se recupera el token de autenticación del encabezado Authorization de la solicitud HTTP y se verifica utilizando jsonwebtoken. //? Se comprueba si el usuario tiene permisos para realizar la acción. En este caso, se verifica si el campo role del token decodificado es "admin". //? Se comprueba si el parámetro id es un número entero válido. const jwt = require('jsonwebtoken'); router.post('/piscina/:id/medicion', (req, res) => { const token = req.headers.authorization; if (!token) { return res.status(401).json({ message: 'No se ha proporcionado un token de autenticación' }); } try { const decoded = jwt.verify(token, 'mi_clave_secreta'); if (decoded.role !== 'admin') { return res.status(403).json({ message: 'No tiene permisos para realizar esta acción' }); } } catch (err) { return res.status(401).json({ message: 'Token inválido o expirado' }); } const id = parseInt(req.params.id); if (isNaN(id)) { return res.status(400).json({ message: 'El parámetro ID debe ser un número entero' }); } const piscina = piscinas.find(element => element.Id === id); if (!piscina) { return res.status(404).json({ message: 'No existe la piscina con el ID proporcionado' }); } const ph = parseFloat(req.body.ph); if (isNaN(ph) || ph < 0 || ph > 14) { return res.status(400).json({ message: 'El valor de pH debe ser un número decimal entre 0 y 14' }); } const cloro = parseFloat(req.body.cloro); if (isNaN(cloro) || cloro < 0) { return res.status(400).json({ message: 'El valor de cloro debe ser un número decimal positivo' }); } const gramos_ph = parseInt(req.body.gramos_ph); if (isNaN(gramos_ph) || gramos_ph < 0) { return res.status(400).json({ message: 'El valor de gramos de pH debe ser un número entero positivo' }); } const gramos_cloro = parseInt(req.body.gramos_cloro); if (isNaN(gramos_cloro) || gramos_cloro < 0) { return res.status(400).json({ message: 'El valor de gramos de cloro debe ser un número entero positivo' }); } const antialgas = req.body.antialgas ? true : false; const fluoculante = req.body.fluoculante ? true : false; const medicion = new modeloPiscina.Medicion(new Date().toISOString().slice(0, 10), ph, cloro, gramos_ph, gramos_cloro, antialgas, fluoculante); piscina.addMedicion(medicion); res.json(medicion); }); /** * Borrar una medición, validar que se tiene permisos (enviar el token), comprobar los parámetros y desinfectar los mismos */ //! ====== HECHO ====== //? Este código primero comprueba que el token enviado sea válido, luego busca la piscina a la que pertenece la medición y comprueba que exista, después busca la medición dentro de la piscina y comprueba que exista, y finalmente borra la medición de la piscina. Si en alguna de estas comprobaciones se detecta un error, se devuelve una respuesta con un mensaje de error correspondiente. router.delete( '/piscina/:idpiscina/medicion/:id', (req, res) => { const idPiscina = parseInt(req.params.idpiscina); const idMedicion = parseInt(req.params.id); const token = req.header('Authorization'); // Comprobamos que el token sea válido if (token !== 'miTokenDeAutenticacion') { res.status(401).json({ error: "No tienes permisos para realizar esta operación" }) return; } // Buscamos la piscina const piscina = piscinas.find(p => p.Id === idPiscina); if (!piscina) { res.status(404).json({ error: "No existe la piscina" }); return; } // Buscamos la medición const medicion = piscina.Mediciones.find(m => m.Id === idMedicion); if (!medicion) { res.status(404).json({ error: "No existe la medición" }); return; } // Borramos la medición piscina.Mediciones = piscina.Mediciones.filter(m => m.Id !== idMedicion); res.json({ message: "Medición eliminada correctamente" }); } ); /** * Obtener una medición concreta. * */ //! ====== HECHO ====== //? Este código ya obtiene la medición concreta ya que esta ruta utiliza los parámetros idpiscina e id para identificar la piscina y la medición concretas. router.get('/piscina/:idpiscina/medicion/:id', function (req, res, next) { var piscina = piscinas.find(element => element.Id == parseInt(req.params.idpiscina)); var medicion; if (piscina == undefined) { res.status(404).json({ error: "No existe la piscina" }) } else { medicion = piscina.Mediciones.find(element => element.Id == parseInt(req.params.id)) if (medicion == undefined) { res.status(404).json({ error: "No existe la medicion" }) } else { res.json(medicion) } } }); module.exports = {router, init};