diff --git a/config/default.js b/config/default.js index 62619336be6..f1515cb585e 100644 --- a/config/default.js +++ b/config/default.js @@ -26,6 +26,7 @@ module.exports = { // 2592000 is 30 days in seconds. cookieMaxAge: 2592000, cookieName: 'jwt_api_auth_token', + cookieSecure: true, isDeployed: true, isDevelopment: false, @@ -50,6 +51,7 @@ module.exports = { 'apiPath', 'cookieName', 'cookieMaxAge', + 'cookieSecure', 'isDeployed', 'isDevelopment', ], diff --git a/config/development.js b/config/development.js index f69bb2c5ae9..8f79b577540 100644 --- a/config/development.js +++ b/config/development.js @@ -14,6 +14,8 @@ module.exports = { isDeployed: false, isDevelopment: true, + cookieSecure: false, + serverPort: 3000, webpackServerHost, webpackServerPort, diff --git a/src/core/components/LoginPage/index.js b/src/core/components/LoginPage/index.js index a36b4d4fd43..96936f0835d 100644 --- a/src/core/components/LoginPage/index.js +++ b/src/core/components/LoginPage/index.js @@ -1,4 +1,5 @@ import React, { PropTypes } from 'react'; +import Helmet from 'react-helmet'; import { startLoginUrl } from 'core/api'; import { gettext as _ } from 'core/utils'; @@ -9,10 +10,12 @@ export default class LoginPage extends React.Component { } render() { + const title = _('Login Required'); const { message } = this.props; return (
-

{_('Login Required')}

+ +

{title}

{message || _('You must be logged in to access this page.')}

diff --git a/src/core/containers/HandleLogin/index.js b/src/core/containers/HandleLogin/index.js index a9a3eaf2454..89509eabb8a 100644 --- a/src/core/containers/HandleLogin/index.js +++ b/src/core/containers/HandleLogin/index.js @@ -55,7 +55,7 @@ function createLoadData(dispatch) { dispatch(setJWT(token)); cookie.save(config.get('cookieName'), token, { path: '/', - secure: true, + secure: config.get('cookieSecure'), maxAge: config.get('cookieMaxAge'), }); router.push('/search'); diff --git a/src/core/containers/LoginRequired/index.js b/src/core/containers/LoginRequired/index.js index e63d06463e8..0f7769922bc 100644 --- a/src/core/containers/LoginRequired/index.js +++ b/src/core/containers/LoginRequired/index.js @@ -2,29 +2,26 @@ import React, { PropTypes } from 'react'; import { connect } from 'react-redux'; import LoginPage from 'core/components/LoginPage'; -export function mapStateToProps(Component) { - return (state) => ({ +export function mapStateToProps(state) { + return { authenticated: !!state.auth.token, - Component, - }); + }; } +// This class is exported for testing outside of redux. export class LoginRequired extends React.Component { static propTypes = { authenticated: PropTypes.bool.isRequired, - // This is really a react component class but I guess that's a function. - Component: PropTypes.func.isRequired, + children: PropTypes.node, } render() { - const { authenticated, Component, ...childProps } = this.props; + const { authenticated, children } = this.props; if (authenticated) { - return ; + return children; } return ; } } -export default function loginRequired(Component) { - return connect(mapStateToProps(Component))(LoginRequired); -} +export default connect(mapStateToProps)(LoginRequired); diff --git a/src/search/routes.js b/src/search/routes.js index d95034655fc..10656339072 100644 --- a/src/search/routes.js +++ b/src/search/routes.js @@ -4,15 +4,15 @@ import { IndexRoute, Route } from 'react-router'; import App from './containers/App'; import CurrentSearchPage from './containers/CurrentSearchPage'; import AddonPage from './containers/AddonPage'; -import loginRequired from 'core/containers/LoginRequired'; +import LoginRequired from 'core/containers/LoginRequired'; import HandleLogin from 'core/containers/HandleLogin'; export default ( - - + + - + ); diff --git a/tests/client/core/containers/TestLoginRequired.js b/tests/client/core/containers/TestLoginRequired.js index 37228e9980a..b823a470ff3 100644 --- a/tests/client/core/containers/TestLoginRequired.js +++ b/tests/client/core/containers/TestLoginRequired.js @@ -4,44 +4,42 @@ import { shallowRender } from 'tests/client/helpers'; import { mapStateToProps, LoginRequired } from 'core/containers/LoginRequired'; import LoginPage from 'core/components/LoginPage'; -describe('LoginRequired helpers', () => { +describe('', () => { class MyComponent extends React.Component { render() { return

Authenticated content.

; } } - describe('rendered component when not authenticated', () => { - it('renders ', () => { - const root = shallowRender(); - assert.equal(root.type, LoginPage); - }); + it('renders when unauthenticated', () => { + const root = shallowRender( + + + + ); + assert.equal(root.type, LoginPage); }); - describe('rendered component when authenticated', () => { - it('renders the child component', () => { - const root = shallowRender(); - assert.equal(root.type, MyComponent); - }); - - it('passes along its props', () => { - const root = shallowRender( - ); - assert.deepEqual(root.props, {foo: 'bar'}); - }); + it('renders the children when authenticated', () => { + const root = shallowRender( + + + + ); + assert.equal(root.type, MyComponent); }); describe('mapStateToProps', () => { - it('sets authenticated and Component when authenticated', () => { + it('sets authenticated to true when there is a token', () => { assert.deepEqual( - mapStateToProps(MyComponent)({auth: {token: 'foo'}}), - {authenticated: true, Component: MyComponent}); + mapStateToProps({auth: {token: 'foo'}}), + {authenticated: true}); }); - it('sets authenticated and Component when unauthenticated', () => { + it('sets authenticated to false when there is not a token', () => { assert.deepEqual( - mapStateToProps(MyComponent)({auth: {}}), - {authenticated: false, Component: MyComponent}); + mapStateToProps({auth: {}}), + {authenticated: false}); }); }); });