From 8c0fdc5f6e8e690d28c49a534579daf8feccdaa4 Mon Sep 17 00:00:00 2001 From: Alex Del Gallego Date: Sat, 16 Apr 2022 14:22:56 +0200 Subject: [PATCH 1/3] =?UTF-8?q?A=C3=B1adida=20funcionalidad=20restapi=20pa?= =?UTF-8?q?ra=20el=20login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- restapi/api.ts | 18 ++++++++++++- restapi/modelos/usuarioModelo.ts | 38 +++++++++++++++++++++++++++ restapi/rutas/usuarioRutas.ts | 39 ++++++++++++++++++++++++++++ restapi/server.ts | 2 ++ webapp/src/api/api.ts | 12 +++++++++ webapp/src/components/Home/List.tsx | 12 ++++----- webapp/src/components/Home/Shoes.tsx | 2 +- 7 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 restapi/modelos/usuarioModelo.ts create mode 100644 restapi/rutas/usuarioRutas.ts diff --git a/restapi/api.ts b/restapi/api.ts index e30f2f8..2bd3fd9 100644 --- a/restapi/api.ts +++ b/restapi/api.ts @@ -1,9 +1,11 @@ import express, { Request, Response, Router } from 'express'; import { check } from 'express-validator'; //import mongoose from 'mongoose'; -import { IProducto, Producto } from './modelos/productoModelo'; +import { IProducto } from './modelos/productoModelo'; +import { IUsuario } from './modelos/usuarioModelo'; const Productos = require('./modelos/productoModelo'); +const Usuarios = require('./modelos/usuarioModelo'); const mongoose = require('mongoose'); const api: Router = express.Router(); @@ -37,6 +39,20 @@ api.post( } ); +api.get( + "/users/login/:user/:pass", + async (req: Request, res: Response): Promise => { + var user:string = req.params.user; + var pass:string = req.params.pass; + const usuario: IUsuario = await Usuarios.findOne( {username: user, password: pass} ); + if (usuario) { + return res.status(200).send(usuario); + } else { + return res.status(404).json({ message: 'El usuario con nombre "${user}" no se ha encontrado.' }); + } + } +) + api.get( "/products/list", async (req: Request, res: Response): Promise => { diff --git a/restapi/modelos/usuarioModelo.ts b/restapi/modelos/usuarioModelo.ts new file mode 100644 index 0000000..2db2672 --- /dev/null +++ b/restapi/modelos/usuarioModelo.ts @@ -0,0 +1,38 @@ +import mongoose, { ObjectId } from 'mongoose'; + +export interface IUsuario { + username:String; + password:String; +} + +interface UsuarioDoc extends mongoose.Document { + _id: ObjectId; + username:String; + password:String; +} + +interface UsuarioModelInterface extends mongoose.Model { + build(attr: IUsuario): UsuarioDoc +} + +const usuarioSchema = new mongoose.Schema({ + username: { + type: String, + required: true, + trim: true + }, + password: { + type: String, + required: true, + trim: true + } +}) + +usuarioSchema.statics.build = (attr: IUsuario) => { + return new Usuario(attr) +} + +const Usuario:UsuarioModelInterface = mongoose.model('Usuario',usuarioSchema) + +export default Usuario + diff --git a/restapi/rutas/usuarioRutas.ts b/restapi/rutas/usuarioRutas.ts new file mode 100644 index 0000000..51dca5d --- /dev/null +++ b/restapi/rutas/usuarioRutas.ts @@ -0,0 +1,39 @@ +import express, { Request, Response } from 'express'; +import Usuario from '../modelos/usuarioModelo'; +import "dotenv/config"; + +//Obtenemos la url de la apirest de Heroku o utilizamos localhost por defecto +let URL_BASE:string = `${process.env.API_REST_URL_BASE_LOCAL}` +if(process.env.PORT) { + URL_BASE = `${process.env.API_REST_URL_BASE_HEROKU}` +} + +const router = express.Router() + +router.get('/users/login/:username/:password', async (req: Request, res: Response) => { + //formato de salida que espera el front-end + type User = { + username: String; + password: String; + } + + let resultado:User[] = new Array(); + //Parametros + const paramUser:string = req.params.username; + const paramPass:string = req.params.password; + //Realizamos la busqueda por referencia + const user = await Usuario.findOne({username: paramUser, password: paramPass}) + if(user){ + let entrada = user; + let salida: User = ({ username: "", password:""}); + salida.username = entrada.username; + salida.password = entrada.password; + resultado.push(salida); + return res.status(200).send(resultado); + } else{ + return res.status(500).json(); + } + +}) + +export { router as usuarioRouter } \ No newline at end of file diff --git a/restapi/server.ts b/restapi/server.ts index e5e8e66..53d7b51 100644 --- a/restapi/server.ts +++ b/restapi/server.ts @@ -3,6 +3,7 @@ import cors from "cors"; import mongoose from 'mongoose'; import { json } from 'body-parser'; import { productoRouter } from './rutas/productoRutas'; +import { usuarioRouter } from './rutas/usuarioRutas'; import { fotoRouter } from './rutas/fotoRutas'; import { tallaRouter } from './rutas/tallaRutas'; import "dotenv/config"; @@ -14,6 +15,7 @@ app.use(cors()) app.use(productoRouter) app.use(fotoRouter) app.use(tallaRouter) +app.use(usuarioRouter) mongoose .connect(`${process.env.MONGODB_URI}`, { diff --git a/webapp/src/api/api.ts b/webapp/src/api/api.ts index a1b9797..002a248 100644 --- a/webapp/src/api/api.ts +++ b/webapp/src/api/api.ts @@ -25,6 +25,18 @@ export async function getUsers():Promise{ return response.json() } +/* +* Metodo que utilizaremos para comprobar si el usuario que intenta logearse, existe en base de datos. +*/ +export async function loginUser(username : string, password : string): Promise { + const apiPetition:string = apiEndPoint+'users/login/' + username + '/' + password; + const response:Response = await fetch(apiPetition); + let result : Promise = response.json(); + // Si encontramos un usuario con esas credenciales, permitimos el inicio de sesion + console.log(result); + return result!=undefined; +} + export async function getProducts(): Promise { const response:Response = await fetch(apiEndPoint+'products/list'); return response.json(); diff --git a/webapp/src/components/Home/List.tsx b/webapp/src/components/Home/List.tsx index e6d8a96..acef9d6 100644 --- a/webapp/src/components/Home/List.tsx +++ b/webapp/src/components/Home/List.tsx @@ -74,32 +74,32 @@ const useStyles = makeStyles({ const itemData = [ { - img: 'https://i.blogs.es/67332d/screenshot_4501/original.jpeg', + img: 'https://i.imgur.com/cyhVYVf.jpg', title: 'Pokemon', featured: true, }, { - img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTviEWtiJBnAfMBudW5kmrIpt9tng4cD2_F_w1HDAnVAcnqoP5LJM9vKNBOBlrvSigJEIM&usqp=CAU', + img: 'https://i.imgur.com/VwtfVgU.jpg', title: 'Zapatillas Baby Yoda', author: '@rollelflex_graphy726', }, { - img: 'https://images.ecestaticos.com/Xt-KJxmVpvzrqtKT8eEnRNxbcTc=/51x0:1249x899/1200x900/filters:fill(white):format(jpg)/f.elconfidencial.com%2Foriginal%2F9c2%2F2d6%2F83d%2F9c22d683d9536e8961c5d4fe8a2f6f4f.jpg', + img: 'https://i.imgur.com/1jWaZbp.jpg', title: 'Style', author: '@helloimnik', }, { - img: 'https://images-eu.ssl-images-amazon.com/images/G/30/AMAZON-FASHION/2021/FASHION/FEATURE_PAGES/SNEAKERS/MENS/04_C12x.jpg', + img: 'https://i.imgur.com/d864pTb.jpg', title: 'Caña Alta', author: '@nolanissac', }, { - img: 'https://ichef.bbci.co.uk/news/640/cpsprodpb/B9FF/production/_117751674_satan-shoes1.jpg', + img: 'https://i.imgur.com/C4fhmzn.jpg', title: 'Lo último', author: '@hjrc33', }, { - img: 'https://www.clara.es/medio/2019/02/28/zapatillas-negras-vans-85%E2%82%AC_482707a2_1000x1500.jpg', + img: 'https://i.imgur.com/nZGVoea.jpg', title: 'Casual', author: '@arwinneil', featured: true, diff --git a/webapp/src/components/Home/Shoes.tsx b/webapp/src/components/Home/Shoes.tsx index ee70303..d5b7f8c 100644 --- a/webapp/src/components/Home/Shoes.tsx +++ b/webapp/src/components/Home/Shoes.tsx @@ -80,7 +80,7 @@ const ShoesView = (parsed : ProductsParsed) => { refreshProductos(); },[]); function filterFunction(texto: any) { - var filter; + var filter:TypeProduct[]; if(texto==""){ filter=parsed.products; } From d4af6d8943a49f9a0a3f1ae1b41a0fc2113d965f Mon Sep 17 00:00:00 2001 From: Alex Del Gallego Date: Sat, 16 Apr 2022 17:31:40 +0200 Subject: [PATCH 2/3] =?UTF-8?q?A=C3=B1adida=20funcionalidad=20completa=20l?= =?UTF-8?q?ogin=20y=20resueltos=20algunos=20errores=20con=20el=20usuario?= =?UTF-8?q?=20en=20sesi=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- restapi/rutas/usuarioRutas.ts | 13 +++------- webapp/src/api/api.ts | 10 ++++---- .../src/components/Details/RightDetails.tsx | 3 ++- webapp/src/components/Fragments/Nav.tsx | 2 +- webapp/src/components/Login/LoginUsrPsswd.tsx | 25 +++++++++++++------ webapp/src/shared/shareddtypes.ts | 1 - 6 files changed, 30 insertions(+), 24 deletions(-) diff --git a/restapi/rutas/usuarioRutas.ts b/restapi/rutas/usuarioRutas.ts index 51dca5d..dbef0e7 100644 --- a/restapi/rutas/usuarioRutas.ts +++ b/restapi/rutas/usuarioRutas.ts @@ -1,6 +1,7 @@ import express, { Request, Response } from 'express'; import Usuario from '../modelos/usuarioModelo'; import "dotenv/config"; +import {User} from '../../webapp/src/shared/shareddtypes'; //Obtenemos la url de la apirest de Heroku o utilizamos localhost por defecto let URL_BASE:string = `${process.env.API_REST_URL_BASE_LOCAL}` @@ -10,13 +11,7 @@ if(process.env.PORT) { const router = express.Router() -router.get('/users/login/:username/:password', async (req: Request, res: Response) => { - //formato de salida que espera el front-end - type User = { - username: String; - password: String; - } - +router.get('/users/login/:username/:password', async (req: Request, res: Response) => { let resultado:User[] = new Array(); //Parametros const paramUser:string = req.params.username; @@ -26,8 +21,8 @@ router.get('/users/login/:username/:password', async (req: Request, res: Respons if(user){ let entrada = user; let salida: User = ({ username: "", password:""}); - salida.username = entrada.username; - salida.password = entrada.password; + salida.username = entrada.username.toString(); + salida.password = entrada.password.toString(); resultado.push(salida); return res.status(200).send(resultado); } else{ diff --git a/webapp/src/api/api.ts b/webapp/src/api/api.ts index 002a248..f7cda09 100644 --- a/webapp/src/api/api.ts +++ b/webapp/src/api/api.ts @@ -28,13 +28,13 @@ export async function getUsers():Promise{ /* * Metodo que utilizaremos para comprobar si el usuario que intenta logearse, existe en base de datos. */ -export async function loginUser(username : string, password : string): Promise { +export async function getUser(username : string, password : string): Promise { const apiPetition:string = apiEndPoint+'users/login/' + username + '/' + password; const response:Response = await fetch(apiPetition); - let result : Promise = response.json(); - // Si encontramos un usuario con esas credenciales, permitimos el inicio de sesion - console.log(result); - return result!=undefined; + if(response.status == 500) { + return null; + } + return response.json(); } export async function getProducts(): Promise { diff --git a/webapp/src/components/Details/RightDetails.tsx b/webapp/src/components/Details/RightDetails.tsx index e178ec5..85fea8c 100644 --- a/webapp/src/components/Details/RightDetails.tsx +++ b/webapp/src/components/Details/RightDetails.tsx @@ -35,6 +35,7 @@ const RightDetails = (parsed:parsedProduct) => { var newCart:string = cart.substring(0, cart.length-1) + JSON.stringify(item) + ']'; } sessionStorage.setItem('cart', newCart); +/* var usuario:string = sessionStorage.getItem('user') as string; const [nombre,pas]=usuario.split(","); const[u,username]=nombre.split(":") @@ -42,8 +43,8 @@ const RightDetails = (parsed:parsedProduct) => { if(usuario!=undefined){ let item2 = {"username":username,"password":password, "cart":sessionStorage.getItem('cart') as string}; sessionStorage.setItem('user',JSON.stringify(item2)); - var Comprueba:string = sessionStorage.getItem('user') as string; } +*/ alert("Artículo: \"" + parsed.product[0].nombre + "\" añadido al carrito."); } diff --git a/webapp/src/components/Fragments/Nav.tsx b/webapp/src/components/Fragments/Nav.tsx index 574b43c..0fedf1a 100644 --- a/webapp/src/components/Fragments/Nav.tsx +++ b/webapp/src/components/Fragments/Nav.tsx @@ -44,7 +44,7 @@ export default function MenuAppBar() { }; const {session, logout} = useSession(); - const usuario = JSON.parse(sessionStorage.getItem('user') as string); + const usuario = sessionStorage.getItem('user'); return ( diff --git a/webapp/src/components/Login/LoginUsrPsswd.tsx b/webapp/src/components/Login/LoginUsrPsswd.tsx index 61c8ab9..bacd195 100644 --- a/webapp/src/components/Login/LoginUsrPsswd.tsx +++ b/webapp/src/components/Login/LoginUsrPsswd.tsx @@ -9,6 +9,7 @@ import Button from '@material-ui/core/Button'; import { Link, Typography } from "@mui/material"; import Nav from '../Fragments/Nav'; import { User } from '../../shared/shareddtypes'; +import { getUser } from '../../api/api'; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -41,11 +42,22 @@ const Login = () => { const classes = useStyles(); const [userName,setUserName]=useState(""); const [password,setPassword]=useState(""); - - function addUserToSession(){ - //IR A LA BASE DE DATOS - let item = {"username":userName,"password":password, "cart":sessionStorage.getItem('cart') as string}; - sessionStorage.setItem('user',JSON.stringify(item)); + + async function addUserToSession(){ + //Comprobamos los credenciales introducidos en base de datos + var user = (await getUser(userName, password)); + if(user==null){ + // Usuario no encontrado + alert('Credenciales incorrectas.'); + } else { + // Usuario encontrado en base de datos + var parsedUser:User = (user as unknown as Array)[0]; + console.log(parsedUser.username); + // Lo guardamos en sesion (solo el usuario, la contraseña no la necesitamos para nada) + sessionStorage.setItem('user', parsedUser.username); + // Redirigimos a inicio + window.location.href='http://localhost:3000/'; + } } return ( <>