User doesnt stay logged in when refreshing page NODE.js - javascript

Good day, I have made a login/register system, where the suer can login/logout and register.
I have made this with JWT and express.
Loggin in and logging out goes well, but when i refresh the page the user gets logged out. How could i fix this?
tokens
const { sign } = require("jsonwebtoken");
// const getToken = (user) => {
// return jwt.sign(
// // payload
// {
// _id: user._id,
// name: user.name,
// email: user.email,
// isAdmin: user.isAdmin,
// },
// process.env.JWT_SECRET,
// {
// expiresIn: '24h',
// }
// )
// }
const createAccessToken = userId => {
return sign(
{
userId,
},
process.env.ACCESS_TOKEN_SECRET,
{
//expire time
expiresIn: "15m",
},
);
};
//you can add versions of refresh tokens. So it only can be used once
const createRefreshToken = userId => {
return sign(
{
userId,
},
process.env.REFRESH_TOKEN_SECRET,
{
//expire time
expiresIn: "7d",
},
);
};
const sendAccessToken = (req, res, accesstoken) => {
res.send({
accesstoken,
email: req.body.email,
});
};
const sendRefreshToken = (res, refreshtoken) => {
//you can call it something different, so it
//will be harder to track which token it is
res.cookie("refreshtoken", refreshtoken, {
httpOnly: true,
path: "/refresh_token",
});
};
module.exports = {
createAccessToken,
createRefreshToken,
sendAccessToken,
sendRefreshToken,
};
Login route
router.post("/signin", async (req, res) => {
try {
const user = await User.findOne({
email: req.body.email,
});
if (!user)
res.status(400).send({
message: "User doesnt exist or password doesnt match",
});
const valid = await compare(req.body.password, user.password);
if (!valid) throw new Error("Invalid password");
const accesstoken = createAccessToken(user._id);
const refreshtoken = createRefreshToken(user._id);
sendRefreshToken(res, refreshtoken);
sendAccessToken(req, res, accesstoken);
res.send({
email: user.email,
refreshtoken: user.refreshtoken,
sendAccessToken: sendAccessToken(req, res, accesstoken),
refreshtoken,
});
} catch (err) {
res.send({
error: `${err.message}`,
});
}
});
generating new token route:
//generating new token
router.post("/refresh_token", (req, res) => {
const token = req.cookies.refreshtoken;
//if we dont have a token in our request
if (!token) return res.send({ accesstoken: "" });
//if we have token. Verify it
let payload = null;
try {
payload = verify(token, process.env.REFRESH_TOKEN_SECRET);
} catch (err) {
return res.send({ accesstoken: "" });
}
//token is valid. Check if user exist
const user = User.findOne(user => user._id === payload.userId);
if (!user) return res.send({ accesstoken: "" });
//user exists, check if refreshtoken exist on user
if (user.refreshtoken !== token) {
return res.send({ accesstoken: "" });
}
//token exist, create new refresh and accesstoken
const accesstoken = createAccessToken(user._id);
const refreshtoken = createRefreshToken(user._id);
//update refresh token in database
user.refreshtoken = refreshtoken;
//all good now, send refreshtoken and accesstoken
sendRefreshToken(res, refreshtoken);
return res.send({ accesstoken });
});
calling the refresh token
export const userContext = React.createContext([]);
function App() {
const [user, setUser] = useState({});
const [loading, setLoading] = useState(true);
const logoutCallback = async () => {
await fetch("http://localhost:5000/users/logout", {
method: "POST",
credentials: "include",
});
//clear user from context
setUser({});
//navigate back to startpage
alert("logged out");
};
useEffect(() => {
async function checkRefreshToken() {
const result = await (
await fetch("http://localhost:5000/users/refresh_token", {
method: "POST",
credentials: "include", //needed to include the cookie
headers: {
"Content-Type": "application/json",
},
})
).json();
setUser({
accesstoken: result.accesstoken,
});
setLoading(false);
}
checkRefreshToken();
}, []);
login page
import React, { useState, useEffect, useContext } from "react";
import { userContext } from "../../App";
function Login(props) {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [user, setUser] = useContext(userContext);
const handleSubmit = async e => {
e.preventDefault();
const result = await (
await fetch("http://localhost:5000/users/signin", {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email,
password,
}),
})
).json();
if (result.accesstoken) {
setUser({
accesstoken: result.accesstoken,
refreshtoken: result.refreshtoken,
});
} else {
alert(result.error);
}
};
useEffect(() => {
console.log(user);
}, [user]);
return (
<div>
<h1 className="login-h">Login</h1>
<form onSubmit={handleSubmit} className="login">
<div className="login-form">
<label>email</label>
<br />
<input
type="email"
placeholder="username or email"
for="email"
onChange={e => setEmail(e.target.value)}
></input>
<br />
<label>Password</label>
<br />
<input
type="password"
placeholder="Password"
for="password"
onChange={e => setPassword(e.target.value)}
></input>
<br />
<p className="forget-pw">
Forgot password?
</p>
<button>Login</button> <br />
<br />
{/* <p style={{ color: 'red' }}>{result.error}</p> */}
</div>
<p className="have-ccl">
{" "}
No account yet?Signup
</p>
</form>
</div>
);
}
export default Login;

Related

Allowing users to Login, and show a message whether it was successful or not, without going through the registration process

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.

Login successful with wrong credentials swagger, nodeJS, JWT

Created a login method but it spits out the token regardless of what is entered in the Userfields
This uses swagger API and I'm trying to develop the frontend and backend
I'm relatively new to nodejs/javascript
Any Help would be appreciated!
login.js
var form = document.getElementById('login')
form.addEventListener('submit', login)
async function login(event) {
event.preventDefault()
const username = document.getElementById('username').value
const password = document.getElementById('password').value
const result = await fetch('/v1/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username,
password
})
}).then((res) => res.json())
if (result.status === 'ok') {
// everythign went fine
console.log('Got the token: ', result.data)
localStorage.setItem('token', result.data)
alert('Login Successful')
return false;
} else {
alert(result.error)
}
}
userController.JS
login: async (req,res)=> {
const { userName, password } = req.body
const existUsername = await userModel.findOne({ userName: req.body.userName, password: req.body.password}).then((existUsername) =>{
if (existUsername){
res.status(400).json({status: 'Failed', message: `User was Not found`, data: null})
return;
}
try{
async() => {
await bcrypt.compare(password, req.body.password) }
// the username, password combination is successful
const token = jwt.sign(
{
id: userModel._id,
userName: userModel.userName
},
JWT_SECRET
)
res.json({ status: 'ok', data: token })
}
catch (e) {
res.status(400).json({status: 'Failed', message: `${e.message}`, data: null})
}
});
},

Why am I getting different response from my data when local and when on heroku?

I am working on an Application which i have also deployed in heroku. The issue is that when I login in using heroku, user is nested inside a data object. but when I work locally or use postman, user isnt nested.
Help Please.
I get this response on the deployed version.
data: {
user: {
email: "my_email"
name: "my_name"
role: "user"
_id: "6205807deeadcfa734f954f3".
}
status: "success"
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYyMDU4MDdkZWVhZGNmYTczNGY5NTRmMyIsImlhdCI6MTY0NDg0NTYyMCwiZXhwIjoxNjQ1NDUwNDIwfQ.YeWFNrN8rsLPJvvU8JQDwBVG4aBqqEuo7ssgLrR3O8M"
But when I log in locally, I get the response as
user: {
email: "my_email"
name: "my_name"
role: "user"
_id: "6205807deeadcfa734f954f3".
}
status: "success"
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYyMDU4MDdkZWVhZGNmYTczNGY5NTRmMyIsImlhdCI
For Heroku, the USER is nested inside data but for local host and postman, the user isnt nested.
My codes are:
exports.login = catchAsync(async (req, res, next) => {
const { email, password } = req.body
if (!email || !password) {
return next(new AppError('Please provide email and password!', 400))
}
const user = await User.findOne({ email }).select('+password')
if (!user || !(await user.comparePassword(password, user.password))) {
return next(new AppError('Incorrect email or password', 401))
}
createSendToken(user, 200, req, res)
})
These are my api codes
const createSendToken = (user, statusCode, req, res) => {
const token = signToken(user._id)
res.cookie('jwt', token, {
expires: new Date(
Date.now() + process.env.JWT_COOKIE_EXPIRES_IN * 24 * 60 * 60 * 1000
),
httpOnly: true,
})
user.password = undefined
res.status(statusCode).json({
status: 'success',
token,
user,
})
}
For my react, The function code is:
function request(path, { data = null, token = null, method = 'GET' }) {
return (
fetch(`${process.env.REACT_APP_API}${path}`, {
method,
headers: {
Authorization: token ? `Bearer ${token}` : '',
'Content-Type': 'application/json',
},
body:
method !== 'GET' && method !== 'DELETE' ? JSON.stringify(data) : null,
})
.then((response) => {
// If Successful
if (response.ok) {
if (method === 'DELETE') {
// If delete, nothing returned
return true
}
return response.json()
}
// If errors
return response
.json()
.then((json) => {
// Handle Json Error response from server
if (response.status === 400) {
const errors = Object.keys(json).map(
(k) => `${json[k].join(' ')}`
)
throw new Error(errors.join(' '))
}
throw new Error(JSON.stringify(json))
})
.catch((e) => {
if (e.name === 'SyntaxError') {
throw new Error(response.statusText)
}
throw new Error(e)
})
})
.catch((e) => {
// Handle all errors
toast(e.message, { type: 'error' })
})
)
}
The main sign in function
export function signIn(email, password) {
return request('/api/v1/auth/login', {
data: { email, password },
method: 'POST',
})
}
Then I import this into my auth context and execute it there
import {signIn as signInApi} from '../apis'
const AuthContext = createContext()
export const AuthProvider = ({ children }) => {
const [token, setToken] = useState(localStorage.getItem('token'))
const [user, setUser] = useState(
JSON.parse(localStorage.getItem('user'))
)
const [loading, setLoading] = useState(false)
const signIn = async (email, password, callback) => {
setLoading(true)
const res = await signInApi(email, password)
if (res.token) {
localStorage.setItem('token', res.token)
localStorage.setItem('user', JSON.stringify(res.user)) // This stores the user in localhost but returns undefined for user in the one deployed to heroku. I have to use
localStorage.setItem('user', JSON.stringify(res.data.user)) which now works on the deployed one but not on the local one
setToken(res.token)
setUser(res.user)
callback()
}
setLoading(false)
}
}
it seems the deployed version is using built in implementaion of createSendToken and not the one you provided. need to check your project structure.
in order to validate this change the function name and the call createSendToken to something else and you will find the issue

How to display server-side validation messages in the client side via react-query?

Here is the Express route for the signup API call, It works as expected on the server-side but I want to display these same validation messages in real-time when the user will put their credentials on the React client
app.post("/signup", async (req, res) => {
try {
// Validate data before submission
const { error } = registerValidation(
req.body.username,
req.body.firstname,
req.body.lastname,
req.body.email,
req.body.password
);
if (error) return res.status(400).send(error.details[0].message);
// Checking if username already exists
const usernameExist = await database.query(
"SELECT username FROM users WHERE username=$1",
[req.body.username]
);
if (usernameExist.rows[0])
return res.status(400).send("Username already taken!");
// Checking if email already exists
const emailExist = await database.query(
"SELECT email FROM users WHERE email=$1",
[req.body.email]
);
if (emailExist.rows[0])
return res.status(400).send("Email already exists!");
// Hash the password
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(req.body.password, salt);
// Save the New User
const newUser = await database.query(
"INSERT INTO users(username, firstname, lastname, email, password) VALUES($1, $2, $3, $4, $5) RETURNING *",
[
req.body.username,
req.body.firstname,
req.body.lastname,
req.body.email,
hashedPassword,
]
);
res.json(newUser.rows[0]);
} catch (err) {
console.error(err.message);
}
});
And here is my fetch POST request for signup.
export const signUp = async (formData) => {
try {
const res = await fetch(`${API_URL}/signup`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(formData),
});
if (!res.ok) {
const errMsg = await res.text();
throw new Error(errMsg);
}
await res.json();
} catch (err) {
console.error(err.message);
}
};
And here is the signup form using react-hook-form and react-query, the error message is displayed on the console but wanted to display it on screen in real-time while the user typing in the form without the need to submit the form to display those messages.
import React from "react";
import { useForm } from "react-hook-form";
import { joiResolver } from "#hookform/resolvers/joi";
import Joi from "joi";
import { useMutation } from "react-query";
import { useHistory } from "react-router-dom";
import { signUp } from "../API/API";
// Signup Form Validation
const schema = Joi.object({
username: Joi.string().min(3).required(),
firstname: Joi.string().min(3).required(),
lastname: Joi.string().min(3).required(),
email: Joi.string()
.min(6)
.required()
.email({ tlds: { allow: false } }),
password: Joi.string().min(6).required(),
});
const SignupForm = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({ resolver: joiResolver(schema) });
const mutation = useMutation(signUp);
const history = useHistory();
// To submit data on server
const onSubmit = async (data) => {
// const res = await mutation.mutate(data);
// console.log(res);
await mutation.mutate(data);
history.push("/");
};
console.log(errors);
return (
<div>
<h3>Sign up</h3>
<form onSubmit={handleSubmit(onSubmit)}>
<input
type="text"
name="username"
placeholder="Username"
{...register("username", { required: true, min: 3 })}
/>
<p>{errors.username?.message}</p>
<br />
<input
type="text"
name="firstname"
placeholder="First Name"
{...register("firstname", { required: true, min: 3 })}
/>
<p>{errors.firstname?.message}</p>
<br />
<input
type="text"
name="lastname"
placeholder="Last Name"
{...register("lastname", { required: true, min: 3 })}
/>
<p>{errors.lastname?.message}</p>
<br />
<input
type="email"
name="email"
placeholder="Email"
{...register("email", {
required: true,
min: 6,
pattern: /^\S+#\S+$/i,
})}
/>
<p>{errors.email?.message}</p>
<br />
<input
type="password"
name="password"
placeholder="Password"
{...register("password", { required: true, min: 6 })}
/>
<p>{errors.password?.message}</p>
<br />
<button type="submit">Sign up</button>
</form>
</div>
);
};
export default SignupForm;
Please check with your syntax and all but did you check onError property?.
const { mutate } = useMutation(signUp, {
onSuccess: () => {
alert("successful");
},
onError: () => {
setStatus("there is an error");
},
});

Can't upload picture to MongoDb from React frontend

I'm creating a tinder clone, I can create a user fine however I cant upload a picture. The error I get is ValidationError: User validation failed: pictures: Cast to embedded failed for value "'picture'" at path "pictures". I'm not sure what I'm doing wrong. The post request seems to fire as excepted with the payload however its when I login when I get the error. So I'm sure this has something to do with initial creation of the account.
create account front and back
import React, { useState } from "react";
import {useHistory } from "react-router-dom";
import axios from "axios";
const CreateAccount = () => {
const api = "http://localhost:5000/user/create-account";
const history = useHistory();
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [emailAddress, setEmailAddress] = useState("");
const [password, setPassword] = useState("");
const [gender, setGender] = useState("Male");
const [sexualPreference, setSexualPreference] = useState("Straight");
const [age, setAge] = useState("");
const [description, setDescription] = useState("");
const [picture, setPicture] = useState("");
const account = {
firstName: firstName,
lastName: lastName,
emailAddress: emailAddress,
password: password,
gender: gender,
sexualPreference: sexualPreference,
age: age,
description: description,
pictures: picture
};
console.log(account.gender);
console.log(account.sexualPreference);
console.log(account.pictures)
const submit = () => {
axios
.post(api, account)
.then((res) => {
console.log(res.data);
history.push({
pathname: "/",
});
})
.catch((err) => console.log(err));
};
const handleSubmit = (event) => {
event.preventDefault();
submit();
};
return (
<div>
<div>
<h1>Create account</h1>
</div>
<form onSubmit={handleSubmit} encType="multipart/form-data">
<p>First Name</p>
<input
id="firstName"
name="firstName"
type="firstName"
onChange={(e) => setFirstName(e.target.value)}
></input>
<p>Last Name</p>
<input
id="lastName"
name="lastName"
type="lastName"
onChange={(e) => setLastName(e.target.value)}
></input>
<p>Email Address</p>
<input
id="emailAddress"
name="emailAddress"
type="emailAddress"
onChange={(e) => setEmailAddress(e.target.value)}
></input>
<p>Password</p>
<input
id="password"
name="password"
type="password"
onChange={(e) => setPassword(e.target.value)}
></input>
<p>Gender</p>
<select
id="gender"
name="gender"
type="gender"
onChange={(e) => setGender(e.target.value)}
>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
<p>Sexual Preference</p>
<select
id="sexualPreference"
name="sexualPreference"
type="sexualPreference"
onChange={(e) => setSexualPreference(e.target.value)}
>
<option value="Straight" >Straight</option>
<option value="Gay" >Gay</option>
<option value="Lesbian" >Lesbian</option>
<option value="Bisexual" >Bisexual</option>
</select>
<p>Age</p>
<input
id="age"
name="age"
type="age"
onChange={(e) => setAge(e.target.value)}
></input>
<p>Description</p>
<input
id="description"
name="description"
type="description"
onChange={(e) => setDescription(e.target.value)}
></input>
<input
type="file"
name="file"
id="picture"
onChange={(e) => setPicture(e.target.id)}
></input>
<button type="submit">Submit</button>
</form>
</div>
);
};
export default CreateAccount;
router.post( "/user/create-account", [
check("firstName")
.exists({ checkNull: true, checkFalsy: true })
.withMessage('Please provide a value for "firstName"'),
check("lastName")
.exists({ checkNull: true, checkFalsy: true })
.withMessage('Please provide a value for "username"'),
check("emailAddress")
.exists({ checkNull: true, checkFalsy: true })
.withMessage('Please provide a value for "emailAddress"'),
check("password")
.exists({ checkNull: true, checkFalsy: true })
.withMessage('Please provide a value for "password"'),
check("gender")
.exists({ checkNull: true, checkFalsy: true })
.withMessage('Please provide a value for "gender"'),
check("sexualPreference")
.exists({ checkNull: true, checkFalsy: true })
.withMessage('Please provide a value for "sexualPreference"'),
check("age")
.exists({ checkNull: true, checkFalsy: true })
.withMessage('Please provide a value for "age"'),
check("description")
.exists({ checkNull: true, checkFalsy: true })
.withMessage('Please provide a value for "description"'),
check("pictures")
.exists({ checkNull: true, checkFalsy: true })
.withMessage('Please provide a value for "pictures"'),
],
asyncHandler(async (req, res, next) => {
// Attempt to get the validation result from the Request object.
const errors = validationResult(req);
// If there are validation errors...
if (!errors.isEmpty()) {
// Use the Array `map()` method to get a list of error messages.
const errorMessages = errors.array().map((error) => error.msg);
// Return the validation errors to the client.
return res.status(400).json({ errors: errorMessages });
}
//new user request body using mongo model from schema
const postUser = new User({
firstName: req.body.firstName,
lastName: req.body.lastName,
emailAddress: req.body.emailAddress,
password: req.body.password,
gender: req.body.gender,
sexualPreference: req.body.sexualPreference,
age: req.body.age,
description: req.body.description,
pictures: req.body.pictures
});
const userEmail = await User.findOne({
emailAddress: postUser.emailAddress,
});
if (postUser.emailAddress === userEmail) {
console.log("User with this email already exists");
return res.status(500).end();
} else if (postUser) {
//if true salts the password with bcryptjs
let salt = await bcryptjs.genSalt(10);
const hashPass = await bcryptjs.hash(postUser.password, salt);
console.log(hashPass);
postUser.password = hashPass;
postUser.save();
res.json({ postUser });
return res.status(201).end();
} else {
res.status(400).send({ error: "Error: Account not created" }).end();
}
})
);
mongoDb Schema
const mongoose = require('mongoose');
const userSchema = mongoose.Schema( {
firstName:{
type: String,
required: true
},
lastName: {
type: String,
require: true
},
emailAddress: {
type: String,
require: true
},
password:{
type: String,
required: true
},
gender:{
type: String,
required: true
},
sexualPreference: {
type: String,
required: true
},
age: {
type: Number,
required: true
},
description: {
type: String,
required: true
},
pictures: {
type: [{
picURL: String,
}],
},
matches: {
type: [{
Object
}],
},
})
module.exports = mongoose.model('User', userSchema);
login backend and frontend
router.post( "/login", asyncHandler(async (req, res, next) => {
const userBody = req.body;
const user = await User.findOne({ emailAddress: req.body.emailAddress });
if (userBody && user) {
console.log(user);
const authenticated = bcryptjs.compare(userBody.password, user.password);
console.log(authenticated);
if (authenticated) {
console.log("match");
const accessToken = jwt.sign(user.toJSON(), process.env.ACCESS_TOKEN_SECRET, { expiresIn: 86400 });
res.cookie("token", accessToken, { httpOnly: false, maxAge: 86400 });
res.setHeader('Authorization', 'Bearer '+ accessToken);
res.json({
user: user,
accessToken: accessToken,
})
.send()
} else {
res.status(403).send({ error: "Login failed: Please try again" }).end();
}
} else {
res.status(403).send({ error: "Login failed: Please try again" }).end();
}
})
);
import React, { useState} from "react";
import { useHistory } from "react-router";
import axios from "axios";
import { Link } from "react-router-dom";
const api = 'http://localhost:5000';
export default function Login () {
const history = useHistory();
const [ email, setEmail ] = useState("");
const [ pass, setPassword ] = useState("");
const submit = () => {
axios.post(`${api}/login`, { emailAddress: email, password: pass }, {withCredentials: true, credentials: 'include'})
.then(res => {
localStorage.setItem('jwt', res.data.accessToken);
history.push({
pathname: `/user/account/${res.data.user._id}`
});
})
.catch(err => console.log(err));
}
const handleSubmit = (event) => {
event.preventDefault();
submit()
}
return (
<div>
<h1>Login</h1>
<form onSubmit={handleSubmit}>
<input
id="emailAddress"
name="emailAddress"
type="text"
placeholder="emailAddress"
onChange={(e) => setEmail(e.target.value)}
/>
<input
id="password"
name="password"
type="password"
placeholder="Password"
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">Submit</button>
<button >Cancel</button>
</form>
<p>Don't have a user account?
<Link to="/user/create-account" >Click here</Link>
to sign up!
</p>
</div>
);
}
first of all you can't upload image like this because you send regular http request if you want to send iamge you need to follow this steps
in the frontend you need to send the request with form data for more info read this blog from mdn what is formData mdn you can do something like that with axios append all of the req body to the formData and add it to the axios add multipart/form-data header
axios({
method: "post",
url: "myurl",
data: bodyFormData,
headers: { "Content-Type": "multipart/form-data" },
})
.then(function (response) {
// handle success
})
.catch(function (response) {
//handle error
});
in the server you need to upload-files-or-images-to-server-using-nodejs

Categories

Resources