I am attempting to setup MFA for users after they reset their passcode. The code runs smoothly until I hit mfaSetup, specifically the line user.associateSoftwareToken(). When I pass in 'this' instead of user, I get the following error:
Uncaught (in promise) TypeError: callback is undefined
When I pass in user I get Uncaught (in promise) TypeError: callback.onFailure is not a function
I am truly at a loss of what to do and would appreciate any help.
Code below:
const onSubmit = (event) => {
event.preventDefault();
const authDetails = new AuthenticationDetails({
Username: email,
Password: password
});
const user = new CognitoUser({
Username: email,
Pool: UserPool
});
user.authenticateUser(authDetails, {
onSuccess: (data) => {
console.log('onSuccess:', data);
if (location.pathname === '/') {
// navigate('dashboard');
}
},
onFailure: (err) => {
console.error('onFailure:', err);
},
newPasswordRequired: (data) => {
console.log(data);
setNewPasscodeRequired(true);
},
mfaRequired: (data) => {
console.log('mfa required');
},
mfaSetup: (challengeName, challengeParameters) => {
console.log('in mfa setup');
console.log(user.Session);
user.associateSoftwareToken(user, {
onFailure: (err) => {
console.error('onFailure', err);
},
onSuccess: (result) => {
console.log(result);
}
});
},
selectMFAType: (challengeName, challengeParameters) => {
console.log(challengeName, challengeParameters);
user.sendMFASelectionAnswer('SOFTWARE_TOKEN_MFA', this);
},
totpRequired: (secretCode) => {
console.log(secretCode);
const challengeAnswer = prompt('Please input the TOTP code.', '');
user.sendMFACode(challengeAnswer, this, 'SOFTWARE_TOKEN_MFA');
},
associateSecretCode: (secretCode) => {
const challengeAnswer = prompt('Please input the TOTP code.', '');
user.verifySoftwareToken(challengeAnswer, 'My TOTP device', this);
}
});
};
const onSubmitPasscode = (event) => {
event.preventDefault();
if (passwordFirst !== passwordSecond) {
alert('the two inputs provided are not the same');
} else {
const user = new CognitoUser({
Username: email,
Pool: UserPool
});
const authDetails = new AuthenticationDetails({
Username: email,
Password: password
});
user.authenticateUser(authDetails, {
onFailure: (err) => {
console.error('onFailure:', err);
},
onSuccess: (result) => {
console.log(result);
},
newPasswordRequired: (userAttributes, requiredAttributes) => {
console.log(userAttributes);
console.log(requiredAttributes);
delete userAttributes.email_verified;
delete userAttributes.phone_number_verified;
delete userAttributes.phone_number;
console.log(userAttributes);
user.completeNewPasswordChallenge(passwordFirst, userAttributes, {
onFailure: (err) => {
console.error('onFailure:', err);
},
onSuccess: (result) => {
console.log('call result: ', result);
},
mfaSetup: (challengeName, challengeParameters) => {
console.log('in mfa setup');
console.log(user.Session);
user.associateSoftwareToken(this, {
onFailure: (err) => {
console.error('onFailure', err);
},
onSuccess: (result) => {
console.log(result);
}
});
},
selectMFAType: (challengeName, challengeParameters) => {
console.log(challengeName, challengeParameters);
user.sendMFASelectionAnswer('SOFTWARE_TOKEN_MFA', this);
},
totpRequired: (secretCode) => {
console.log(secretCode);
const challengeAnswer = prompt('Please input the TOTP code.', '');
user.sendMFACode(challengeAnswer, this, 'SOFTWARE_TOKEN_MFA');
},
associateSecretCode: (secretCode) => {
const challengeAnswer = prompt('Please input the TOTP code.', '');
user.verifySoftwareToken(challengeAnswer, 'My TOTP device', this);
}
});
}
});
}
};
const onMFASetup = () => {
const user = new CognitoUser({
Username: email,
Pool: UserPool
});
const authDetails = new AuthenticationDetails({
Username: email,
Password: passwordFirst
});
console.log(email);
console.log(passwordFirst);
user.authenticateUser(authDetails, {
onFailure: (err) => {
console.error('onFailure:', err);
},
onSuccess: (result) => {
console.log(result);
},
mfaSetup: (challengeName, challengeParameters) => {
user.associateSoftwareToken(this);
},
selectMFAType: (challengeName, challengeParameters) => {
user.sendMFASelectionAnswer('SOFTWARE_TOKEN_MFA', this);
},
totpRequired: (secretCode) => {
const challengeAnswer = prompt('Please input the TOTP code.', '');
user.sendMFACode(challengeAnswer, this, 'SOFTWARE_TOKEN_MFA');
},
mfaRequired: (codeDeliveryDetails) => {
const verificationCode = prompt('Please input verification code', '');
user.sendMFACode(verificationCode, this);
}
});
};
const sendVerificationPin = (event) => {
event.preventDefault();
const user = new CognitoUser({
Username: email,
Pool: UserPool
});
user.forgotPassword({
onSuccess: (result) => {
console.log('call result: ', result);
},
onFailure: (err) => {
alert(err);
}
});
};
const onResetPassword = (event) => {
event.preventDefault();
console.log('in reset');
const user = new CognitoUser({
Username: email,
Pool: UserPool
});
console.log('user made');
if (passwordFirst !== passwordSecond) {
alert('the two inputs provided are not the same');
} else {
console.log('inputs are the same');
user.confirmPassword(pin, passwordSecond, {
onSuccess() {
console.log('Password confirmed!');
window.location.reload(true);
},
onFailure(err) {
console.log('Password not confirmed!');
console.log(err);
}
});
}
};
return (
<div>
{!newPasscodeRequired && !forgotPassword && !setupMFA && (
<div>
<form onSubmit={onSubmit}>
<input type="text" required value={email} onChange={(e) => setEmail(e.target.value)} />
<input
type="text"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">Login</button>
</form>
<button onClick={(e) => setForgotPassword(true)}>
<Typography sx={{ paddingX: 5 }}>Forgot password?</Typography>
</button>
</div>
)}
{newPasscodeRequired && (
<div>
<form onSubmit={onSubmitPasscode}>
<Typography>New Password</Typography>
<input type="text" required onChange={(e) => setPasswordFirst(e.target.value)} />
<Typography>New Password Again</Typography>
<input type="text" required onChange={(e) => setPasswordSecond(e.target.value)} />
<Typography>New Password Requirements</Typography>
<Typography>
At least 8 characters long, requiring upper and lower case letters, numbers, and
special characters
</Typography>
<button type="submit">Submit new passcode</button>
</form>
</div>
)}
{forgotPassword && !newPasscodeRequired && (
<div>
<form onSubmit={sendVerificationPin}>
<Typography>Please input the email for the account</Typography>
<input type="text" required onChange={(e) => setEmail(e.target.value)} />
<button type="submit">Send verification pin</button>
</form>
<form onSubmit={onResetPassword}>
<Typography>Input the verification pin sent to your email below</Typography>
<input type="text" required onChange={(e) => setPin(e.target.value)} />
<Typography>New Password</Typography>
<input type="text" required onChange={(e) => setPasswordFirst(e.target.value)} />
<Typography>New Password Again</Typography>
<input type="text" required onChange={(e) => setPasswordSecond(e.target.value)} />
<Typography>New Password Requirements</Typography>
<Typography>
At least 8 characters long, requiring upper and lower case letters, numbers, and
special characters
</Typography>
<button type="submit">Reset Password</button>
</form>
</div>
)}
{setupMFA && (
<div>
<div>SetupMFA</div>
<button onClick={(e) => onMFASetup()}>Generate QR Code</button>
</div>
)}
</div>
);
};
have you tried this:
cognitoUser.associateSoftwareToken({
onFailure : (error)=>{
console.error(error);
},
associateSecretCode:(code)=>{
console.debug(code);
}
});
Related
I recently created a web application for login and registration, however I ran into a difficulty. In order to enable users to login or register, I've created a few endpoints using express.js. If a user tries to register an account that already exists in the database, an error message stating "User already exists" will be displayed. If not, the user will be able to create an account and login successfully. However, if I launch the app without first registering a new user, I am unable to log in. For instance, if I try to register an existing user who is already listed in the database, it informs me that the user already exists there before allowing me to log in, but if I try to log in first, nothing happens, so I can't login without going through the registration process. " so, I have added some fake data manually to my database and I try to access them with the login process but it won't work as I have not registered a user using the register process." Any idea of how to fix this problem?
Frontend:
import React, { useState, useEffect } from "react";
import axios from 'axios';
function Login2() {
const [form, setForm] = useState({
username: '',
email: '',
password: '',
});
const [mode, setMode] = useState('login');
const [errors, setErrors] = useState({});
const [message, setMessage] = useState('');
const handleChange = (e) => {
setForm({
...form,
[e.target.name]: e.target.value,
});
};
const validateInfo = (form) => {
let errors = {};
if (!form.username.trim()) {
errors.username = 'Username is required!';
}
if (!form.email) {
errors.email = 'Email is required!';
} else if (!/\S+#\S+\.\S+/.test(form.email)) {
errors.email = 'Email address is invalid';
}
if (!form.password) {
errors.password = 'Password is required';
} else if (form.password.length < 6) {
errors.password = 'Password must be at least 6 characters long!';
}
return errors;
};
const handleSubmit = (e) => {
e.preventDefault();
const errors = validateInfo(form);
setErrors(errors);
if (Object.keys(errors).length === 0) {
if (mode === 'login') {
axios.post('http://localhost:4000/login', form)
.then((response) => {
if (response.data === 'Logged in successfully') {
setMessage('Logged in successfully');
window.location.href = '/';
} else {
setMessage('Login was unsuccessful');
}
})
.catch((error) => {
setMessage(error.message);
});
} else {
axios.get(`http://localhost:4000/checkUser/${form.username}`)
.then((response) => {
if (response.data === 'User exists') {
setMessage('User already exists');
return;
} else {
axios.post('http://localhost:4000/register', form)
.then((response) => {
setMessage(response.data);
})
.catch((error) => {
setMessage(error.message);
});
}
})
.catch((error) => {
setMessage(error.message);
});
}
}
};
return (
<div className="App">
<form onSubmit={handleSubmit}>
<input
type="text"
name="username"
placeholder="Username"
value={form.username}
onChange={handleChange}
/>
{errors.username && <p> {errors.username}</p>}
{mode === 'register' && (
<>
<input
type="email"
name="email"
placeholder="Email"
value={form.email}
onChange={handleChange}
/>
{errors.email && <p> {errors.email}</p>}
</>
)}
<input
type="password"
name="password"
placeholder="Password"
value={form.password}
onChange={handleChange}
/>
{errors.password && <p> {errors.password}</p>}
<button type="submit">
{mode === 'login' ? 'Login' : 'Register'}
</button>
<button type="button" onClick={() => setMode(mode === 'login' ? 'register' : 'login')}>
Switch to {mode === 'login' ? 'Register' : 'Login'}
</button>
</form>
{message && <p>{message}</p>}
</div>
);
};
export default Login2;
Backend:
const express = require('express');
const app = express();
const cors = require('cors');
const mysql = require('mysql2');
const connection = mysql.createConnection({
host: "??",
user: "??",
password: "??",
database: "??",
});
app.use(cors({
origin: 'http://localhost:3000'
}))
app.use(express.json());
app.get('/checkUser/:username', (req, res) => {
const query = `SELECT * FROM userTable WHERE username = '${req.params.username}'`;
connection.query(query, (error, results) => {
if (error) {
return res.status(500).send(error);
}
if (results.length > 0) {
return res.send('User exists');
}
return res.send('User does not exist');
});
});
app.post('/register', (req, res) => {
const { username, email, password } = req.body;
const reg = `INSERT INTO userTable (username, email, password) VALUES (?,?,?)`;
connection.query(reg, [username, email, password], (error) => {
if (error) throw error;
res.send('User registered successfully');
});
});
app.post('/login', (req, res) => {
const { username, password } = req.body;
const log = `SELECT * FROM userTable WHERE username = ? AND password = ?`;
connection.query(log, [username, password], (error, results) => {
if (error) throw error;
if (results.length > 0) {
return res.send('Logged in successfully');
} else {
return res.send('Login was unsuccessful');
}
});
});
app.listen(4000, () => {
console.log('Server listening on port 4000');
});
So the exact problem is how I can login without going through the registration process.
Note:
I'm using MYSQL database, node.js, express server, Cors and axios to make the http requests.
I have been struggling with this for a few days and i'm new to reactjs and javascript. I have a form that submit successfully to database then it redirect me to an other page where there is a Quiz to do. When you answer all the questions and click on "Apply", you submit the Quiz score by updating the database and add the score value. How to update database at button click?
Quiz.js:
function EndScreen() {
const { score } = useContext(QuizContext);
return (
<div className='EndScreen'>
<h1>Test finished</h1>
<br></br>
<h3> You scored:</h3>
<h1 style={{ fontSize: '70px' }}>{score}/{Questions.length}</h1>
<br></br>
<br></br>
<button>Apply</button> //Clicking on this button should submit score to database
</div>
)
}
formServices.js:
export const FormService = {
store: (data) => {
console.log('data===>>>', data);
const { title, fname, lname, email, phoneNumber, cv, coverLetter } = data;
const formData = new FormData();
formData.append('fname', fname);
formData.append('lname', lname);
formData.append('email', email);
formData.append('phoneNumber', phoneNumber);
formData.append('coverLetter', coverLetter);
formData.append('title', title);
formData.append('cv', cv);
Axios.post(requests.formApi.store, formData)
.then((res) => {
return res;
})
.catch((err) => {
return err;
});
}
};
FormController.js:
const form = require('../models/FormModel')
module.exports = {
store: (req, res, next) => {
let candidate = new form({
title: req.body.title,
fname: req.body.fname,
lname: req.body.lname,
email: req.body.email,
phoneNumber: req.body.phoneNumber,
coverLetter: req.body.coverLetter,
cv: req.body.cv,
score: req.body.score
})
if (req.file) {
candidate.cv = req.file.path
}
candidate.save()
.then(response => {
res.json({
success: true,
message: 'Candidate added successfully!',
data: candidate,
})
})
.catch(error => {
res.json({
success: false,
message: 'An error occured!',
error: error,
})
})
}
}
I'm trying to use a method in a React class component, to send user data from my front-end to my back-end. Right now, I can get it to go through if I hard code it. But I'm having a hard time passing in the values, as they change, as in, their state. Initial state is set to 0, then a user will input a number, and the state will change, but I can't get that changed state to come through to my database/back-end. Here's my code below.
Front-end:
class App extends Component {
constructor(props) {
super(props);
this.state = {
hits: [],
desc: [],
outdoor: 0,
water: 0,
value: null,
outBeforeCalc: [],
waterBeforeCalc: [],
waterPercentage: 0,
outdoorPercentage: 0,
userId: null
};
}
componentDidMount() {
this.fetchData();
this.addHealthData();
}
...
addHealthData = () => {
let addHealthDataUrl = "http://localhost:10240/weather/save"
let queryParams = {
'userId': this.state.userId,
'sun': this.state.outdoor,
'water': this.state.water,
'progress': this.state.value
}
fetch(addHealthDataUrl, {
method: 'post',
body: JSON.stringify(queryParams),
headers: {
"Content-Type": "application/json"
}
})
.then(response => response.json())
.then(data => {
if (data.code == "200") {
this.props.sendMessage("Your data has been saved!")
} else {
this.props.sendMessage(`We've encountered a problem.`);
}
})
.catch((error) => {
console.error('Error:', error);
})
}
Back-end:
app.post('/weather/save', (req, res) => {
try {
let userId = req.body.userId;
let sun = req.body.sun;
let water = req.body.water;
let progress = req.body.progress;
console.log(req.body)
db.run(queries.Save(userId, sun, water, progress),
(message) => {
res.write(`Weather information saved successfully.`);
console.log(`Weather information saved successfully.`);
res.end();
return;
},
(error) => {
res.write(`Error saving weather information`);
console.log('Error saving weather information. ', error);
res.end();
return;
});
} catch (er) {
res.send('Error: ' + er)
}
});
And I need to get my userId somehow, from the server.
Back-end:
app.post('/account/login', (req, res) => {
try {
let email = req.body.email;
let password = req.body.password;
db.run(queries.Login(email, password),
(message) => {
let id = '';
if (message.length > 0)
id = message[0].ID;
if (id > 0) {
res.write(`Login was successful, UserId: ${id}`);
console.log(`Login was successful, UserId: ${id}`);
}
else {
res.write(`Login ecnountered error! Please specify valid EMAIL and PASSWORD`);
console.log('Login ecnountered error! Please specify valid EMAIL and PASSWORD. ');
}
res.end();
return;
},
(error) => {
res.write(`Login ecnountered an error! Please specify valid EMAIL and PASSWORD`);
console.log('Login ecnountered an error! Please specify valid EMAIL and PASSWORD. ', error);
res.end();
return;
});
} catch (er) {
res.send('Error: ' + er)
}
});
Front-end:
getUserId =() => {
let getUserIdUrl = `http://localhost:10240/weather/fetch?user=${this.state.userId}`
let queryParams = {
"userId": this.state.userId
}
fetch(getUserIdUrl, {
method: 'get',
body: JSON.stringify(queryParams),
headers: {
"Content-Type": "application/json"
}
})
.then(response => response.json())
.then(data => {
if (data.code == "200") {
if (data.userId) {
this.setState({
userId: data.userId
})
}
} else {
console.log(`We've encountered a problem`);
}
})
.catch((error) => {
console.error('Error:', error);
})
}
Code in which user updates state:
onChangeOutdoor = e => {
this.setState({
outdoor: +e.target.value
})
}
onChangeWater = e => {
this.setState({
water: +e.target.value
})
}
Formula(e) {
e.preventDefault();
let joinedOut = this.state.outBeforeCalc.concat(this.state.outdoor);
this.setState({ outBeforeCalc: joinedOut });
let joinedWater = this.state.waterBeforeCalc.concat(this.state.water);
this.setState({ waterBeforeCalc: joinedWater });
let OutdoorCo;
let WaterCo;
this.setState({}, () => {
let outSum = this.state.outBeforeCalc.reduce((a, b) => a + b, 0);
OutdoorCo = (outSum * 100) / 15;
let waterSum = this.state.waterBeforeCalc.reduce((a, b) => a + b, 0);
WaterCo = (waterSum * 100) / 80;
const sum = (WaterCo + OutdoorCo) / 2;
this.setState({
value: +sum,
waterPercentage: WaterCo,
outdoorPercentage: OutdoorCo
});
this.setState({
// hits: [],
// desc: [],
outdoor: 0,
water: 0
});
});
}
...
<form onSubmit={e => this.Formula(e) && this.addHealthData }>
<div>
<div className="field1">
<TextField
id="standard-number1"
label="Outdoor Time"
type="number"
value={`${this.state.outdoor}`}
onChange={this.onChangeOutdoor}
InputLabelProps={{
shrink: true,
}}
/>
outdoor percentage : {this.state.outdoorPercentage}
</div>
<div className="field2" noValidate autoComplete="off">
<TextField
id="standard-number2"
label="Water Consumption"
type="number"
value={`${this.state.water}`}
onChange={this.onChangeWater}
InputLabelProps={{
shrink: true,
}}
/>
water percentage : {this.state.waterPercentage}
</div>
</div>
<Button variant="contained" color="secondary" style={{ marginTop: 25, marginLeft: '44%' }} type="submit" onKeyDown={keyPress}>
{" "}
Get Energy Level{" "}
</Button>
</form>
<div className="progress-div">
<LinearProgress
classes={{barColorPrimary: classes.barColorPrimary}}
variant="determinate"
style={{ margin: 20, width: 400, marginLeft: '36%', height: 50 }}
value={this.state.value <= 100 ? this.state.value : 100}
/>
<h4 style={{marginLeft:"45%"}}>
{typeof this.state.value === "number"
? `${this.state.value}%`
: this.state.value}
</h4>
</div>
{/* <ProgressBar width={400} percent={this.state.percent} /> */}
</div>
Thanks!
There is a React form. What I want to achieve: I fill out the form. I click on the submit button. Then this form should generate a PDF that is sent as an attachment through Nodemailer. I already achieved sending the email and generating the PDF (can download it), but I do not know how to attach that PDF to the email. There is a signature too, that I could already attach to the PDF. I just want this PDF to be sent as an attachment in the email. Now when I submit, it just downloads the PDF for me (which is good) and only sends a simple email (no PDF attachment).
Server:
app.post('/create-pdf', (req, res) => {
pdf.create(pdfTemplate(req.body), {}).toFile('result.pdf', (err) => {
if (err) {
res.send(Promise.reject());
}
res.send(Promise.resolve());
});
});
app.post('/api/contact', contact);
app.get('/fetch-pdf', (req, res) => {
res.sendFile(`${__dirname}/result.pdf`);
});
Nodemailer:
exports.contact = async (req, res) => {
const htmlEmail = `
<h1>Hello!</h1>
`;
const mailOptions = {
from: req.body.name,
to: 'xxxxxxxxxxxxxxxxxxx',
subject: 'Message',
html: htmlEmail,
attachments: [{}],
};
const transporter = nodemailer.createTransport({
host: 'smtp.ethereal.email',
port: 587,
auth: {
user: 'xxxxxxxxxxxxxxx',
pass: 'xxxxxxxxxxxxxxx',
},
});
transporter.sendMail(mailOptions, (err, data) => {
if (err) {
res.json({
status: 'fail',
});
} else {
res.json({
status: 'success',
});
}
});
return console.log('email sent');
};
Client:
class Contact extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
phone: '',
message: '',
trimmedDataURL: null,
file: null,
};
}
sigPad = {};
clear = () => {
this.sigPad.clear();
};
trim = (e) => {
e.preventDefault();
this.setState({ trimmedDataURL: this.sigPad.getTrimmedCanvas().toDataURL('image/png') });
this.fileUpload(this.state.file).then((response) => {
console.log(response);
});
};
fileUpload(file) {
const url = 'http://localhost:3000/create-pdf';
const formData = new FormData();
formData.append('file', file);
const config = {
headers: {
'content-type': 'multipart/form-data',
},
};
return post(url, formData, config);
}
handleSubmit(e) {
e.preventDefault();
axios({
method: 'POST',
url: '/api/contact',
data: this.state,
}).then((response) => {
if (response.data.status === 'success') {
console.log('success');
} else if (response.data.status === 'fail') {
console.log('not success');
}
});
axios
.post('/create-pdf', this.state)
.then(() => axios.get('fetch-pdf', { responseType: 'blob' }))
.then((res) => {
const pdfBlob = new Blob([res.data], { type: 'application/pdf' });
saveAs(pdfBlob, 'newpdf.pdf');
});
}
render() {
return (
<div className="contact">
<h1>GET IN TOUCH</h1>
<div>
<form onSubmit={this.handleSubmit.bind(this)} method="POST">
<label htmlFor="name">NAME</label>
<br />
<input
onChange={this.onNameChange.bind(this)}
value={this.state.name}
type="text"
name="name"
placeholder="Your full name..."
/>
<br />
<label htmlFor="phone">PHONE</label>
<br />
<input
onChange={this.onPhoneChange.bind(this)}
type="text"
name="phone"
placeholder="Your phone number..."
value={this.state.phone}
/>
<br />
<label htmlFor="email">EMAIL</label>
<br />
<input
onChange={this.onEmailChange.bind(this)}
type="text"
name="email"
placeholder="Your email address..."
value={this.state.email}
/>
<br />
<label htmlFor="message">MESSAGE</label>
<br />
<textarea
onChange={this.onMessageChange.bind(this)}
type="text"
name="message"
value={this.state.message}
rows="5"
/>
<button className="contact-button" type="submit">
Send
</button>
<button onClick={this.createAndDownloadPdf}>download</button>
<br />
<SignatureCanvas
canvasProps={{ className: styles.sigPad }}
backgroundColor="gray"
ref={(ref) => {
this.sigPad = ref;
}}
/>
<img
alt=""
className={styles.sigImage}
src={this.state.trimmedDataURL}
style={{ width: '50px' }}
/>
<button className={styles.buttons} onClick={this.clear}>
Clear
</button>
<button
className={styles.buttons}
onClick={this.trim}
onChange={this.onFileChange.bind(this)}
>
Trim
</button>
</form>
</div>
</div>
);
}
onNameChange(event) {
this.setState({ name: event.target.value });
}
onEmailChange(event) {
this.setState({ email: event.target.value });
}
onPhoneChange(event) {
this.setState({ phone: event.target.value });
}
onMessageChange(event) {
this.setState({ message: event.target.value });
}
onFileChange(e) {
this.setState({ file: e.target.files[0] });
}
}
export default Contact;
attachments: [
{
filename: 'result.pdf',
path: '../grovespine/result.pdf',
},
],
a new result.pdf is always generated in my folder and just attach that to the nodemailer
I save an email address in mysql bdd, and I would like to send an email to this address with nodemailer.
but I can't get the email in the back-end.
How can i get the email address from back-end please ?
I use apollo server for my back-end, and I use react-apollo for the frontend. I connect to my server with axios. But I can't find a way to retrieve the email address entered in the frontend.
My front-end code :
const CREATE_USER = gql`
mutation createUser($firstName: String!, $lastName: String!, $email: String!) {
createUser(firstName: $firstName, lastName: $lastName, email: $email) {
id
firstName
lastName
email
}
}
`;
class DataInput extends Component {
constructor(props) {
super(props);
this.state = {
firstName: '',
lastName: '',
email: ''
}
}
handleSubmit(e){
e.preventDefault();
axios({
method: "POST",
url:"http://localhost:4000/graphql",
data: this.state
}).then((response)=>{
if (response.data.status === 'success'){
alert("Message Sent.");
this.resetForm()
}else if(response.data.status === 'fail'){
alert("Message failed to send.")
}
})
}
render() {
const { firstName, lastName, email } = this.state
return (
<div>
<div className="flex flex-column mt3">
<input
className="mb2"
value={firstName}
onChange={e => this.setState({ firstName: e.target.value })}
type="text"
placeholder="John"
/>
<input
className="mb2"
value={lastName}
onChange={e => this.setState({ lastName: e.target.value })}
type="text"
placeholder="Do"
/>
<input
className="mb2"
value={email}
onChange={e => this.setState({ email: e.target.value })}
type="text"
placeholder="your#email.com"
/>
</div>
<Mutation mutation={CREATE_USER} variables={{ firstName, lastName, email }}>
{ createUser => <button onClick={createUser}> Submit </button> }
</Mutation>
</div>
)
}
}
And my back-end function for send email :
const sendCertificate = () => {
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL,
pass: process.env.PASSWORD,
},
});
transporter.verify((error, success) => {
if (error) {
console.log(error);
} else {
console.log('Server is ready to take messages');
}
});
transporter.sendMail(email, (err, data) => {
if (err) {
console.log(err)
}
else {
console.log('Success');
}
transporter.sendMail({
from: "sendcertificate#gmail.com",
to: email,
subject: "Submission was successful",
text: `Hello ${firstName} ${lastName}\n`
}, function(error, info){
if(error) {
console.log(error);
} else{
console.log('Message sent: ' + info.response);
}
});
}
)
}