diff --git a/packages/vulcan-core/lib/modules/containers/withAccess.js b/packages/vulcan-core/lib/modules/containers/withAccess.js index a778e5f82..b48ba6b01 100644 --- a/packages/vulcan-core/lib/modules/containers/withAccess.js +++ b/packages/vulcan-core/lib/modules/containers/withAccess.js @@ -1,31 +1,63 @@ -import React, { PureComponent } from 'react'; -import { withCurrentUser } from 'meteor/vulcan:core'; -import { withRouter } from 'react-router'; +import React, {PureComponent} from 'react'; +import {Components} from 'meteor/vulcan:lib'; +import withCurrentUser from './withCurrentUser'; +import {withRouter} from 'react-router'; import Users from 'meteor/vulcan:users'; -export default function withAccess (options) { +/** + * withAccess - description + * + * @param {Object} options the options that define the hoc + * @param {string[]} options.groups the groups that have access to this component + * @param {string} options.redirect the link to redirect to in case the access is not granted (optional) + * @param {string} options.failureComponentName the name of a component to display if access is not granted (optional) + * @param {Component} options.failureComponent the component to display if access is not granted (optional) + * @return {PureComponent} a React component that will display only if the acces is granted + */ - const { groups, redirect } = options; +export default function withAccess(options) { + const { + groups = [], + redirect = null, + failureComponent = null, + failureComponentName = null, + } = options; // we return a function that takes a component and itself returns a component return WrappedComponent => { class AccessComponent extends PureComponent { - // if there are any groups defined check if user belongs, else just check if user exists canAccess = currentUser => { return groups ? Users.isMemberOf(currentUser, groups) : currentUser; - } + }; // redirect on constructor if user cannot access constructor(props) { super(props); - if(!this.canAccess(props.currentUser) && typeof redirect === 'string') { + if ( + !this.canAccess(props.currentUser) && + typeof redirect === 'string' + ) { props.router.push(redirect); } } + renderFailureComponent() { + if (failureComponentName) { + const FailureComponent = Components[failureComponentName]; + return ; + } else if (failureComponent) { + const FailureComponent = failureComponent; // necesary because jsx components must be uppercase + return ; + } else return null; + } + render() { - return this.canAccess(this.props.currentUser) ? : null; + return this.canAccess(this.props.currentUser) ? ( + + ) : ( + this.renderFailureComponent() + ); } }