Created
August 11, 2016 19:34
-
-
Save jackmccloy/3cb07e8c2a57299586a86c2eb7e484b5 to your computer and use it in GitHub Desktop.
This file contains 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 characters
import React from 'react'; | |
import { connect } from 'react-redux'; | |
import { push, replace } from 'redux-router'; | |
export function requireLoggedIn(Component) { | |
// a wrapper that requires a user be logged in. You can decide what 'logged in' means - in this example, | |
// a user is considered to be logged in if usersStore.meta.self !== null | |
class AuthComponent extends React.Component { | |
static displayName = 'AuthComponent'; | |
static propTypes = { | |
dispatch: React.PropTypes.func, | |
location: React.PropTypes.object, | |
usersStore: React.PropTypes.object, | |
}; | |
componentWillMount() { | |
// the check happens before the component mounts | |
if (this.props.usersStore.meta.self === null) { | |
// redirect to login and add next param so we can redirect again after login | |
this.props.dispatch(push(`/login?next=${this.props.location.pathname}`)); | |
} | |
} | |
render() { | |
// if a user isn't logged in, they'll never get this far. if they are, the component that is | |
// passed to this wrapper will be rendered | |
return ( | |
<Component {...this.props} /> | |
); | |
} | |
} | |
function mapStateToProps(state) { | |
return { | |
usersStore: state.usersStore, | |
}; | |
} | |
return connect(mapStateToProps)(AuthComponent); | |
} | |
export function requireLoggedOut(Component) { | |
// requireLoggedOut is similar to requireLoggedIn, but but if a user is | |
// logged in will redirect them to this.props.location.query.next (or to | |
// the site's homepage if this.props.location.query.next is undefined) | |
class AuthComponent extends React.Component { | |
static displayName = 'AuthComponent'; | |
static propTypes = { | |
dispatch: React.PropTypes.func, | |
location: React.PropTypes.object, | |
usersStore: React.PropTypes.object, | |
}; | |
componentWillMount() { | |
if (this.props.usersStore.meta.self !== null) { | |
if (this.props.location.query.next !== undefined) { | |
// redirects to next page | |
this.props.dispatch(replace(this.props.location.query.next)); | |
} else { | |
// redirect to home | |
this.props.dispatch(replace('/')); | |
} | |
} | |
} | |
componentDidUpdate() { | |
this.componentWillMount(); | |
} | |
render() { | |
return ( | |
// render the component that requires the user be logged out (passed to this wrapper) | |
<Component {...this.props} /> | |
); | |
} | |
} | |
function mapStateToProps(state) { | |
return { | |
usersStore: state.usersStore, | |
}; | |
} | |
return connect(mapStateToProps)(AuthComponent); | |
} | |
export function requireSuperUser(Component) { | |
// You've probably got the idea by now, but here's how it might look if you want to | |
// restrict access to superusers | |
class AuthComponent extends React.Component { | |
static displayName = 'AuthComponent'; | |
static propTypes = { | |
dispatch: React.PropTypes.func, | |
location: React.PropTypes.object, | |
usersStore: React.PropTypes.object, | |
}; | |
componentWillMount() { | |
const usersStore = this.props.usersStore; | |
if (usersStore.meta.self === null) { | |
// redirect to login and add next param so we can redirect again after login | |
this.props.dispatch(push(`/login?next=${this.props.location.pathname}`)); | |
} else if (usersStore.list.items[usersStore.meta.self].isSuperuser === false) { | |
// redirect to home | |
this.props.dispatch(push('/')); | |
} | |
} | |
render() { | |
// render the component that requires the user be logged out (passed to this wrapper) | |
return ( | |
<Component {...this.props} /> | |
); | |
} | |
} | |
function mapStateToProps(state) { | |
return { | |
usersStore: state.usersStore, | |
}; | |
} | |
return connect(mapStateToProps)(AuthComponent); | |
} | |
// Then, when you export a component that you want to be permission restricted, wrap the exported component in your permission wrapper. The export method for the profile page on a site I built looks like this: | |
/* | |
module.exports = { | |
getComponent(location, callback) { | |
callback(null, requireLoggedIn( | |
connect(mapStateToProps)(Radium(Profile)) | |
)); | |
}, | |
path: 'profile', | |
}; | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment