Правильно ли реализована отправка сброса пароля по электронной почте? - PullRequest
0 голосов
/ 18 января 2020

Я прочитал эту статью https://ahrjarrett.com/posts/2019-02-08-resetting-user-passwords-with-node-and-jwt, чтобы узнать, как сбросить пароль в express.

mailer.js


const nodemailer = require("nodemailer")

export const transporter = nodemailer.createTransport({
    service: "gmail",
    auth: {
        user: process.env.EMAIL,
        pass: process.env.PASSWORD
    }
})

export const getPasswordResetURL = (user, token) => {
    `http://localhost:3000/password/reset/${user._id}/${token}`
}

export const resetPasswordTemplate = (user, url) => {
    const from = process.env.EMAIL
    const to = user.email
    const subject = "Password Reset"
    const html = `
        <p>Hey ${user.name || user.email},</p>
        <p>We heard that you forgot your password. Sorry about that!</p>
        <p>But don’t worry! You can use the following link to reset your password:</p>
        <a href=${url}>${url}</a>
        <p>If you don’t use this link within 1 hour, it will expire.</p>
    `
}

return { from, to, subject, html }
emailController.js


const jwt = require("jsonwebtoken")
const bcrypt = require("bcrypt")
const User = require("../models/User")
import { transporter, getPasswordResetURL, resetPasswordTemplate } from "../utils/mailer"

export const usePasswordHashToMakeToken = ({
    password: passwordHash,
    _id: userId,
    createdAt
  }) => {
    const secret = passwordHash + "-" + createdAt
    const token = jwt.sign({ userId }, secret, {
      expiresIn: 3600 // 1 hour
    })
    return token
  }

  export const sendPasswordResetEmail = async (req, res) => {
    const { email } = req.params
    let user
    try {
      user = await User.findOne({ email }).exec()
    } catch (err) {
      res.status(404).json("No user with that email")
    }
    const token = usePasswordHashToMakeToken(user)
    const url = getPasswordResetURL(user, token)
    const emailTemplate = resetPasswordTemplate(user, url)

    const sendEmail = () => {
      transporter.sendMail(emailTemplate, (err, info) => {
        if (err) {
          res.status(500).json("Error sending email")
        }
        console.log(`** Email sent **`, info.response)
      })
    }
    sendEmail()
  }

  export const receiveNewPassword = (req, res) => {
    const { userId, token } = req.params
    const { password } = req.body

    User.findOne({ _id: userId })

      .then(user => {
        const secret = user.password + "-" + user.createdAt
        const payload = jwt.decode(token, secret)
        if (payload.userId === user.id) {
          bcrypt.genSalt(10, function(err, salt) {
            if (err) return
            bcrypt.hash(password, salt, function(err, hash) {
              if (err) return
              User.findOneAndUpdate({ _id: userId }, { password: hash })
                .then(() => res.status(202).json("Password changed accepted"))
                .catch(err => res.status(500).json(err))
            })
          })
        }
      })

      .catch(() => {
        res.status(404).json("Invalid user")
      })
  }

users.js

const express = require('express');
const router = express.Router();
const userController = require("../controllers/userController")
const emailController = require("../controllers/emailController")

router.post("/register", userController.registerUser)
router.post("/login", userController.loginUser)
router.get("/:userId", userController.getUser)
router.post("/user/:email", emailController.sendPasswordResetEmail)
router.post("/receive_new_password/:userId/:token", emailController.receiveNewPassword)


module.exports = router;

Это дает мне ошибку неожиданного токена {в этой строке

import {transporter, getPasswordResetURL, resetPasswordTemplate} из "../utils/mailer"

Могу ли я преобразовать этот экспорт const в module.exports и потребовать вышеуказанного:

const {transporter, getPasswordResetURL, resetPasswordTemplate} = require (»../utils/mailer")

1 Ответ

2 голосов
/ 18 января 2020

Как вы упомянули в вопросе, замените все const экспорта и замените его на

module.exports = {transporter, getPasswordResetURL, resetPasswordTemplate}

Также замените строку

import { transporter, getPasswordResetURL, resetPasswordTemplate } from "../utils/mailer"

на

const { transporter, getPasswordResetURL, resetPasswordTemplate } = require("../utils/mailer")

As import, export - это синтаксис es6 и требуется, module.exports - это синтаксис es5. Если вы хотите использовать импорт, вам нужно настроить Babel.

Предложения

Скорее всего, вы взяли пример, что он использует синтаксис es6 и es5 вместе (он должен настроили бабел). Но в вашем случае я не думаю, что вы настроили Babel. Поэтому я предлагаю вам либо настроить babel, либо изменить весь синтаксис es6 на es5. В es6 вы можете использовать es5, но в es5 вы не можете использовать es6

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...