login integration complete
This commit is contained in:
parent
410ccadfd6
commit
f80c6a8142
|
@ -2,7 +2,7 @@ const jwt = require('jsonwebtoken')
|
|||
const User = require('../models/user')
|
||||
|
||||
module.exports.register = async (req, res) => {
|
||||
const { name, email, password } = req.body;
|
||||
const { name, email, password } = req.body
|
||||
|
||||
try {
|
||||
// if any fields are missing
|
||||
|
@ -11,15 +11,15 @@ module.exports.register = async (req, res) => {
|
|||
}
|
||||
|
||||
// if the user is already registered
|
||||
let oldUser = await User.findOne({ email }).catch((err) => {
|
||||
const oldUser = await User.findOne({ email }).catch((err) => {
|
||||
console.error(err)
|
||||
})
|
||||
if (oldUser){
|
||||
return res.status(409).send('User already exists')
|
||||
return res.status(409).send("User already exists")
|
||||
}
|
||||
|
||||
// saving new user to database
|
||||
let user = new User({ email })
|
||||
let user = new User({ email, name })
|
||||
user.setPassword(password)
|
||||
|
||||
let validationError = false
|
||||
|
@ -29,15 +29,19 @@ module.exports.register = async (req, res) => {
|
|||
})
|
||||
|
||||
if (!validationError){
|
||||
return res.status(200).json({ jwt: user.generateJWT(), message: "User successfully registered"})
|
||||
return res.status(200).json({
|
||||
access_token: user.generateJWT(),
|
||||
message: "User successfully registered",
|
||||
user : { name: user.name, email: user.email }
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e)
|
||||
return res.status(500).send('Internal Server Error')
|
||||
return res.status(500).send("Internal Server Error")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports.login = async (req, res) => {
|
||||
const { email, password } = req.body;
|
||||
|
||||
|
@ -51,33 +55,43 @@ module.exports.login = async (req, res) => {
|
|||
console.error(err)
|
||||
)
|
||||
|
||||
console.log(user);
|
||||
// if user is not registered
|
||||
if(!user){
|
||||
return res.status(404).send("User not found");
|
||||
}
|
||||
|
||||
// if password doesn't match
|
||||
if(!user.validatePassword(password)){
|
||||
return res.status(401).send("Incorrect email or password");
|
||||
}
|
||||
|
||||
if (user && user.validatePassword(password))
|
||||
return res.status(200).json({ access_token: user.generateJWT(), message: "Logged In" })
|
||||
return res.status(401).send(null)
|
||||
return res.status(200).json({
|
||||
access_token: user.generateJWT(),
|
||||
message: "Logged In",
|
||||
user : { name: user.name, email: user.email }
|
||||
})
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err)
|
||||
return res.sendStatus(500)
|
||||
return res.status(500).send("Internal Server Error")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports.me = async (req, res) => {
|
||||
module.exports.authenticate = async (req, res) => {
|
||||
try {
|
||||
if (!req.user.isAuthenticated) {
|
||||
res.sendStatus(401)
|
||||
return
|
||||
return res.status(401).send('Not Authenticated')
|
||||
}
|
||||
let user = req.user.data
|
||||
res.send({
|
||||
|
||||
const user = req.user.data
|
||||
|
||||
return res.status(200).json({
|
||||
email: user.email,
|
||||
name: user.name,
|
||||
phone: user.phone,
|
||||
name: user.name
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
return res.sendStatus(500)
|
||||
return res.status(500).send("Internal Server Error")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,23 +3,31 @@ const User = require('../models/user')
|
|||
|
||||
module.exports.auth = async (req, res, next) => {
|
||||
let user = { isAuthenticated: false }
|
||||
if (req.headers.authorization && req.headers.authorization !== null) {
|
||||
const authHeader = req.headers.authorization
|
||||
const token = authHeader.split(' ')[1]
|
||||
|
||||
if (authHeader && token) {
|
||||
try {
|
||||
let jwtData = jwt.verify(
|
||||
req.headers.authorization.replace('Bearer ', ''),
|
||||
process.env.AUTH_SECRET
|
||||
)
|
||||
let userData = await User.findOne({
|
||||
// throws error if token is invalid
|
||||
const jwtData = jwt.verify(token, process.env.AUTH_SECRET)
|
||||
console.log(jwtData);
|
||||
|
||||
const userData = await User.findOne({
|
||||
email: jwtData.email,
|
||||
hash: jwtData.hash,
|
||||
}).catch((err) => console.error(err))
|
||||
|
||||
console.log(`User data: ${userData}`);
|
||||
|
||||
user.isAuthenticated = userData ? true : false
|
||||
user.data = userData
|
||||
} catch (err) {
|
||||
}
|
||||
catch (err) {
|
||||
user.isAuthenticated = false
|
||||
user.data = null
|
||||
}
|
||||
}
|
||||
|
||||
req.user = user
|
||||
next()
|
||||
}
|
||||
|
|
|
@ -44,11 +44,12 @@ UsersSchema.methods.generateJWT = function () {
|
|||
return jwt.sign(
|
||||
{
|
||||
email: this.email,
|
||||
name: this.name,
|
||||
hash: this.hash,
|
||||
id: this._id,
|
||||
exp: parseInt(String(expirationDate.getTime() / 1000), 10),
|
||||
},
|
||||
process.env.AUTH_SECRET
|
||||
process.env.AUTH_SECRET,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,6 @@ const router = Router()
|
|||
|
||||
router.post('/login', controller.login)
|
||||
router.post('/register', controller.register)
|
||||
router.get('/me', auth, controller.me)
|
||||
router.get('/authenticate', auth, controller.authenticate)
|
||||
|
||||
module.exports = router
|
||||
|
|
|
@ -6,19 +6,19 @@ import { faUser, faEnvelope, faLock } from '@fortawesome/free-solid-svg-icons'
|
|||
import { UserContext } from '../../helpers/user/usercontext'
|
||||
import { useState } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { useContext } from 'react'
|
||||
import CloseIcon from '@mui/icons-material/Close'
|
||||
import axios from 'helpers/Axios'
|
||||
import { userAuth } from 'helpers/user/usercontext'
|
||||
|
||||
function Login() {
|
||||
const [email, setEmail] = useState('tejascs84@gmail.com')
|
||||
const [password, setPassword] = useState('123')
|
||||
const [email, setEmail] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
const [message, setMessage] = useState('')
|
||||
const [isLoading, setisLoading] = useState(false)
|
||||
const { login } = userAuth()
|
||||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault()
|
||||
|
||||
|
||||
if (!email) {
|
||||
setMessage('Email should not be blank')
|
||||
|
@ -33,13 +33,18 @@ function Login() {
|
|||
setisLoading(true)
|
||||
|
||||
try {
|
||||
const res = await axios.post(`/user/login`, { email, password })
|
||||
console.log(res);
|
||||
setMessage(res.data.message)
|
||||
const { data } = await axios.post(`/user/login`, { email, password })
|
||||
const { user } = data
|
||||
|
||||
// add user to context
|
||||
login({name: user.name, email: user.email})
|
||||
|
||||
// store token after logging in
|
||||
localStorage.setItem('token', data.access_token);
|
||||
setMessage(data.message)
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error);
|
||||
setMessage('Error occured while Loggin in, please try again!!')
|
||||
setMessage(error.response.data)
|
||||
}
|
||||
|
||||
setisLoading(false)
|
||||
|
@ -100,7 +105,7 @@ function Login() {
|
|||
|
||||
<p className="foot-text">
|
||||
New here?
|
||||
<Link href="/signup" exact className="foot-text underline">
|
||||
<Link href="/signup" className="foot-text underline">
|
||||
Create an account
|
||||
</Link>
|
||||
</p>
|
||||
|
|
|
@ -13,7 +13,7 @@ export default function Logo() {
|
|||
<motion.svg
|
||||
initial={{ rotate: -180 }}
|
||||
animate={{ rotate: 0 }}
|
||||
class="logo"
|
||||
className="logo"
|
||||
data-name="Layer 4"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 65 65"
|
||||
|
@ -25,7 +25,7 @@ export default function Logo() {
|
|||
d="M58.84,53.91a9.2,9.2,0,0,1-6.54-2.72L50.14,49a2.59,2.59,0,1,1,3.67-3.66L56,47.53a4.07,4.07,0,0,0,5.76,0L75.24,34.08a4.08,4.08,0,0,0,0-5.76L70.94,24a4.08,4.08,0,0,0-5.76,0l-6.76,6.73A2.59,2.59,0,0,1,54.76,27l6.76-6.73a9.27,9.27,0,0,1,13.09,0l4.31,4.33a9.27,9.27,0,0,1,0,13.09L65.39,51.21A9.22,9.22,0,0,1,58.84,53.91Z"
|
||||
transform="translate(-28.21 -17.61)"
|
||||
stroke="white"
|
||||
stroke-linecap="round"
|
||||
strokeLinecap="round"
|
||||
strokeWidth="3"
|
||||
fill="none"
|
||||
/>
|
||||
|
@ -37,7 +37,7 @@ export default function Logo() {
|
|||
transform="translate(-28.21 -17.61)"
|
||||
stroke="white"
|
||||
strokeWidth="3"
|
||||
stroke-linecap="round"
|
||||
strokeLinecap="round"
|
||||
fill="none"
|
||||
/>
|
||||
</motion.svg>
|
||||
|
|
|
@ -17,10 +17,9 @@ import GitHubIcon from '@mui/icons-material/GitHub'
|
|||
import MenuIcon from '@mui/icons-material/Menu'
|
||||
import NavbarStyle from './Navbar.style'
|
||||
import Logo from './Logo'
|
||||
import UserAuth, { UserContext } from 'helpers/user/usercontext'
|
||||
import UserContextProvider, { userAuth } from 'helpers/user/usercontext'
|
||||
import Link from 'next/link'
|
||||
const settings = ['Profile', 'Account', 'Dashboard', 'Logout']
|
||||
import NotFound from '@pages/404'
|
||||
|
||||
function Index(props) {
|
||||
const [anchorElNav, setAnchorElNav] = React.useState(null)
|
||||
|
@ -41,15 +40,16 @@ function Index(props) {
|
|||
setAnchorElUser(null)
|
||||
}
|
||||
|
||||
const { user, login, logout } = useContext(UserAuth)
|
||||
|
||||
const { user, login, logout } = userAuth()
|
||||
// user = 0
|
||||
|
||||
return (
|
||||
<NavbarStyle
|
||||
position="relative"
|
||||
sx={{ bgcolor: alpha('#000000', 0.5), m: '0px' }}
|
||||
>
|
||||
<Container maxWidth="xl">
|
||||
<Toolbar disableGutters="false">
|
||||
<Toolbar disableGutters={false}>
|
||||
<span><Logo /></span>
|
||||
<Typography component={motion.div} initial={{ y: -50, opacity: 0 }} animate={{ y: 0, opacity: 1, transition: { delay: 1 } }} variant="h5" sx={{ fontWeight: 'bold', fontFamily: "'Montserrat Alternates', sans-serif;" }}>
|
||||
UrlMiniFy
|
||||
|
@ -101,7 +101,7 @@ function Index(props) {
|
|||
</a>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleCloseNavMenu}>
|
||||
<a href={NotFound}>
|
||||
<a>
|
||||
<Typography textAlign="center" variant="h6" sx={{ display: 'flex' }}>
|
||||
CREDITS
|
||||
</Typography>
|
||||
|
@ -143,7 +143,7 @@ function Index(props) {
|
|||
GitHub
|
||||
</Button>
|
||||
</a>
|
||||
<a href={NotFound}>
|
||||
<a>
|
||||
<Button
|
||||
component={motion.div}
|
||||
initial={{ y: -50, opacity: 0 }}
|
||||
|
@ -163,7 +163,7 @@ function Index(props) {
|
|||
</a>
|
||||
</Box>
|
||||
|
||||
{user ? (
|
||||
{user.name ? (
|
||||
<Box sx={{ flexGrow: 0 }}>
|
||||
<Tooltip title="Open settings">
|
||||
<IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
|
||||
|
@ -207,7 +207,7 @@ function Index(props) {
|
|||
}} component={motion.div}
|
||||
initial={{ y: -50, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1, transition: { delay: 1 } }}
|
||||
whileHover={{ scale: 1.1, textShadow: '2px 2px black' }} onClick={login}>
|
||||
whileHover={{ scale: 1.1, textShadow: '2px 2px black' }}>
|
||||
<Link href="./login">LOGIN</Link>
|
||||
</Typography>
|
||||
)}
|
||||
|
|
|
@ -3,21 +3,22 @@ import RegStyle from './Reg.style'
|
|||
import Image from 'next/image'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faUser, faEnvelope, faLock } from '@fortawesome/free-solid-svg-icons'
|
||||
import { useState, useContext } from 'react'
|
||||
import { useState } from 'react'
|
||||
import { Link } from '@mui/material'
|
||||
import UserAuth from 'helpers/user/usercontext'
|
||||
import CloseIcon from '@mui/icons-material/Close'
|
||||
import axios from 'helpers/Axios'
|
||||
import { userAuth } from 'helpers/user/usercontext'
|
||||
|
||||
function Reg() {
|
||||
const [name, setName] = useState('Tejas')
|
||||
const [email, setEmail] = useState('tejascs84@gmail.com')
|
||||
const [password, setPassword] = useState('123')
|
||||
const [repassword, setRepassword] = useState('123')
|
||||
const [name, setName] = useState('')
|
||||
const [email, setEmail] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
const [repassword, setRepassword] = useState('')
|
||||
const [message, setMessage] = useState('')
|
||||
const [isLoading, setisLoading] = useState(false)
|
||||
const { login } = userAuth()
|
||||
|
||||
const context = useContext(UserAuth);
|
||||
|
||||
async function handleSubmit(e){
|
||||
e.preventDefault()
|
||||
|
@ -35,9 +36,15 @@ function Reg() {
|
|||
setisLoading(true)
|
||||
|
||||
try {
|
||||
const res = await axios.post(`/user/register`, { name, email, password })
|
||||
console.log(res)
|
||||
setMessage(res.data.message)
|
||||
const { data } = await axios.post(`/user/register`, { name, email, password })
|
||||
const { user } = data
|
||||
|
||||
// login user after registering
|
||||
login({ name: user.name, email: user.email })
|
||||
|
||||
// store the token in localStorage after loggin in
|
||||
localStorage.setItem('token', data.access_token);
|
||||
setMessage(data.message)
|
||||
}
|
||||
catch (error) {
|
||||
setMessage(error.response.data)
|
||||
|
@ -128,7 +135,7 @@ function Reg() {
|
|||
|
||||
<p className="foot-text">
|
||||
Already registered? Login
|
||||
<Link href="/login" exact className="foot-text underline">
|
||||
<Link href="/login" className="foot-text underline">
|
||||
here
|
||||
</Link>
|
||||
</p>
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
import UserAuth from './usercontext'
|
||||
import { useState } from 'react'
|
||||
import axios from 'helpers/Axios'
|
||||
|
||||
const UserAuthProvider = ({ children }) => {
|
||||
const [user, setUser] = useState(null)
|
||||
const login = () => {
|
||||
setUser('default')
|
||||
}
|
||||
const createAcc = (data) => {
|
||||
axios
|
||||
.post(`/user/register`, {
|
||||
email: data.email,
|
||||
password: data.password,
|
||||
name: data.name,
|
||||
})
|
||||
.then(function (response) {
|
||||
console.log(response)
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
|
||||
const logout = () => {
|
||||
setUser(null)
|
||||
}
|
||||
const context = { user, login, logout, createAcc }
|
||||
|
||||
return <UserAuth.Provider value={context}>{children}</UserAuth.Provider>
|
||||
}
|
||||
export default UserAuthProvider
|
|
@ -1,5 +1,25 @@
|
|||
import { createContext } from "react";
|
||||
import { createContext, useState, useContext } from 'react'
|
||||
|
||||
const UserAuth = createContext();
|
||||
const UserContext = createContext()
|
||||
|
||||
export default UserAuth;
|
||||
export default function UserContextProvider({ children }) {
|
||||
const [user, setUser] = useState({})
|
||||
|
||||
function login({ name, email }){
|
||||
setUser({ name, email })
|
||||
}
|
||||
|
||||
function logout(){
|
||||
setUser({})
|
||||
}
|
||||
|
||||
return (
|
||||
<UserContext.Provider value={{ user, login, logout }}>
|
||||
{children}
|
||||
</UserContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function userAuth() {
|
||||
return useContext(UserContext)
|
||||
}
|
||||
|
|
|
@ -3,19 +3,41 @@ import '../styles/logostyles.css'
|
|||
import '../styles/formStyles.css'
|
||||
import '../styles/index.css'
|
||||
import '../styles/404.css'
|
||||
import UserAuthProvider from 'helpers/user/userState'
|
||||
import Page from 'react-page-loading'
|
||||
|
||||
import UserContextProvider, { userAuth } from 'helpers/user/usercontext'
|
||||
import { useEffect } from 'react'
|
||||
import axios from 'helpers/Axios'
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
useEffect(async () => {
|
||||
const token = localStorage.getItem('token')
|
||||
|
||||
if(!token){
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await axios.get(`/user/authenticate`, { headers: { authorization: `Bearer ${token}` }})
|
||||
console.log(res)
|
||||
|
||||
// add user to the context here if the token is valid
|
||||
|
||||
}
|
||||
catch (error) {
|
||||
// if token is invalid remove it from localStorage
|
||||
if(error.response.status === 401){
|
||||
console.log(error.response.data)
|
||||
localStorage.removeItem("token")
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<UserAuthProvider>
|
||||
<UserContextProvider>
|
||||
<Page loader={"bar"} color={"#03b1fc"} size={10} >
|
||||
<Component {...pageProps} />
|
||||
|
||||
</Page>
|
||||
|
||||
</UserAuthProvider>
|
||||
</UserContextProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
.form-wrapper {
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
padding: 20px 30px 40px 30px;
|
||||
padding: 20px 30px;
|
||||
border-radius: 20px;
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
|
@ -107,7 +107,7 @@
|
|||
.message_container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 300px;
|
||||
width: 70%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
|
@ -116,7 +116,7 @@
|
|||
|
||||
.message {
|
||||
width: 100%;
|
||||
font-size: 1.1rem;
|
||||
font-size: 1rem;
|
||||
background-color: white;
|
||||
padding: 7px;
|
||||
border-radius: 6px;
|
||||
|
@ -136,7 +136,7 @@
|
|||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
margin-top: 50px;
|
||||
margin-top: 20px;
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue