diff --git a/frontend/components/AuthenticatedRoutes/AuthenticatedRoutes.jsx b/frontend/components/AuthenticatedRoutes/AuthenticatedRoutes.jsx
index 151e9ffdb0..7f4ad1d5d4 100644
--- a/frontend/components/AuthenticatedRoutes/AuthenticatedRoutes.jsx
+++ b/frontend/components/AuthenticatedRoutes/AuthenticatedRoutes.jsx
@@ -1,12 +1,44 @@
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
+import { isEqual } from 'lodash';
+import { push } from 'react-router-redux';
+import paths from '../../router/paths';
export class AuthenticatedRoutes extends Component {
static propTypes = {
children: PropTypes.element,
+ dispatch: PropTypes.func,
+ loading: PropTypes.bool.isRequired,
user: PropTypes.object,
};
+ componentWillMount () {
+ const { loading, user } = this.props;
+ const { redirectToLogin } = this;
+
+ if (!loading && !user) return redirectToLogin();
+
+ return false;
+ }
+
+ componentWillReceiveProps (nextProps) {
+ if (isEqual(this.props, nextProps)) return false;
+
+ const { loading, user } = nextProps;
+ const { redirectToLogin } = this;
+
+ if (!loading && !user) return redirectToLogin();
+
+ return false;
+ }
+
+ redirectToLogin = () => {
+ const { dispatch } = this.props;
+ const { LOGIN } = paths;
+
+ return dispatch(push(LOGIN));
+ }
+
render () {
const { children, user } = this.props;
@@ -21,9 +53,9 @@ export class AuthenticatedRoutes extends Component {
}
const mapStateToProps = (state) => {
- const { user } = state.auth;
+ const { loading, user } = state.auth;
- return { user };
+ return { loading, user };
};
export default connect(mapStateToProps)(AuthenticatedRoutes);
diff --git a/frontend/components/AuthenticatedRoutes/AuthenticatedRoutes.tests.jsx b/frontend/components/AuthenticatedRoutes/AuthenticatedRoutes.tests.jsx
index 85fa8e100a..55dccfa839 100644
--- a/frontend/components/AuthenticatedRoutes/AuthenticatedRoutes.tests.jsx
+++ b/frontend/components/AuthenticatedRoutes/AuthenticatedRoutes.tests.jsx
@@ -6,16 +6,35 @@ import AuthenticatedRoutes from './index';
import helpers from '../../test/helpers';
describe('AuthenticatedRoutes - component', () => {
+ const redirectToLoginAction = {
+ type: '@@router/CALL_HISTORY_METHOD',
+ payload: {
+ method: 'push',
+ args: ['/login'],
+ },
+ };
const renderedText = 'This text was rendered';
const storeWithUser = {
auth: {
+ loading: false,
user: {
id: 1,
email: 'hi@thegnar.co',
},
},
};
- const storeWithoutUser = { auth: {} };
+ const storeWithoutUser = {
+ auth: {
+ loading: false,
+ user: null,
+ },
+ };
+ const storeLoadingUser = {
+ auth: {
+ loading: true,
+ user: null,
+ },
+ };
it('renders if there is a user in state', () => {
const { reduxMockStore } = helpers;
@@ -31,7 +50,7 @@ describe('AuthenticatedRoutes - component', () => {
expect(component.text()).toEqual(renderedText);
});
- it('does not render without a user in state', () => {
+ it('redirects to login without a user', () => {
const { reduxMockStore } = helpers;
const mockStore = reduxMockStore(storeWithoutUser);
const component = mount(
@@ -42,6 +61,22 @@ describe('AuthenticatedRoutes - component', () => {
);
+ expect(mockStore.getActions()).toInclude(redirectToLoginAction);
+ expect(component.html()).toNotExist();
+ });
+
+ it('does not redirect to login if the user is loading', () => {
+ const { reduxMockStore } = helpers;
+ const mockStore = reduxMockStore(storeLoadingUser);
+ const component = mount(
+
+
+ {renderedText}
+
+
+ );
+
+ expect(mockStore.getActions()).toNotInclude(redirectToLoginAction);
expect(component.html()).toNotExist();
});
});
diff --git a/frontend/redux/middlewares/auth.js b/frontend/redux/middlewares/auth.js
index 1d5cb2f538..e84fe8268c 100644
--- a/frontend/redux/middlewares/auth.js
+++ b/frontend/redux/middlewares/auth.js
@@ -1,13 +1,15 @@
/* eslint-disable no-unused-vars */
import { push } from 'react-router-redux';
import kolide from '../../kolide';
-import { LOGIN_SUCCESS, LOGOUT_SUCCESS } from '../nodes/auth/actions';
+import { LOGIN_FAILURE, LOGIN_SUCCESS, LOGOUT_SUCCESS } from '../nodes/auth/actions';
import local from '../../utilities/local';
import paths from '../../router/paths';
const authMiddleware = store => next => action => {
- if (action.type === LOGIN_SUCCESS) {
- const { token } = action.payload.data;
+ const { type, payload } = action;
+
+ if (type === LOGIN_SUCCESS) {
+ const { token } = payload.data;
if (token) {
local.setItem('auth_token', token);
@@ -15,7 +17,7 @@ const authMiddleware = store => next => action => {
}
}
- if (action.type === LOGOUT_SUCCESS) {
+ if (type === LOGOUT_SUCCESS || type === LOGIN_FAILURE) {
const { LOGIN } = paths;
local.clear();
diff --git a/frontend/router/index.jsx b/frontend/router/index.jsx
index f0cb0d886d..1a786edfcc 100644
--- a/frontend/router/index.jsx
+++ b/frontend/router/index.jsx
@@ -20,7 +20,6 @@ const routes = (
-
@@ -30,6 +29,9 @@ const routes = (
+
+
+