auth backend complete
This commit is contained in:
parent
3486554f39
commit
35e1d4b08c
3
.env
3
.env
|
@ -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
|
|
@ -5,6 +5,7 @@
|
|||
/.pnp
|
||||
/.env
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
|
|
|
@ -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"
|
||||
}
|
|
@ -2,7 +2,8 @@ const router = require("express").Router();
|
|||
const bcrypt = require("bcryptjs");
|
||||
const jwt = require("jsonwebtoken");
|
||||
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) => {
|
||||
try {
|
||||
|
@ -10,16 +11,12 @@ router.post("/register", async (req, res) => {
|
|||
|
||||
// validate
|
||||
|
||||
if (!email || !password || !passwordCheck)
|
||||
if (!email || !password )
|
||||
return res.status(400).json({ msg: "Not all fields have been entered." });
|
||||
if (password.length < 5)
|
||||
return res
|
||||
.status(400)
|
||||
.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 });
|
||||
if (existingUser)
|
||||
|
@ -62,7 +59,7 @@ router.post("/login", async (req, res) => {
|
|||
const isMatch = await bcrypt.compare(password, user.password);
|
||||
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({
|
||||
token,
|
||||
user: {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
require("dotenv").config();
|
||||
const express = require("express");
|
||||
const config = require("config");
|
||||
const mongoose = require("mongoose");
|
||||
const cors = require("cors");
|
||||
|
||||
|
@ -16,7 +16,7 @@ app.listen(PORT, () => console.log(`The server has started on port: ${PORT}`));
|
|||
// set up mongoose
|
||||
|
||||
mongoose.connect(
|
||||
process.env.MONGODB_CONNECTION_STRING,
|
||||
config.get('mongoURI'),
|
||||
{
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: true,
|
||||
|
@ -30,4 +30,4 @@ mongoose.connect(
|
|||
|
||||
// set up routes
|
||||
|
||||
app.use("/users", require("./routes/userRouter"));
|
||||
app.use("/users", require("./routes/users"));
|
47
src/App.js
47
src/App.js
|
@ -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 Login from "./components/SignIn";
|
||||
import PricingPlan from "./components/PricingPlan";
|
||||
import LogInContainer from "./components/LogInContainer";
|
||||
import { BrowserRouter, Route, Switch } from 'react-router-dom';
|
||||
class App extends Component {
|
||||
render(){
|
||||
import UserContext from "./context/UserContext";
|
||||
|
||||
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 (
|
||||
<div className="App">
|
||||
<BrowserRouter>
|
||||
<UserContext.Provider value= {{userData, setUserData}}>
|
||||
<Switch>
|
||||
<Route exact path="/home" component={HomePage} />
|
||||
<Route path="/user" component={LogInContainer} />
|
||||
<Route path="/pricing" component={PricingPlan} />
|
||||
</Switch>
|
||||
</UserContext.Provider>
|
||||
</BrowserRouter>
|
||||
|
||||
|
||||
|
@ -21,6 +57,5 @@ class App extends Component {
|
|||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
import React, { Component } from 'react';
|
||||
import { HashRouter as BrowserRouter, Route, Link, NavLink, Switch } from 'react-router-dom';
|
||||
import SignUpForm from './SignUp';
|
||||
import SignInForm from './SignIn';
|
||||
import { BrowserRouter, Route, NavLink, Switch } from 'react-router-dom';
|
||||
import Register from './Register';
|
||||
import Login from './Login';
|
||||
|
||||
import '../login_reg.css';
|
||||
|
||||
class LogInContainer extends Component {
|
||||
render() {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<BrowserRouter basename="user">
|
||||
<div className="Apper">
|
||||
<div className="Apper__Aside">
|
||||
<div className="Apper__Aside__text">
|
||||
|
@ -18,21 +18,21 @@ class LogInContainer extends Component {
|
|||
</div>
|
||||
<div className="Apper__Form">
|
||||
<div className="PageSwitcher">
|
||||
<NavLink to="/sign-in" 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="/login" activeClassName="PageSwitcher__Item--Active" className="PageSwitcher__Item">Sign In</NavLink>
|
||||
<NavLink to="/register" activeClassName="PageSwitcher__Item--Active" className="PageSwitcher__Item">Sign Up</NavLink>
|
||||
</div>
|
||||
<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>
|
||||
<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>
|
||||
</BrowserRouter>
|
||||
</BrowserRouter>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import Axios from "axios";
|
|||
import { Link } from "react-router-dom";
|
||||
import ErrorNotice from "./ErrorNotice";
|
||||
|
||||
const SignInForm = () => {
|
||||
const Login = () => {
|
||||
|
||||
const [email, setEmail] = useState();
|
||||
const [password, setPassword] = useState();
|
||||
|
@ -58,4 +58,4 @@ const SignInForm = () => {
|
|||
);
|
||||
}
|
||||
|
||||
export default SignInForm;
|
||||
export default Login;
|
|
@ -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 Axios from "axios";
|
||||
import UserContext from "../context/UserContext";
|
||||
|
||||
export default function NavBar() {
|
||||
const [userData, setUserData] = useState({
|
||||
token: undefined,
|
||||
user: undefined,
|
||||
});
|
||||
const { userData, setUserData } = useContext(UserContext);
|
||||
|
||||
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,
|
||||
});
|
||||
}
|
||||
};
|
||||
const history = useHistory();
|
||||
|
||||
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");
|
||||
header.classList.toggle("sticky",window.scrollY > 0);
|
||||
|
||||
})
|
||||
return(
|
||||
<div class="navbar">
|
||||
<header>
|
||||
<input type="checkbox" id="check"/>
|
||||
<label for="check" class="checkbtn">
|
||||
<i class="fas fa-bars" id="btn"></i>
|
||||
</label>
|
||||
})
|
||||
return (
|
||||
<div class="navbar">
|
||||
<header>
|
||||
<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>
|
||||
<ul>
|
||||
<li><a href="#">Home</a></li>
|
||||
<li><a href="#">About</a></li>
|
||||
<li><a href="#">Services</a></li>
|
||||
<li><a href="#">Contact us</a></li>
|
||||
<li><a href="#">Register</a></li>
|
||||
<li><a href="#">Log In</a></li>
|
||||
</ul>
|
||||
<a href="/home" class="logo">locaft</a>
|
||||
<ul>
|
||||
<li><a href="#">Home</a></li>
|
||||
<li><a href="#">About</a></li>
|
||||
<li><a href="#">Services</a></li>
|
||||
<li><a href="#">Contact us</a></li>
|
||||
<li><a href="#">Log In</a></li>
|
||||
{userData.user ? (
|
||||
<li><a href="#">Log Out</a></li>
|
||||
) : (
|
||||
<li><a href="#">Register</a></li>
|
||||
)}
|
||||
</ul>
|
||||
|
||||
</header>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
Loading…
Reference in New Issue