mirror of
https://github.com/idanoo/GoScrobble
synced 2025-07-01 05:32:18 +00:00
0.0.3
- Clean up login/redirect flow - Add redirect when not authed on other endpoints - Add GET /stats endpoint for overal stats
This commit is contained in:
parent
5fd9d41069
commit
038823055a
23 changed files with 413 additions and 178 deletions
2
web/.env.example
Normal file
2
web/.env.example
Normal file
|
@ -0,0 +1,2 @@
|
|||
REACT_APP_API_URL=http://127.0.0.1:42069/api/v1/
|
||||
REACT_APP_REGISTRATION_DISABLED=false
|
29
web/src/Actions/api.js
Normal file
29
web/src/Actions/api.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { toast } from 'react-toastify';
|
||||
import ApiService from "../Services/api.service";
|
||||
|
||||
export const getStats = () => () => {
|
||||
return ApiService.getStats().then(
|
||||
(data) => {
|
||||
console.log(data);
|
||||
if (data.error) {
|
||||
toast.error(data.error)
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
},
|
||||
(error) => {
|
||||
const message =
|
||||
(error.response &&
|
||||
error.response.data &&
|
||||
error.response.data.message) ||
|
||||
error.message ||
|
||||
error.toString();
|
||||
console.log(message);
|
||||
|
||||
toast.error(message);
|
||||
return Promise.reject();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
@ -3,20 +3,30 @@ import {
|
|||
REGISTER_FAIL,
|
||||
LOGIN_SUCCESS,
|
||||
LOGIN_FAIL,
|
||||
SET_MESSAGE,
|
||||
} from "./types";
|
||||
import { toast } from 'react-toastify'
|
||||
|
||||
import { toast } from 'react-toastify';
|
||||
import jwt from 'jwt-decode'
|
||||
import AuthService from "../Services/auth.service";
|
||||
|
||||
export const register = (username, email, password) => (dispatch) => {
|
||||
return AuthService.register(username, email, password).then(
|
||||
(response) => {
|
||||
(data) => {
|
||||
if (data.message) {
|
||||
toast.success('Successfully registered. Please sign in');
|
||||
dispatch({
|
||||
type: REGISTER_SUCCESS,
|
||||
});
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
toast.error(data.error ? data.error: 'An Unknown Error has occurred')
|
||||
dispatch({
|
||||
type: REGISTER_SUCCESS,
|
||||
type: REGISTER_FAIL,
|
||||
});
|
||||
|
||||
return Promise.resolve();
|
||||
return Promise.reject();
|
||||
},
|
||||
(error) => {
|
||||
const message =
|
||||
|
@ -26,13 +36,10 @@ import {
|
|||
error.message ||
|
||||
error.toString();
|
||||
|
||||
dispatch({
|
||||
type: REGISTER_FAIL,
|
||||
});
|
||||
toast.error(message);
|
||||
|
||||
dispatch({
|
||||
type: SET_MESSAGE,
|
||||
payload: message,
|
||||
type: REGISTER_FAIL,
|
||||
});
|
||||
|
||||
return Promise.reject();
|
||||
|
@ -45,9 +52,11 @@ import {
|
|||
(data) => {
|
||||
if (data.token) {
|
||||
toast.success('Login Success');
|
||||
let user = jwt(data.token)
|
||||
|
||||
dispatch({
|
||||
type: LOGIN_SUCCESS,
|
||||
payload: { user: data },
|
||||
payload: { jwt: data.token, sub: user.sub, exp: user.exp },
|
||||
});
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
@ -71,17 +80,17 @@ import {
|
|||
type: LOGIN_FAIL,
|
||||
});
|
||||
|
||||
// dispatch({
|
||||
// type: SET_MESSAGE,
|
||||
// payload: message,
|
||||
// });
|
||||
|
||||
return Promise.reject();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export const logout = () => () => {
|
||||
export const logout = () => (dispatch) => {
|
||||
AuthService.logout();
|
||||
|
||||
// dispatch({
|
||||
// type: LOGOUT,
|
||||
// });
|
||||
|
||||
window.location.reload();
|
||||
};
|
||||
|
|
13
web/src/Actions/eventBus.js
Normal file
13
web/src/Actions/eventBus.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
const eventBus = {
|
||||
on(event, callback) {
|
||||
document.addEventListener(event, (e) => callback(e.detail));
|
||||
},
|
||||
dispatch(event, data) {
|
||||
document.dispatchEvent(new CustomEvent(event, { detail: data }));
|
||||
},
|
||||
remove(event, callback) {
|
||||
document.removeEventListener(event, callback);
|
||||
},
|
||||
};
|
||||
|
||||
export default eventBus
|
|
@ -11,8 +11,6 @@ import Register from './Pages/Register';
|
|||
import Navigation from './Components/Navigation';
|
||||
|
||||
import { logout } from './Actions/auth';
|
||||
import { clearMessage } from './Actions/message';
|
||||
import { history } from './Helpers/history';
|
||||
import { Route, Switch, withRouter } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import { Component } from 'react';
|
||||
|
@ -37,10 +35,6 @@ class App extends Component {
|
|||
// exact="true".. it has to be a bool :|
|
||||
true: true,
|
||||
};
|
||||
|
||||
history.listen((location) => {
|
||||
props.dispatch(clearMessage()); // clear message when changing location
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
|
0
web/src/Components/HomeBanner.css
Normal file
0
web/src/Components/HomeBanner.css
Normal file
44
web/src/Components/HomeBanner.js
Normal file
44
web/src/Components/HomeBanner.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
import React from 'react';
|
||||
import '../App.css';
|
||||
import './HomeBanner.css';
|
||||
import { getStats } from '../Actions/api';
|
||||
|
||||
class HomeBanner extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isLoading: true,
|
||||
userCount: 0,
|
||||
scrobbleCount: 0,
|
||||
trackCount: 0,
|
||||
artistCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
getStats()
|
||||
// .then((data) => {
|
||||
// this.setState({
|
||||
// loading: false,
|
||||
// userCount: data.users,
|
||||
// scrobbleCount: data.scrobbles,
|
||||
// trackCount: data.tracks,
|
||||
// artistCount: data.artists,
|
||||
// });
|
||||
// })
|
||||
// .catch(() => {
|
||||
// this.setState({
|
||||
// loading: false
|
||||
// });
|
||||
// });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="container">
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default HomeBanner;
|
|
@ -5,6 +5,12 @@ import logo from '../logo.png';
|
|||
import './Navigation.css';
|
||||
import { connect } from 'react-redux';
|
||||
import { logout } from '../Actions/auth';
|
||||
import eventBus from "../Actions/eventBus";
|
||||
|
||||
import {
|
||||
LOGIN_SUCCESS,
|
||||
LOGOUT,
|
||||
} from "../Actions/types";
|
||||
|
||||
const menuItems = [
|
||||
'Home',
|
||||
|
@ -24,32 +30,62 @@ class Navigation extends Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
const isLoggedIn = this.props.isLoggedIn;
|
||||
|
||||
const { isLoggedIn } = this.props;
|
||||
if (isLoggedIn) {
|
||||
this.setState({
|
||||
isLoggedIn: true,
|
||||
});
|
||||
}
|
||||
|
||||
eventBus.on(LOGIN_SUCCESS, () =>
|
||||
this.setState({ isLoggedIn: true })
|
||||
);
|
||||
|
||||
eventBus.on(LOGOUT, () =>
|
||||
this.setState({ isLoggedIn: false })
|
||||
);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
eventBus.remove(LOGIN_SUCCESS);
|
||||
eventBus.remove(LOGOUT);
|
||||
}
|
||||
|
||||
|
||||
_handleClick(menuItem) {
|
||||
this.setState({ active: menuItem });
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const activeStyle = { color: '#FFFFFF' };
|
||||
|
||||
const renderAuthButtons = () => {
|
||||
if (this.state.isLoggedIn) {
|
||||
return <div className="navLinkLogin">
|
||||
<Link to="/profile" className="navLink">Profile</Link>
|
||||
<Link
|
||||
to="/profile"
|
||||
style={this.state.active === "profile" ? activeStyle : {}}
|
||||
onClick={this._handleClick.bind(this, "profile")}
|
||||
className="navLink"
|
||||
>Profile</Link>
|
||||
<Link to="/" className="navLink" onClick={logout()}>Logout</Link>
|
||||
</div>;
|
||||
} else {
|
||||
return <div className="navLinkLogin">
|
||||
<Link to="/login" className="navLink">Login</Link>
|
||||
<Link to="/register" className="navLink" history={this.props.history}>Register</Link>
|
||||
<Link
|
||||
to="/login"
|
||||
style={this.state.active === "login" ? activeStyle : {}}
|
||||
onClick={this._handleClick.bind(this, "login")}
|
||||
className="navLink"
|
||||
>Login</Link>
|
||||
<Link
|
||||
to="/register"
|
||||
className="navLink"
|
||||
style={this.state.active === "register" ? activeStyle : {}}
|
||||
onClick={this._handleClick.bind(this, "register")}
|
||||
history={this.props.history}
|
||||
>Register</Link>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +125,7 @@ class Navigation extends Component {
|
|||
return (
|
||||
<div>
|
||||
<Navbar color="dark" dark fixed="top">
|
||||
<NavbarBrand href="/" className="mr-auto"><img src={logo} className="nav-logo" alt="logo" /> GoScrobble</NavbarBrand>
|
||||
<NavbarBrand className="mr-auto"><img src={logo} className="nav-logo" alt="logo" /> GoScrobble</NavbarBrand>
|
||||
{renderMenuButtons()}
|
||||
{renderAuthButtons()}
|
||||
</Navbar>
|
||||
|
|
|
@ -10,7 +10,6 @@ class Dashboard extends React.Component {
|
|||
|
||||
if (!isLoggedIn) {
|
||||
history.push("/login")
|
||||
window.location.reload()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +17,7 @@ class Dashboard extends React.Component {
|
|||
return (
|
||||
<div className="pageWrapper">
|
||||
<h1>
|
||||
Hai Dashboard!
|
||||
Dashboard!
|
||||
</h1>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import logo from '../logo.png';
|
||||
import '../App.css';
|
||||
import HomeBanner from '../Components/HomeBanner';
|
||||
import React from 'react';
|
||||
|
||||
function Home() {
|
||||
return (
|
||||
class Home extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="App-header">
|
||||
<img src={logo} className="App-logo" alt="logo" />
|
||||
<p>
|
||||
|
@ -16,8 +19,10 @@ function Home() {
|
|||
>
|
||||
gitlab.com/idanoo/go-scrobble
|
||||
</a>
|
||||
<HomeBanner />
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Home;
|
||||
|
|
|
@ -6,6 +6,8 @@ import { Formik, Form, Field } from 'formik';
|
|||
import ScaleLoader from 'react-spinners/ScaleLoader';
|
||||
import { connect } from 'react-redux';
|
||||
import { login } from '../Actions/auth';
|
||||
import eventBus from "../Actions/eventBus";
|
||||
import { LOGIN_SUCCESS } from '../Actions/types';
|
||||
|
||||
class Login extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -13,6 +15,14 @@ class Login extends React.Component {
|
|||
this.state = {username: '', password: '', loading: false};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { history, isLoggedIn } = this.props;
|
||||
|
||||
if (isLoggedIn) {
|
||||
history.push("/dashboard")
|
||||
}
|
||||
}
|
||||
|
||||
handleLogin(values) {
|
||||
this.setState({loading: true});
|
||||
|
||||
|
@ -22,9 +32,11 @@ class Login extends React.Component {
|
|||
.then(() => {
|
||||
this.setState({
|
||||
loading: false,
|
||||
isLoggedIn: true
|
||||
});
|
||||
|
||||
eventBus.dispatch(LOGIN_SUCCESS, { isLoggedIn: true });
|
||||
history.push("/dashboard");
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
this.setState({
|
||||
|
@ -82,10 +94,8 @@ class Login extends React.Component {
|
|||
|
||||
function mapStateToProps(state) {
|
||||
const { isLoggedIn } = state.auth;
|
||||
const { message } = state.message;
|
||||
return {
|
||||
isLoggedIn,
|
||||
message
|
||||
isLoggedIn
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,10 @@ import { connect } from 'react-redux';
|
|||
|
||||
class Profile extends React.Component {
|
||||
componentDidMount() {
|
||||
const { history } = this.props;
|
||||
const isLoggedIn = this.props.isLoggedIn;
|
||||
|
||||
const { history, isLoggedIn } = this.props;
|
||||
|
||||
if (!isLoggedIn) {
|
||||
history.push("/login")
|
||||
window.location.reload()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,86 +1,42 @@
|
|||
import React from 'react';
|
||||
import '../App.css';
|
||||
import './Login.css';
|
||||
import { Button } from 'reactstrap';
|
||||
import { Button, Form } from 'reactstrap';
|
||||
import ScaleLoader from "react-spinners/ScaleLoader";
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import { register } from '../Actions/auth';
|
||||
import { Formik, Field } from 'formik';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
class Register extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {username: '', email: '', password: '', passwordconfirm: '', loading: false};
|
||||
this.handleUsernameChange = this.handleUsernameChange.bind(this);
|
||||
this.handleEmailChange = this.handleEmailChange.bind(this);
|
||||
this.handlePasswordChange = this.handlePasswordChange.bind(this);
|
||||
this.handlePasswordConfirmChange = this.handlePasswordConfirmChange.bind(this);
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
}
|
||||
|
||||
handleUsernameChange(event) {
|
||||
this.setState({username: event.target.value});
|
||||
}
|
||||
componentDidMount() {
|
||||
const { history, isLoggedIn } = this.props;
|
||||
|
||||
handleEmailChange(event) {
|
||||
this.setState({email: event.target.value});
|
||||
}
|
||||
|
||||
handlePasswordChange(event) {
|
||||
this.setState({password: event.target.value});
|
||||
}
|
||||
|
||||
handlePasswordConfirmChange(event) {
|
||||
this.setState({passwordconfirm: event.target.value});
|
||||
}
|
||||
|
||||
handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
||||
if (this.state.password !== this.state.passwordconfirm) {
|
||||
this.props.addToast('Passwords do not match', { appearance: 'error' });
|
||||
return
|
||||
if (isLoggedIn) {
|
||||
history.push("/dashboard")
|
||||
}
|
||||
}
|
||||
|
||||
// if (this.state.password.len < 8) {
|
||||
// this.props.addToast('Password must be at least 8 characters', { appearance: 'error' });
|
||||
// return
|
||||
// }
|
||||
|
||||
handleRegister(values) {
|
||||
this.setState({loading: true});
|
||||
const requestOptions = {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
timeout: 5000,
|
||||
body: JSON.stringify({
|
||||
username: this.state.username,
|
||||
email: this.state.email,
|
||||
password: this.state.password,
|
||||
})
|
||||
};
|
||||
|
||||
const apiUrl = process.env.REACT_APP_API_URL + '/api/v1/register';
|
||||
console.log(apiUrl);
|
||||
fetch(apiUrl, requestOptions)
|
||||
.then((response) => {
|
||||
if (response.status === 429) {
|
||||
this.props.addToast("Rate limited. Please try again soon", { appearance: 'error' });
|
||||
return "{}"
|
||||
} else {
|
||||
return response.json()
|
||||
}
|
||||
const { dispatch, history } = this.props;
|
||||
|
||||
dispatch(register(values.username, values.email, values.password))
|
||||
.then(() => {
|
||||
this.setState({
|
||||
loading: false,
|
||||
});
|
||||
history.push("/login");
|
||||
})
|
||||
.then((function(data) {
|
||||
console.log(data);
|
||||
if (data.error) {
|
||||
this.props.addToast(data.error, { appearance: 'error' });
|
||||
} else if (data.message) {
|
||||
this.props.addToast(data.message, { appearance: 'success' });
|
||||
this.props.history.push('/login')
|
||||
}
|
||||
this.setState({loading: false});
|
||||
}).bind(this))
|
||||
.catch(() => {
|
||||
this.props.addToast('Error submitting form. Please try again', { appearance: 'error' });
|
||||
this.setState({loading: false});
|
||||
this.setState({
|
||||
loading: false
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -98,57 +54,57 @@ class Register extends React.Component {
|
|||
Register
|
||||
</h1>
|
||||
<div className="loginBody">
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<label>
|
||||
Username*<br/>
|
||||
<input
|
||||
type="text"
|
||||
required={trueBool}
|
||||
className="loginFields"
|
||||
value={this.state.username}
|
||||
onChange={this.handleUsernameChange}
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Email<br/>
|
||||
<input
|
||||
type="email"
|
||||
className="loginFields"
|
||||
value={this.state.email}
|
||||
onChange={this.handleEmailChange}
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Password*<br/>
|
||||
<input
|
||||
type="password"
|
||||
required={trueBool}
|
||||
className="loginFields"
|
||||
value={this.state.password}
|
||||
onChange={this.handlePasswordChange}
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Password*<br/>
|
||||
<input
|
||||
type="password"
|
||||
required={trueBool}
|
||||
className="loginFields"
|
||||
value={this.state.passwordconfirm}
|
||||
onChange={this.handlePasswordConfirmChange}
|
||||
/>
|
||||
</label>
|
||||
<br/><br/>
|
||||
<Button
|
||||
color="primary"
|
||||
type="submit"
|
||||
className="loginButton"
|
||||
disabled={this.state.loading}
|
||||
>{this.state.loading ? <ScaleLoader color="#FFF" size={35} /> : "Register"}</Button>
|
||||
</form>
|
||||
<Formik
|
||||
initialValues={{ username: '', email: '', password: '', passwordconfirm: '' }}
|
||||
onSubmit={async values => this.handleRegister(values)}>
|
||||
<Form>
|
||||
<label>
|
||||
Username*<br/>
|
||||
<Field
|
||||
name="username"
|
||||
type="text"
|
||||
required={trueBool}
|
||||
className="loginFields"
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Email<br/>
|
||||
<Field
|
||||
name="email"
|
||||
type="email"
|
||||
className="loginFields"
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Password*<br/>
|
||||
<Field
|
||||
name="password"
|
||||
type="password"
|
||||
required={trueBool}
|
||||
className="loginFields"
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Confirm Password*<br/>
|
||||
<Field
|
||||
name="passwordconfirm"
|
||||
type="password"
|
||||
required={trueBool}
|
||||
className="loginFields"
|
||||
/>
|
||||
</label>
|
||||
<br/><br/>
|
||||
<Button
|
||||
color="primary"
|
||||
type="submit"
|
||||
className="loginButton"
|
||||
disabled={this.state.loading}
|
||||
>{this.state.loading ? <ScaleLoader color="#FFF" size={35} /> : "Register"}</Button>
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -157,4 +113,11 @@ class Register extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
export default withRouter(Register);
|
||||
function mapStateToProps(state) {
|
||||
const { isLoggedIn } = state.auth;
|
||||
return {
|
||||
isLoggedIn
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(Register);
|
||||
|
|
|
@ -6,11 +6,11 @@ import {
|
|||
LOGOUT,
|
||||
} from "../Actions/types";
|
||||
|
||||
const jwt = localStorage.getItem("jwt");
|
||||
const user = JSON.parse(localStorage.getItem('user'));
|
||||
|
||||
const initialState = jwt
|
||||
? { isLoggedIn: true, jwt }
|
||||
: { isLoggedIn: false, jwt };
|
||||
const initialState = user
|
||||
? { isLoggedIn: true, user: user }
|
||||
: { isLoggedIn: false, user: null };
|
||||
|
||||
export default function authReducer(state = initialState, action) {
|
||||
const { type, payload } = action;
|
||||
|
@ -30,13 +30,16 @@ import {
|
|||
return {
|
||||
...state,
|
||||
isLoggedIn: true,
|
||||
user: payload.user,
|
||||
user: {
|
||||
jwt: payload.jwt,
|
||||
uuid: payload.sub,
|
||||
exp: payload.exp,
|
||||
}
|
||||
};
|
||||
case LOGIN_FAIL:
|
||||
return {
|
||||
...state,
|
||||
isLoggedIn: false,
|
||||
user: null,
|
||||
};
|
||||
case LOGOUT:
|
||||
return {
|
||||
|
|
13
web/src/Services/api.service.js
Normal file
13
web/src/Services/api.service.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import axios from "axios";
|
||||
|
||||
class ApiService {
|
||||
async getStats() {
|
||||
return axios.get(process.env.REACT_APP_API_URL + "stats")
|
||||
.then((response) => {
|
||||
return response.data;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default new ApiService();
|
|
@ -1,8 +1,8 @@
|
|||
export default function authHeader() {
|
||||
const token = JSON.parse(localStorage.getItem('jwt'));
|
||||
const auth = localStorage.getItem('user');
|
||||
|
||||
if (token) {
|
||||
return { Authorization: 'Bearer ' + token };
|
||||
if (auth && auth.jwt) {
|
||||
return { Authorization: 'Bearer ' + auth.jwt };
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -7,10 +7,13 @@ class AuthService {
|
|||
.post(process.env.REACT_APP_API_URL + "login", { username, password })
|
||||
.then((response) => {
|
||||
if (response.data.token) {
|
||||
let user = jwt(response.data.token)
|
||||
localStorage.setItem("jwt", response.data.token);
|
||||
localStorage.setItem("uuid", user.sub);
|
||||
localStorage.setItem("exp", user.exp);
|
||||
let expandedUser = jwt(response.data.token)
|
||||
let user = {
|
||||
jwt: response.data.token,
|
||||
uuid: expandedUser.sub,
|
||||
exp: expandedUser.exp,
|
||||
}
|
||||
localStorage.setItem('user', JSON.stringify(user))
|
||||
}
|
||||
|
||||
return response.data;
|
||||
|
@ -18,9 +21,7 @@ class AuthService {
|
|||
}
|
||||
|
||||
logout() {
|
||||
localStorage.removeItem("jwt");
|
||||
localStorage.removeItem("uuid");
|
||||
localStorage.removeItem("exp");
|
||||
localStorage.removeItem("user");
|
||||
}
|
||||
|
||||
register(username, email, password) {
|
||||
|
|
|
@ -6,7 +6,6 @@ import { HashRouter } from 'react-router-dom';
|
|||
import { ToastContainer } from 'react-toastify';
|
||||
import 'react-toastify/dist/ReactToastify.min.css'
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import store from "./store";
|
||||
|
||||
ReactDOM.render(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue