401 error in axios post request to local server - node.js

Context
I'm building a simple web application using the MERN stack for practice. In the app, logged-in users should be able to add a new blog to the site. However, for some reason my axios post request to the backend is failing and I'm receiving a 401 error. I'm using jsonwebtoken to handle the authentication. Submitting a POST request via Insomnia works fine so I don't believe it's an issue with my endpoint. I'm running backend server locally on my machine on port 3003 and have set up a proxy so there's no issues with cors. This works fine as the blogs from the backend are displays on the frontend once a user has logged in.
I've also checked the headers and can confirm that logged-in users have a valid bearer token.
What could be causing the issue?
Frontend
I can't post any images but here's a link to the frontend view:
https://imgur.com/a/DdUlfg9
App.js
import React, { useState, useEffect } from 'react'
import Blog from './components/Blog'
import blogService from './services/blogs'
import loginService from './services/login'
import LoginForm from './components/loginForm'
import BlogForm from './components/blogForm'
const App = () => {
const [blogs, setBlogs] = useState([])
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [user, setUser] = useState(null)
const [errorMessage, setErrorMessage] = useState(null)
const [newBlog, setNewBlog] = useState({
title: '',
author: '',
url: ''
})
useEffect(() => {
blogService.getAll().then(blogs =>
setBlogs( blogs )
)
}, [])
useEffect(() => {
const loggedInUser = window.localStorage.getItem("loggedBlogUser")
if(loggedInUser){
const user = JSON.parse(loggedInUser)
setUser(user)
}
},[])
const handleLogin = async (event) => {
event.preventDefault()
try {
const user = await loginService.login({
username, password
})
window.localStorage.setItem(
'loggedBlogUser', JSON.stringify(user)
)
blogService.setToken(user.token)
setUser(user)
setUsername('')
setPassword('')
} catch (exception){
setErrorMessage('Wrong credentials')
setTimeout(() => {
setErrorMessage(null)
}, 5000)
}
}
const handleLogout = async (event) => {
event.preventDefault()
if(user){
window.localStorage.removeItem("loggedBlogUser")
setUser(null)
}
}
const handleBlogField = (event) => {
event.preventDefault()
const {name, value} = event.target
console.log(newBlog.title)
setNewBlog(prevBlog => ({
...prevBlog,
[name] : value
}))
}
const addBlog = async (event) => {
event.preventDefault()
try {
const blog = await blogService.create(newBlog)
console.log("POST REQUEST: ",newBlog)
console.log('lets geddit')
setBlogs(blogs.concat(blog))
} catch (exception){
setErrorMessage('Uh oh, try again :[')
setTimeout(() => {
setErrorMessage(null)
}, 5000)
}
}
if(user === null){
return(
<>
{errorMessage}
<h2>Log into application</h2>
<LoginForm handleLogin={handleLogin} setUsername={setUsername} setPassword={setPassword} username={username} password={password}/>
</>
)
}
return (
<div>
<h2>blogs</h2>
{user &&
<div>
<h3>{user.username} logged in</h3>
<button onClick={handleLogout}>Logout</button>
</div>
}
<BlogForm handleSubmission={addBlog} newBlog={newBlog} handleBlogField={setNewBlog}/>
{/* <BlogForm addBlog={addBlog} title={newBlog.title} setTitle={setTitle} setAuthor={setAuthor} author={newBlog.author} url={newBlog.url} setUrl={setUrl}/> */}
{blogs.map(blog =>
<Blog key={blog.id} blog={blog} />
)}
</div>
)
}
export default App
Blogs.js
import axios from 'axios'
const baseUrl = '/api/blogs'
let token = null
//let config
const setToken = (newToken) => {
token = `bearer ${newToken}`
}
const getAll = async () => {
const response = await axios.get(baseUrl)
return response.data
}
const create = async (newObject) => {
const config = {
headers: {
Authorization: token
}
}
const response = await axios.post(baseUrl, newObject, config)
console.log(`RESPONSE: ${newObject}`)
return response.data
}
const blogService = {
getAll, setToken, create
}
export default blogService

Have you configured CORS?, in order to accept your localhost requests?

Related

Cookies doesn't show up in my application ReactJS

Hello i'm trying to code auth for my app i'm using json web token the problem is when i send post request using postman i can see the cookie and access token in headers but in my application i can't see anything in my localstorage&cookies
Here is my code
authContext.js
import axios from "axios";
import { createContext, useEffect, useState } from "react";
export const AuthContext = createContext();
export const AuthContextProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState(
JSON.parse(localStorage.getItem("user")) || null
);
const login = async (inputs) => {
const res = await axios.post("http://localhost:8800/api/auth/login", inputs, {
withCredentials: true,
});
setCurrentUser(res.data)
};
useEffect(() => {
localStorage.setItem("user", JSON.stringify(currentUser));
console.log(currentUser);
}, [currentUser]);
return (
<AuthContext.Provider value={{ currentUser, login }}>
{children}
</AuthContext.Provider>
);
};
in login.jsx
const [inputs, setInputs] = useState({
username: "",
password: "",
});
const [err, setErr] = useState(null);
const navigate = useNavigate()
const handleChange = (e) => {
setInputs((prev) => ({ ...prev, [e.target.name]: e.target.value }));
};
const login = useContext(AuthContext);
const handleLogin = async (e) => {
e.preventDefault();
try {
await login(inputs);
navigate("/")
} catch (err) {
setErr(err.response.data);
}
};
console.log(err);
console.log(inputs);
I'm trying to solve the problem because i'm trying to create a basic social app i need accessToken to display posts in my feed easily

How do I make redirections with Next.js after user is authenticated?

I'm working on a web application with next.js and I have a separated API where I generate the JWT token.
I have a login form that I use to send the user info and recover the JWT. Everything is working fine, but when I persist the data and I try to redirect the user to the dashboard which is supposed to be a protected route, it stays protected even though the user is authenticated. I don't know what am I doing wrong..
Here is the context file :
import React, {createContext, useEffect, useState} from 'react'
import { useRouter } from "next/router";
import axios from 'axios'
export const Context = createContext(null)
const devURL = "http://localhost:4444/api/v1/"
export const ContextProvider = ({children}) => {
const router = useRouter()
const [user, setUser] = useState()
const [userToken, setUserToken] = useState()
const [loading, setLoading] = useState(false)
const [successMessage, setSuccessMessage] = useState("")
const [errorMessage, setErrorMessage] = useState("")
const Login = (em,pass) => {
setLoading(true)
axios.post(devURL+"authentication/login", {
email : em,
password : pass
})
.then((res)=>{
setSuccessMessage(res.data.message)
setErrorMessage(null)
setUser(res.data.user)
setUserToken(res.data.token)
localStorage.setItem('userToken', res.data.token)
localStorage.setItem('user', res.data.user)
setLoading(false)
})
.catch((err)=>{
setErrorMessage(err.response.data.message)
setSuccessMessage(null)
setLoading(false)
})
}
const Logout = () => {
setUserToken()
setUser()
localStorage.removeItem('userToken')
localStorage.removeItem('user')
router.push('/authentication/admin')
}
const isUserAuthenticated = () => {
return !!userToken
}
useEffect(()=>{
let token = localStorage.getItem('userToken')
if(token){
setUserToken(token)
}
},[userToken])
return (
<Context.Provider value={{
Login,
user,
loading,
userToken,
setUserToken,
Logout,
successMessage,
setSuccessMessage,
setErrorMessage,
isUserAuthenticated,
errorMessage}}>
{children}
</Context.Provider>
)
}
and here is the dashboard page :
import React, {useContext, useEffect} from 'react'
import DashboardIndexView from '../../views/dashboard'
import { useRouter } from "next/router";
import { Context } from '../../context/context';
export default function DashboardIndex() {
const router = useRouter();
const {isUserAuthenticated} = useContext(Context);
console.log(isUserAuthenticated())
useEffect(()=>{
if(isUserAuthenticated()) {
router.push("/dashboard")
} else {
router.push("/authentication/admin")
}
}, [])
return (
<>
<DashboardIndexView />
</>
)
}
I believe that the useEffect in the dashboard page is always going to be redirecting the user to the authentication form, because I debugged what happens (picture) and apparently the isUserAuthenticated function runs twice, once it returns false, and then true, and the first return 'false' redirects the user to the authentication form.
How can I fix this ?
Picture of the console :

window.stripe is not a function

I am trying to create a stripe checkout project but was stuck when I found that the loadStripe promise was not working fine and I have to change the code window.stripe but this is also not working .
Her is my react code :
import React, { useEffect, useRef } from "react";
import { isAuth } from "../helpers/auth";
import { useNavigate } from "react-router-dom";
import styles from "./Pricing.module.scss";
import ScriptTag from "react-script-tag";
const Stripe = require('stripe')
const stripe = window.Stripe('pk_8734579834958')
export const Pricing = () => {
const buttonValue = useRef();
const navigate = useNavigate();
const setBtnValue = (e) => {
buttonValue.current = e.target.value;
};
const checkoutHandler = async (e) => {
const btnValue = buttonValue.current;
console.log(btnValue);
fetch("http://localhost:5000/api/checkout", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
btnValue,
}),
})
.then((result) => result.json())
.then(({ sessionID }) => stripe.redirectToCheckout({ sessionID }))
.then((result) => {
console.log(result.error.message);
});
};
return (
<div>
<ScriptTag
isHydrating={true}
type="text/javascript"
src="https://js.stripe.com/v3/"
/>
<form onSubmit = {checkoutHandler}>
<button
value= 'price_bdsahfbadshb'
type="submit"
className="btn"
name="product"
onClick={setBtnValue}
>
Upgrade Now
</button>
</div>
)
}
Here is my backend code :
router.post('/checkout' , async(req,res) => {
const product = req.body;
console.log(product);
}
As you want to redirect, just try adding <script src="https://js.stripe.com/v3/"></script> into index.html (if not added) so you will able to use window.Stripe.
and remove line const Stripe = require('stripe')
if you want more clarification, go through its official documentation.

Why is the response (payment Intent) after completing the payment undefined?

myReactApp/functions/index.js
const functions = require("firebase-functions");
const express = require("express");
const cors = require("cors");
const stripe = require('stripe')
('sk_test_**********');
// API
// App config
const app = express();
// Middlewares
app.use( cors({origin:true}) );
app.use(express.json());
// API routes
app.get('/', (request, respond) => respond.status(200).send("page is working") );
app.post('/payment/create', async (request, response) => {
const total = request.query.total;//get the value of total from URL using query
console.log('payment request recived >>>' , total);
const paymentIntent = await stripe.paymentIntents.create({
amount: total,
currency: 'USD'
})
response.status(201).send({
clientSecret : paymentIntent.client_secret,
})
})
//http://localhost:5001/clone-21937/us-central1/api
// Listen command
exports.api = functions.https.onRequest(app);
myReactApp/src/payment.js
import React, { useEffect, useState } from 'react';
import Orders from './Orders';
import CheckoutProduct from './CheckoutProduct';
import CurrencyFormat from 'react-currency-format';
import { CardElement, useElements, useStripe } from '#stripe/react-stripe-js';
import { collection, addDoc, setDoc } from 'firebase/firestore/lite'
import { Link, useNavigate } from 'react-router-dom';
import { useStateValue } from './StateProvider';
import { db } from './firebase';
import axios from './axios';
const Payment = () => {
const stripe = useStripe();
const elements = useElements();
const navigate = useNavigate();
const [{ basket, subtotal, user }, dispatch] = useStateValue();
const [succeeded, setSucceeded] = useState(false);
const [processing, setProcessing] = useState('');
const [error, setError] = useState(null);
const [disabled, setDisabled] = useState(true);
const [clientSecret, setClientSecret] = useState(true);
useEffect(() => {
const getClientSecret = async () => {
const response = await axios({
method: 'POST',
url: `/payment/create?total=${subtotal * 100}`
});
//clientSecret is the amount to be paid
//fetching the clientSecret send from response (Index.js)
setClientSecret(response.data.clientSecret);
}
getClientSecret();
}, [basket]);
//handle submitting the form
const handleSubmit = async (event) => {
event.preventDefault();
setProcessing(true);
const payload = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement)
}
}).then( ({paymentIntent}) => {
console.log(paymentIntent);//undefined
try {
addDoc(
collection(db,'users', user?.uid, 'orders'),{
basket:basket
}
)
}
catch (error) {
alert(error.message);
}
//empty the basket after order
dispatch({
type: 'EMPTY_BASKET'
})
setSucceeded(true);
setProcessing(false);
setError(null);
// navigate('/orders');
})
}
const handleChange = (event) => {
setDisabled(event.empty);
setError(event.error ? event.error.message : '');
}
return (
<div className="payment_sectionTransaction">
<form onSubmit={handleSubmit}>
<CardElement className='payment_cardElement' onChange={handleChange}/>
<CurrencyFormat
value={subtotal}
prefix={'$'}
decimalScale={2}
thousandSeparator={true}
displayType={'text'}
renderText={(value) => {
return <>
<p><strong>Amount: {value}</strong></p>
</>
}} />
<button type='submit' disabled={processing || succeeded || disabled} >
{processing ? 'Processing..' : 'Confirm Order'}
</button>
</form>
</div>
)
}
export default Payment
After payment I am trying to get the response-paymentIntent but it shows to be undefined.
I can see the payment in the stripe dashboard so may be payment sections is all good but response after the payment is not good.
I also get this error in console after payment get done:
POST http://localhost:5001/clone-21937/us-central1/api/payment/create?total=0 net::ERR_FAILED 200
getClientSecret is async function. You must write code look like
const result = await getClientSecret();

App does not reload, authentication fails despite JWT token remaining in local storage react/node.js

I have had success implementing the application in its entirety but the only problem I am having deals with authorization when reloading the page. I have set a "token" key in localStorage but it fails to retrieve this key or token (presumably) on reload. I can clearly see it is defined in Chrome's Inspect but when I try to console.log or use that localStorage variable in anyway after reloading it is reads undefined. I can still see the token visible in Chrome's Application Storage and I am not sure how this is possible. The app works properly in development but when deployed to heroku or when express is used to deliver the static file it also stops working and this behavior of returning undefined keeps happening always returning "res.status(403).json("Not Authorized (authorization catch)")"
I have gone through many documents in express and jwt along with many SO solutions. It seems most people lose their token but that is not the case here.
My server code looks like:
const express= require("express")
const app = express()
const cors = require("cors")
const path = require('path')
// middleware
app.use(express.json())
app.use(cors())
// ROUTES
// register and login
app.use("/auth", require("./routes/jwtAuth"))
app.use("/dashboard", require("./routes/dashboard"))
app.use("/", express.static(path.join(__dirname, 'client/build')))
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "client/build/index.html"));
});
const PORT = process.env.PORT || 5000
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`)
})
And the page that I would like to reload includes:
import React, { Fragment, useState, useEffect } from 'react'
//components
import InputConnection from './connectionlist/InputConnection'
import ListConnections from './connectionlist/ListConnections'
import LogoutBtn from './LogoutBtn'
import ReportingLayout from './reporting/Layout/ReportingLayout'
const Dashboard = ({ setAuth }) => {
const [name, setName] = useState("")
const [allConnections, setAllConnections] = useState([])
const [connectionsChange, setConnectionsChange] = useState(false)
const auth = setAuth
const getName = async () => {
try {
const response = await fetch("/dashboard/", {
method:"GET",
headers:{ token: localStorage.token }
})
const parseData = await response.json()
// console.log(parseData)
if (parseData.admin === 'lead') {
setName("Lead School Counselor")
setAllConnections(parseData.results)
}else{
setName(parseData[0].user_name)
setAllConnections(parseData)
}
} catch (error) {
}
}
useEffect(() => {
getName()
setConnectionsChange(false)
}, [connectionsChange])
if(name === "Lead School Counselor" ){
return(
<div>
<ReportingLayout auth={auth} allConnections={ allConnections } />
</div>
)
}else{
return(
<Fragment>
<div className="container">
<div className='btn-group '>
<LogoutBtn setAuth = {setAuth}/>
</div>
<h1 className="d-flex rm-3" > Welcome {name}, </h1>
<InputConnection setConnectionsChange={setConnectionsChange}/>
<ListConnections allConnections={ allConnections } setConnectionsChange=
{setConnectionsChange}/>
</div>
</Fragment>
)
}
}
export default Dashboard;
This is where the code fails. It is a middleware that deals with the authorization and prinst the error message from step 1:
const jwt = require("jsonwebtoken")
require("dotenv").config()
module.exports = async (req, res, next) => {
try {
// step 1 destructure
const jwtToken = req.header("token")
if(!jwtToken){
return res.status(403).json("Not Authorized (authorization not jwt Token)")
}
// step 2 check if the token is valid
const payload = jwt.verify(jwtToken, process.env.jwtSecret)
// step 3 gives access as req.user
req.user = payload.user
next()
} catch (err) {
console.error(err.message)
return res.status(403).json("Not Authorized (authorization catch)")
}
}
App.js:
import React, { Fragment, useState, useEffect } from 'react';
import './App.css';
import {BrowserRouter as Router, Switch, Route, Redirect} from 'react-
router-dom'
// components
import Dashboard from './components/dashboard/Dashboard'
import Login from './components/Login'
import Register from './components/Register'
import Landing from './components/Landing'
//toastify
import "react-toastify/dist/ReactToastify.css";
import { toast } from "react-toastify";
toast.configure()
function App() {
const [isAuthenticated, setIsAuthenticated] = useState(false)
const setAuth = (boolean) => {
setIsAuthenticated(boolean)
}
async function isAuth(){
try {
const response = await fetch("/auth/is-verified", {
method:"GET",
headers:{token: localStorage.getItem("token") }
app.s })
const parseRes = await response.json()
console.log(`this message is ${parseRes}`)
parseRes === true ? setIsAuthenticated(true): setIsAuthenticated(false)
} catch (err) {
console.error(err.message)
}
}
useEffect(() => {
isAuth()
})
return (
<Fragment>
<Router>
<div>
<Switch>
<Route exact path="/landing" render={props => !isAuthenticated
? <Landing {...props} /> : <Redirect to='/dashboard'/>} />
<Route exact path="/register" render={props => !isAuthenticated ?
<Register {...props} setAuth ={setAuth} /> : <Redirect to='/login'/>} />
<Route exact path="/login" render={props => !isAuthenticated ?
<Login {...props} setAuth ={setAuth} auth={isAuthenticated}/> : <Redirect
to='/dashboard'/>} />
<Route exact path="/dashboard" render={props => isAuthenticated ?
<Dashboard {...props} setAuth ={setAuth} /> : <Redirect to='/login'/>} />
</Switch>
</div>
</Router>
</Fragment>
);
}
export default App;
here is the dashboard.js db and connections:
const router = require("express").Router()
const pool = require("../db")
const authorization = require("../middleware/authorization")
// all connections and name
router.get("/", authorization, async (req, res) => {
try {
res.json(req.user.name)
if(req.user.name === 'lead'){
const lead = await pool.query("SELECT * FROM connections LEFT JOIN
users ON users.user_id = connections.user_id")
... A bunch of sql queries here that work fine...
res.json({
admin: req.user.name,
results: lead.rows,
// aggregated queries
studentsEngaged: studentsEngaged.rows,
gender:gender.rows,
distinctStudents: distinctStudents.rows,
amountSep: amountSep.rows,
amountOct:amountOct.rows,
amountNov: amountNov.rows,
amountDec: amountDec.rows,
studentSessions:studentSessions.rows,
homeVisits: homeVisits.rows,
outsideAgencies: outsideAgencies.rows,
cpReferrals: cpReferrals.rows,
amountReferrals:amountReferrals.rows,
amountDischarges: amountDischarges.rows,
classroomPresentations: classroomPresentations.rows,
groupSessions: groupSessions.rows,
checkins: checkins.rows,
crisisInterventions: crisisInterventions.rows,
parentContacts: parentContacts.rows,
meetings : meetings.rows
})
}else{
const user = await pool.query("SELECT u.user_name, c.connection_id,
c.contact_type, c.contact_method, c.provision, c.connection_date,
c.student_id,
c.purpose, c.gender, c.yearGroup, c.school, c.referral_discharge,
c.cp_referral
FROM users AS u LEFT JOIN connections AS c ON u.user_id = c.user_id WHERE
u.user_id= $1", [req.user.id])
res.json(user.rows)
}
} catch (err) {
console.error(err.message)
res.status(500).json("Server Error (dashboard catch)")
}
})
// create connection
router.post("/connections", authorization, async (req, res) => {
try {
// console.log(req.body);
const { student_id, contact_type, yearGroup, school, contact_method,
gender, purpose, provision, connection_date, referral_discharge, cp_referral}
=
req.body;
const newConnection = await pool.query(
"INSERT INTO connections (user_id, student_id, user_name, contact_type,
yearGroup, school, contact_method, gender, purpose, provision,
connection_date,
referral_discharge, cp_referral) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9,
$10, $11, $12, $13) RETURNING *",
[req.user.id, student_id, req.user.name, contact_type, yearGroup, school,
contact_method, gender, purpose, provision, connection_date,
referral_discharge,
cp_referral]
);
res.json(newConnection.rows[0]);
// console.log(newConnection.rows[0])
} catch (err) {
console.error(err.message)
}
});
// update connection
router.put("/connections/:id", authorization, async (req, res) => {
try {
const { id } = req.params;
const { student_id, contact_type, yearGroup, school, contact_method,
gender, purpose, provision, connection_date, referral_discharge, cp_referral
} =
req.body;
const updateConneciton = await pool.query(
"UPDATE connections SET student_id=$1, contact_type=$2, yearGroup=$3,
school=$4, contact_method=$5, gender=$6, purpose=$7, provision=$8,
connection_date=$9, referral_discharge=$10, cp_referral=$11 WHERE
connection_id =
$12 AND user_id = $13 RETURNING *",
[student_id, contact_type, yearGroup, school, contact_method, gender,
purpose, provision, connection_date, referral_discharge, cp_referral, id,
req.user.id]
);
if (updateConneciton.rows.length === 0) {
return res.json("This connection is not yours");
}
res.json("Connection was updated");
} catch (err) {
console.error(err.message);
}
});
// delete connection
router.delete("/connections/:id", authorization, async (req, res) => {
try {
const { id } = req.params;
const deleteConnection = await pool.query(
"DELETE FROM connections WHERE connection_id = $1 AND user_id = $2
RETURNING *",
[id, req.user.id]
);
if (deleteConnection.rows.length === 0) {
return res.json("This connection is not yours");
}
res.json("Connection was deleted");
} catch (err) {
console.error(err.message);
}
}) ;
At input is appended to the headers:
import React, { Fragment, useState } from "react";
import { toast } from 'react-toastify'
const InputTodo = ({ setConnectionsChange }) => {
const [contact_type, setContactType] = useState("");
const [contact_method, setContactMethod] = useState("");
const [provision, setProvision] = useState("");
const [connection_date, setDate] = useState("");
const [student_id, setStudentID] = useState("");
const [purpose, setPurpose] = useState("");
const [gender, setGender] = useState("");
const [yearGroup, setYearGroup] = useState("");
const [school, setSchool] = useState("");
const [referral_discharge, setReferralDischarge] = useState("");
const [cp_referral, setCPReferral] = useState("");
const onSubmitForm = async e => {
e.preventDefault();
try {
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("token", localStorage.token);
const body = {
contact_type,
contact_method,
provision,
connection_date,
student_id,
purpose,
gender,
yearGroup,
school,
referral_discharge,
cp_referral
};
const response = await fetch("/dashboard/connections", {
method: "POST",
headers: myHeaders,
body: JSON.stringify(body)
});
const parseResponse = await response.json();
console.count(parseResponse);
setConnectionsChange(true);
setContactType("")
setContactMethod("")
setProvision("")
setDate("")
setStudentID("")
setPurpose("")
setGender("")
setYearGroup("")
setSchool("")
setReferralDischarge("")
setCPReferral("")
toast.success('Contact has been added', {
position: "top-center",
autoClose: 3000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
});
} catch (error) {
console.error(error.message);
}
};
return (
<Fragment> A form
</Fragment>
)
Authorization check on back end:
const router = require("express").Router()
const pool = require("../db")
const bcrypt = require("bcrypt")
const jwtGenerator = require("../utils/jwtGenerator")
const validInfo = require("../middleware/validInfo")
const authorization = require("../middleware/authorization")
// registering
router.post("/register", validInfo, async(req, res) =>{
try {
// step1 destructure
const { name, email, password } = req.body
// step2 check if the user exists
const user = await pool.query("SELECT * FROM users WHERE
user_email=$1", [email])
if(user.rows.length >0){
return res.status(401).json("User already exists; email is
already registered with the database")
}
// step3 bcrypt the user password for db
const saltRound = 10;
const salt = await bcrypt.genSalt(saltRound)
const bcryptPassword = await bcrypt.hash(password, salt)
// step4 insert the info into the db
const newUser = await pool.query("INSERT INTO users (user_name,
user_email, user_password) VALUES ($1, $2, $3) RETURNING *", [name, email,
bcryptPassword])
// step5 generate a jwt token
const token = jwtGenerator(newUser.rows[0].user_id,
newUser.rows[0].user_name)
res.json({ token })
} catch (err) {
console.error(err.message)
res.status(500).json("Server Error (register)")
}
})
// login and logout
router.post("/login", validInfo, async (req, res) => {
try {
// step1 deconstruct req.body
const { email, password } = req.body
// step 2 check if user doesnt exist and if not throw and error
const user = await pool.query("SELECT * FROM users WHERE
user_email=$1", [email])
if(user.rows.length === 0){
return res.status(401).json("User email is incorrect or does not
exist.")
}
// step 3 check if incoming pword is the same as db password
const validPassword = await bcrypt.compare(password,
user.rows[0].user_password)
if(!validPassword){
return res.status(401).json("Password is incorrect.")
}
// step4 give them a jwt token
const token = jwtGenerator(user.rows[0].user_id, user.rows[0].user_name)
res.json({ token })
} catch (err) {
console.log(err.Message)
res.statusMessage(500).json("Server Error (login)")
}
})
router.get("/is-verified", authorization, (req, res) => {
try {
res.json(true)
} catch (error) {
console.log(err.Message)
res.statusMessage(500).json("Server Error (is-verified)")
}
})
module.exports = router;
Instead of reloading, I will type in "/login" into the url and it will then redirect me (using the routes set up) to dashboard no problem. Could I just direct the user to log in on reloading and if so what is an optimal way to implement it?

Resources