import React from "react"; import { BrowserRouter, Switch, Route } from "react-router-dom"; import MemberList from "./MemberList"; import ProductList from "./ProductList"; import Dashboard from "./Dashboard"; import Purchase from "./purchase/Purchase"; import Topup from "./Topup"; import ShowTransaction from "./ShowTransaction"; import ShowOrder from "./order/ShowOrder"; import CreateOrder from "./order/CreateOrder"; import AuthContext from "./AuthContext"; import SignIn from "./SignIn"; import Head from "./Head"; function Panel(props) { return ( <div> <BrowserRouter> <Head onLogout={props.onLogout} /> <Switch> <Route path="/members"> <MemberList /> </Route> <Route path="/products"> <ProductList /> </Route> <Route path="/transaction/:id"> <ShowTransaction /> </Route> <Route path="/purchase"> <Purchase /> </Route> <Route path="/topup"> <Topup /> </Route> <Route path="/order/create"> <CreateOrder /> </Route> <Route path="/order/:id" component={ShowOrder} /> <Route path="/"> <Dashboard /> </Route> </Switch> </BrowserRouter> </div> ); } function getClaims(token) { const base64Url = token.split(".")[1]; const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/"); const jsonPayload = decodeURIComponent( atob(base64) .split("") .map(function (c) { return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2); }) .join("") ); return JSON.parse(jsonPayload); } class App extends React.Component { constructor(props) { super(props); this.state = { num: null, role: null, token: null, }; this.logout = this.logout.bind(this); this.login = this.login.bind(this); } componentDidMount() { const token = localStorage.getItem("token"); if (token) { const num = localStorage.getItem("num"); const role = localStorage.getItem("role"); this.setState({ num, role, token }); if (getClaims(token)["exp"] !== undefined) { this.timerID = setInterval( () => this.renewToken(), 60000 // every minute ); } } } componentWillUnmount() { if (this.timeID) { clearInterval(this.timerID); } } storeState(token, num, role) { localStorage.setItem("token", token); localStorage.setItem("num", num); localStorage.setItem("role", role); } login(token, member) { this.setState({ num: member.num, role: member.role, token: token, }); this.storeState(token, member.num, member.role); if (getClaims(token)["exp"] !== undefined) { this.timerID = setInterval( () => this.renewToken(), 60000 // every minute ); } } logout() { if (this.timeID) { clearInterval(this.timerID); } this.setState({ num: null, role: null, token: null, }); this.storeState("", "", ""); } isLoged() { if (!this.state.token) { return false; } const claims = getClaims(this.state.token); if (claims["exp"] === undefined) { return true; } return claims["exp"] > Date.now() / 1000; } renewToken() { fetch("/api/token", { headers: { "x-authentication": this.state.token } }) .then((response) => { if (!response.ok) { throw new Error( response.status.toString() + " " + response.statusText ); } return response.json(); }) .then((data) => { const token = data.token; this.setState({ token }); localStorage.setItem("token", token); }) .catch((error) => { console.log("Error renewing token: " + error.message); }); } render() { let component; if (!this.isLoged()) { component = <SignIn onLogin={this.login} />; } else { component = <Panel onLogout={this.logout} />; } return ( <AuthContext.Provider value={this.state}> {component} </AuthContext.Provider> ); } } export default App;