login integration complete

This commit is contained in:
Tejas 2022-03-18 17:15:15 +05:30
parent 410ccadfd6
commit f80c6a8142
12 changed files with 152 additions and 107 deletions

View File

@ -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")
}
}

View File

@ -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()
}

View File

@ -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,
)
}

View File

@ -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

View File

@ -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?&nbsp;
<Link href="/signup" exact className="foot-text underline">
<Link href="/signup" className="foot-text underline">
Create an account
</Link>
</p>

View File

@ -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>

View File

@ -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>
)}

View File

@ -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&nbsp;
<Link href="/login" exact className="foot-text underline">
<Link href="/login" className="foot-text underline">
here
</Link>
</p>

View File

@ -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

View File

@ -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)
}

View File

@ -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>
)
}

View File

@ -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;
}