AuthRoute.jsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import React, { Component } from "react";
  2. import { connect } from "react-redux";
  3. import PropTypes from "prop-types";
  4. import { Redirect, Route } from "react-router-dom";
  5. import io from "io";
  6. @connect(state => ({
  7. loggedIn: state.user.get("loggedIn"),
  8. role: state.user.get("role"),
  9. authProcessed: state.user.get("authProcessed"),
  10. }))
  11. export default class AuthRoute extends Component {
  12. static propTypes = {
  13. loggedIn: PropTypes.bool,
  14. title: PropTypes.string,
  15. role: PropTypes.string,
  16. auth: PropTypes.string,
  17. authProcessed: PropTypes.bool,
  18. component: PropTypes.oneOfType([
  19. PropTypes.element,
  20. PropTypes.func,
  21. ]),
  22. computedMatch: PropTypes.object,
  23. };
  24. static defaultProps = {
  25. loggedIn: false,
  26. title: "Musare",
  27. role: "default",
  28. auth: "ignored",
  29. authProcessed: false,
  30. component: () => {},
  31. computedMatch: {},
  32. };
  33. constructor(props) {
  34. super(props);
  35. const state = {
  36. stationName: props.computedMatch.params.name,
  37. waitingFor: "",
  38. continue: false,
  39. stationData: null,
  40. receivedStationData: false,
  41. };
  42. const { auth } = props;
  43. if (auth === "ignored") state.continue = true;
  44. else if (auth === "station") {
  45. state.waitingFor = "station";
  46. this.getStationData();
  47. } else state.waitingFor = "auth";
  48. this.state = state;
  49. }
  50. componentWillUpdate(nextProps) {
  51. document.title = `${ nextProps.title } - Musare`;
  52. }
  53. getStationData = () => {
  54. io.getSocket(socket => {
  55. socket.emit("stations.findByName", this.state.stationName, res => {
  56. this.setState({
  57. receivedStationData: true,
  58. stationData: res.data,
  59. });
  60. });
  61. });
  62. };
  63. render() {
  64. const { auth, role, loggedIn, authProcessed } = this.props;
  65. const { stationName, waitingFor, receivedStationData, stationData } = this.state;
  66. if (this.state.continue) {
  67. return <Route props={ this.props } component={ this.props.component } />;
  68. } else if (waitingFor === "station" && receivedStationData) {
  69. if (stationData) {
  70. const props = JSON.parse(JSON.stringify(this.props));
  71. // TODO Replace the above hack with a proper Object.clone
  72. props.stationName = stationName;
  73. props.stationData = stationData;
  74. return <Route props={ props } component={ this.props.component } />;
  75. }
  76. return <Redirect to={ "/" } />;
  77. } else if (waitingFor === "auth" && authProcessed) {
  78. if (auth === "required") {
  79. if (loggedIn) return <Route props={ this.props } component={ this.props.component } />;
  80. return <Redirect to={ "/" } />;
  81. } else if (auth === "disallowed") {
  82. if (!loggedIn) return <Route props={ this.props } component={ this.props.component } />;
  83. return <Redirect to={ "/login" } />;
  84. } else if (auth === "admin") {
  85. if (role === "admin") return <Route props={ this.props } component={ this.props.component } />;
  86. return <Redirect to={ "/" } />;
  87. }
  88. }
  89. return <h1>Loading...</h1>;
  90. }
  91. }