Browse Source

Improved AuthRoute system.

KrisVos130 7 years ago
parent
commit
2e3d07e831
2 changed files with 75 additions and 17 deletions
  1. 10 8
      frontend/app/js/app.jsx
  2. 65 9
      frontend/app/js/components/AuthRoute.jsx

+ 10 - 8
frontend/app/js/app.jsx

@@ -76,7 +76,7 @@ class App extends Component { // eslint-disable-line react/no-multi-comp
 						component={ asyncComponent(() =>
 							System.import("views/Auth/Login").then(module => module.default)
 						) }
-						authRequired={ false }
+						auth="disallowed"
 					/>
 					<AuthRoute
 						exact
@@ -84,7 +84,7 @@ class App extends Component { // eslint-disable-line react/no-multi-comp
 						component={ asyncComponent(() =>
 							System.import("views/Auth/Logout").then(module => module.default)
 						) }
-						authRequired={ true }
+						auth="required"
 					/>
 					<AuthRoute
 						exact
@@ -92,7 +92,7 @@ class App extends Component { // eslint-disable-line react/no-multi-comp
 						component={ asyncComponent(() =>
 							System.import("views/Auth/Register").then(module => module.default)
 						) }
-						authRequired={ false }
+						auth="disallowed"
 					/>
 					<AuthRoute
 						exact
@@ -100,7 +100,7 @@ class App extends Component { // eslint-disable-line react/no-multi-comp
 						component={ asyncComponent(() =>
 							System.import("views/Auth/Settings").then(module => module.default)
 						) }
-						authRequired={ true }
+						auth="required"
 					/>
 					<AuthRoute
 						exact
@@ -108,7 +108,7 @@ class App extends Component { // eslint-disable-line react/no-multi-comp
 						component={ asyncComponent(() =>
 							System.import("views/Auth/Settings/SetPassword").then(module => module.default)
 						) }
-						authRequired={ true }
+						auth="required"
 					/>
 					<AuthRoute
 						exact
@@ -116,20 +116,22 @@ class App extends Component { // eslint-disable-line react/no-multi-comp
 						component={ asyncComponent(() =>
 							System.import("views/Auth/ForgotPassword").then(module => module.default)
 						) }
-						authRequired={ false }
+						auth="disallowed"
 					/>
-					<Route
+					<AuthRoute
 						exact
 						path="/"
 						component={ asyncComponent(() =>
 							System.import("views/Home").then(module => module.default)
 						) }
+						auth="ignored"
 					/>
-					<Route
+					<AuthRoute
 						path="*"
 						component={ asyncComponent(() =>
 							System.import("views/Errors/Error404").then(module => module.default)
 						) }
+						auth="ignored"
 					/>
 				</Switch>
 			</div>

+ 65 - 9
frontend/app/js/components/AuthRoute.jsx

@@ -3,37 +3,93 @@ import { connect } from "react-redux";
 import PropTypes from "prop-types";
 import { Redirect, Route } from "react-router-dom";
 
+import io from "io";
+
 @connect(state => ({
 	loggedIn: state.user.get("loggedIn"),
+	role: state.user.get("role"),
 	authProcessed: state.user.get("authProcessed"),
 }))
 
 export default class AuthRoute extends Component {
 	static propTypes = {
 		loggedIn: PropTypes.bool,
-		authRequired: PropTypes.bool,
+		role: PropTypes.string,
+		auth: PropTypes.string,
 		authProcessed: PropTypes.bool,
 		component: PropTypes.oneOfType([
 			PropTypes.element,
 			PropTypes.func,
 		]),
-	}
+		computedMatch: PropTypes.object,
+	};
 
 	static defaultProps = {
 		loggedIn: false,
-		authRequired: true,
+		role: "default",
+		auth: "ignored",
 		authProcessed: false,
 		component: () => {},
+		computedMatch: {},
+	};
+
+	constructor(props) {
+		super(props);
+		const state = {
+			stationName: props.computedMatch.params.name,
+			waitingFor: "",
+			continue: false,
+			stationData: null,
+			receivedStationData: false,
+		};
+		const { auth } = props;
+
+		if (auth === "ignored") state.continue = true;
+		else if (auth === "station") {
+			state.waitingFor = "station";
+			this.getStationData();
+		} else state.waitingFor = "auth";
+
+		this.state = state;
 	}
 
+	getStationData = () => {
+		io.getSocket(socket => {
+			socket.emit("stations.findByName", this.state.stationName, res => {
+				this.setState({
+					receivedStationData: true,
+					stationData: res.data,
+				});
+			});
+		});
+	};
+
 	render() {
-		const { authRequired, loggedIn, authProcessed } = this.props;
-		if (!authRequired) return <Route props={ this.props } component={ this.props.component } />;
-		else if (authProcessed) {
-			if (loggedIn) {
-				return <Route props={ this.props } component={ this.props.component } />;
+		const { auth, role, loggedIn, authProcessed } = this.props;
+		const { stationName, waitingFor, receivedStationData, stationData } = this.state;
+
+		if (this.state.continue) {
+			return <Route props={ this.props } component={ this.props.component } />;
+		} else if (waitingFor === "station" && receivedStationData) {
+			if (stationData) {
+				const props = JSON.parse(JSON.stringify(this.props));
+				// TODO Replace the above hack with a proper Object.clone
+				props.stationName = stationName;
+				props.stationData = stationData;
+				return <Route props={ props } component={ this.props.component } />;
+			}
+			return <Redirect to={ "/" } />;
+		} else if (waitingFor === "auth" && authProcessed) {
+			if (auth === "required") {
+				if (loggedIn) return <Route props={ this.props } component={ this.props.component } />;
+				return <Redirect to={ "/" } />;
+			} else if (auth === "disallowed") {
+				if (!loggedIn) return <Route props={ this.props } component={ this.props.component } />;
+				return <Redirect to={ "/login" } />;
+			} else if (auth === "admin") {
+				if (role === "admin") return <Route props={ this.props } component={ this.props.component } />;
+				return <Redirect to={ "/" } />;
 			}
-			return <Redirect to={ "/login" } />;
 		}
 		return <h1>Loading...</h1>;
 	}