Skip to content

Instantly share code, notes, and snippets.

@chrisabrams
Created May 1, 2018 14:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisabrams/a975867321238b37c90b5965902e2dd2 to your computer and use it in GitHub Desktop.
Save chrisabrams/a975867321238b37c90b5965902e2dd2 to your computer and use it in GitHub Desktop.
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
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment