diff --git a/server/index.js b/server/index.js index 31db3a30..6fc52234 100644 --- a/server/index.js +++ b/server/index.js @@ -150,7 +150,15 @@ app.get('*', (req, res) => { .then(preloadedState => { const html = render(req.url, context, preloadedState); - if (context.url) { + if (context.forbidden) { + // Routes component injects the context.forbidden when the + // user isn't logged in to view the page that requires + // authentication. + // + // TODO: separate 401 and 403 cases when authorization is done + // as well. + res.status(403).send(html); + } else if (context.url) { // React Router injects the context.url if a redirect was rendered res.redirect(context.url); } else if (context.notfound) { diff --git a/src/Routes.js b/src/Routes.js index f4fc7d92..8b5ade8d 100644 --- a/src/Routes.js +++ b/src/Routes.js @@ -1,17 +1,22 @@ import React, { PropTypes } from 'react'; +import { compose } from 'redux'; import { connect } from 'react-redux'; -import { Switch, Route } from 'react-router-dom'; +import { Switch, Route, withRouter } from 'react-router-dom'; import { NotFoundPage } from './containers'; import { NamedRedirect } from './components'; +import { withFlattenedRoutes } from './util/routes'; import * as propTypes from './util/propTypes'; const Routes = props => { - const { isAuthenticated, flattenedRoutes } = props; + const { isAuthenticated, flattenedRoutes, staticContext } = props; const renderComponent = (route, matchProps) => { const { auth, component: RouteComponent } = route; const { match, location } = matchProps; const canShowComponent = !auth || isAuthenticated; + if (!canShowComponent) { + staticContext.forbidden = true; + } return canShowComponent ? : ; @@ -34,13 +39,16 @@ const Routes = props => { ); }; -const { bool, arrayOf } = PropTypes; +Routes.defaultProps = { staticContext: {} }; + +const { bool, arrayOf, object } = PropTypes; Routes.propTypes = { isAuthenticated: bool.isRequired, flattenedRoutes: arrayOf(propTypes.route).isRequired, + staticContext: object, }; const mapStateToProps = state => ({ isAuthenticated: state.Auth.isAuthenticated }); -export default connect(mapStateToProps)(Routes); +export default compose(connect(mapStateToProps), withRouter, withFlattenedRoutes)(Routes); diff --git a/src/app.js b/src/app.js index fcb3e19a..08a4cd34 100644 --- a/src/app.js +++ b/src/app.js @@ -21,7 +21,7 @@ export const ClientApp = props => { - + @@ -42,7 +42,7 @@ export const ServerApp = props => { - +