Password hashing not working on Put request - node.js

Using bcryptjs library and got 2 issues when performing Put request:
1- On insomnia / postman, server returns hashed password, but it returns "unhashed" on client side inspect console tools.
2- I can not perform a login with new password credential.
Any visible syntax mistake on server code or quick suggestions please? Tks!
CLIENT SIDE CODE:
function DevUpdateForm() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [techs, setTechs] = useState("");
async function updateUser(e) {
e.preventDefault()
const dataUpdate = { name, email, password, techs}
const response = await api.put(`/devs/${dev._id}`, dataUpdate);
console.log(response);
setName('');
setEmail('');
setPassword('');
setTechs([]);
}
return (
<div className="update-profile">
<strong>Alterar</strong>
<img src={dev.avatar_url} alt={dev.name}/>
<form onSubmit={updateUser} >
<div className="input-block">
<label htmlFor="name">Nome:</label>
<input
name="name"
id="name"
type="text"
placeholder={"Alterar nome"}
value={name}
onChange={e => setName(e.target.value)}
/>
</div>
<div className="input-block">
<label htmlFor="email">E-mail:</label>
<input
name="email"
id="email"
type="text"
placeholder={"Alterar email"}
value={email}
onChange={e => setEmail(e.target.value)}
/>
</div>
<div className="input-block">
<label htmlFor="password">Senha:</label>
<input
name="password"
id="password"
type="password"
placeholder={"Digite nova senha"}
value={password}
onChange={e => setPassword(e.target.value)}
/>
</div>
<div className="input-block">
<label htmlFor="techs">Techs:</label>
<input
name="techs"
id="techs"
type="text"
placeholder={"Alterar tecnologias"}
value={techs}
onChange={e => setTechs(e.target.value)}
/>
</div>
<button type="submit" >Salvar</button>
</form>
</div>
)
}
export default DevUpdateForm;
SERVER SIDE UPDATE CONTROLLER:
async update(req, res, next) {
try {
const { name, email, password, techs } = req.body;
const { _id } = req.params;
const techsArray = parseStringAsArray(techs);
let dev = await Dev.findByIdAndUpdate(_id, {
name,
email,
password,
techs: techsArray
},
{new: true});
dev = await Dev.findById(_id)
dev.password = await bcrypt.hash(dev.password, 8)
if (dev !== null) {
res.status(200).send({
data: dev,
message: "Dev has been updated!"
});
} else {
res.status(404).end();
}
} catch (error) {
next(error)
}
},
ROUTE:
routes.put('/devs/:_id', DevController.allowIfLoggedin, DevController.grantAccess('updateAny', 'profile'), DevController.update);

After finding the model and set new values to user model. you have to execute .save() statement to update existing changes.
async update(req, res, next) {
try {
const { name, email, password, techs } = req.body;
const { _id } = req.params;
const techsArray = parseStringAsArray(techs);
let dev = await Dev.findByIdAndUpdate(_id, {
name,
email,
password,
techs: techsArray
},
{new: true});
dev = await Dev.findById(_id)
dev.password = await bcrypt.hash(dev.password, 8)
dev.save();// add this to save new password
if (dev !== null) {
res.status(200).send({
data: dev,
message: "Dev has been updated!"
});
} else {
res.status(404).end();
}
} catch (error) {
next(error)
}
},

Related

Unable to signup once login detail have been entered

I'm pretty new to React & node.js , and have attempted to create a chat messaging app. However im unable to access the rest of my app as every-time i sign in there is an error stating:
**Uncaught (in promise) Error: Request failed with status code 404
at createError (createError.js:16:1)
at settle (settle.js:17:1)
at XMLHttpRequest.onloadend (xhr.js:66:1)**
Auth.jsx file in client server
import React, {useState} from 'react';
import Cookies from 'universal-cookie';
import axios from 'axios';
import signinImage from '../assets/Group 2.png';
const cookies = new Cookies();
//forming the inital state of input fields
const initialState = {
fullName:'',
username:'',
password:'',
confirmPassword:'',
phoneNumber:'',
avatarURL:'',
}
const Auth = () => {
const [form, setForm] = useState(initialState);
const [isSignup , setIsSignup] = useState(true);
const handleChange = (e) => {
setForm({...form,[e.target.name]: e.target.value});
}
const handleSubmit = async (e)=>{
e.preventDefault();
const {username , password , phoneNumber , avatarURL } = form;
const URL = 'http://localhost:5009/auth'
//making requests to different url backened each time
const {data : { token ,userId , hashedPassword , fullName }} = await axios.post(`${URL}/${isSignup ? 'Sign Up ' : 'Sign In'}`,{
username , password , fullName: form.fullName , phoneNumber , avatarURL,
})
//storing data in cookies
cookies.set('token ' , token )
cookies.set('username ' , username )
cookies.set('fullName' , fullName)
cookies.set('userId ' , userId )
if (isSignup){
cookies.set('phoneNumber' , phoneNumber )
cookies.set('avatarURL' , avatarURL)
cookies.set('hashedPassword' , hashedPassword )
}
//reloads application
window.location.reload();
}
//changing state of my sign up screen depending on the state before
const switchMode = () => {
setIsSignup((prevIsSignup) => !prevIsSignup);
}
return (
<div className=" auth__form-container">
<div className="auth__form-container_fields">
<div className="auth__form-container_fields-content">
<p>{isSignup ? 'Sign up' : 'Sign In'}</p>
<form onSubmit= {handleSubmit}>
{isSignup &&(
<div className= "auth__form-container_fields-content_input">
<label htmlFor="fullName">Full Name</label>
<input
name="fullName"
type="text"
placeHolder= "Full Name"
onChange={handleChange}
required
/>
</div>
) }
<div className= "auth__form-container_fields-content_input">
<label htmlFor="username">Username</label>
<input
name="username"
type="text"
placeHolder= "Username"
onChange={handleChange}
required
/>
</div>
{isSignup &&(
<div className= "auth__form-container_fields-content_input">
<label htmlFor="phoneNumber">Phone Number</label>
<input
name="phoneNumber"
type="text"
placeHolder= "Phone Number"
onChange={handleChange}
required
/>
</div>
) }
{isSignup &&(
<div className= "auth__form-container_fields-content_input">
<label htmlFor="avatarURL">Avatar URL</label>
<input
name="avatarURL"
type="text"
placeHolder= "Avatar URL"
onChange={handleChange}
required
/>
</div>
) }
<div className= "auth__form-container_fields-content_input">
<label htmlFor="password">Password</label>
<input
name="password"
type="password"
placeHolder= "Password"
onChange={handleChange}
required
/>
</div>
{isSignup &&(
<div className= "auth__form-container_fields-content_input">
<label htmlFor="confirmPassword">Confirm Password</label>
<input
name="confirmPassword"
type="password"
placeHolder= "Confirm Password"
onChange={handleChange}
required
/>
</div>
) }
<div className="auth__form-container_fields-content_button">
<button>{isSignup ? "Sign up " : "Sign In"}</button>
</div>
</form>
<div className="auth__form-container_fields-account">
<p>
{isSignup
? "Already have an account?"
:"Dont have an account ?"
}
<span onClick={switchMode}>
{isSignup ? ' Sign In' : ' Sign up'}
</span>
</p>
</div>
</div>
</div>
<div className="auth__form-container_image">
<img src = {signinImage} alt ="Sign In" />
</div>
</div>
)
}
export default Auth
Below is the code for files in my server folder :
index.js
const express = require ('express');
const cors = require ('cors');
//adding routes for sign in + registrationn//
const authRoutes = require("./routes/auth.js");
const app = express ();
const PORT = process.env.PORT || 5009;
require ('dotenv').config();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded());
app.get('/' , (req,res) => {
res.send('ne, world');
});
app.use('/auth', authRoutes);
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Auth.js file in Controllers folder:
const { connect } = require('getstream');
const bcrypt = require('bcrypt');
const StreamChat = require('stream-chat').StreamChat;
const crypto = require('crypto');
require('dotenv').config();
const api_key = process.env.STREAM_API_KEY;
const api_secret = process.env.STREAM_API_SECRET;
const app_id = process.env.STREAM_APP_ID;
const signup = async (req, res) => {
try {
const { fullName, username, password, phoneNumber } = req.body;
const userId = crypto.randomBytes(16).toString('hex');
const serverClient = connect(api_key, api_secret, app_id);
const hashedPassword = await bcrypt.hash(password, 10);
const token = serverClient.createUserToken(userId);
res.status(200).json({ token, fullName, username, userId, hashedPassword, phoneNumber });
} catch (error) {
console.log(error);
res.status(500).json({ message: error });
}
};
const login = async (req, res) => {
try {
const { username, password } = req.body;
const serverClient = connect(api_key, api_secret, app_id);
const client = StreamChat.getInstance(api_key, api_secret);
const { users } = await client.queryUsers({ name: username });
if(!users.length) return res.status(400).json({ message: 'User not found' });
const success = await bcrypt.compare(password, users[0].hashedPassword);
const token = serverClient.createUserToken(users[0].id);
if(success) {
res.status(200).json({ token, fullName: users[0].fullName, username, userId: users[0].id});
} else {
res.status(500).json({ message: 'Incorrect password' });
}
} catch (error) {ads
console.log(error);
res.status(500).json({ message: error });
}
};
module.exports = { signup, login }
Auth.js file in routes folder
const express = require ('express');
const { signup, login } = require('../controllers/auth.js');
const router = express.Router();
//initialising my 2 different routes //
//post route sending data from frontend to backend
router.post('/signup', signup);
router.post('/login', login);
module.exports = router;
Any thought on what im doing wrong or can implement to change these errors would be much appreciated !

React after posting new password for user can't log in

I have a big problem with updating user info with fetch PUT. When I do it everything seems to work correctly I even get encrypted password but then when I try to log in with data I changed it says it's incorrect. For example I change password to Admin123! it gets saved in MongoDB like this: $2b$10$w9h6TjiXcTeDHFVYLPoDzeRNqapnU4LE4geEGPk6D9sC.vsT/rjwm, but when I go to Login page it says password is incorrect. Before I update password it is also encrypted but I can log in without a problem. Could you please tell me what could couse this problem?
Here is React function for Updating user info:
import React, { useState, useEffect } from "react";
import Alert from "../elements/Alert";
import { useHistory } from "react-router-dom";
export default function EditProfile() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [name, setName] = useState("");
const [phone, setPhone] = useState("");
const [premium, setPremium] = useState("");
const [alert, setAlert] = useState("");
const history = useHistory();
const info = localStorage.getItem("user-info");
const result = JSON.parse(info);
const id = result._id;
useEffect(() => {
async function getData() {
setEmail(result.email);
setPassword();
setName(result.name);
setPhone(result.phone);
setPremium(result.premium);
}
getData();
}, []);
async function update() {
let user = password
? {
name,
email,
password,
phone,
premium,
}
: {
name,
email,
phone,
premium,
};
console.log(user.password);
let result = await fetch(`http://localhost:1234/api/users/${id}`, {
method: "PUT",
body: JSON.stringify(user),
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
});
console.log(result);
if (result.status !== 200) {
return setAlert(
result.status + " " + result.statusText + " - Please check input fields"
);
}
result = await result.json();
if (result) {
localStorage.removeItem("user-info");
localStorage.setItem("user-info", JSON.stringify(result));
}
// history.push("/profile");
// window.location.reload();
}
return (
<div style={{ minWidth: "70rem" }}>
<h1 className="bigBar" style={{ textAlign: "center" }}>
Edit account
</h1>
<div
style={{
backgroundColor: "#f1f1f1",
padding: "3rem",
borderRadius: "1rem",
marginBottom: "7rem",
}}
>
<div style={{}}>
{alert !== "" && (
<div style={{ display: "flex", justifyContent: "center" }}>
<Alert alert={alert}></Alert>
</div>
)}
<div>
<h6>User name</h6>
<input
autoFocus="autofocus"
required="required"
type="text"
className="form-control"
placeholder={name}
onChange={e => setName(e.target.value)}
/>
</div>
<br />
<div>
<h6>email</h6>
<input
required="required"
type="text"
className="form-control"
placeholder={email}
onChange={e => setEmail(e.target.value)}
/>
</div>
<br />
<div>
<h6>Pasword</h6>
<input
type="text"
onChange={e => setPassword(e.target.value)}
className="form-control"
required="required"
/>
</div>
<br />
<div>
<h6>Phone</h6>
<input
type="text"
onChange={e => setPhone(e.target.value)}
className="form-control"
required="required"
placeholder={phone}
/>
</div>
<br />
<div style={{ textAlign: "center" }}>
<button onClick={update} className=" prettyB">
Submit
</button>
</div>
</div>
</div>
</div>
);
}
Here is PUT method from Node.js:
router.put("/:id", async (req, res) => {
const { error } = validateUser(req.body);
if (error)
//400 Bad request
return res.status(400).send(error.details[0].message);
let user = await User.findById(req.params.id);
user.name = req.body.name;
user.email = req.body.email;
user.phone = req.body.phone;
user.admin = req.body.admin;
user.premium = req.body.premium;
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(user.password, salt);
user = await user.save();
if (!user)
return res.status(404).send(`User with the given ID was not found`);
res.send(user);
});
Logging in:
import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import Alert from "../elements/Alert";
export default function Login() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [alert, setAlert] = useState("");
const history = useHistory();
async function login() {
let item = { email, password };
let result = await fetch("http://localhost:1234/api/auth/user", {
method: "POST",
body: JSON.stringify(item),
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
});
console.log(result.status);
if (result.status !== 200) {
return setAlert(" Incorrect email or password");
}
await fetch("http://localhost:1234/api/auth", {
method: "POST",
body: JSON.stringify(item),
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
})
.then(function (response) {
console.log(response);
return response.json();
})
.then(function (data) {
localStorage.setItem("token", data.token);
});
result = await result.json();
if (result) localStorage.setItem("user-info", JSON.stringify(result));
history.push("/");
window.location.reload();
}
return (
<div className="col-sm-6" style={{ textAlign: "center" }}>
<h1 className="bigBar">Login Page</h1>
{alert !== "" && (
<div style={{ display: "flex", justifyContent: "center" }}>
<Alert alert={alert}></Alert>
</div>
)}
<input
type="text"
onChange={e => setEmail(e.target.value)}
className="form-control"
placeholder="email"
/>
<br />
<input
type="password"
onChange={e => setPassword(e.target.value)}
className="form-control"
placeholder="password"
/>
<br />
<button onClick={login} className="btn btn-primary">
Sign up
</button>
</div>
);
}
And here is method for posting new users, who also have encrypted passwords but when I create theese passwords this wya they work like a charm:
router.post("/", async (req, res) => {
const { error } = validateUser(req.body);
if (error)
// 400 Bad request
return res.status(400).send(error.details[0].message);
let user = await User.findOne({
email: req.body.email,
});
if (user) return res.status(400).send(`User already registered`);
user = new User(
_.pick(req.body, [`name`, `email`, `password`, `phone`, `admin`, `premium`])
);
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(user.password, salt);
user = await user.save();
const token = user.generateAuthenticationToken();
res
.header(`x-auth-token`, token)
.send(_.pick(user, [`_id`, `name`, `email`]));
user = await user.save();
res.send(_.pick(user, [`_id`, `name`, `email`]));
});
The logic for updating is incorrect. I'd suggest these improvements
Throws status 400 when user is not found.
If user is found, keep it. Do not create new user
Change its password from request body
let user = await User.findOne({
email: req.body.email,
});
if (!user) return res.status(400).send(`User not found`);
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(req.body.password, salt);
user = await user.save();

i have integrated nodejs backend to reactjs front end

hi i have integrated nodejs backend to reactjs front end. i have done these ways. but it shows error . i am new to react pls help.
function Register() {
const [data, setData] = useState({
name: "",
phone: "",
password: "",
confirmpassword: "",
});
const InputEvent = (event) => {
const { name, value } = event.target;
setData((preVal) => {
return {
...preVal,
[name]: value,
};
});
};
const formSubmit = (e) => {
e.preventDefault();
const registered = {
name: "data.name",
phone: "data.phone",
password: "data.password",
};
const isValid = formValidation();
if (isValid) {
//if form is valid, route
axios
.post(`https://localhost:5000/api/v1/auth/register/`, registered)
.then((res) => {
console.log(res);
console.log(res.data);
})
.catch((err) => {
console.log(err);
});
history.push("/myvehicles" );
}
};
return (
<div className="signup__container">
<form className="register__form" onSubmit={formSubmit}>
<h5 className="h5__form"> Name</h5>
<input
type="text"
placeholder="पुरा नाम लेख्नुहोस्"
name="name"
value={data.name}
onChange={InputEvent}
/>
);
})}
<h5 className="h5__form"> phone </h5>
<input
type="text"
placeholder="फोन लेख्नुहोस्"
name="phone"
value={data.phone}
onChange={InputEvent}
/>
);
})}
<h5 className="h5__form"> Password </h5>
<input
type="Password"
placeholder="पासवर्ड लेख्नुहोस्s"
name="password"
value={data.password}
onChange={InputEvent}
/>
);
})}
<h5 className="h5__form"> Confirm Password </h5>
<input
type="Password"
placeholder="पुन: पासवर्ड लेख्नुहोस्"
name="confirmpassword"
value={data.confirmpassword}
onChange={InputEvent}
/>
);
})}
<p>
<button type="submit" className="signup__registerButton">
Register Now
</button>
</p>
</form>
</div>
);
}
export default Register;
the code is as above when i run both backend and front end server and post values from UI. it gives error. the error comes from the post function. if i am doing wrong pls correct.
You can remove double quotes because you pass the wrong parameters and http instead of https in your api url.
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [data, setData] = useState({
name: "",
phone: "",
password: "",
confirmpassword: ""
});
const InputEvent = (event) => {
const { name, value } = event.target;
setData((preVal) => {
return {
...preVal,
[name]: value
};
});
};
const formSubmit = (e) => {
e.preventDefault();
const registered = {
name: data.name,
phone: data.phone,
password: data.password
};
const isValid = formValidation();
if (isValid) {
//if form is valid, route
axios
.post(`http://localhost:5000/api/v1/auth/register/`, registered)
.then((res) => {
console.log(res);
console.log(res.data);
})
.catch((err) => {
console.log(err);
});
// history.push("/myvehicles" );
}
};
return (
<div className="signup__container">
<form className="register__form" onSubmit={formSubmit}>
<h5 className="h5__form"> Name</h5>
<input
type="text"
placeholder="पुरा नाम लेख्नुहोस्"
name="name"
value={data.name}
onChange={InputEvent}
/>
<h5 className="h5__form"> phone </h5>
<input
type="text"
placeholder="फोन लेख्नुहोस्"
name="phone"
value={data.phone}
onChange={InputEvent}
/>
<h5 className="h5__form"> Password </h5>
<input
type="Password"
placeholder="पासवर्ड लेख्नुहोस्s"
name="password"
value={data.password}
onChange={InputEvent}
/>
<h5 className="h5__form"> Confirm Password </h5>
<input
type="Password"
placeholder="पुन: पासवर्ड लेख्नुहोस्"
name="confirmpassword"
value={data.confirmpassword}
onChange={InputEvent}
/>
<p>
<button type="submit" className="signup__registerButton">
Register Now
</button>
</p>
</form>
</div>
);
}
Firstly, try to post errors in the question itself
your code seems quite complicated for just a simple form submission
const registered = {
name: data.name,
phone: data.phone,
password: data.password,
};
Here data.name was string
For 400 bad request, check your node application have you defined any headers or any particular format, something like this you need to send
const article = { title: 'React POST Request Example' };
const headers = {
'Authorization': 'Bearer my-token',
'Content-Type': 'application/json'
};
axios.post('https://reqres.in/api/articles', article, { headers })
.then(response => this.setState({ articleId: response.data.id }));
}
Also, for httpsSSL issue means it is expecting Secure Certificate (as you cant hit https without its certificate- which is for encrypt-decrypt ) whereas for localhost try http even if getting error try your ip address and port (usually 8080)on which app is running on backend
shows while running the server on terminal itself
for pc ip address -> go to cmd-> type ipconfig

How to send User to Next Page After form validation in react?

This in My SignUp Component, Im trying To send User to Signin Component If Username And Password Is correct.
this is Signup Code Below,
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import Axios from 'axios';
const initianValue = {
username: '',
password: '',
nameError: '',
passError: '',
dataError: '',
};
class SignUp extends Component {
constructor(props) {
super(props);
this.state = initianValue;
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInputChange = (e) => {
this.setState({
[e.target.name]: e.target.value,
});
};
validForm() {
let nameError = '';
let passError = '';
let dataError = '';
const user = {
username: this.state.username,
password: this.state.password,
};
if (!this.state.username) {
nameError = 'Enter Name';
}
if (user.username !== '' && user.password !== '') {
Axios.post('http://localhost:9000/checkUser', user)
.then((res) => this.setState({ dataError: res.data }))
.catch((err) => console.log(err));
}
if (!this.state.password) {
passError = 'Enter Password';
}
if (nameError || passError || dataError) {
this.setState({
nameError,
passError,
dataError,
});
return false;
}
return true;
}
handleSubmit = (e) => {
e.preventDefault();
const isvalid = this.validForm();
if (isvalid) {
this.setState(initianValue, () => this.props.history.push('/SignIn'));
}
};
render() {
return (
<div className='Main'>
<span className='create'>Create Account</span>
<div className='SignUp'>
<form onSubmit={this.handleSubmit}>
<div className='form-group'>
<label>Username</label>
<input
type='text'
name='username'
value={this.state.username}
className='form-control'
onChange={this.handleInputChange}
/>
<div className='error'>
{this.state.nameError}
{this.state.dataError}
</div>
<br />
<label>Password</label>
<input
type='password'
name='password'
value={this.state.password}
className='form-control'
onChange={this.handleInputChange}
/>
<div className='error'>{this.state.passError}</div>
<br />
<button type='submit' className='btn btn-primary'>
Sign Up
</button>
</div>
</form>
</div>
<div className='signinForm'>
<label>
Already Have Account <Link to='/Signin'> Sign In </Link>
</label>
</div>
</div>
);
}
}
export default SignUp;
Its Works Perfect If I Put Right username and password but in wrong username / password its also send me to Signin Page and Shows warning in console like this
index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in SignUp (created by Context.Consumer)
i wrap Both Component SignUp And Signin In Router,
this is my server.js file to send data if username and password is correct in database
app.post('/checkUser', function (req, res) {
const name = req.body.username;
const pass = req.body.password;
conn.query(
`SELECT * FROM users WHERE username = (?) AND password = (?) `,
[name, pass],
(err, rows) => {
if (err) throw err;
if (!rows.length) {
res.send('Wrong Data');
}
}
);
});
Your validForm makes an async call. By the time the async call is finished the validForm function as well as handleSubmit function execution is already completed. Then the then block is executed where you are setting state and therefore the error.
Solution: Make validForm an async function and await for your async call. Also make handleSubmit function an async and await for validForm.
Working demo
Code snippet
class SignUp extends Component {
constructor(props) {
super(props);
this.state = initianValue;
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInputChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
async validForm() {
let nameError = "";
let passError = "";
let dataError = "";
const user = {
username: this.state.username,
password: this.state.password
};
if (!this.state.username) {
nameError = "Enter Name";
}
if (user.username !== "" && user.password !== "") {
await Axios.get("https://jsonplaceholder.typicode.com/todos/1", user) //fake api
.then(res => {
dataError = "user already exists"; //provide dynamic error..
//this.setState({ dataError: res.data }); // not required
})
.catch(err => console.log("err", err));
}
if (!this.state.password) {
passError = "Enter Password";
}
if (nameError || passError || dataError) {
this.setState({
nameError,
passError,
dataError
});
return false;
}
return true;
}
handleSubmit = async e => {
e.preventDefault();
const isvalid = await this.validForm();
if (isvalid) {
this.setState(initianValue, () => this.props.history.push("/SignIn"));
}
};
render() {
return (
<div className="Main">
<span className="create">Create Account</span>
<div className="SignUp">
<form onSubmit={this.handleSubmit}>
<div className="form-group">
<label>Username</label>
<input
type="text"
name="username"
value={this.state.username}
className="form-control"
onChange={this.handleInputChange}
/>
<div className="error">
{this.state.nameError}
{this.state.dataError}
</div>
<br />
<label>Password</label>
<input
type="password"
name="password"
value={this.state.password}
className="form-control"
onChange={this.handleInputChange}
/>
<div className="error">{this.state.passError}</div>
<br />
<button type="submit" className="btn btn-primary">
Sign Up
</button>
</div>
</form>
</div>
<div className="signinForm">
<label>
Already Have Account <Link to="/Signin"> Sign In </Link>
</label>
</div>
</div>
);
}
}
The issue could be on the handling of the response of the fetch. This is just a quick guess but try to not set the state of dataError and just modify the value of your variable dataError that you declared in this local function instead of the class variable. Does that make sense? when you check in your "if (nameError || passError || dataError)" you are checking for the local variable of your function and not the class which I think is fine but you aren't changing the variable if the response is an error.
Second if you change the setState and then check the state.dataError you might not get the updated value refresh yet in the function.
Let me know if that makes sense and if it 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