11import React from 'react' ;
22import { IndexRoute , Route } from 'react-router' ;
3+ import { routerActions } from 'react-router-redux' ;
4+ import { UserAuthWrapper } from 'redux-auth-wrapper' ;
5+ import async from 'async' ;
6+ import isPromise from 'is-promise' ;
37import { isLoaded as isAuthLoaded , load as loadAuth } from 'redux/modules/auth' ;
48import { App , Home , NotFound } from 'containers' ;
59
610// eslint-disable-next-line import/no-dynamic-require
711if ( typeof System . import === 'undefined' ) System . import = module => Promise . resolve ( require ( module ) ) ;
812
913export default store => {
10- const loadAuthIfNeeded = cb => {
14+ const injectReducerAndRender = ( name , reducerPromise , containerPromise ) =>
15+ Promise . all ( [ reducerPromise , containerPromise ] )
16+ . then ( ( [ reducer , container ] ) => {
17+ store . inject ( name , reducer . default || reducer ) ;
18+ return container . default || container ;
19+ } ) ;
20+
21+ const onEnterChain = ( ...listOfOnEnters ) => ( nextState , replace , onEnterCb ) => {
22+ let redirected = false ;
23+ const wrappedReplace = ( ...args ) => {
24+ replace ( ...args ) ;
25+ redirected = true ;
26+ } ;
27+ async . eachSeries ( listOfOnEnters , ( onEnter , callback ) => {
28+ if ( ! redirected ) {
29+ const result = onEnter ( store , nextState , wrappedReplace ) ;
30+ if ( isPromise ( result ) ) return result . then ( ( ) => callback ( ) , callback ) ;
31+ }
32+ callback ( ) ;
33+ } , err => {
34+ if ( err ) onEnterCb ( err ) ;
35+ onEnterCb ( ) ;
36+ } ) ;
37+ } ;
38+
39+ const loadAuthIfNeeded = ( ) => {
1140 if ( ! isAuthLoaded ( store . getState ( ) ) ) {
12- return store . dispatch ( loadAuth ( ) ) . then ( ( ) => cb ( ) ) . catch ( cb ) ;
41+ return store . dispatch ( loadAuth ( ) ) . catch ( ( ) => { } ) ;
1342 }
14- return cb ( ) ;
15- } ;
16- const checkUser = ( cond , replace , cb ) => {
17- const { auth : { user } } = store . getState ( ) ;
18- if ( ! cond ( user ) ) replace ( '/' ) ;
19- cb ( ) ;
43+ return Promise . resolve ( ) ;
2044 } ;
2145
22- const requireNotLogged = ( nextState , replace , cb ) => {
23- const cond = user => ! user ;
24- loadAuthIfNeeded ( ( ) => checkUser ( cond , replace , cb ) ) ;
25- } ;
26- const requireLogin = ( nextState , replace , cb ) => {
27- const cond = user => ! ! user ;
28- loadAuthIfNeeded ( ( ) => checkUser ( cond , replace , cb ) ) ;
46+ const checkPermissions = chainedPermissions => loadAuthIfNeeded ( ) . then ( ( ) => chainedPermissions ) ;
47+
48+ const enterPermissions = ( ...listOfPermissions ) => {
49+ const permissions = [ loadAuthIfNeeded ] . concat ( listOfPermissions . map ( perm => perm . onEnter || perm ) ) ;
50+ return onEnterChain ( ...permissions ) ;
2951 } ;
3052
31- const injectAndRender = ( name , reducerPromise , containerPromise ) =>
32- Promise . all ( [ reducerPromise , containerPromise ] )
33- . then ( ( [ reducer , container ] ) => {
34- store . inject ( name , reducer . default || reducer ) ;
35- return container . default || container ;
36- } ) ;
53+ const permissionsComponent = ( ...listOfPermissions ) => ( {
54+ onEnter : enterPermissions ( ...listOfPermissions ) ,
55+ getComponent : ( ) => checkPermissions ( listOfPermissions . reduceRight (
56+ ( prev , next ) => next ( prev ) ,
57+ props => props . children
58+ ) )
59+ } ) ;
60+
61+ /* Permissions */
62+
63+ const isAuthenticated = UserAuthWrapper ( {
64+ authSelector : state => state . auth . user ,
65+ redirectAction : routerActions . replace ,
66+ wrapperDisplayName : 'UserIsAuthenticated'
67+ } ) ;
68+
69+ const isNotAuthenticated = UserAuthWrapper ( {
70+ authSelector : state => state . auth . user ,
71+ redirectAction : routerActions . replace ,
72+ wrapperDisplayName : 'UserIsNotAuthenticated' ,
73+ predicate : user => ! user ,
74+ failureRedirectPath : '/' ,
75+ allowRedirectBack : false
76+ } ) ;
3777
3878 /**
3979 * Please keep routes in alphabetical order
@@ -44,19 +84,19 @@ export default store => {
4484 < IndexRoute component = { Home } />
4585
4686 { /* Routes requiring login */ }
47- < Route onEnter = { requireLogin } >
87+ < Route { ... permissionsComponent ( isAuthenticated ) } >
4888 < Route path = "loginSuccess" getComponent = { ( ) => System . import ( './containers/LoginSuccess/LoginSuccess' ) } />
4989 < Route
5090 path = "chatFeathers"
51- getComponent = { ( ) => injectAndRender (
52- 'chat' ,
53- System . import ( './redux/modules/chat' ) ,
91+ getComponent = { ( ) => injectReducerAndRender (
92+ 'chat' , System . import ( './redux/modules/chat' ) ,
5493 System . import ( './containers/ChatFeathers/ChatFeathers' )
55- ) } />
94+ ) }
95+ />
5696 </ Route >
5797
5898 { /* Routes disallow login */ }
59- < Route onEnter = { requireNotLogged } >
99+ < Route { ... permissionsComponent ( isNotAuthenticated ) } >
60100 < Route path = "register" getComponent = { ( ) => System . import ( './containers/Register/Register' ) } />
61101 </ Route >
62102
@@ -65,18 +105,18 @@ export default store => {
65105 < Route path = "about" getComponent = { ( ) => System . import ( './containers/About/About' ) } />
66106 < Route
67107 path = "survey"
68- getComponent = { ( ) => injectAndRender (
69- 'survey' ,
70- System . import ( './redux/modules/survey' ) ,
108+ getComponent = { ( ) => injectReducerAndRender (
109+ 'survey' , System . import ( './redux/modules/survey' ) ,
71110 System . import ( './containers/Survey/Survey' )
72- ) } />
111+ ) }
112+ />
73113 < Route
74114 path = "widgets"
75- getComponent = { ( ) => injectAndRender (
76- 'widgets' ,
77- System . import ( './redux/modules/widgets' ) ,
115+ getComponent = { ( ) => injectReducerAndRender (
116+ 'widgets' , System . import ( './redux/modules/widgets' ) ,
78117 System . import ( './containers/Widgets/Widgets' )
79- ) } />
118+ ) }
119+ />
80120 < Route path = "chat" getComponent = { ( ) => System . import ( './containers/Chat/Chat' ) } />
81121
82122 { /* Catch all route */ }
0 commit comments