‫Instrutor: Portanto, agora precisamos
‫enviar o token de redefinição de senha por e-mail para o usuário.
‫E então, nesta aula, vamos
‫aprender como enviar e-mail usando uma solução muito
‫popular chamada Nodemailer.
‫Mas antes de fazermos isso, eu realmente queria
‫mostrar a vocês o efeito de não ter essa opção aqui,
‫porque na verdade eu nunca mostrei a vocês antes.
‫Então, vamos cortar aqui, tente agora, novamente, e
‫agora você verá todos esses erros surgindo,
‫como confirme sua senha.
‫E, na verdade, deveria haver mais,
‫mas, bem, agora este é o primeiro que você recebe.
‫Basicamente, porque não temos nenhum
‫valor no campo de confirmação de senha.
‫OK?
‫E então, novamente, isso é por causa
‫da validação e então novamente podemos, é claro, desligá-lo
‫facilmente com esta opção.
‫De qualquer forma, vamos criar uma função de tratamento de
‫e-mail que podemos usar em todo o nosso aplicativo.
‫Vou fazer isso
‫aqui mesmo na pasta Utilitários,
‫novamente, e simplesmente chamando de e-mail. js.
‫Tudo bem?
‫E antes de
‫qualquer coisa, vamos instalar o pacote Nodemailer.
‫Esse é o pacote que mencionei no
‫início, que usaremos
‫para enviar e-mail usando o Node. js.
‫Então, como sempre, npm instale o nodemailer.
‫E aqui.
‫Tudo bem, e agora vamos criar essa função aqui.
‫E-mail constante, ok,
‫e
‫aqui, vamos passar algumas opções basicamente.
‫Então, o endereço de e-mail para o qual queremos enviar
‫um e-mail, a linha de assunto, o conteúdo do
‫e-mail e talvez algumas outras coisas.
‫Tudo bem.
‫E agora precisamos seguir três
‫passos para enviar emails com o Nodemailer.
‫Então, primeiro, precisamos criar um transportador.
‫Em
‫segundo lugar, precisamos definir as opções de email, basicamente,
‫e então
‫no final, realmente enviar o email com Nodemailer.
‫OK?
‫Então, o transportador que fizemos na primeira etapa aqui,
‫é basicamente um serviço que vai realmente enviar o e-mail, porque não
‫é um nó. js que irá
‫enviar o próprio e-mail.
‫É apenas um serviço que definimos aqui.
‫Algo como o Gmail, por exemplo.
‫Bem, o Gmail não é realmente
‫o serviço
‫que vamos usar, mas deixe-me mostrar rapidamente como
‫ele funciona com o Gmail, porque sei que
‫muitas pessoas vão se interessar por isso, ok?
‫De qualquer forma, precisamos sempre criar um transportador, e é sempre
‫o mesmo,
‫não importa qual serviço usaremos.
‫Portanto, o transportador será o
‫nodemailer. createTransport e
‫então, é claro, precisamos de algumas opções lá.
‫Tudo bem?
‫Portanto, podemos especificar o serviço e podemos
‫dizer que queremos usar o Gmail.
‫Então, assim.
‫E há alguns serviços bem
‫conhecidos que o Nodemailer sabe como lidar,
‫então não temos que configurá-los manualmente.
‫E então o Gmail é apenas um deles.
‫Mas também tem o Yahoo, ou o Hotmail, ou muitos outros, ok?
‫Então esse
‫é o serviço e também precisamos especificar a propriedade
‫auth, basicamente para autenticação.
‫Portanto, precisamos de um usuário e uma senha.
‫E assim como antes, salvamos
‫esse tipo de coisa em nossa configuração. n arquivo.
‫Tudo bem.
‫E-mail, é
‫um nome de
‫usuário, e agora não vou usar um endereço real
‫do Gmail aqui porque, novamente, não
‫estamos usando o Gmail, mas apenas como um exemplo aqui, tudo bem.
‫Sua senha.
‫Tudo bem.
‫Concluímos, digamos, processar ponto final
‫ponto EMAIL_USERNAME a
‫senha
‫processar ponto final ponto
‫EMAIL_PASSWORD e
‫espero ter escrito corretamente.
‫OK?
‫E então esta é
‫a configuração para o transporte no Nodemailer.
‫Então, em sua conta do
‫Gmail, você terá que
‫ativar algo chamado de opção de aplicativo menos segura.
‫Então, deixe-me escrever isso aqui.
‫E, novamente, não vou fazer isso
‫aqui, mas sei
‫que muitas pessoas vão realmente querer usá-lo.
‫E a razão pela qual não estamos usando
‫o Gmail neste aplicativo é
‫porque o Gmail não é uma boa ideia para um
‫aplicativo de produção.
‫E isso é basicamente o que estamos tentando construir aqui.
‫OK?
‫Então, usando o Gmail para esse
‫tipo de coisa, você só pode enviar 500 e-mails
‫por dia, e também, provavelmente, muito rapidamente, será
‫marcado como um spammer e, a partir daí, só irá piorar.
‫Tudo bem?
‫Então, a menos que seja como um aplicativo
‫privado, e você apenas envia e-mails para
‫si mesmo, ou, tipo,
‫10 amigos, bem, então você deve usar outro serviço.
‫E alguns bem conhecidos são SendGrid e Mailgun.
‫E, na verdade, usaremos o SendGrid um pouco mais
‫adiante neste curso.
‫Agora, o que vamos fazer
‫agora é usar um serviço de desenvolvimento
‫especial, que basicamente falsifica para enviar e-mails para endereços reais.
‫Mas, na realidade, esses e-mails acabam presos em uma caixa
‫de entrada de desenvolvimento, para que possamos dar uma olhada em
‫como eles ficarão mais tarde na produção.
‫Tudo bem?
‫Esse serviço é chamado Mailtrap, e agora
‫vamos nos inscrever para isso.
‫Então.
‫Mailtrap. io, tudo
‫bem?
‫Então, e como eu disse, teste de e-mail
‫seguro para teste e desenvolvimento.
‫Então, basicamente, com
‫este serviço, você pode fingir enviar e-mails para clientes,
‫mas esses e-mails nunca chegarão a esses clientes
‫e, em vez disso, ficarão presos em seu Mailtrap, certo?
‫E dessa forma você
‫não pode enviar acidentalmente alguns e-mails de desenvolvimento para
‫todos os seus clientes ou usuários, ok.
‫Então vá em frente e inscreva-se agora.
‫Eu, claro, já tenho minha conta, então
‫vou simplesmente fazer login agora.
‫Então, nos vemos em um segundo, depois
‫de criar sua conta gratuita.
‫Certo, então, depois de criar sua
‫conta, ela provavelmente ficará um pouco assim.
‫Agora, você não terá nenhuma caixa de entrada por
‫enquanto, então vamos apenas criar uma nova, com
‫o nome de natours.
‫Então, eu já tenho um, mas basta criar um novo aqui, com
‫o nome natours, e clicar em Criar caixa de entrada.
‫Tudo bem?
‫Então podemos abri-lo
‫e você vê que não temos e-mail neste
‫momento, mas o que
‫importa agora são essas credenciais aqui.
‫Como você pode ver, temos nosso host
‫aqui, a porta, o nome de usuário e a senha.
‫E é isso que vamos
‫especificar em nosso transporte no Nodemailer agora.
‫Tudo bem?
‫Então, vamos começar com o host, bem,
‫na verdade, com
‫o nome de usuário, então esses
‫dois, eu só preciso copiar, vamos copiá-lo para nosso arquivo
‫de configuração, esse é o nome
‫de usuário, essa é
‫a senha, e agora também precisamos especifique o host.
‫Ok, isso é porque Mailtrap não é
‫um desses serviços predefinidos que vem com o Nodemailer.
‫Tudo bem.
‫A porta é 25.
‫Portanto, salve-o e, em
‫seguida, vamos nos livrar disso, e o que
‫eu preciso especificar em vez disso é
‫o
‫host para e-mail,
‫host e, claro, a porta.
‫Então, tudo o que acabamos de salvar antes.
‫Tudo bem, então a autenticação aqui é
‫exatamente a mesma.
‫Vamos nos livrar disso também
‫e passar para a etapa número dois.
‫Então, basicamente definindo algumas opções para nosso e-mail.
‫Tudo bem, poderíamos, é claro, executar
‫as etapas dois e três ao mesmo tempo,
‫mas gosto de simplesmente preferir essas opções aqui primeiro.
‫Ok, aqui especificamos de onde
‫vem o e-mail, o
‫nome
‫e o endereço de e-mail como este.
‫Em seguida, precisamos do endereço do
‫destinatário e, para esse, irei especificar como uma opção,
‫certo?
‫Então, basicamente, vindo como um argumento para esta função.
‫Portanto, este objeto de opções
‫aqui, é aquele que passamos para a função.
‫Tudo bem.
‫Então, na verdade, o mesmo para o assunto e para o texto.
‫Vamos apenas duplicar
‫isso aqui, então o assunto
‫e então apenas especificamos a propriedade text,
‫e essa, nas opções, estou apenas chamando de mensagem.
‫Tudo bem, então esta é basicamente a
‫versão em texto do e-mail.
‫Mas também podemos especificar a propriedade HTML.
‫Ok, então agora podemos converter esta mensagem para HTML.
‫E mais tarde, vamos fazer isso, mas
‫por enquanto, vamos mantê-lo simples e não especificar o HTML aqui, de forma alguma.
‫OK?
‫Portanto, basta deixar no texto.
‫OK!
‫E finalmente, no
‫final, transporter, então esse é o objeto transporter que
‫criamos bem aqui no início, e
‫sobre isso, podemos chamar sendMail
‫e para isso precisamos passar nossas opções de mail, ok?
‫E agora isso realmente retorna uma promessa.
‫Ok, então novamente, esta é uma função assíncrona,
‫e como não queremos trabalhar diretamente com Promises, vamos usar
‫async / await.
‫Tudo bem.
‫Declarar isso como uma função assíncrona
‫e pronto.
‫Tudo bem.
‫Não queremos armazenar nenhum resultado aqui,
‫o que poderíamos, mas não estou realmente interessado nisso.
‫Ok, e agora vamos simplesmente exportá-lo como padrão
‫a partir deste módulo.
‫Ok, parece bom!
‫Agora vamos prosseguir e realmente tentar isso.
‫E então, para começar, precisamos importá-lo aqui, é claro.
‫Então, vamos apenas duplicar isso
‫aqui, então
‫este é o e-mail, e a função se chama sendEmail, eu acho.
‫OK.
‫Portanto, vamos voltar à nossa função de middleware aqui e
‫começar definindo a URL de redefinição.
‫Portanto, o ideal é que o usuário clique neste e-mail
‫e possa fazer a solicitação a partir daí.
‫E isso vai
‫funcionar mais tarde, quando implementarmos nosso
‫site dinâmico, mas ainda assim, queremos criar essa URL aqui, para
‫que o usuário possa simplesmente copiá-la, para
‫tornar mais fácil fazer essa solicitação.
‫Ok, então basicamente precisamos
‫recriar essa estrutura de URL que temos aqui.
‫Portanto, este é para esquecer a
‫senha e vamos salvá-la aqui.
‫Então, esqueci a senha e agora a URL que estamos criando
‫é, na verdade, para redefinir a senha.
‫Então, lembre-se, nós realmente implementamos isso antes.
‫OK.
‫Vamos apenas
‫copiar aqui, então redefina a senha, certo?
‫E isso irá usar o
‫token como parâmetro.
‫Ok, então vamos colocar qualquer token aleatório aqui por enquanto.
‫Portanto, não importa de forma alguma.
‫Deixe-me
‫apenas salvá-lo aqui, como redefinir a senha.
‫OK.
‫E também não é GET, também não
‫é POST, mas é PATCH, pois
‫o resultado disso será a modificação da propriedade da
‫senha no documento do usuário.
‫E então o PATCH é o melhor, certo?
‫Portanto, vamos mudar rapidamente nossa implementação de rota para isso.
‫Então, está aqui em userRoute, então não
‫é POST, é PATCH,
‫e também queremos especificar um parâmetro.
‫Portanto, lembre-se de como fazemos isso.
‫Então é como aqui embaixo.
‫Outra barra, dois pontos e o nome
‫do parâmetro, que será o token.
‫Ok, vamos construir isso
‫agora, começando com o protocolo.
‫Então, HTTP ou HTTPS, ok?
‫E basicamente vamos obter esses dados de nossa solicitação.
‫Então, isso é armazenado no protocolo de
‫ponto de solicitação, em seguida, dois pontos, barra, barra e, em seguida, o host, certo?
‫Então, basicamente estamos preparando este aqui para funcionar
‫tanto no desenvolvimento quanto na produção.
‫Portanto, solicite ponto get e, em seguida,
‫host.
‫Tudo bem, então é assim que obtemos
‫o host e, em seguida, slash api slash versão um, e acho que
‫não é ideal definir uma camada codificada como
‫esta, mas, novamente,
‫isso é algo que iremos corrigir
‫um pouco mais tarde, Certo?
‫E vejo que isso não é correto.
‫Essas chaves devem estar lá.
‫Então, agora, usuários,
‫resetPassword,
‫e então outra barra e, finalmente, o token.
‫Ok, então, resetToken.
‫Tudo bem?
‫E como discutimos antes, na última
‫aula, aqui realmente
‫temos que enviar o resetToken simples e original, e não o criptografado.
‫Tudo bem?
‫Iremos então, na
‫próxima etapa, comparar o token original com o criptografado.
‫Então, novamente, exatamente como discutimos no último vídeo.
‫Salve aqui agora, e esse é o nosso URL de redefinição.
‫E agora, com base neste URL, vamos criar rapidamente
‫a mensagem aqui também.
‫Então, esqueceu sua senha?
‫Envie uma solicitação PATCH com sua nova senha
‫e senhaConfirme, é claro, para
‫a URL de
‫redefinição que acabamos de criar, certo?
‫Então, basicamente, dando ao usuário algumas instruções aqui.
‫Então, em uma nova linha,
‫também dizemos, se você não esqueceu sua senha,
‫ignore este e-mail.
‫Então, essa é uma mensagem comum e,
‫novamente, tenho certeza de que você viu de uma forma
‫ou de outra, tudo bem.
‫Então, vamos agora, finalmente, enviar o e-mail
‫e lembrar que sendEmail é
‫uma função assíncrona.
‫E então, portanto, precisamos aguardar por aqui.
‫OK?
‫Porque, é claro, vai retornar uma promessa.
‫E lembre-se agora que a função sendEmail aqui
‫pega um objeto com algumas opções.
‫Portanto, o e-mail é do usuário. email, certo?
‫Ou também poderíamos dizer, req. corpo. o email.
‫Então é exatamente a mesma coisa, certo?
‫Então, o assunto que
‫queremos dizer é, Seu token de redefinição de senha.
‫Digamos desde já que só é válido por 10
‫minutos, para que o usuário saiba que tem que se apressar.
‫Ok, e finalmente, a mensagem também.
‫OK.
‫Então, aguardamos isso, e
‫depois disso, vamos mandar também, é claro, alguma resposta.
‫Ok, então sempre precisa haver uma resposta, caso contrário,
‫como você já sabe,
‫o ciclo de solicitação / resposta nunca vai terminar.
‫Então, simplesmente enviamos um código
‫200 e, em seguida, uma mensagem bem formatada
‫com um status
‫de sucesso e, em seguida, apenas
‫uma mensagem rápida dizendo: Token enviado para e-mail.
‫Tudo bem.
‫E, claro, não podemos enviar o token de reinicialização aqui mesmo,
‫pelo adjacente, certo, porque, então, todos poderiam redefinir a
‫senha de qualquer um
‫e assumir qualquer conta que quisessem.
‫E essa é a razão pela qual o
‫enviamos para um endereço de email, porque assumimos
‫que o email é um
‫lugar seguro, ao qual apenas o usuário tem acesso.
‫Tudo bem.
‫Uau, então, este vídeo, novamente, está demorando bastante, mas
‫ainda não terminamos.
‫Estamos quase terminando, mas não de
‫todo, pois pode acontecer um
‫erro, usando este sendEmail, ok, e então nesse caso, queremos,
‫claro, enviar uma mensagem de erro para o cliente.
‫Mas, neste caso, realmente precisamos fazer mais do que
‫simplesmente enviar uma mensagem de erro.
‫Basicamente, precisamos restaurar o token de redefinição de
‫senha e a redefinição de senha expirou que definimos, certo?
‫E agora não é suficiente simplesmente capturar
‫o erro e enviá-lo para
‫o nosso middleware global de tratamento de erros.
‫Mas, em vez disso, precisamos simplesmente adicionar
‫um bloco try-catch bem aqui.
‫Então, novamente, porque nós realmente queremos
‫fazer mais do que simplesmente enviar um erro
‫para o cliente, então tentamos basicamente fazer
‫isso, certo, mas caso haja um erro,
‫então, é claro, este bloco aqui é executado.
‫Tudo bem?
‫Então, o que queremos fazer nesse
‫caso, bem, queremos basicamente, como
‫eu disse, redefinir o token e a propriedade expires.
‫OK.
‫Então, passwordResetToken, e
‫defina-o como undefined, tudo bem.
‫E o mesmo para passwordResetExpires.
‫OK.
‫E então, é claro, assim como
‫antes, isso apenas modifica os dados, mas não os salva de verdade.
‫Então, vamos adicionar, pegar
‫este e, basicamente, salvar os dados neste caso.
‫Ok, e só para terminar,
‫nós, é claro, voltamos com um erro para
‫o próximo middleware.
‫Então, newAppError,
‫Ocorreu um erro ao enviar o e-mail.
‫Tente mais tarde.
‫E, neste caso, o código de erro pode realmente ser 500.
‫Então, isso é realmente então, como um erro que aconteceu
‫no servidor, e então tem que ser um
‫código cinco, e 500 é apenas, tipo, o código padrão.
‫Tudo bem.
‫Então, vamos prosseguir e tentar novamente, tudo bem.
‫Portanto, este é um pouco longo de novo, mas, bem, temos
‫que fazer isso, certo?
‫Então, esqueci a senha, com este e-mail, vamos dar uma olhada.
‫Então isso pode não
‫demorar muito, por causa do envio
‫do e-mail, mas na verdade funcionou agora, levou uns cinco segundos,
‫mas vemos Token enviado para o e-mail.
‫e, como sabemos, como usamos o Mailtrap, ele não enviou
‫este e-mail para hello @ jones. io, mas
‫em vez disso, o e-mail deve
‫estar preso dentro do Mailtrap.
‫E, de fato, aqui no lado esquerdo, agora apareceu.
‫Tudo bem.
‫Então, esse é o e-mail que especificamos e aqui
‫obtemos nosso URL legal.
‫Ok, então aquele que criamos com o protocolo, o
‫host, e também com o token.
‫Então, vamos apenas dar uma
‫olhada se este
‫é realmente nosso token
‫simples, terminando em 88df, e, de fato, temos resetToken aqui, 88df.
‫E agora, no banco de
‫dados, devemos ter o token terminando em 1111.
‫Então, vamos confirmar que, aqui no
‫Compass, dê uma recarga e, de fato, lá vamos nós, ok?
‫E então, novamente, isso aqui é em 10 minutos a partir de agora.
‫Ótimo, então terminamos essa parte.
‫Em seguida, no próximo vídeo, iremos redefinir
‫a senha, com base,
‫é claro, na nova senha que
‫o usuário envia com a solicitação de redefinição de senha.
‫Então, até lá.