Created
May 1, 2018 14:41
-
-
Save chrisabrams/a975867321238b37c90b5965902e2dd2 to your computer and use it in GitHub Desktop.
Revisions
-
chrisabrams created this gist
May 1, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,116 @@ import React, {Component} from 'react' import {Route, Redirect} from 'react-router-dom' import userProvider from 'store/providers/user' export default class ProtectedRoute extends Component { constructor(props) { super(props) this.inProgress = false /* NOTE: Can't render a route with a both component & render property */ this.rProps = Object.assign({}, props) delete this.rProps.component this.state = { authed: false, completed: false, redirectPathname: this.props.redirectPathname || '/auth/login', // Default path to send on redirect props: this.rProps } } auth() { this.inProgress = true const user = userProvider.get() if(!user.__loaded) { return setTimeout(this.auth.bind(this), 100) } let authed = (user && user.id) ? true : false if(this.props.roles instanceof Array) { let roleAuthed = false for(let i = 0, l = this.props.roles.length; i < l; i++) { const role = this.props.roles[i] if(user.roles && user.roles.includes(role)) { roleAuthed = true continue } } if(!roleAuthed) { authed = false } this.setState({ authed, completed: true, redirectPathname: '/dashboard' }) } else { this.setState({ authed, completed: true }) } this.inProgress = false } componentWillMount() { this.auth() } componentWillReceiveProps(nextProps) { /* This is a Component that was mounted from another route; let the component know that the route has changed */ if(this.state.completed && this.props.computedMatch.path != nextProps.computedMatch.path) { this.setState({props: nextProps}) } } redirect = (props, pathname) => { const options = {pathname, state: {from: props.location}} return <Redirect to={options} /> } renderComponent = (props) => { const authed = this.state.authed const Component = this.props.component if(authed === true) { return <Component {...props} /> } return this.redirect(props, this.state.redirectPathname) } render() { // Can use this to create an optional spinner component while waiting for async function to complete const spinner = null return this.state.completed ? <Route {...this.state.props} ref='route' render={this.renderComponent} /> : spinner } }