‫-: Entonces, en los últimos videos,
‫permitimos a un usuario restablecer su contraseña y
‫luego crear una nueva, pero
‫ahora también queremos
‫permitir que un usuario que inició sesión simplemente actualice
‫su contraseña sin tener que olvidarla,
‫y así sin todo ese proceso de reinicio.
‫Entonces, construyamos eso ahora.
‫Y, como
‫antes, hagámoslo en nuestro controlador de autenticación.
‫Entonces, exportar. Actualiza contraseña.
‫Está bien, y así, como siempre,
‫aquí nuestros tres parámetros de Middleware, y está bien.
‫Ahora recuerde que esta funcionalidad de actualización de contraseña
‫es solo para usuarios registrados,
‫pero aún necesitamos que el usuario ingrese su contraseña actual,
‫para confirmar que
‫el usuario realmente es quien dice ser.
‫Por lo tanto, solo como medida
‫de seguridad, imagine que alguien encontraría su computadora abierta y
‫luego podría cambiar las contraseñas en los sitios que
‫tiene abiertos actualmente
‫sin que se le solicite una contraseña nuevamente.
‫Y eso básicamente lo desconectaría
‫de todas sus aplicaciones existentes, lo que,
‫por supuesto, sería una experiencia terrible.
‫Entonces, como medida de seguridad, siempre
‫debemos pedir la contraseña actual antes de actualizarla, de acuerdo.
‫Y, con eso en mente, expongamos
‫todos los pasos que
‫debemos seguir para implementar esta funcionalidad como antes.
‫Entonces, primero, necesitamos obtener el usuario
‫de la colección, básicamente.
‫Luego, en segundo lugar, debemos
‫verificar si la contraseña publicada es correcta.
‫Derecha.
‫Luego, tercero, si la contraseña es
‫correcta, actualice la contraseña.
‫Y finalmente, tenemos que volver a iniciar la sesión
‫del usuario, así que básicamente para enviar el jsonwebtoken al usuario, que
‫ahora inició sesión con la nueva contraseña que se acaba de actualizar.
‫De acuerdo, y en realidad todo esto es muy
‫similar a lo que
‫hicimos antes, así que te dejo
‫este como un desafío, ¿de acuerdo?
‫Entonces, intente seguir adelante e implementar esto por su cuenta, y
‫si lo necesita, por supuesto, puede echar un vistazo
‫al código que escribimos
‫antes, pero realmente intente escribir el código por su
‫cuenta sin copiar demasiado, de acuerdo. ?
‫Entonces, puede echar un vistazo al resto del
‫código para ver cómo funciona, pero luego no lo copie, ¿de acuerdo?
‫Porque entonces no vas a aprender realmente, de acuerdo.
‫Entonces, pausa el video aquí, y te veré en un
‫segundo con mi solución.
‫Bien, entonces esperaba que lograras implementar esto
‫y hacerlo funcionar, así es como lo hice.
‫Entonces, como siempre, creamos una nueva variable de usuario, y allí
‫esperamos el resultado de hacer User. findById, y ahora,
‫¿de dónde proviene realmente esta identificación?
‫Bueno, recuerde nuevamente que esta contraseña de actualización es solo para
‫usuarios autenticados, por lo tanto, para usuarios registrados y, por
‫lo tanto, en este punto, ya tendremos el usuario
‫actual en nuestro objeto de solicitud.
‫Bien, eso viene de la protección Middleware.
‫Entonces, req. usuario. id, y
‫luego recuerde que debemos pedir explícitamente la contraseña, ¿de acuerdo?
‫Porque, de forma predeterminada, no se incluye en la salida.
‫Entonces, lo definimos en el esquema, ¿recuerdas?
‫Y, de hecho, necesitamos esa
‫contraseña porque ahora queremos compararla con la que está
‫almacenada en la base de
‫datos, y para eso,
‫al igual que antes, usaremos este objeto de instancia que
‫tenemos en algún lugar aquí.
‫Sí, tan correctPassword, que está disponible en todos
‫los documentos del usuario,
‫por lo que primero se incluye la
‫contraseña del candidato y luego la contraseña del usuario real, de acuerdo.
‫Ah, y ahora me
‫está dando este error porque, por supuesto, todavía no
‫lo he declarado como una función asíncrona.
‫Entonces, async, y antes de que
‫lo olvidemos, envuémoslo aquí también en la función catchAsync.
‫De todos modos, al
‫igual que antes, básicamente queremos crear un
‫error aquí si la contraseña actual no es correcta,
‫así que escribamos eso en código.
‫Entonces, si no usuario. correctPassword, y
‫luego la contraseña del candidato,
‫recuerde, por lo que uno
‫estará en un cuerpo, en una propiedad que llamaremos passwordConfirm.
‫De acuerdo, y luego, como segundo argumento, la contraseña real, es
‫un usuario. contraseña.
‫Y luego, recuerde que esta es una función asincrónica,
‫por lo que también debemos esperarla aquí.
‫Bien, así que en caso de que la contraseña no
‫sea correcta, como siempre, creamos un nuevo error aquí.
‫Entonces, nuevo AppError, y esta vez decimos
‫que su contraseña actual es incorrecta, y luego
‫el código de estado 401 para no autorizado.
‫Está bien, genial.
‫Ahora, si llegamos a este punto
‫en el código, entonces básicamente si la contraseña también
‫es correcta, entonces podemos actualizar la contraseña,
‫y ¿cómo lo hacemos?
‫Bueno, muy simple, lo hicimos antes.
‫Todo lo que decimos es usuario. contraseña es igual a req. cuerpo. contraseña, y
‫luego lo mismo, por supuesto, para confirmar la contraseña.
‫De acuerdo, y la validación la realizará automáticamente el
‫validador que especificamos en el esquema, y eso se hará
‫una vez que lo guardemos.
‫Entonces, esperamos user. save, por lo
‫que esta vez no desactivamos la
‫validación porque, por supuesto, queremos que suceda, así
‫que como dije antes, queremos verificar que
‫la contraseña de confirmación sea la
‫misma que la contraseña, ¿verdad?
‫Bueno.
‫Y, ahora solo para asegurarnos de que comprende por qué
‫no hicimos algo como usuario. findByIdAndUpdate.
‫Entonces, ¿por qué no lo hicimos así?
‫Y sé que hablé de esto muchas veces antes,
‫pero quiero que comprendan al cien por cien por
‫qué no podemos usar esta actualización, y es
‫por dos razones,
‫así que permítanme volver a nuestro modelo.
‫Entonces, el primero
‫es que esta validación aquí no va a funcionar, ¿de acuerdo?
‫Y eso es básicamente porque esto. La contraseña no está
‫definida cuando actualizamos, por lo tanto, cuando usamos buscar por ID y actualizar,
‫porque internamente, detrás de escena, Mongoose
‫realmente no mantiene el objeto actual en la memoria y, por
‫lo tanto, esto aquí no va a funcionar.
‫Y, como dije, ya hablé de eso antes,
‫así que en realidad también está escrito aquí, ¿de acuerdo?
‫Pero, es muy importante tener en cuenta que
‫no usar la actualización para nada relacionado con las contraseñas, ¿de acuerdo?
‫Entonces, este no
‫va a funcionar, y además, estos
‫dos Middlewares pre-guardados tampoco van a funcionar.
‫Entonces, si usamos simplemente actualizar para actualizar la
‫contraseña, entonces esa contraseña no estaría encriptada, cuál
‫es este primer
‫Middleware, y luego también, la marca
‫de tiempo passwordChangedAt tampoco se establecería, ¿de acuerdo?
‫Entonces, nada de esto
‫funcionaría, y nuevamente, realmente necesitamos hacerlo así.
‫Pongamos eso aquí de nuevo.
‫Y ahora, (murmura), iniciamos la sesión del
‫usuario y le enviamos el token al cliente.
‫Ahora, esa sería la cuarta vez que
‫hicimos el mismo código, así que
‫básicamente este fragmento de código,
‫y eso es ahora muy rápidamente refactorizar esto
‫en su propia función.
‫Ahora bien, este código en realidad no es el mismo en todas partes.
‫Entonces, aquí enviamos el código de estado
‫400 y no enviamos
‫al usuario, pero aquí en el controlador de registro, en realidad
‫tenemos un código de estado diferente
‫y también enviamos el usuario al cliente, ¿de acuerdo?
‫Entonces, hagamos que nuestra función tenga eso en cuenta.
‫Entonces, creemos una función aquí, creemos y enviemos un token,
‫y luego los argumentos que necesitamos
‫aquí son el usuario porque ahí es
‫donde se almacena la ID.
‫Entonces, también queremos el
‫código de estado y, por supuesto, necesitamos tener acceso
‫al objeto de respuesta para poder enviar
‫una respuesta al cliente, ¿de acuerdo?
‫Entonces, básicamente ahora lo que necesitamos es este código.
‫Entonces, copiemos, pongámoslo aquí
‫y luego reemplacemos las variables irrelevantes.
‫Entonces, el usuario simplemente se llama usuario, así que
‫así, y aquí, lo mismo.
‫Entonces, no
‫es un usuario nuevo, y luego lo reemplazamos con el código
‫de estado, por lo que el que está entrando en
‫nuestra función, y supongo que eso es todo.
‫Entonces, sigamos adelante y reemplácelo, así que
‫createSendToken, y aquí el usuario se llama newUser, el código de estado
‫es 201, y
‫luego, por supuesto, el objeto de respuesta.
‫Bien, ahora podemos deshacernos de este código
‫y simplemente copiemos.
‫Muy bien, en el inicio de sesión, por supuesto, también enviamos un
‫token, pero esta vez el usuario se llama realmente usuario y el código
‫de estado es 200.
‫Y ahora, copiemos este.
‫Entonces, el siguiente debería estar aquí y restablecer la contraseña, y
‫aquí es realmente el
‫mismo, por lo que el nombre es usuario
‫y código 200, y ahora, finalmente, aquí también es el mismo.
‫Y así, termina nuestra función de actualización de contraseña.
‫Ahora, para que esto funcione,
‫por supuesto, necesitamos implementar la ruta aquí también en nuestro
‫enrutador de usuario.
‫Entonces, enrutador. parche, y haremos un parche
‫porque en realidad estamos cambiando, por lo que estamos
‫manipulando el documento del usuario, y para eso es el parche.
‫Y la ruta se llama updateMyPassword.
‫Entonces, mi contraseña
‫es para el usuario que ha iniciado sesión actualmente, y luego
‫recuerde, nuevamente, esto solo funciona para usuarios
‫registrados, por lo que debemos usar authController. proteger, que luego también colocará
‫el objeto de usuario
‫en un objeto de solicitud, ¿de acuerdo?
‫Entonces, proteja, y luego authController actualice la contraseña
‫que acabamos de crear, de acuerdo.
‫Y entonces, vayamos ahora y probemos esto, ¿de acuerdo?
‫Entonces, copiemos esta ruta aquí, entonces UpdateMyPassword,
‫y ahora lo que
‫necesitamos enviar en el cuerpo son estas tres contraseñas en
‫realidad, así que es
‫básicamente la contraseña actual, y por ahora las dejo
‫vacías, simplemente quiero
‫poner el campo nombres aquí por ahora.
‫Entonces, passwordCurrent luego solo password, que es básicamente
‫la nueva,
‫y luego, por supuesto, passwordConfirm.
‫De acuerdo, y ahora necesitamos iniciar sesión como usuario
‫porque recuerde, esto solo funciona si
‫el usuario ya ha iniciado sesión, de acuerdo.
‫Entonces, hagámoslo con el administrador aquí.
‫Y esta debe ser la contraseña actual y,
‫de hecho, ya estamos conectados.
‫Y recuerde que este token ahora se
‫almacena en la variable de
‫entorno JWT, por lo que aquí,
‫para autenticarnos, usemos eso como lo hicimos antes.
‫Entonces, en esta pestaña de autorización, seleccionamos Bearer Token,
‫y luego automáticamente completará automáticamente
‫esta variable JWT.
‫Muy bien, y de ahí es de
‫donde vendrá realmente la ID de usuario, ¿recuerdas?
‫De todos modos, ahora especifiquemos la contraseña actual, entonces pass1234, y luego
‫digamos nueva contraseña, ¿de acuerdo?
‫Cópielo y péguelo
‫aquí, pero en realidad, nuevamente, quiero
‫comenzar probándolo con una confirmación de contraseña
‫incorrecta, solo para ver si nuestra validación
‫sigue funcionando, y ahora la ruta no está
‫definida, pero eso es simplemente porque estamos usando el verbo equivocado aquí.
‫Por supuesto, debe ser parcheado.
‫Intentémoslo de nuevo, pero ahora
‫sabemos que su contraseña actual es incorrecta, pero en realidad no
‫lo es, por lo que en realidad es correcta.
‫Entonces, algo debe estar mal con nuestro código, así que
‫intentemos echarle un vistazo aquí.
‫Y sí, aquí está
‫el problema porque no queremos comparar o confirmar la contraseña,
‫por supuesto, sino con la contraseña actual.
‫De acuerdo, eso es solo un error estúpido, de acuerdo, y
‫ahora debería estar funcionando.
‫Entonces, por supuesto, queremos comparar la contraseña actual con
‫la que está almacenada
‫actualmente en la base de datos, de acuerdo.
‫Entonces, intentémoslo de
‫nuevo, y ese es el error de validación que
‫estábamos buscando, entonces las contraseñas no
‫son las mismas porque, de hecho, no lo son.
‫Y ahora, antes de actualizar la contraseña, echemos
‫un vistazo a Compass aquí.
‫Actualicémoslo aquí rápidamente, así que,
‫ahora mismo, esta es la contraseña.
‫Entonces, terminar aquí es pW1i, ¿de acuerdo?
‫Entonces, actualice la contraseña
‫ahora y veamos cómo se verá después, ¿de acuerdo?
‫Entonces, ahora todo debería estar correcto.
‫Y, de hecho, obtenemos nuestro éxito y nuestro token, de acuerdo.
‫Entonces, confirmemos eso aquí rápidamente, y, de hecho,
‫ves que la contraseña cambió y también la
‫marca de tiempo actual, por lo
‫que básicamente es el momento en el que estoy grabando este video.
‫Muy bien, y ahora, como antes,
‫hagamos esta prueba aquí.
‫Entonces, básicamente, almacenar el token como una variable de entorno.
‫Entonces, para que todo funcione realmente aquí en Postman.
‫Bien, guardemos eso en realidad,
‫actualice la contraseña del usuario actual para que sea realmente explícita,
‫y sí, creo que eso es todo.
‫Creo que esto es todo lo que necesitamos hacer
‫para actualizar la contraseña de un usuario.
‫A continuación, implementaremos la actualización de otros datos de usuario,
‫por ejemplo, correo electrónico o contraseñas.