1 : import React from 'react' 2 : import hoistStatics from 'hoist-non-react-statics' 3 : import { validateStringOrFunction } from './helpers' 4 : 5 : const defaults = { 6 : authenticatedSelector: p => Boolean(p.isAuthenticated), 7 : authenticatingSelector: p => Boolean(p.isAuthenticating), 8 : AuthenticatingComponent: () => null, // dont render anything while authenticating 9 : FailureComponent: () => null, // dont render anything on failure of the predicate10 : wrapperDisplayName: 'AuthWrapper' 11 : } 12 : 13 : /** 14 : * A simple wrapper to any component that will only display the component if the user is in an authenticated state. 15 : * It will look for props injected into the component to determine whether to display either: 16 : * - A Failure Component (when the `authenticatedSelector` returns `false`) 17 : * - An Authenticating/Pending Component (when `authenticatingSelector` returns `true` and `authenticatedSelector` also returns `false`) 18 : * - Your actual Component (when the `authenticatedSelector` returns `true`) 19 : * If the optional components are not provided `null` will be rendered/returned when in those states. 20 : * 21 : * @func 22 : * @sig {k: v} -> (Component -> ({k: v} -> Component)) 23 : * @param {Function|String} args.authenticatedSelector A prop name OR a selector function 24 : * that will find the prop injected into the component that identifies whether the user is authenticated or not 25 : * (defaults to look for a prop named `isAuthenticated`) 26 : * @param {Function|String} args.authenticatingSelector A prop name OR a selector function 27 : * that will find the prop injected into the component that identifies whether the user authentication 28 : * is in-progress or not (defaults to look for a prop named `isAuthenticating`) 29 : * @param {Function} args.AuthenticatingComponent An optional component that would be 30 : * displaying while authentication is in-progress (defaults to an empty Component that returns `null`) 31 : * @param {Function} args.FailureComponent An optional component that would be diplayed 32 : * when authentication fails (defaults to a Component Component that returns `null`) 33 : * @param {String} args.wrapperDisplayName An optional display name to give to 34 : * the wrapper component (defaults to just 'AuthWrapper') 35 : * @returns {Function} A function that is ready to receive a Component to decorate36 : */ 37 : function withAuth(args = {}) { 38 : const { 39 : FailureComponent, 40 : wrapperDisplayName, 41 : authenticatedSelector, 42 : authenticatingSelector, 43 : AuthenticatingComponent 44 : } = { ...defaults, ...args } 45 : 46 : const getAuthenticated = validateStringOrFunction(authenticatedSelector, 'authenticatedSelector') 47 : const getAuthenticating = validateStringOrFunction(authenticatingSelector, 'authenticatingSelector') 48 : 49 : // Wraps the component that needs the auth enforcement 50 : function wrapComponent(DecoratedComponent) { 51 : const displayName = DecoratedComponent.displayName || DecoratedComponent.name || 'Component' 52 : 53 : const AuthWrapper = props => { 54 : const isAuthenticated = getAuthenticated(props) 55 : const isAuthenticating = getAuthenticating(props) 56 : 57 : if (isAuthenticated) { 58 : return <DecoratedComponent {...props} /> 59 : } else if (isAuthenticating) { 60 : return <AuthenticatingComponent {...props} /> 61 : } else {62 : return <FailureComponent {...props} /> 63 : } 64 : } 65 : 66 : AuthWrapper.displayName = `${wrapperDisplayName}(${displayName})` 67 : 68 : return hoistStatics(AuthWrapper, DecoratedComponent) 69 : } 70 : 71 : return wrapComponent 72 : } 73 : 74 : export default withAuth

"withAuth.js" in react

Similar Code Examples