Stripe js: uncompleted payment, payment is not defined - node.js

So I am working on payment processing with stripe. When I go to the payments on stripe it says they are uncompleted, the customer did not define the payment method...
React component
useEffect(() => {
const getClientSecret = async () => {
const responce = await axios({
method: "post",
url: `/payments/create?total=${getBasketTotal(basket) * 100}`,
});
setClientSecret(responce.data.clientSecret);
};
getClientSecret();
}, [basket]);
console.log("THE SECRET IS >>> ", clientSecret);
const submitHandler = async (e) => {
//stripe magic
e.preventDefault();
setProcessing(true);
const payload = await stripe
.confirmCardPayment(clientSecret, {
payment_method: {
card: elements?.getElement(CardElement),
},
})
.then(({ paymentIntent }) => {
//paymentIntent = payment confirmation
console.log(paymentIntent);
setSucceeded(true);
setError(null);
setProcessing(false);
dispatch({
type: "EMPTY_BASKET",
});
history.replace("/orders");
});
};
const changeHandler = (e) => {
//stripe magic
setDisabled(e.empty);
setError(e.error ? e.error.message : "");
};
return (
<div className="payment">
<div className="payment__container">
<h1>
Checkout(<Link to="/checkout">{basket?.length} items</Link>)
</h1>
<div className="payment__section">
<div className="payment__title">
<h3>Delivery Address</h3>
</div>
<div className="payment__address">
<p>{user?.email}</p>
<p>123 React Lane</p>
<p>Los Angeles, CA</p>
</div>
</div>
<div className="payment__section">
<div className="payment__title">
<h3>Review items and delivery</h3>
</div>
<div className="payment__items">
<FlipMove>
{basket.map((item) => (
<div>
<CheckoutProduct
id={item.id}
title={item.title}
image={item.image}
price={item.price}
rating={item.rating}
/>
</div>
))}
</FlipMove>
</div>
</div>
<div className="payment__section">
<div className="payment__title">
<h3>Payment Method</h3>
</div>
<div className="payment__details">
<form onSubmit={submitHandler}>
<CardElement onChange={changeHandler} />
<div className="payment__priceContainer">
<CurrencyFormat
renderText={(value) => (
<>
<h3>Order Total: {value}</h3>
</>
)}
decimalScale={2}
value={getBasketTotal(basket)}
displayType={"text"}
thousandSeperator={true}
prefix={"$"}
/>
<button
disabled={
processing || disabled || succeeded || clientSecret === null
}
>
<span>{processing ? <p>Processing</p> : "Buy Now"}</span>
</button>
</div>
{error && <div>{error}</div>}
</form>
</div>
</div>
</div>
</div>
);
}
export default Payment;
Node JS
const app = express();
// - Middlewares
app.use(cors({ origin: true }));
app.use(express.json());
// - API routes
app.get("/", (request, responce) => responce.status(200).send("hello world"));
app.post("/payments/create", async (request, responce) => {
const total = request.query.total;
console.log("Payment Request Received >>> ", total);
const paymentIntent = await stripe.paymentIntents.create({
amount: total,
currency: "usd",
});
// OK - Created
responce.status(201).send({
clientSecret: paymentIntent.client_secret,
});
});
// - Listen command
exports.api = functions.https.onRequest(app);
I have two questions: 1st, is this going to b a problem when working on order history? an 2nd, how do I fix this?
Thank you in advance

Related

Why are my POST and PUT requests from Node/Express not working in React/Redux? My GET and DELETE requests all work fine. All requests work in Postman

So, I have the issue that everything works in Postman and my GET and DELETE requests even work in the full-stack program (Node/Express, React/Redux/Hooks, Microsoft SQL Server), but my POST and PUT requests are not working. As you can see in the image below, I have 403 errors and those lines are from "console.log(data);", not my error handler/catcher, so it is a "good" request, but something is not authorizing. Console logs and service file to show that data is passing, but not being accepted can be viewed here.
I have tried many, many solutions and much research. As far as I understand, this COULD be an issue with CORS, but I'm really not sure. Also, in Redux DevTools, it does not show my "UPDATE_DEVICE" OR "CREATE_DEVICE" actions, so I know that they are not even being accepted.
Here is code from AddDevice:
import { useDispatch } from "react-redux";
import { createDevice } from "../actions/devices";
const AddDevice = () => {
const initialDeviceState = {
id: null,
title: "",
detail: "",
published: false
};
const [device, setDevice] = useState(initialDeviceState);
const [submitted, setSubmitted] = useState(false);
const dispatch = useDispatch();
const handleInputChange = event => {
const { name, value } = event.target;
setDevice({ ...device, [name]: value });
};
const saveDevice = () => {
const { title, detail } = device;
dispatch(createDevice(title, detail))
.then(data => {
setDevice({
id: data.id,
title: data.title,
detail: data.detail,
published: data.published
});
setSubmitted(true);
console.log(data);
})
.catch(e => {
console.log(e);
});
};
const newDevice = () => {
setDevice(initialDeviceState);
setSubmitted(false);
};
return (
<div className="submit-form">
{submitted ? (
<div>
<h4>You submitted successfully!</h4>
<button className="btn btn-success" onClick={newDevice}>
Add
</button>
</div>
) : (
<div>
<div className="form-group">
<label htmlFor="title">Title</label>
<input
type="text"
className="form-control"
id="title"
required
value={device.title}
onChange={handleInputChange}
name="title"
/>
</div>
<div className="form-group">
<label htmlFor="detail">Detail</label>
<input
type="text"
className="form-control"
id="detail"
required
value={device.detail}
onChange={handleInputChange}
name="detail"
/>
</div>
<button onClick={saveDevice} className="btn btn-success">
Add
</button>
</div>
)}
</div>
);
};
export default AddDevice;
And here is from my code for updating the device:
useEffect(() => {
getDevice(props.match.params.id);
}, [props.match.params.id]);
const handleInputChange = event => {
const { name, value } = event.target;
setCurrentDevice({ ...currentDevice, [name]: value });
};
const updateStatus = status => {
const data = {
id: currentDevice.id,
title: currentDevice.title,
detail: currentDevice.detail,
published: status
};
dispatch(updateDevice(currentDevice.id, data))
.then(response => {
console.log(response);
setCurrentDevice({ ...currentDevice, published: status });
setMessage("The status was updated successfully!");
})
.catch(e => {
console.log(e);
});
};
const updateContent = () => {
dispatch(updateDevice(currentDevice.id, currentDevice))
.then(response => {
console.log(response);
setMessage("The device was updated successfully!");
props.history.push("/devices");
})
.catch(e => {
console.log(e);
});
};
const removeDevice = () => {
dispatch(deleteDevice(currentDevice.id))
.then(() => {
props.history.push("/devices");
})
.catch(e => {
console.log(e);
});
};
return (
<div>
{currentDevice ? (
<div className="edit-form">
<h4>Device</h4>
<form>
<div className="form-group">
<label htmlFor="title">Title</label>
<input
type="text"
className="form-control"
id="title"
name="title"
value={currentDevice.title}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<label htmlFor="detail">Detail</label>
<input
type="text"
className="form-control"
id="detail"
name="detail"
value={currentDevice.detail}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<label>
<strong>Status:</strong>
</label>
{currentDevice.published ? "Published" : "Pending"}
</div>
</form>
{currentDevice.published ? (
<button
className="m-3 btn btn-sm btn-danger"
onClick={() => updateStatus(false)}
>
UnPublish
</button>
) : (
<button
className="m-3 btn btn-sm btn-danger"
onClick={() => updateStatus(true)}
>
Publish
</button>
)}
<button className="m-3 btn btn-sm btn-danger" onClick={removeDevice}>
Delete
</button>
<button
type="submit"
className="btn btn-success"
onClick={updateContent}
>
Update
</button>
<p>{message}</p>
</div>
) : (
<div>
<br />
<p>Please click on a device.</p>
</div>
)}
</div>
);
};
export default Device;
And finally, this is my server.js code from back-end:
var express = require('express');
var bodyParser = require('body-parser');
const cors = require("cors");
var app = express();
var corsOptions = {
origin: "http://localhost:8083"
};
app.use(cors(corsOptions));
app.use(express.json());
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }));
const db = require('./app/config/db.config');
const Role = db.role;
db.sequelize.sync();
// db.sequelize.sync({ force: true }).then(() => {
// console.log("Drop and re-sync db.");
// initial();
// });
// CODE ABOVE MAY BE NECESSARY FOR DATABASE TESTING, ESPECIALLY IF DATABASE MIGRATION OCCURS BECAUSE THE "initial" FUNCTION ESTABLISHES ROLES, WHICH IS CRUCIAL
require("./app/router/router.js")(app);
var server = app.listen(3000, function () {
var host = server.address().address
var port = server.address().port
console.log("App listening at http://%s:%s", host, port)
})
function initial(){
Role.create({
id: 1,
name: "USER"
});
Role.create({
id: 2,
name: "ADMIN"
});
Role.create({
id: 3,
name: "PM"
});
}
Sending request is in a wrong format.
axios.post (url, data, {...headers here})

Cannot parse to get the token

For some reason I cannot get the token from the localstorage in order to make the request, it says that there is no token. I am using cookie parser. I am trying to create a new category for my shop. It is not recognizing the token, although it is here.
here is my client:
adminDashoard.js
import { useState } from 'react';
import { createCategory } from './api/category';
import isEmpty from 'validator/lib/isEmpty';
import { showErrorMsg, showSuccessMsg } from './helpers/message';
import { showLoading } from './helpers/Loading'
export default function AdminDashboard() {
const [category, setCategory] = useState('');
const [errorMsg, setErrorMsg] = useState('');
const [successMsg, setSuccessMsg] = useState('');
const [loading, setLoading] = useState(false);
const handleMessages= evt =>{
setErrorMsg('');
setSuccessMsg('');
}
const handleCategoryChange = (evt) => {
setErrorMsg('');
setSuccessMsg('');
setCategory(evt.target.value);
}
const handleCategorySubmit = (evt) => {
evt.preventDefault();
if (isEmpty(category)) {
setErrorMsg('Please enter a category')
} else {
const data = { category }
setLoading(true);
createCategory(data)
.then(response => {
setLoading(false);
setSuccessMsg(response.data.successMessage)
})
.catch(err => {
setLoading(false);
setErrorMsg(err.response.data.errorMessage)
console.log(err)
})
}
};
function ShowHeader() {
return (
<div className='bg-dark text-white py-4'>
<div className='container'>
<div className='row'>
<div className='col-md-6'>
<h1>
<i className='fas fa-home'> Dashboard</i>
</h1>
</div>
</div>
</div>
</div>
)
}
function ShowActionBtns() {
return (
<div className='bg-light my-2'>
<div className='container'>
<div className='row pb-3'>
<div className='col-md-4 my-1 '>
<button
className='btn btn-outline-info btn-block'
data-toggle='modal'
data-target='#addCategoryModal'>
<i className=' fas fa-plus'>Add Category</i>
</button>
</div>
<div className='col-md-4 my-1 '>
<button className='btn btn-outline-danger btn-block'>
<i className=' fas fa-plus'>Add Products</i>
</button>
</div>
<div className='col-md-4 my-1 '>
<button className='btn btn-outline-success btn-block'>
<i className=' fas fa-plus'>Add Blog</i>
</button>
</div>
</div>
</div>
</div>
)
}
function ShowCategoryModal() {
return (
<div id='addCategoryModal' className='modal' onClick={handleMessages}>
<div className='modal-dialog modal-dialog-centered modal-lg'>
<div className='modal-content'>
<form onSubmit={handleCategorySubmit}>
<div className='modal-header bg-info text-white'>
<h5 className='modal-title'>Add Category</h5>
<button className='close' data-dismiss='modal'>
<span>
<i className='fas fa-times'></i>
</span>
</button>
</div>
<div className='modal-body my-2'>
{errorMsg && showErrorMsg(errorMsg)}
{successMsg && showSuccessMsg(successMsg)}
{
loading ? (
<div className='text-center'>{showLoading()}</div>
) : (
<>
<label className='text-secondary'> Category</label>
<input
type='text'
className='form-control'
name='category'
value={category}
onChange={handleCategoryChange}
/>
</>
)
}
</div>
<div className='modal-footer'>
<button data-dismiss='modal' className='btn btn-secondary'>Close</button>
<button className='btn btn-info' type='submit'>Submit</button>
</div>
</form>
</div>
</div>
</div>
)
}
return <div>
{ShowHeader()}
{ShowActionBtns()}
{ShowCategoryModal()}
</div>
}
Here is my api file:
import axios from "axios"
export const createCategory = async (formData) => {
const config = {
headers: {
'Content-Type': 'application/json'
},
};
const response = await axios.post('http://localhost:5000/api/category', formData, config);
return response;
}
on the server side,
here is my server.js :
const express=require('express');
const app= express();
const cors=require('cors');
const connectDB= require('./database/db');
const morgan= require('morgan');
const authRoutes= require ('./routes/auth')
const categoryRoutes = require ('./routes/category');
const cookieParser = require('cookie-parser')
//middleware
app.use(cors());
app.use(morgan('dev'));
app.use(express.json());
app.use(cookieParser());
app.use('/api/auth', authRoutes);
app.use('/api/category', categoryRoutes);
connectDB();
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Listening on port ${port}`));
app.get('/', (req, res) =>{
res.send(' hello server')
})
here is my route file :
const express = require('express');
const router = express.Router();
const categoryController = require('../routes/controllers/category');
const {authenticatateJWT} = require('./middleware/authenticator');
router.post('/', authenticatateJWT, categoryController.create);
module.exports = router;
here is my controller:
exports.create = (req, res)=>{
console.log(req.user);
setTimeout(() =>{
res.json({
successMessage: `${req.body.category} was created!`
});
}, 5000)
}
here is my middleware:
const jwt = require('jsonwebtoken');
const { jwtSecret } = require('../../config/keys');
exports.authenticatateJWT = (req, res, next) => {
const token = req.cookies.token;
console.log(token);
if (!token) {
return res.status(401).json({
errorMessage: 'No token. Authorization denied',
});
}
try {
const decoded = jwt.verify(token, jwtSecret);
req.user = decoded.user;
next();
} catch (err) {
console.log('jwt error:', err)
res.status(401).json({
errorMessage: 'Invalid token',
});
}
};

Unable to fetch data from Form using FormData

I am creating an 'edit profile' page for a dashboard the technologies that I use for the same are Next.js, Node.js & MongoDB.
Note: skip to the backend part if you just wanted to know the issue.
Frontend
Firstly,let me explain the Frontend part.
I am using useRef() inorder to reference data(name,bio) in the inputfields. which are working nicely.
Everything is fine the issue is in the handlesbumit() event_handler.
I am using FormData to send my form data to the backend API
If you're thinking why I'm not using a usual body object to send data the reason is that I have to add the profile picture updation later for which I have to send files , which as far I know we can't do that with an Object and yeah just to inform you it works fine if I would have used that Object part but can't use it with profilepicture updation.
The value that I have consoled out for the references are all good, and the rest of the handler is just as it is written can't find anything odd in that.
import { useUser } from '../../../lib/hooks';
import React, { useState, useEffect, useRef } from 'react';
import Head from 'next/head';
import { ImBook, ImListNumbered } from 'react-icons/im';
import { AiFillGithub, AiOutlineTwitter, AiFillFacebook, AiFillInstagram, AiFillLinkedin } from 'react-icons/ai'
import { FaFacebook, FaStackOverflow } from 'react-icons/fa';
const ProfileSection = () => {
const [user, { mutate }] = useUser();
const [isUpdating, setIsUpdating] = useState(false);
const nameRef = useRef();
const profilePictureRef = useRef();
const bioRef = useRef();
const [msg, setMsg] = useState({ message: '', isError: false });
useEffect(() => {
nameRef.current.value = user.name;
bioRef.current.value = user.Bio;
}, [user]);
const handleSubmit = async (event) => {
event.preventDefault();
if (isUpdating) return;
setIsUpdating(true);
console.log(nameRef.current.value); //Testing
console.log(bioRef.current.value); //Testing
const formData = new FormData();
formData.append('name', nameRef.current.value);
formData.append('Bio', bioRef.current.value);
console.log(formData.get('name'));
const res = await fetch('/api/user', {
method: 'PATCH',
body: formData,
});
if (res.status === 200) {
const userData = await res.json();
mutate({
user: {
...user,
...userData.user,
},
});
setMsg({ message: 'Profile updated' });
} else {
setMsg({ message: await res.text(), isError: true });
}
};
return (
<>
<Head>
<title>Settings</title>
</Head>
<main>
<div class="row">
<div class="col s12 m12">
<div className="card-panel br-10">
{msg.message ? <p style={{ color: msg.isError ? 'red' : '#0070f3', textAlign: 'center' }}>{msg.message}</p> : null}
<form onSubmit={handleSubmit}>
<div className="row">
<div className="col s12 m6 l6">
<label htmlFor="name">
Name
<input
required
id="name"
name="name"
type="text"
ref={nameRef}
/>
</label>
</div>
<div className="col s12 m6 l6">
<label htmlFor="bio">
Bio
<textarea
id="bio"
name="bio"
type="text"
ref={bioRef}
/>
</label>
</div>
</div>
<div className="center-align">
<button disabled={isUpdating} className="btn" type="submit" >Save</button>
</div>
</form>
</div>
</div>
</div>
</main>
</>
);
};
const SettingPage = () => {
const [user] = useUser();
if (!user) {
return (
<>
<p>Please sign in</p>
</>
);
}
return (
<>
<ProfileSection />
</>
);
};
export default SettingPage;
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
import { useUser } from '../../../lib/hooks';
import React, { useState, useEffect, useRef } from 'react';
import Head from 'next/head';
import { ImBook, ImListNumbered } from 'react-icons/im';
import { AiFillGithub, AiOutlineTwitter, AiFillFacebook, AiFillInstagram, AiFillLinkedin } from 'react-icons/ai'
import { FaFacebook, FaStackOverflow } from 'react-icons/fa';
const ProfileSection = () => {
const [user, { mutate }] = useUser();
const [isUpdating, setIsUpdating] = useState(false);
const nameRef = useRef();
const profilePictureRef = useRef();
const bioRef = useRef();
const [msg, setMsg] = useState({ message: '', isError: false });
useEffect(() => {
nameRef.current.value = user.name;
bioRef.current.value = user.Bio;
}, [user]);
const handleSubmit = async (event) => {
event.preventDefault();
if (isUpdating) return;
setIsUpdating(true);
console.log(nameRef.current.value);
console.log(bioRef.current.value);
const formData = new FormData();
formData.append('name', nameRef.current.value);
formData.append('Bio', bioRef.current.value);
console.log(formData.get('name'));
const res = await fetch('/api/user', {
method: 'PATCH',
body: formData,
});
if (res.status === 200) {
const userData = await res.json();
mutate({
user: {
...user,
...userData.user,
},
});
setMsg({ message: 'Profile updated' });
} else {
setMsg({ message: await res.text(), isError: true });
}
};
return (
<>
<Head>
<title>Settings</title>
</Head>
<main>
<div class="row">
<div class="col s12 m12">
<div className="card-panel br-10">
{msg.message ? <p style={{ color: msg.isError ? 'red' : '#0070f3', textAlign: 'center' }}>{msg.message}</p> : null}
<form onSubmit={handleSubmit}>
<div className="row">
<div className="col s12 m6 l6">
<label htmlFor="name">
Name
<input
required
id="name"
name="name"
type="text"
ref={nameRef}
/>
</label>
</div>
<div className="col s12 m6 l6">
<label htmlFor="bio">
Bio
<textarea
id="bio"
name="bio"
type="text"
ref={bioRef}
/>
</label>
</div>
</div>
<div className="center-align">
<button disabled={isUpdating} className="btn" type="submit" >Save</button>
</div>
</form>
</div>
</div>
</div>
</main>
</>
);
};
const SettingPage = () => {
const [user] = useUser();
if (!user) {
return (
<>
<p>Please sign in</p>
</>
);
}
return (
<>
<ProfileSection />
</>
);
};
export default SettingPage;
Backend
Now, the backend API for the same handlesubmit() event_handler i.e. 'api/user'
Please ignore the handler, it's just a predefined middleware npm next-connect which itself checks what type of request is coming if its 'PATCH' it will run handler.patch.
The Issue is the value of name & Bio is undefined,which means its not getting values from req.body;
And to check I also consoled out req.body which give out this
The data is correct but req.body is not a Object its a String now and I get it, its because I'm using formdata so how to get the values of name & Bio from this req.body ?
import nextConnect from 'next-connect';
import middleware from '../../../middlewares/middleware';
import { extractUser } from '../../../lib/api-helpers';
const handler = nextConnect();
handler.use(middleware);
handler.get(async (req, res) => res.json({ user: extractUser(req) }));
handler.patch(async (req, res) => {
if (!req.user) {
req.status(401).end();
return;
}
const { name, Bio } = req.body;
await req.db.collection('users').updateOne(
{ _id: req.user._id },
{
$set: {
name:name,
Bio: Bio,
},
},
);
res.json({ user: { name, Bio } });
});
export default handler;
I have encountered a this issue.
I was resolve it by use 2 form, a form use to get user's info as email, password and the other for send user's picture.
Maybe has best practice for this case.

Redirect to profile after login

I am doing google auth with passport and
I wanna redirect to the profile after successfully logged in.
The problem is my method of this.props.history.push('/profile') dont work.
By the way, it's from my router that I need to redirect the user to profile.
All the authentication is in the route.
Here is my code any suggestions?
The if (user) {} is true my only problem is on how to redirect the user.
Route:
const Strategy = require('passport-local').Strategy
const mongoose = require('mongoose')
const GoogleUser = require('../models/google');
const GoogleAuth = new Strategy(
{ passReqToCallback: true, usernameField: "email", passwordField: "id" },
function(req, email, id, done) {
GoogleUser.findOne({ email: req.body.email })
.lean()
.exec((err, user) => {
if (err) {
return done(err, null);
}
if (!user) {
let newUser = new GoogleUser({
email: req.body.email,
id: req.body.id,
name: req.body.name,
token: req.body.token,
image: req.body.image
});
newUser.save((error, inserted) => {
if (error) {
return done(error, null);
}
return done(null, inserted);
});
}
if (user) {
this.props.history.push("/profile");
}
});
}
);
module.exports = GoogleAuth;
Here is the React code if needed:
import React, { Component } from 'react';
import axios from "axios";
import {Redirect} from "react-router-dom"
import styles from '../styles/loginsignup.css'
import logo from '../img/nowyourguest.png'
import 'bootstrap/dist/css/bootstrap.min.css'
import 'jquery/dist/jquery.min.js'
import 'bootstrap/dist/js/bootstrap.min.js'
export default class Login extends Component {
componentDidMount() {
this.googleSDK();
console.log('sfsfd');
}
prepareLoginButton = () => {
console.log(this.refs.googleLoginBtn);
this.auth2.attachClickHandler(this.refs.googleLoginBtn, {},
(googleUser) => {
let profile = googleUser.getBasicProfile();
const email = profile.getEmail()
const id = profile.getId()
const name = profile.getName()
const token = googleUser.getAuthResponse().id_token
const image = profile.getImageUrl()
axios({
url: "/authentication/google",
method: "POST",
data: {
email,
id,
name,
token,
image
}
})
.then(response => {
const isAuthenticated = response.data.isAuthenticated
window.localStorage.setItem('isAuthenticated', isAuthenticated);
this.props.history.push('/profile')
})
.catch(error =>{
this.setState({
errorMessage:error.response.data.message
})
})
})
}
googleSDK = () => {
window['googleSDKLoaded'] = () => {
window['gapi'].load('auth2', () => {
this.auth2 = window['gapi'].auth2.init({
client_id: 'clientID',
cookiepolicy: 'single_host_origin',
scope: 'profile email'
});
this.prepareLoginButton();
});
}
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "https://apis.google.com/js/platform.js?onload=googleSDKLoaded";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'google-jssdk'));
}
state = {
email: '',
password: ''
};
handleSubmit = event => {
event.preventDefault();
const {email, password } = this.state;
axios({
url: "/authentication/signin",
method: "POST",
data: {
email,
password
}
})
.then(response => {
const isAuthenticated = response.data.isAuthenticated
window.localStorage.setItem('isAuthenticated', isAuthenticated);
this.props.history.push('/profile')
})
.catch(error =>{
this.setState({
errorMessage:error.response.data.message
})
})
};
handleChange = event => {
const {name, value} = event.target;
this.setState({
[name]:value
})
}
render() {
const isAuthenticated = window.localStorage.getItem('isAuthenticated');
if (isAuthenticated) {
return <Redirect to='/profile' />
}
return(
<div>
<div>
<nav className="navbar navbar-expand-lg navbar-light bg-info sticky-top" id="shadow">
<a className="navbar-brand text-warning" href="/">NowYourGuest</a>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent" >
<ul className="navbar-nav mr-auto">
<li className="nav-item">
<a className="nav-link text-white" href="/add-your-accomodation">Add your accomodation</a>
</li>
<li className="nav-item active">
<a className="nav-link" href="/login">Login<span className="sr-only">(current)</span></a>
</li>
<li className="nav-item">
<a className="nav-link text-white" href="/signup">Signup</a>
</li>
</ul>
</div>
<form className="form-inline my-2 my-lg-0">
<input className="form-control mr-sm-2" type="search" placeholder="Search for accomodation" aria-label="Search" />
</form>
</nav>
</div>
<div className="container">
<div className="card card-container">
<center><img id="profile-img" className="profile-img" src={logo} /></center>
<p id="profile-name" className="profile-name-card" />
<form onSubmit={this.handleSubmit} className="form-signin">
<span id="reauth-email" className="reauth-email" />
<input type="text" id="inputEmail" className="form-control" name="email" onChange={this.handleChange} placeholder="Email address" required autofocus />
<input type="password" id="inputPassword" className="form-control" name="password" onChange={this.handleChange} placeholder="Password" required />
<center><p style={{color: 'red'}}>{this.state.errorMessage}</p></center>
<button className="btn btn-lg btn-primary btn-block btn-signin" type="submit">Sign in</button>
</form>
<button className="loginBtn loginBtn--google" ref="googleLoginBtn">Login with Google</button>
<a href="#" className="forgot-password">
Forgot the password?
</a>
</div>
</div>
</div>
)
}
}
module.exports = Login;
you need to use "withRouter" from "react-router-dom".
All you need to do is import withRouter and wrap your component at export:
import { withRouter } from "react-router-dom";
//.
//.
//.
export default class (withRouter(Login))
You can also use Redirect component from "react-router-dom" and return it instead
import { Redirect } from "react-router-dom";
// Your code
render() {
if (User) {
return <Redirect to={"/route"} />
}
return(
// If user is not logged...
)
}
I just made 2 different routes in one login and one register.
And it perfectly works.

Cannot POST /Admin

I was connecting react with my api in node js, but when connecting to the login the only thing that appears is "Cannot POST / Admin"
I have used the Postman and it seems that the back part works because the token returns, but I think there is some problem in the connection between the two.
I am working on react, nodejs, redux and mongodb
interface IProps {}
interface IPropsGlobal {
setToken: (t: string) => void;
setName: (u: string) => void;
}
const Login: React.FC<IProps & IPropsGlobal> = props => {
const [username, setUsername] = React.useState("");
const [password, setPassword] = React.useState("");
const [error, setError] = React.useState("");
const updateUsername = (event: React.ChangeEvent<HTMLInputElement>) => {
setUsername(event.target.value);
setError("");
};
const updatePassword = (event: React.ChangeEvent<HTMLInputElement>) => {
setPassword(event.target.value);
setError("");
};
const signIn = () => {
fetch("http://localhost:3006/api/auth", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
username: username,
password: password
})
})
.then(response => {
if (response.ok) {
response
.text()
.then(token => {
console.log(token);
props.setToken(token);
props.setName(username);
});
} else {
setError("Usuario o ContraseƱa incorrectos");
}
})
.catch(err => {
setError("Usuario o ContraseƱa incorrectos.");
});
};
return (
<div>
<div className="section"></div>
<h5 className="indigo-text">Please, login into your account</h5>
<div className="section"></div>
<div className="container">
<div className="z-depth-1 grey lighten-4 row er" >
<form className="col s12" method="post">
<div className='row'>
<div className='col s12'>
</div>
</div>
<div className='row'>
<div className='input-field col s12'>
<input className='validate' name='email' id='email' value={username}
onChange={updateUsername}/>
<label >Enter your email</label>
</div>
</div>
<div className='row'>
<div className='input-field col s12'>
<input className='validate' type='password' name='password' id='password' value={password}
onChange={updatePassword} />
<label >Enter your password</label>
</div>
<label >
<a className='pink-text' href='#!'><b>Forgot Password?</b></a>
</label>
</div>
<br />
<div className='row'>
<button type='submit' name='btn_login' className='col s12 btn btn-large waves-effect indigo'
onClick={signIn}>Login</button>
</div>
</form>
</div>
</div>
Create account
</div>
);
};
const mapDispatchToProps = {
setToken: actions.setToken,
setName: actions.setName
};
export default connect(
null,
mapDispatchToProps
)(Login);
Postman returns the token
The api console shows me:
POST /api/auth - - ms - -
Connected successfully to server
In the Web page
Failed to load resource: the server responded with a status of 404 (Not Found)
I have used this code or a similar one before in other projects but I do not understand what happened to me this time
const md5 = require('md5');
// Connection URL
const mongoUrl = 'mongodb://localhost:27017';
// Database Name
const mongoDBName = 'ArdalesTur';
/* GET users listing. */
router.get('/', (req, res) => {
res.send('respond with a resource');
});
const secret = 'mysecret';
// para interactuar con la base de datos
router.post('/auth', (req, res) => {
mongo.MongoClient.connect(mongoUrl, (err, client) => {
assert.equal(null, err);
console.log('Connected successfully to server');
const db = client.db(mongoDBName);
const query = db.collection('Admin').find({
username: req.body.username,
password: md5(req.body.password),
});
query.toArray().then((documents) => {
if (documents.length > 0) {
const token = jwt.sign(
{
_id: documents[0]._id,
username: documents[0].username
},
secret,
// {
// expiresIn: 86400
// }
);
res.send(token);
} else {
res.status(400).send('Invalid credentials');
}
});
client.close();
});
});
here you have the api

Resources