React Native Sending Email - node.js

Goodday everyone, I am using AWS SES for sending a email, the storyline is, if the user forgot their password, the user will put their email address in the TextInput and it will send a code via email, (please refer to the image below)
note: in my AWS SES, my account is already verified,
this is my sample code
import React, {useState, createRef} from 'react';
//i dont know if i am doing right here
const submitForm = ({ event }) => {
const payload = {
url: '/user/forgotpassword',
email: this.state.Email,
};
post(payload)
.then(() => {
// on success, clear any errors and set submitted state to true
this.useState({ error: null, submitted: true });
})
.catch((error) => {
// on error, update error state with the error message and set submitted to false
this.setState({ error: error.message, submitted: false });
});
};
<View style={formStyles.SectionStyle}>
<Text style={formStyles.label1}>Email Address:</Text>
<TextInput
name="email"
id="email"
style={formStyles.inputStyle}
onChangeText={(text) => this.setState({ Email: text })}
placeholder="Enter Email Address"
placeholderTextColor="#8b9cb5"
autoCapitalize="none"
keyboardType="email-address"
returnKeyType="next"
underlineColorAndroid="#f000"
blurOnSubmit={false}
/>
</View>
<Hoverable>
{isHovered => (
<TouchableOpacity
style={{
backgroundColor: isHovered ? '#FFFFFF':'#00ADEF',
borderWidth: 1,
color: '#FFFFFF',
borderColor: '#008ABE',
height: 37,
width: '90%',
alignItems: 'center',
borderRadius: 8,
marginTop: 20,
marginLeft: 50,
marginRight: 50,
//
}}
onPress={() => submitForm()}
activeOpacity={0.5}>
<Text style={{
color: isHovered ? '#00ADEF':'#FFFFFF',
paddingVertical:5,
fontSize: 18,
}}>Proceed to Password Reset</Text>
</TouchableOpacity>
)}
</Hoverable>
node.js api
async function forgotpassword(req, res, next){
var nodemailer = require('nodemailer');
let transporter = nodemailer.createTransport({
host: "email-smtp.ap-southeast-1.amazonaws.com",
port: 465,
secure: true,
auth: {
user: "******************",
pass: "******************"
}
});
var mailOptions = {
from: 'support#ecomerce.com',
to: 'testingfor573#gmail.com',
subject: 'Sending Email using Node.js',
text: 'That was easy!'
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
}
this is the error

For this create a state variable called Email and store its value.
On Pressing the submit button use this value to send mail..
Like this -
In your constructor
this.state = {
...
Email: "",
...
}
Your `` function should look like this -
const submitForm = ({ event }) => {
const payload = {
url: '/user/forgotpassword',
email: this.state.Email,
};
post(payload)
.then(() => {
// on success, clear any errors and set submitted state to true
this.setState({ error: null, submitted: true });
})
.catch((error) => {
// on error, update error state with the error message and set submitted to false
this.setState({ error: error.message, submitted: false });
});
};
Render code
<View style={formStyles.SectionStyle}>
<Text style={formStyles.label1}>Email Address:</Text>
<TextInput
name="email"
id="email"
style={formStyles.inputStyle}
onChangeText={(text) => this.setState({ Email: text })}
placeholder="Enter Email Address"
placeholderTextColor="#8b9cb5"
autoCapitalize="none"
keyboardType="email-address"
returnKeyType="next"
underlineColorAndroid="#f000"
blurOnSubmit={false}
/>
</View>
<Hoverable>
{(isHovered) => (
<TouchableOpacity
style={{
backgroundColor: isHovered ? '#FFFFFF' : '#00ADEF',
borderWidth: 1,
color: '#FFFFFF',
borderColor: '#008ABE',
height: 37,
width: '90%',
alignItems: 'center',
borderRadius: 8,
marginTop: 20,
marginLeft: 50,
marginRight: 50,
//
}}
onPress={() => submitForm()}
activeOpacity={0.5}>
<Text
style={{
color: isHovered ? '#00ADEF' : '#FFFFFF',
paddingVertical: 5,
fontSize: 18,
}}>
Proceed to Password Reset
</Text>
</TouchableOpacity>
)}
</Hoverable>

Related

how to implement subscriptions to next.js app (apollo)?

i have a simple app, that fetch my database via graphql node.js server, and i want to implement subscriptions to it, backend is already written, but i don`t know what to do in frontend.
so i have a query and subscription, and i`m returning a map of data with messages and displaying it in my application, what i need to update, to make it work with subscriptions?
export const SUBSCRIPTION_MESSAGES = gql`
subscription {
messageCreated {
content
id
user
}
}
`;
export const GET_MESSAGES = gql`
query {
messages {
content
id
user
}
}
`;
<Messages user={state.user} />
--------------------
import { useQuery, useSubscription } from "#apollo/client";
import { useEffect } from "react";
import { GET_MESSAGES, SUBSCRIPTION_MESSAGES } from "../graphql/queries";
const Messages = ({ user }: any) => {
const { subscribeToMore, data } = useQuery(GET_MESSAGES);
console.log(subscribeToMore);
useEffect(() => {
subscribeToMore({
document: SUBSCRIPTION_MESSAGES,
updateQuery: (prev, { subscriptionData }: any) => {
if (!subscriptionData.data) return prev;
const newMessage = subscriptionData.data.messageCreated;
return Object.assign({}, prev, {
messages: [newMessage, ...prev.messages],
});
},
});
}, []);
if (!data) {
console.log("lol");
return null;
}
return (
<div>
{data.messages.map(({ id, user: messageUser, content }: any) => (
<div
key={id}
style={{
display: "flex",
justifyContent: user == messageUser ? "flex-end" : "flex-start",
paddingBottom: "1em",
}}
>
{user != messageUser && (
<div
style={{
height: 50,
width: 50,
marginRight: "0.5em",
border: "2px solid #e5e6ea",
borderRadius: 25,
textAlign: "center",
fontSize: "18pt",
paddingTop: 5,
}}
>
{messageUser.slice(0, 2).toUpperCase()}
</div>
)}
<div
style={{
background: user == messageUser ? "#58bf56" : "#e5e6ea",
color: user == messageUser ? "white" : "black",
paddingBottom: "1em",
borderRadius: "1em",
maxWidth: "60%",
padding: "10px",
}}
>
{content}
</div>
</div>
))}
</div>
);
};
export default Messages;

FFMPEG: Cannot read properties of undefined (reading 'format')

I am currently to convert a video file to produce a thumbnail through ffmpeg, react-dropzone, and express. However I keep getting a error of "Cannot read properties of undefined (reading 'format')" in my console. For some reason it can not read the "metadata.format.duration" in my program, I have checked if ffmpeg is properly installed by running the ffmpeg --version in my console, and I get all the details, along with ffprobe --version as well.
Here is my code:
upload.js
router.post("/thumbnail", (req, res) => {
let thumbsFilePath ="";
let fileDuration ="";
// req.body.filepath
ffmpeg.ffprobe(req.body.filepath, function(err, metadata){
console.dir(metadata);
console.log(metadata.format.duration);
fileDuration = metadata.format.duration;
})
ffmpeg(req.body.filepath) //req.body.filepath
.on('filenames', function (filenames) {
console.log('Will generate ' + filenames.join(', '))
console.log(filenames);
thumbsFilePath = "./uploads/thumbnails/" + filenames[0];
})
.on('end', function () {
console.log('Screenshots taken');
return res.json({ success: true, thumbsFilePath: thumbsFilePath, fileDuration: fileDuration})
})
.screenshots({
// Will take screens at 20%, 40%, 60% and 80% of the video
count: 3,
folder: './uploads/thumbnails',
size:'320x240',
// %b input basename ( filename w/o extension )
filename:'thumbnail-%b.png'
});
})
FrontEnd drop code:
AddVideo.js
const onDrop = (files) => {
let formData = new FormData();
const config = {
header: { 'content-type': 'multipart/form-data' }
}
console.log(files)
formData.append("file", files[0])
axios.post('http://localhost:5000/api/upload/uploadfiles', formData, config)
.then(response => {
if (response.data.success) {
let variable = {
filePath: response.data.filePath,
fileName: response.data.fileName
}
setFilePath(response.data.filePath)
//gerenate thumbnail with this filepath !
axios.post('http://localhost:5000/api/upload/thumbnail', variable)
.then(response => {
if (response.data.success) {
setDuration(response.data.fileDuration)
setThumbnail(response.data.thumbsFilePath)
} else {
alert('Failed to make the thumbnails');
}
})
} else {
alert('failed to save the video in server')
}
})
}
return (
<div style={{ maxWidth: '700px', margin: '2rem auto' }}>
<div style={{ textAlign: 'center', marginBottom: '2rem' }}>
{/* <Title level={2} > Upload Video</Title> */}
</div>
<FormControl>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Dropzone
onDrop={onDrop}
multiple={false}
maxSize={800000000}>
{({ getRootProps, getInputProps }) => (
<div style={{ width: '300px', height: '240px', border: '1px solid lightgray', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
{...getRootProps()}
>
<input {...getInputProps()} />
<Icon type="plus" style={{ fontSize: '3rem' }} />
</div>
)}
</Dropzone>
</div>
</FormControl>
</div>
)
}
The video I am trying to upload is a mp4 file. I am using fluent-ffmpeg as a dependency.

How to do payment with stripe in react native?

I'm creating a react native app and I need to do payment with stripe. Is there any way to do it with or without using any third-party libraries?
And I am able to create a Token with fetch method by accessing stripe API with the following code snippet.
Code Snippet
var cardDetails = {
'card[number]': this.state.cardData.values.number.replace(/ /g, ''),
'card[exp_month]': this.state.cardData.values.expiry.split('/')[0],
'card[exp_year]': this.state.cardData.values.expiry.split('/')[1],
'card[cvc]': this.state.cardData.values.cvc
};
var formBody = [];
for(var property in cardDetails){
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(cardDetails[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
fetch('https://api.stripe.com/v1/tokens', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer '+ STRIPE_PUBLISHABLE_KEY
},
body: formBody
})
.then(responseJson => {
responseJson.json().then(solved=>{
cardToken =solved.id;
})
This is what I tried.
Here I used the react-native-credit-card-input library for taking credit card detail. I am new to react-native. And I don't know how to implement the code after this. I am able to get the token from the stripe by accessing 'https://api.stripe.com/v1/tokens' this URL with the above code snippet. But when I am going to create a charge with that token it gives me an error ('https://api.stripe.com/v1/charges'). What is the correct flow to create a payment in stripe with react-native?
import React, {Component} from 'react';
import {
View,
Text,
TouchableOpacity,
TextInput,
Platform,
StyleSheet,
StatusBar,
Alert,
Image,
ScrollView,
Animated,
Dimensions,
Modal,
} from 'react-native';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import Feather from 'react-native-vector-icons/Feather';
import {
CreditCardInput,
LiteCreditCardInput,
} from 'react-native-credit-card-input';
class stripePay extends Component {
constructor(props) {
super(props);
this.state = { cardData: { valid: false },tokenCRD:'' };
}
ContFunction = () => {
this.getCreditCardToken();
};
getCreditCardToken = () => {
var cardToken;
var STRIPE_PUBLISHABLE_KEY = 'pk_test_*****************';
var STRIPE_SECRET_KEY ='sk_test_*************************';
var cardDetails = {
'card[number]': this.state.cardData.values.number.replace(/ /g, ''),
'card[exp_month]': this.state.cardData.values.expiry.split('/')[0],
'card[exp_year]': this.state.cardData.values.expiry.split('/')[1],
'card[cvc]': this.state.cardData.values.cvc
};
var amount= 1*100;
var formBody = [];
for(var property in cardDetails){
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(cardDetails[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
fetch('https://api.stripe.com/v1/tokens', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer '+ STRIPE_PUBLISHABLE_KEY
},
body: formBody
})
.then(responseJson => {
// console.log(responseJson);
responseJson.json().then(solved=>{
cardToken =solved.id;
// console.log(cardToken);
var paymentbody = {
amount: amount,
currency: 'usd',
description: 'Example charge',
source: cardToken,
//source: "tok_visa",
}
if(cardToken!=""){
//console.log(cardToken);
fetch('https://api.stripe.com/v1/charges', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer '+ STRIPE_SECRET_KEY
},
body:paymentbody
})
.then(response => response.json())
.then(responseJson => {
console.log(responseJson);
})
.catch(error => {
console.error(error);
});
}else{
console.log("Error")
}
});
})
.catch(error => {
console.error(error);
});
}
render() {
return (
<View style={styles.container}>
<StatusBar backgroundColor="#009387" barStyle="light-content" />
<View style={styles.header}>
<Text style={styles.text_header}>Testing Stripe Payment!</Text>
</View>
<View style={[styles.footer]}>
<View style={styles.cardContainer}>
<CreditCardInput
autoFocus
requiresName
requiresCVC
requiresPostalCode
labelStyle={styles.label}
inputStyle={styles.input}
validColor={'black'}
invalidColor={'red'}
placeholderColor={'darkgray'}
onFocus={this._onFocus}
// onChange={this._onChange}
onChange={(cardData) => this.setState({ cardData })}
/>
</View>
<View style={styles.button1}>
<TouchableOpacity
style={styles.btnCon}
onPress={() => this.ContFunction()}>
<View
style={styles.btnCon}>
<Text style={[styles.textCon]}>Pay Now</Text>
</View>
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
export default stripePay;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#009387',
},
header: {
flex: 1,
justifyContent: 'flex-end',
paddingHorizontal: 20,
paddingBottom: 30,
},
text_header: {
color: '#fff',
fontWeight: 'bold',
fontSize: 30,
},
footer: {
flex: 3,
backgroundColor: '#fff',
borderTopLeftRadius: 30,
borderTopRightRadius: 30,
paddingHorizontal: 20,
paddingVertical: 30,
},
cardContainer: {
backgroundColor: '#fff',
marginTop: 60,
},
label: {
color: 'black',
fontSize: 12,
},
input: {
fontSize: 16,
color: 'black',
},
button1: {
alignItems: 'center',
marginTop: 40,
// width:'80%',
},
btnCon: {
width: '80%',
height: 50,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
backgroundColor: '#00b530',
},
textCon: {
fontSize: 18,
fontWeight: 'bold',
color: 'white',
},
});
I got the following error.
All stripe payments can be handled through api using fetch, so there is no need in using 3rd party libraries.
You need to create a customer, add the card to the customer, then create the payment, create one-time-use card token and confirm the payment with the card token.
Payment verification is handled through the link in response, which is supposed to be opened in browser, where the user can confirm the payment manually. In this case, use the PaymentIntents api.

React Native - can't import mongoose on the front end(but it works from the backend)

I cant import mongoose on the frontend but it worked on the backend.
I have a separate directory for the backend. I have some code to add a couple users to my database. Here it is.....
import mongoose from 'mongoose';
import User from './models/user';
const users = [
{
id: 1,
username: 'Matthew',
password: 'Smith',
},
{
id: 2,
username: 'Deborah',
password: 'Smith',
},
];
// Connect to MongoDB
mongoose.connect('mongodb://localhost/users');
// Go through each movie
users.map(data => {
// Initialize a model with movie data
const user = new User(data);
// and save it into the database
user.save();
});
The above code works.
Now I want my login screen to accept the username and password and send it to the database. I'm stuck because I cant even import mongoose(you'll see below that I commented it out).
The error I get is:
'TransformError: [directory path of my project]/node_modules/mongoose/lib/drivers/index.js: require() must have a single string literal argument: [directory path of my project]/mongoose/lib/drivers/index.js:7'
The login screen code:
import React from 'react';
import { StyleSheet, Text, View,Navigator,TextInput, KeyboardAvoidingView,TouchableOpacity,
AsyncStorage,
} from 'react-native';
//import mongoose from 'mongoose';
import {
StackNavigator,
} from 'react-navigation';
export default class Login extends React.Component {
//check to see if user has logged in already
componentDidMount(){
this._loadInitialState().done();
}
//get info from async storage
_loadInitialState = async () => {
var value = await AsyncStorage.getItem('user');
if(value != null){ //if the user is already logged in
this.props.navigation.navigate('Profile'); //**profile page that we will create later
}
}
constructor(props){
super(props);
this.state = {
username: '',
password: '',
}
}
render() {
return (
//<View style={styles.container}>
<KeyboardAvoidingView behavior = 'padding' style = {styles.wrapper}>
<View style = {styles.container}>
<Text style={styles.header}> - LOGIN - </Text>
<TextInput
style={styles.textInput} placeholder='Username'
onChangeText={(username) => this.setState({username})}
/>
<TextInput
style={styles.textInput} placeholder='Password'
onChangeText={(password) => this.setState({password})}
/>
</View>
<TouchableOpacity
style={styles.btn}
onPress = {this.login}>
<Text>Log in</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
// </View>
);
}
login = () => {
alert('test');
//send to server
fetch('http://1.1.1.1/3000/users', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password,
})
})
//handle response
.then((response) => response.json())
.then((res) => {
//if user and pass exists, then log them in
// res: result
if(res.sucess === true){
AysncStorage.setItem('user',res.user);
this.props.navigation.navigate('Profile'); //navigate user to profile page
}
//else, tell the user they dont exist in the database
else{
alert(res.message);
}
})
.done();
}
}
const styles = StyleSheet.create({
wrapper: {
flex: 1,
},
container: {
flex: 1,
backgroundColor: '#2896d3',
alignItems: 'center',
justifyContent: 'center',
paddingLeft: 40,
paddingRight: 40,
},
header: {
fontSize: 24,
marginBottom: 60,
color: '#fff',
justifyContent: 'center',
paddingLeft: 40,
paddingRight: 40,
},
textInput: {
alignSelf: 'stretch',
paddingLeft: 16,
marginBottom: 20,
backgroundColor: '#fff',
},
btn: {
alignSelf: 'stretch',
padding: 20,
marginBottom: 20,
backgroundColor: '#01c853',
alignItems: 'center',
},
});
Why can't I import it?
Mongoose's browser library doesn't support mongoose.connect(). It only supports schemas and document validation, it can't actually connect to MongoDB or save documents currently.
Just today I found out about Mongoose's browser module while trying to solve similar problems to you. It's a very limited version of Mongoose but will let you do validation against schemas, for example, on the front-end. Sorry I only found this 6 months after your post.

React Native and node js - fetching input values and using them in controllers

I have a react native component that has username and password text input fields. I want the values which are entered to be available in the node js controller to query my db. I am not able to use AsyncStorage as I cannot import AsyncStorage inside controller. How do I make this work? Please help.
My login screen:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Image,
TextInput,
Alert,
Navigator,
TouchableHighlight,
BackAndroid,
ScrollView,
AsyncStorage,
} from 'react-native';
var _navigator;
import Container from './Container';
import Button from './Button';
import Label from './Label';
import ImageContainer from './ImageContainer';
import RegisterView from './RegisterView';
export default class LoginView extends Component {
constructor(props) {
super(props);
this.state = {
userName: '',
userPass: '',
error:null,
};
}
_navigate(){
this.props.navigator.push({
name: 'RegisterView', // Matches route.name
})
}
_handleAdd = () => {
if((this.state.userName)!=="" && (this.state.userPass)!=="" ){
const data = {
username: this.state.userName,
password: this.state.userPass
}
// Serialize and post the data
const json = JSON.stringify(data)
fetch('http://10.0.2.2:3000/users/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: json
})
.then((response) => response.json())
.then((res) => {
if (res.error) {
alert(res.error)
} else {
this.props.navigator.push({
name: 'CheckList', // Matches route.name
})
}
})
.catch(() => {
alert('There was an error logging in.');
})
.done()
}
else{
alert('Cannot be empty!');
}
}
render() {
return (
<ScrollView style={styles.scroll}>
<ImageContainer>
<Image
style={{width:110,height: 110, justifyContent: 'center',
alignItems: 'center'}}
source={require('./Logo.png')}>
</Image>
</ImageContainer>
<Container>
<TextInput
placeholder="Username"
style={styles.textInput}
onChangeText={(text) => this.setState({userName:text})}
autoCapitalize="none"
autoCorrect={false}
onSubmitEditing={(event) => {
const{userName}=this.state.userName;
const{onSubmitEditing}=this.props;
if(!userName) return
onSubmitEditing(userName)
this.refs.SecondInput.focus();
}}
/>
<TextInput
placeholder="Password"
ref='SecondInput'
secureTextEntry={true}
onChangeText={(text) => this.setState({userPass:text})}
style={styles.textInputPass}
/>
</Container>
<Container>
<Button
label="Sign In"
styles={{button: styles.primaryButton, label:
styles.buttonWhiteText}}
onPress={() => this._handleAdd()}
/>
</Container>
<Container>
<TouchableHighlight onPress={ () => this._navigate()}
underlayColor= 'transparent'>
<Text style ={styles.buttonBlackText}>New? Register
</Text>
</TouchableHighlight>
</Container>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
scroll: {
backgroundColor: '#FFFFFF',
padding: 30,
flexDirection: 'column'
},
buttonWhiteText: {
fontSize: 20,
color: '#FFF'
},
buttonBlackText: {
fontSize: 20,
marginTop: 20,
textAlign:'center',
color: '#000000'
},
textInput: {
fontSize: 20,
backgroundColor: '#FFF',
marginBottom: 20,
marginTop: 20
},
textInputPass: {
fontSize: 20,
backgroundColor: '#FFF',
marginBottom: 20,
},
primaryButton: {
backgroundColor: '#34A853'
},
});
Controller to query the username from db. For now, it's hardcoded.
import Profile from '../models/profile';
import moment from 'moment';
export const index = (req, res, next) => {
Profile.find({'username': 'John'}).lean().exec((err, profiles) =>
res.json(
// Iterate through each movie
{ profiles: profiles.map(profile => ({
...profile,
}))}
));
};

Resources