auth backend complete

This commit is contained in:
Priyatham-sai-chand 2020-11-30 22:26:17 +05:30
parent 3486554f39
commit 35e1d4b08c
13 changed files with 245 additions and 161 deletions

3
.env
View File

@ -1,2 +1,3 @@
MONGODB_CONNECTION_STRING = mongodb+srv://admin:ABxXFUBs5FMiAaDJ@form.iynew.mongodb.net/<dbname>?retryWrites=true&w=majority MONGODB_CONNECTION_STRING = mongodb+srv://admin:ABxXFUBs5FMiAaDJ@form.iynew.mongodb.net/form?retryWrites=true&w=majority
JWT_SECRET = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

1
.gitignore vendored
View File

@ -5,6 +5,7 @@
/.pnp /.pnp
/.env /.env
.pnp.js .pnp.js
# testing # testing
/coverage /coverage

View File

@ -1,4 +1,4 @@
{ {
"mongoURI": "mongodb+srv://admin:admin@form.iynew.mongodb.net/<dbname>?retryWrites=true&w=majority", "mongoURI": "mongodb+srv://admin:ABxXFUBs5FMiAaDJ@form.iynew.mongodb.net/<dbname>?retryWrites=true&w=majority",
"jwtSecret": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" "jwtSecret": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
} }

View File

@ -2,7 +2,8 @@ const router = require("express").Router();
const bcrypt = require("bcryptjs"); const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken"); const jwt = require("jsonwebtoken");
const auth = require("../middleware/auth"); const auth = require("../middleware/auth");
const User = require("../models/userModel"); const User = require("../schemas/User");
const config = require("config");
router.post("/register", async (req, res) => { router.post("/register", async (req, res) => {
try { try {
@ -10,16 +11,12 @@ router.post("/register", async (req, res) => {
// validate // validate
if (!email || !password || !passwordCheck) if (!email || !password )
return res.status(400).json({ msg: "Not all fields have been entered." }); return res.status(400).json({ msg: "Not all fields have been entered." });
if (password.length < 5) if (password.length < 5)
return res return res
.status(400) .status(400)
.json({ msg: "The password needs to be at least 5 characters long." }); .json({ msg: "The password needs to be at least 5 characters long." });
if (password !== passwordCheck)
return res
.status(400)
.json({ msg: "Enter the same password twice for verification." });
const existingUser = await User.findOne({ email: email }); const existingUser = await User.findOne({ email: email });
if (existingUser) if (existingUser)
@ -62,7 +59,7 @@ router.post("/login", async (req, res) => {
const isMatch = await bcrypt.compare(password, user.password); const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) return res.status(400).json({ msg: "Invalid credentials." }); if (!isMatch) return res.status(400).json({ msg: "Invalid credentials." });
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET); const token = jwt.sign({ id: user._id },config.get('jwtSecret'));
res.json({ res.json({
token, token,
user: { user: {

View File

@ -1,5 +1,5 @@
require("dotenv").config();
const express = require("express"); const express = require("express");
const config = require("config");
const mongoose = require("mongoose"); const mongoose = require("mongoose");
const cors = require("cors"); const cors = require("cors");
@ -16,7 +16,7 @@ app.listen(PORT, () => console.log(`The server has started on port: ${PORT}`));
// set up mongoose // set up mongoose
mongoose.connect( mongoose.connect(
process.env.MONGODB_CONNECTION_STRING, config.get('mongoURI'),
{ {
useNewUrlParser: true, useNewUrlParser: true,
useUnifiedTopology: true, useUnifiedTopology: true,
@ -30,4 +30,4 @@ mongoose.connect(
// set up routes // set up routes
app.use("/users", require("./routes/userRouter")); app.use("/users", require("./routes/users"));

View File

@ -1,19 +1,55 @@
import React, { Component } from 'react'; import React, { useEffect, useState } from 'react';
import Axios from 'axios';
import HomePage from "./components/HomePage"; import HomePage from "./components/HomePage";
import Login from "./components/SignIn";
import PricingPlan from "./components/PricingPlan"; import PricingPlan from "./components/PricingPlan";
import LogInContainer from "./components/LogInContainer"; import LogInContainer from "./components/LogInContainer";
import { BrowserRouter, Route, Switch } from 'react-router-dom'; import { BrowserRouter, Route, Switch } from 'react-router-dom';
class App extends Component { import UserContext from "./context/UserContext";
render(){
export default function App() {
const [userData, setUserData ] = useState({
token: undefined,
user: undefined
});
useEffect(() => {
const checkLoggedIn = async () => {
let token = localStorage.getItem("auth-token");
if (token == null) {
localStorage.setItem("auth-token","");
token ="";
}
const tokenRes = await Axios.post(
"http://localhost:5000/users/tokenIsValid",
null,
{headers: {"x-auth-token": token }}
);
if (tokenRes.data) {
const userRes = await Axios.get("http://localhost:5000/users/",
{headers:{"x-auth-token":token},
});
setUserData({
token,
user: userRes.data,
});
}
};
checkLoggedIn();
},[])
return ( return (
<div className="App"> <div className="App">
<BrowserRouter> <BrowserRouter>
<UserContext.Provider value= {{userData, setUserData}}>
<Switch> <Switch>
<Route exact path="/home" component={HomePage} /> <Route exact path="/home" component={HomePage} />
<Route path="/user" component={LogInContainer} /> <Route path="/user" component={LogInContainer} />
<Route path="/pricing" component={PricingPlan} /> <Route path="/pricing" component={PricingPlan} />
</Switch> </Switch>
</UserContext.Provider>
</BrowserRouter> </BrowserRouter>
@ -21,6 +57,5 @@ class App extends Component {
); );
} }
}
export default App;

View File

@ -0,0 +1,32 @@
import React, { useContext } from "react";
import { useHistory } from "react-router-dom";
import UserContext from "../../context/UserContext";
export default function AuthOptions() {
const { userData, setUserData } = useContext(UserContext);
const history = useHistory();
const register = () => history.push("/register");
const login = () => history.push("/login");
const logout = () => {
setUserData({
token: undefined,
user: undefined,
});
localStorage.setItem("auth-token", "");
};
return (
<nav className="auth-options">
{userData.user ? (
<button onClick={logout}>Log out</button>
) : (
<>
<button onClick={register}>Register</button>
<button onClick={login}>Log in</button>
</>
)}
</nav>
);
}

View File

@ -1,14 +1,14 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { HashRouter as BrowserRouter, Route, Link, NavLink, Switch } from 'react-router-dom'; import { BrowserRouter, Route, NavLink, Switch } from 'react-router-dom';
import SignUpForm from './SignUp'; import Register from './Register';
import SignInForm from './SignIn'; import Login from './Login';
import '../login_reg.css'; import '../login_reg.css';
class LogInContainer extends Component { class LogInContainer extends Component {
render() { render() {
return ( return (
<BrowserRouter> <BrowserRouter basename="user">
<div className="Apper"> <div className="Apper">
<div className="Apper__Aside"> <div className="Apper__Aside">
<div className="Apper__Aside__text"> <div className="Apper__Aside__text">
@ -18,21 +18,21 @@ class LogInContainer extends Component {
</div> </div>
<div className="Apper__Form"> <div className="Apper__Form">
<div className="PageSwitcher"> <div className="PageSwitcher">
<NavLink to="/sign-in" activeClassName="PageSwitcher__Item--Active" className="PageSwitcher__Item">Sign In</NavLink> <NavLink to="/login" activeClassName="PageSwitcher__Item--Active" className="PageSwitcher__Item">Sign In</NavLink>
<NavLink to="/sign-up" activeClassName="PageSwitcher__Item--Active" className="PageSwitcher__Item">Sign Up</NavLink> <NavLink to="/register" activeClassName="PageSwitcher__Item--Active" className="PageSwitcher__Item">Sign Up</NavLink>
</div> </div>
<div className="FormTitle"> <div className="FormTitle">
<NavLink to="/sign-in" activeClassName="FormTitle__Link--Active" className="FormTitle__Link">Sign In</NavLink> or <NavLink exact to="/sign-up" activeClassName="FormTitle__Link--Active" className="FormTitle__Link">Sign Up</NavLink> <NavLink to="/login" activeClassName="FormTitle__Link--Active" className="FormTitle__Link">Sign In</NavLink> or <NavLink exact to="/register" activeClassName="FormTitle__Link--Active" className="FormTitle__Link">Sign Up</NavLink>
</div> </div>
<Switch>
<Route path="/register" component={Register} />
<Route path="/login" component={Login} />
</Switch>
<Switch>
<Route path="/sign-up" component={SignUpForm} />
<Route path="/sign-in" component={SignInForm} />
</Switch>
</div> </div>
</div> </div>
</BrowserRouter> </BrowserRouter>
); );
} }
} }

View File

@ -6,7 +6,7 @@ import Axios from "axios";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import ErrorNotice from "./ErrorNotice"; import ErrorNotice from "./ErrorNotice";
const SignInForm = () => { const Login = () => {
const [email, setEmail] = useState(); const [email, setEmail] = useState();
const [password, setPassword] = useState(); const [password, setPassword] = useState();
@ -58,4 +58,4 @@ const SignInForm = () => {
); );
} }
export default SignInForm; export default Login;

View File

@ -1,66 +1,54 @@
import React, { useState, useEffect, Component} from 'react'; import React, { useState, useEffect, useContext } from 'react';
import { useHistory } from "react-router-dom";
import '../navbar.css'; import '../navbar.css';
import Axios from "axios"; import Axios from "axios";
import UserContext from "../context/UserContext";
export default function NavBar() { export default function NavBar() {
const [userData, setUserData] = useState({ const { userData, setUserData } = useContext(UserContext);
token: undefined,
user: undefined,
});
useEffect(() => { const history = useHistory();
const checkLoggedIn = async () => {
let token = localStorage.getItem("auth-token");
if (token === null) {
localStorage.setItem("auth-token", "");
token = "";
}
const tokenRes = await Axios.post(
"http://localhost:5000/users/tokenIsValid",
null,
{ headers: { "x-auth-token": token } }
);
if (tokenRes.data) {
const userRes = await Axios.get("http://localhost:5000/users/", {
headers: { "x-auth-token": token },
});
setUserData({
token,
user: userRes.data,
});
}
};
checkLoggedIn(); const register = () => history.push("/register");
}, []); const login = () => history.push("/login");
const logout = () => {
setUserData({
token: undefined,
user: undefined,
});
localStorage.setItem("auth-token", "");
};
window.addEventListener("scroll", () => {
var header = document.querySelector("header");
header.classList.toggle("sticky", window.scrollY > 0);
window.addEventListener("scroll", () =>{ })
var header = document.querySelector("header"); return (
header.classList.toggle("sticky",window.scrollY > 0); <div class="navbar">
<header>
}) <input type="checkbox" id="check" />
return( <label for="check" class="checkbtn">
<div class="navbar"> <i class="fas fa-bars" id="btn"></i>
<header> </label>
<input type="checkbox" id="check"/>
<label for="check" class="checkbtn">
<i class="fas fa-bars" id="btn"></i>
</label>
<a href="/home" class="logo">locaft</a> <a href="/home" class="logo">locaft</a>
<ul> <ul>
<li><a href="#">Home</a></li> <li><a href="#">Home</a></li>
<li><a href="#">About</a></li> <li><a href="#">About</a></li>
<li><a href="#">Services</a></li> <li><a href="#">Services</a></li>
<li><a href="#">Contact us</a></li> <li><a href="#">Contact us</a></li>
<li><a href="#">Register</a></li> <li><a href="#">Log In</a></li>
<li><a href="#">Log In</a></li> {userData.user ? (
</ul> <li><a href="#">Log Out</a></li>
) : (
<li><a href="#">Register</a></li>
)}
</ul>
</header> </header>
</div> </div>
) )
} }

102
src/components/Register.js Normal file
View File

@ -0,0 +1,102 @@
import React, { Component, useState, useContext } from "react";
import { useHistory } from "react-router-dom";
import UserContext from "../context/UserContext";
import Axios from "axios";
import { Link } from "react-router-dom";
import ErrorNotice from "./ErrorNotice";
const Register = () => {
const [email, setEmail] = useState();
const [password, setPassword] = useState();
const [phonenumber, setPhonenumber] = useState();
const [username, setUsername] = useState();
const [error, setError] = useState();
const { setUserData } = useContext(UserContext);
const history = useHistory();
const submit = async (e) => {
e.preventDefault();
try {
const newUser = { username,email,phonenumber,password};
await Axios.post("http://localhost:5000/users/register", newUser);
const loginRes = await Axios.post("http://localhost:5000/users/login", {
email,
password,
});
setUserData({
token: loginRes.data.token,
user: loginRes.data.user,
});
localStorage.setItem("auth-token", loginRes.data.token);
history.push("/");
} catch (err) {
err.response.data.msg && setError(err.response.data.msg);
}
};
return (
<div className="FormCenter">
{error && (
<ErrorNotice message={error} clearError={() => setError(undefined)} />
)}
<form className="FormFields" onSubmit={submit}>
<div className="FormField">
<label className="FormField__Label" htmlFor="name">UserName</label>
<input
type="text"
id="name"
className="FormField__Input"
placeholder="Enter your full name"
onChange= { (e) => setUsername(e.target.value)}
/>
</div>
<div className="FormField">
<label className="FormField__Label" htmlFor="password">Password</label>
<input
type="password"
id="password"
className="FormField__Input"
placeholder="Enter your password"
onChange= { (e) => setPassword(e.target.value)}
/>
</div>
<div className="FormField">
<label className="FormField__Label" htmlFor="email">E-Mail Address</label>
<input
type="email"
id="email"
className="FormField__Input"
placeholder="Enter your email"
onChange= { (e) => setEmail(e.target.value)}
/>
</div>
<div className="FormField">
<label className="FormField__Label" htmlFor="phone">Phone number</label>
<input
type="number"
id="phonenumber"
className="FormField__Input"
placeholder="Enter your Phone no. (+91)"
onChange= { (e) => setPhonenumber(e.target.value)}
/>
</div>
<div className="FormField">
<label className="FormField__CheckboxLabel">
<input className="FormField__Checkbox" type="checkbox" name="hasAgreed" /> I agree all statements in <a href="" className="FormField__TermsLink">terms of service</a>
</label>
</div>
<div className="FormField">
<button className="FormField__Button mr-20">Sign Up</button> <Link to="/sign-in" className="FormField__Link">already a member?</Link>
</div>
</form>
</div>
);
}
export default Register;

View File

@ -1,72 +0,0 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
class SignUpForm extends Component {
constructor() {
super();
this.state = {
email: '',
password: '',
name: '',
hasAgreed: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
let target = e.target;
let value = target.type === 'checkbox' ? target.checked : target.value;
let name = target.name;
this.setState({
[name]: value
});
}
handleSubmit(e) {
e.preventDefault();
console.log('The form was submitted with the following data:');
console.log(this.state);
}
render() {
return (
<div className="FormCenter">
<form onSubmit={this.handleSubmit} className="FormFields">
<div className="FormField">
<label className="FormField__Label" htmlFor="name">Full Name</label>
<input type="text" id="name" className="FormField__Input" placeholder="Enter your full name" name="name" value={this.state.name} onChange={this.handleChange} />
</div>
<div className="FormField">
<label className="FormField__Label" htmlFor="password">Password</label>
<input type="password" id="password" className="FormField__Input" placeholder="Enter your password" name="password" value={this.state.password} onChange={this.handleChange} />
</div>
<div className="FormField">
<label className="FormField__Label" htmlFor="email">E-Mail Address</label>
<input type="email" id="email" className="FormField__Input" placeholder="Enter your email" name="email" value={this.state.email} onChange={this.handleChange} />
</div>
<div className="FormField">
<label className="FormField__Label" htmlFor="phone">Phone number</label>
<input type="email" id="email" className="FormField__Input" placeholder="Enter your Phone no. (+91)" name="phone" value={this.state.phone} onChange={this.handleChange} />
</div>
<div className="FormField">
<label className="FormField__CheckboxLabel">
<input className="FormField__Checkbox" type="checkbox" name="hasAgreed" value={this.state.hasAgreed} onChange={this.handleChange} /> I agree all statements in <a href="" className="FormField__TermsLink">terms of service</a>
</label>
</div>
<div className="FormField">
<button className="FormField__Button mr-20">Sign Up</button> <Link to="/sign-in" className="FormField__Link">already a member?</Link>
</div>
</form>
</div>
);
}
}
export default SignUpForm;