Я хочу отправить сброс сообщения электронной почты, используя nodemailer. На самом деле я смог отправить его с использованием необработанных данных. Вот модули / mailModule. js:
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "rawmail@gmail.com",
pass: "rawpass"
}
})
const getPasswordResetURL = (user, token) =>
`http://localhost:3000/password/reset/${user._id}/${token}`
const resetPasswordTemplate = (user, url) => {
console.log("this");
console.log(process.env.EMAIL_LOGIN); // this is undefined, but I want to use it in the future
console.log("email");
const from = "rawmail@gmail.com"
const to = user.email
const subject = "Password Reset"
const html = `
<p>Hey ${user.name || user.email},</p>
<p>We heard that you lost 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 }
}
module.exports = { transporter, getPasswordResetURL, resetPasswordTemplate }
в маршрутах / api / auth. js (я не включил получение пароля, логин и другие функции, чтобы сконцентрироваться на этом)
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const config = require('config');
const jwt = require('jsonwebtoken');
const auth = require('../../middleware/auth')
const { transporter, getPasswordResetURL, resetPasswordTemplate } = require('../../modules/mailModule');
// Item Model
const User = require('../../models/User');
router.post('/user', (req, res) => {
const { email } = req.body
console.log(email);
User.findOne({ email })
.then(user => {
if (!user) return res.status(400).json({ msg: 'User does not exist' });
jwt.sign(
{ id: user.id },
config.get('jwtSecret'),
{ expiresIn: 3600 },
(err, token) => {
if (err) throw err;
res.json({
token,
user: {
id: user.id,
name: user.name,
email: user.email
}
});
transporter.sendMail(resetPasswordTemplate(user, getPasswordResetURL(user, token)), (err, info) => {
if (err) {
res.status(500).json("Error sending email")
}
// console.log(`** Email sent **`, info.response)
})
}
)
})
});
, а также config: config / default. json
{
"mongoURI": "linkToMyMongoDBCluster",
"jwtSecret": "jwtSecretPassword"
}
И это самая важная часть. 1) Я пытался передать сообщение с необработанными данными на свою почту, но я получаю сообщения об ошибках:
в терминале:
_http_outgoing.js:470
[0] throw new ERR_HTTP_HEADERS_SENT('set');
[0] ^
[0]
[0] Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
[0] at ServerResponse.setHeader (_http_outgoing.js:470:11)
[0] at ServerResponse.header (/home/wiktor/myApp/node_modules/express/lib/response.js:771:10)
[0] at ServerResponse.send (/home/wiktor/myApp/node_modules/express/lib/response.js:170:12)
[0] at ServerResponse.json (/home/wiktor/myApp/node_modules/express/lib/response.js:267:15)
[0] at transporter.sendMail (/home/wiktor/myApp/routes/api/auth.js:88:31)
[0] at transporter.send.args (/home/wiktor/myApp/node_modules/nodemailer/lib/mailer/index.js:226:21)
[0] at connection.login.err (/home/wiktor/myApp/node_modules/nodemailer/lib/smtp-transport/index.js:282:36)
[0] at SMTPConnection._actionAUTHComplete (/home/wiktor/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:1523:20)
[0] at SMTPConnection._responseActions.push.str (/home/wiktor/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:550:26)
[0] at SMTPConnection._processResponse (/home/wiktor/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:942:20)
[0] at SMTPConnection._onData (/home/wiktor/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:749:14)
[0] at TLSSocket.SMTPConnection._onSocketData.chunk (/home/wiktor/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)
[0] at TLSSocket.emit (events.js:189:13)
[0] at addChunk (_stream_readable.js:284:12)
[0] at readableAddChunk (_stream_readable.js:265:11)
[0] at TLSSocket.Readable.push (_stream_readable.js:220:10)
на gmail:
Login attempt has been blocked
Someone just tried to sign in to your account using a non-Google application. We blocked this attempt, but we advise you to check.(translated by google translator)
2 ) Я также не могу получить этот process.env.EMAIL_LOGIN и process.env.EMAIL_PASSWORD. Где я могу установить или получить их?
А вот мои authActions и authReducer. js:
client / src / actions / authActions. js (без входа в систему, регистрации и других действия, также я не использую тип RESET_PASSWORD, потому что я еще не сделал редуктор, поэтому я использую LOGIN_SUCCESS и LOGIN_FAIL, но это скоро изменится):
import axios from 'axios';
import { returnErrors } from './errorActions';
import {
USER_LOADED,
USER_LOADING,
AUTH_ERROR,
LOGIN_SUCCESS,
LOGIN_FAIL,
LOGOUT_SUCCESS,
REGISTER_SUCCESS,
REGISTER_FAIL,
CHANGE_PASSWORD,
CHANGE_PASSWORD_FAIL,
RESET_PASSWORD
} from './types';
// reset password
export const resetPassword = (email) => (dispatch) => {
// Headers
console.log(email);
const config = {
headers: {
'Content-Type': 'application/json'
}
}
// Request body
// const body = JSON.stringify(email)
axios.post(`/api/auth/user`, email, config)
.then(res => dispatch({
type: LOGIN_SUCCESS,
payload: res.data
}))
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status, 'LOGIN_FAIL'));
dispatch({
type: LOGIN_FAIL
});
});
}
и client / src / redurs /authReducers.js
import {
USER_LOADED,
USER_LOADING,
AUTH_ERROR,
LOGIN_SUCCESS,
LOGIN_FAIL,
LOGOUT_SUCCESS,
REGISTER_SUCCESS,
REGISTER_FAIL,
CHANGE_PASSWORD,
CHANGE_PASSWORD_FAIL,
RESET_PASSWORD
} from '../actions/types';
const initialState = {
token: localStorage.getItem('token'),
isAuthenticated: false,
user: null
};
export default function (state = initialState, action) {
switch (action.type) {
case USER_LOADING:
return {
...state,
isLoading: true
};
case USER_LOADED:
return {
...state,
isAuthenticated: true,
isLoading: false,
user: action.payload
};
case LOGIN_SUCCESS:
case REGISTER_SUCCESS:
localStorage.setItem('token', action.payload.token);
return {
...state,
...action.payload,
isAuthenticated: true,
isLoading: false
};
case RESET_PASSWORD:
localStorage.setItem('token', action.payload.token);
return {
...state,
...action.payload,
isAuthenticated: true,
isLoading: false
}
case AUTH_ERROR:
case LOGIN_FAIL:
case LOGOUT_SUCCESS:
localStorage.removeItem('token');
return {
...state,
token: null,
user: null,
isAuthenticated: false,
isLoading: false
};
case REGISTER_FAIL:
return {
...state
};
case CHANGE_PASSWORD:
return {
...state,
user: action.payload,
};
case CHANGE_PASSWORD_FAIL:
return {
...state
}
default:
return state;
}
}