Aula 27 - Implementação da Funcionalidade Redefinir Senha

Links da Aula:

Código da Aula MailHog

Introdução

Nesta aula, iremos implementar a funcionalidade de redefinição de senha para o nosso aplicativo, que foi inicialmente abordada na aula anterior com a funcionalidade de recuperação de senha. Vamos criar o componente Reset em React e integrá-lo ao backend em Golang usando o framework Fiber.

1. Criação do Componente Reset.tsx

O componente Reset.tsx será responsável por permitir que o usuário defina uma nova senha, utilizando o token de recuperação que foi enviado por email.
  • Formulário de Redefinição: O formulário conterá dois campos: um para a nova senha e outro para a confirmação da senha. Ambos os campos serão validados no frontend antes de serem enviados ao backend.
  • Integração com Token: O token de recuperação será capturado dos parâmetros da URL e enviado ao backend junto com a nova senha.
  • Redirecionamento após Sucesso: Após a redefinição bem-sucedida da senha, o usuário será redirecionado para a página de login.

src/pages/Reset.tsx


import React, { useState, SyntheticEvent } from 'react';
import axios from 'axios';
import { Navigate, useParams } from 'react-router-dom';

const Reset = () => {
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [redirect, setRedirect] = useState(false);
  const { token } = useParams<{ token: string }>();

  const submit = async (e: SyntheticEvent) => {
    e.preventDefault();

    if (password !== confirmPassword) {
      console.error('Passwords do not match!');
      return;
    }

    try {
      // Use a consistent base URL, defined as an environment variable or fallback to localhostt
      const apiURL = process.env.REACT_APP_API_URL || 'http://localhost:3001';

      // Make a POST request to the /api/reset route with the necessary data
      await axios.post(`${apiURL}/api/reset`, {
        token,
        password,
        confirm_password: confirmPassword,
      });

      setRedirect(true);
    } catch (e: any) {
      console.error('Failed to reset password:', e.response?.data || e.message);
    }
  };

  // Redirect to the login page if the password reset is successful
  if (redirect) {
    return <Navigate to="/login" />;
  }

  return (
    <form className="form-floating" onSubmit={submit}>
      <h1 className="h3 mb-3 font-weight-normal">Reset your password</h1>
      <div className="form-signin">
        <input
          type="password"
          className="form-control mb-3"
          placeholder="New Password"
          required
          onChange={e => setPassword(e.target.value)}
        />
      </div>
      <div className="form-signin">
        <input
          type="password"
          className="form-control mb-3"
          placeholder="Confirm Password"
          required
          onChange={e => setConfirmPassword(e.target.value)}
        />
      </div>
      <button className="form-signin btn btn-primary w-100 py-2" type="submit">
        Reset Password
      </button>
      <p className="mt-5 mb-3 text-body-secondary">© 2017–2024</p>
    </form>
  );
};

export default Reset;

2. Configuração de Rotas no App.tsx

  • Importação do Componente Reset:
    • Foi adicionada a importação do componente Reset no topo do arquivo: import Reset from "./pages/Reset";
    • Este componente será usado para lidar com a funcionalidade de redefinição de senha, geralmente acessada através de um link enviado por e-mail contendo um token.
  • Adição da Rota /reset/:token:
    • Uma nova rota foi adicionada para a página de redefinição de senha:
      javascript
      <Route path="/reset/:token" element={<Reset />} />
    • Esta rota permite que o usuário acesse a página de redefinição de senha. O :token na URL é um parâmetro dinâmico que captura o token enviado ao usuário para verificar e permitir a redefinição da senha.
As alterações estão em azul.

src/App.tsx

import React, { useState, useEffect } from "react";
import axios from "axios";
import "./App.css";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Login from "./pages/Login";
import Home from "./pages/Home";
import Register from "./pages/Register";
import Forgot from "./pages/Forgot";
import Nav from "./components/Nav";
import Reset from "./pages/Reset";

function App() {
  const [user, setUser] = useState(null); // State to store user data
  const [login, setLogin] = useState(false);

  useEffect(() => {
    (async () => {
      try {
        const response = await axios.get("user");
        const user = response.data;
        setUser(user);// Update the state with user data
      } catch (e) {
        console.error("Error loading user data", e);
        setUser(null); // Sets the user to null in case of error
      }
    })();
  }, [login]);

  return (
    <div className="App">
      <Router>
        <Nav user={user} setLogin={ () => setLogin(false) }/>
        <Routes>

          <Route path="/login" element={<Login setLogin={() => setLogin(true)} />} />
          <Route path="/register" element={<Register />} />
          <Route path="/forgot" element={<Forgot />} />
          <Route path="/reset/:token" element={<Reset />} />

          {/* Protected route that requires authentication */}
          <Route path="/" element={<Home user={user} />} />
        </Routes>
      </Router>
    </div>
  );
}

export default App;

3. Testando a Feature "Reset Password" com MailHog

Para garantir que a funcionalidade "Reset Password" funcione corretamente, podemos utilizar o MailHog para emular um serviço de email durante nossos testes, assim como fizemos na aula anterior.

Passos para Testar a Feature "Reset Password":

Inicie o MailHog e acesse: localhost:8025
  1. Com o MailHog em execução, acesse a página de "Reset Password" usando o link fornecido no email de recuperação.
  2. Insira a nova senha e a confirmação da senha.
  3. Envie o formulário e verifique se o redirecionamento para a página de login ocorre corretamente.
  4. Tente fazer login com a nova senha para confirmar que a redefinição foi bem-sucedida.

Conclusão

Parabéns por concluir a aula de hoje sobre a implementação da funcionalidade "Reset Password"! Agora você tem uma aplicação completa com as funcionalidades de recuperação e redefinição de senha, integradas com um backend em Golang e testadas utilizando o MailHog.

O que foi abordado:

  • Criação do componente de redefinição de senha.
  • Integração do frontend com o backend usando Axios.
  • Testes da funcionalidade de redefinição de senha utilizando o MailHog.
Com isso, posso considerar esse tutorial finalizado, mas, provavelmente farei mais algumas aulas ainda, dedicada a fazer o deploy desse 2 projetos, o de backend com golang/fiber e o frontend com react, com o mysql como o banco de dados. Acredito que essas aulas serão postada nesse tutorial e também no de Kubernates, na aba DevOps, porque o plano é fazer o deploy usando containers Docker em um cluster K8S, usando Terraform.

Nos vemos em breve em outros tutoriais!

Valeu, ;) \o/