‫-: En esta lección, permitiremos que el usuario
‫que ha iniciado sesión actualmente manipule sus datos de usuario.
‫Y ahora, al implementar actualizaciones de usuarios,
‫realmente estamos dejando el dominio de autenticación y
‫nos estamos moviendo más hacia cosas relacionadas con usuarios reales, ¿de acuerdo?
‫Entonces, en lugar de usar el controlador de
‫autenticación ahora, implementemos esta funcionalidad de actualización
‫directamente en su userController.
‫Bien, tenemos
‫un montón de controladores, así que
‫rutas, que no están realmente implementadas aquí, ¿de acuerdo?
‫Pero dejémoslos de lado por
‫ahora y creemos nuestra nueva función de controlador aquí.
‫Y este se llamará updateMe.
‫Y nuevamente, es updateMe porque es para actualizar
‫el usuario actualmente autenticado.
‫Más adelante, también implementaremos esta función
‫updateUser aquí, pero eso es para que, como un administrador,
‫actualice todos los datos del usuario, mientras que el usuario
‫solo puede actualizar, al menos por ahora, el nombre y la
‫dirección de correo electrónico.
‫Entonces, solicitud, respuesta y siguiente.
‫(chasquido del teclado) Y en realidad estamos haciendo esto,
‫así que actualizamos los datos del usuario, en una ruta
‫diferente a la actualización de la contraseña del usuario, bueno,
‫porque generalmente en una aplicación web típica siempre es
‫así como se hace.
‫Por lo tanto, generalmente tiene
‫un lugar donde puede actualizar su
‫contraseña y luego otro lugar donde puede actualizar
‫los datos sobre el usuario o la cuenta en sí.
‫Y aquí, básicamente, estamos siguiendo ese patrón.
‫Entonces, nuevamente, comencemos por establecer nuestros pasos.
‫Y lo primero que queremos
‫hacer aquí es básicamente crear un
‫error si el usuario intenta actualizar la contraseña.
‫Por lo tanto, cree un error si el usuario
‫publica básicamente datos de contraseña.
‫Pero si no es así, simplemente tenemos que actualizar el documento de usuario.
‫Es bastante simple y, por supuesto, comencemos con
‫el primero.
‫Por supuesto, habrá un
‫cuerpo donde pasaremos los datos,
‫y si en ese cuerpo hay datos sobre la contraseña,
‫o una contraseña, confirme ...
‫(llaves tintineando) Confirmar.
‫Bueno, en ese caso, queremos volver de inmediato y
‫crear un nuevo Apperror.
‫Ah, y supongo que todavía no lo implementamos aquí, o
‫realmente lo requerimos, así
‫que vamos a tomarlo de aquí.
‫Entonces AppError ...
‫No está aquí,
‫por lo que el userController ...
‫Así que AppError, aquí vamos.
‫Entonces 'Esta ruta no es para actualizaciones de contraseñas.
‫'Por favor use / updateMYPassword. Básicamente, la
‫ruta que especificamos antes.
‫Así que actualiceMYPassword.
‫Y luego también, un código 400 para una mala solicitud.
‫Y probemos este de inmediato.
‫Y para eso, solo
‫dos cosas, primero tenemos que enviar
‫una respuesta, así que digamos res. status (200) para okay, y
‫luego json,
‫agregue el status como éxito.
‫Y luego también enviaremos el usuario actualizado, pero
‫dejémoslo para más adelante.
‫Así que esa es la respuesta, y ahora,
‫por supuesto, también debemos agregar esta ruta a nuestro enrutador de usuario.
‫Por supuesto, eso es similar a actualizar mi contraseña,
‫por lo que el enrutador y, por supuesto, un
‫parche,
‫/ updateMe, nuevamente, es una ruta protegida,
‫por lo que solo el usuario actualmente autenticado puede actualizar los
‫datos del usuario actual.
‫Y todo esto, por supuesto, es realmente seguro,
‫nuevamente porque la identificación del usuario que se actualizará proviene
‫de la solicitud. usuario, que
‫fue configurado por este middleware de protección aquí, que a su
‫vez tomó la idea del token web json, y
‫dado que nadie puede cambiar la ID en ese
‫token web json sin conocer el secreto,
‫sabemos que la ID es segura por eso.
‫Y por eso, aquí todo está seguro.
‫Entonces, userController. Ponme al día.
‫Ahora bien...
‫Así que probemos esto ahora.
‫Continúe y copie esto de nuevo.
‫Y antes que nada, configuremos la autorización.
‫Nuevamente del Bearer Token y, por supuesto, con
‫esta variable de entorno.
‫También debe ser una solicitud de parche
‫y debemos especificar un cuerpo.
‫Y quiero comenzar probándolo, causando este
‫error, por supuesto, así que
‫especifiquemos una contraseña y
‫luego un nombre.
‫Entonces, digamos que este es el nombre que queremos actualizar, así
‫que guardemos esto aquí.
‫Y, por supuesto, está en la carpeta Usuarios.
‫Datos del usuario.
‫Y de hecho creemos una nueva
‫carpeta aquí y coloquemos las cosas relacionadas con la autenticación
‫en su propia carpeta.
‫Entonces aquí arriba, creamos
‫una nueva carpeta y la llamamos Autenticación.
‫Eso no es correcto.
‫AH-ENTONCES-TICACIÓN.
‫(se ríe) Así que eso es todo.
‫Y así, la contraseña está relacionada con la autenticación,
‫también con el restablecimiento de la contraseña, el olvido de la contraseña, el inicio
‫de sesión y el cierre de sesión.
‫Entonces, cerremos estos dos y ahora
‫inicie sesión como, o en realidad
‫creemos un nuevo usuario.
‫Así que registremos aquí,
‫como un usuario normal, para que podamos deshacernos de estos dos aquí.
‫Y ahora simplemente lo llamo, bueno, prueba de nuevo, ¿de acuerdo?
‫Y echemos un vistazo a los usuarios que tenemos actualmente
‫en nuestra base de datos.
‫Tenemos hello y
‫admin, y ahora usemos test.
‫Y siempre vuelvo a usar la misma contraseña
‫para que sea realmente fácil.
‫Muy bien, también necesitamos dar el nombre, llamémoslo
‫J aquí.
‫Y ahora, de hecho, obtenemos nuestro token, y ya
‫hemos iniciado sesión, por lo
‫que ahora, cuando actualizamos el usuario, eso
‫debería ser para este usuario que acaba de iniciar sesión.
‫Así que no estoy tratando de actualizar y,
‫por supuesto, aún no se ha implementado ninguna actualización, por lo que no funcionará.
‫Todo lo que quiero ver es el error
‫que debería ocurrir porque especifiqué esta propiedad de contraseña aquí en el cuerpo.
‫Así que probémoslo.
‫Y aquí obtenemos este tipo de error de aspecto extraño,
‫pero supongo que es simplemente porque en realidad
‫no actualizamos la ruta
‫aquí, así que recuerde que solo copié una ruta, entonces la
‫URL, y la pegué aquí.
‫Pero, por supuesto, necesita ser updateME.
‫Intentémoslo de nuevo.
‫Y ahora, de hecho, obtenemos el error que especificamos.
‫"Esta ruta no es para actualizaciones de contraseñas.
‫"Utilice / updateMyPassowrd. "Muy bien,
‫esa parte está funcionando y
‫también está funcionando que necesitamos estar autenticados.
‫Porque digamos que no tenemos autenticación, y entonces
‫digamos que: No Auth.
‫Intentémoslo de nuevo ahora.
‫Y así, de hecho, "¡No ha iniciado sesión!
‫"Inicie sesión para obtener acceso. "Así que
‫solo para demostrarle que nuestra autenticación también
‫está haciendo su trabajo aquí.
‫Pero, por supuesto, queremos nuestro Bearer
‫Token, y ahora obtenemos ese otro error.
‫Genial, ahora vamos a implementar
‫el resto de la funcionalidad para el controlador updateMe.
‫Así que actualizando el documento de usuario, podríamos
‫intentar hacerlo con user. a salvo.
‫Así que, al igual que antes, básicamente hacer que
‫el usuario actualice las propiedades y, al
‫final, guardar el documento.
‫Pero el problema con eso es que hay
‫algunos campos que son obligatorios y que no estamos
‫actualizando, y luego,
‫debido a eso, tendremos algún error.
‫Y para demostrártelo rápidamente, déjame
‫hacer eso.
‫Bien, muy rápido, trayendo al usuario aquí.
‫Así que findbyId, así que solicítalo. usuario como ya sabemos,. identificación.
‫Y luego digamos, usuario. name = 'Jonas' y luego esperar
‫al usuario. ahorrar.
‫Pero nuevamente ves que esto nos dará un error entonces.
‫Pero por ahora, por supuesto, también vamos a
‫declararlo como una función asíncrona.
‫Y esta bien.
‫Así que probémoslo
‫ahora, pero deberíamos esperar ver un error ahora.
‫Así que, por supuesto, eliminemos
‫este, y de hecho obtenemos: "Por favor, confirme su contraseña".
‫Y eso es porque passwordConfirm es un campo obligatorio pero,
‫por supuesto, no lo especificamos.
‫Por tanto, el método seguro no es realmente la
‫opción correcta en este caso.
‫Entonces, en cambio, lo
‫que podemos hacer ahora es usar findById y actualizar.
‫Así que no podíamos usar eso antes por todas las
‫razones que ya te expliqué varias veces.
‫Pero ahora, dado que no estamos
‫tratando con contraseñas, sino solo con estos datos no confidenciales como el
‫nombre o el correo electrónico, ahora podemos usar findById y actualizar.
‫Entonces, deshagámonos de esto.
‫Llamémoslo también aquí updatedUser.
‫Y luego aquí, debemos pasar no solo la identificación,
‫sino también los datos que deben actualizarse,
‫y luego algunas opciones.
‫Entonces, los datos, por ahora llamémoslos x aquí, y les
‫diré por qué en
‫un segundo, y luego las opciones que queremos pasar.
‫Y así es como antes,
‫la nueva opción establecida en verdadera, de modo que
‫devuelve el nuevo objeto,
‫básicamente el objeto actualizado en lugar del anterior.
‫Y los también runValidators establecidos en true.
‫Porque de hecho queremos que los modelos validen nuestro documento.
‫Entonces, por ejemplo, si ingresamos una dirección de correo electrónico no
‫válida, el Validador debería detectarla y devolver un error.
‫Ahora, ¿por qué estoy poniendo x aquí, y no simplemente solicitando. ¿cuerpo?
‫Bueno, eso es porque en realidad no queremos
‫actualizar todo lo que hay en el cuerpo,
‫porque digamos que el usuario pone, en el cuerpo, el
‫rol, por ejemplo.
‫Podríamos tener cuerpo. rol establecido en admin, por
‫ejemplo, y entonces esto permitiría a cualquier
‫usuario cambiar el rol, por ejemplo, a administrador.
‫Y, por supuesto, eso no se puede permitir.
‫O el usuario también podría cambiar su token de
‫reinicio, o cuando ese token de reinicio
‫caduque, y todo eso no debería estar permitido, por supuesto.
‫Entonces, hacer algo como esto, por
‫supuesto, sería un gran error.
‫Y entonces debemos asegurarnos de que el
‫objeto que pasamos aquí, nuevamente
‫ese objeto que contendrá los datos que se actualizarán,
‫solo contenga el
‫nombre y el correo electrónico, porque por ahora
‫estos son los únicos campos que queremos
‫permitir que se actualicen .
‫Básicamente, queremos filtrar el cuerpo para que,
‫al final, solo contenga el nombre y el correo electrónico
‫y nada más.
‫Entonces, si el usuario intenta cambiar el rol,
‫se filtrará para
‫que nunca llegue a nuestra base de datos.
‫Entonces, lo que queremos hacer es básicamente crear una variable
‫y digamos filterBody,
‫y luego crearemos la función en un segundo, pero ya la
‫usaremos aquí, solo para que veas
‫cómo va a funcionar.
‫Y luego aquí pasamos
‫los datos, por lo que el objeto que
‫queremos filtrar, por lo que req. body, porque ahí es donde están todos
‫los datos, y luego pasamos un par de argumentos.
‫Uno para cada uno de los campos que queramos mantener
‫en el objeto.
‫Así que queremos mantener el campo llamado nombre
‫y el campo llamado correo electrónico.
‫Y nuevamente, un poco más tarde, podríamos agregar más campos aquí,
‫por ejemplo, más adelante podríamos permitir que
‫el usuario cargue una imagen.
‫Y, por supuesto, también necesitamos actualizar en la
‫base de datos.
‫Pero por ahora, todo lo que
‫queremos mantener en el cuerpo es el nombre y el correo electrónico y filtrar el resto.
‫Y aquí, usemos filterBody, en lugar
‫de x, por supuesto.
‫Y ahora lo que tenemos que hacer
‫es implementar esta función que se encargará de filtrar el objeto.
‫Así que hagámoslo aquí.
‫FilterObj,
‫que tomará un objeto y luego
‫el resto de parámetros para todos los campos permitidos.
‫Y entonces esto básicamente creará
‫una matriz que contiene todos los argumentos que pasamos.
‫Básicamente, eso se pasó después de este primero.
‫Entonces, en ese caso, es una matriz que contiene el nombre y el correo electrónico.
‫Entonces, lo que tenemos que
‫hacer ahora es básicamente recorrer el objeto y, para cada elemento, verificar
‫si es uno de los campos
‫permitidos, y si lo es, simplemente agregarlo a un nuevo
‫objeto, que luego regresaremos al final. .
‫Y probablemente hay mejores formas más eficientes
‫de implementar esto,
‫pero hagámoslo muy rápido aquí.
‫Así que vamos a hacer
‫un bucle del objeto diciendo Object. claves del objeto que pasamos.
‫Esa es una de las formas fáciles de
‫recorrer un objeto en JavaScript.
‫Entonces, esto aquí básicamente devuelve una matriz que contiene todos
‫los nombres de clave, por
‫lo que los nombres de campo de
‫este objeto, y luego podemos recorrerlos.
‫Entonces nuestra función de devolución de llamada.
‫Y para cada elemento, esto es lo que haremos.
‫Entonces, si la matriz de campos permitidos incluye
‫el elemento actual, entonces el nombre del campo actual, entonces queremos agregar
‫eso a un nuevo objeto.
‫Así que creemos rápidamente ese aquí,
‫entonces const newObj que está vacío por ahora,
‫y al final,
‫ese es el que vamos a devolver.
‫Tan nuevoObj.
‫Entonces, si el campo actual es uno de los campos
‫permitidos, entonces newObj con el nombre de campo del campo actual, debería ser igual a
‫lo que esté en el objeto en el elemento actual, por
‫lo que el nombre del campo actual.
‫Así que no lo hagas si esto
‫parece un poco confuso, esto es nuevamente solo
‫JavaScript estándar, no tiene nada que ver con JS o eXpress o algo
‫por el estilo.
‫Entonces, nuevamente, todo lo que hacemos aquí es básicamente recorrer
‫todos los campos que están en el objeto y
‫luego, para cada campo, verificamos
‫si es uno de los campos permitidos.
‫Y si es así, entonces creamos un nuevo campo en el nuevo objeto,
‫por supuesto con el
‫mismo nombre, por lo que aún nombre del elemento, con el
‫mismo valor exacto que tiene en el objeto original.
‫Y luego, al final, por supuesto, devolvemos ese.
‫Y entonces todo esto debería estar funcionando ahora aquí.
‫Entonces, todo lo que tenemos que
‫hacer al final es enviar ese usuario actualizado al cliente.
‫Entonces, usuario.
‫Ahora, por supuesto, tenemos que poner el udatedUser aquí,
‫guardarlo de nuevo, y ahora debería funcionar.
‫Realmente lo que hicimos aquí fue ...
‫Actualizamos al usuario por
‫último, y antes de hacerlo, en realidad filtramos los
‫nombres de campo no deseados que no pueden actualizarse.
‫Intentémoslo ahora.
‫Y este usuario aquí es un usuario regular, así que lo acabamos
‫de crear, recuerda
‫con el nombre de J.
‫Entonces, echemos un vistazo rápido a Compass.
‫Entonces es un usuario normal, con un nombre de J.
‫Así que ahora actualicemos
‫el nombre y también intentemos actualizar el rol,
‫que de nuevo no está permitido.
‫Pero para ver si nuestro código funciona, intentémoslo.
‫Así que ya existe el nombre, y digamos que
‫somos un usuario
‫malintencionado que intenta cambiar nuestro rol a administrador.
‫Entonces, todo está correcto, supongo, así
‫que enviemos esto ahora,
‫y de hecho aquí está nuestro objeto actualizado.
‫Entonces obtenemos nuestro nuevo nombre, que es Jonas Schmedtmann, y
‫luego el rol, que sigue siendo usuario.
‫No actualizó el rol a administrador.
‫Perfecto. Eso es exactamente lo que queríamos.
‫Entonces, guarde esto y regresemos y, de hecho,
‫acabamos de terminar este video.
‫A continuación, implementaremos una funcionalidad para
‫eliminar el usuario actual.
‫Así que trabajamos en la actualización, a continuación queremos permitir que un
‫usuario se elimine básicamente a sí mismo cuando ya no
‫quiera ser parte de nuestra aplicación.