├── src
├── reducers
│ ├── index.js
│ └── auth.js
├── middlewares
│ ├── index.js
│ ├── hook.js
│ └── token.js
├── index.js
├── constants.js
├── dev.js
├── demo.js
├── redux-setup.js
└── component.js
├── .gitignore
├── .npmignore
├── .babelrc
├── test
└── test.spec.js
├── index.tpl.html
├── devserver.js
├── README.md
├── customize.js
├── webpack.config.js
└── package.json
/src/reducers/index.js:
--------------------------------------------------------------------------------
1 | export auth from './auth'
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.sw*
2 | node_modules
3 | dist
4 | lib
5 | es
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | *.sw*
2 | .gitconfig
3 | .package.json
4 | .webpack.config.js
5 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react", "babel-preset-stage-0"]
3 | }
4 |
--------------------------------------------------------------------------------
/src/middlewares/index.js:
--------------------------------------------------------------------------------
1 | export TokenMiddleware from './token'
2 | export AuthMiddlewareHook from './hook'
3 |
--------------------------------------------------------------------------------
/test/test.spec.js:
--------------------------------------------------------------------------------
1 | import expect from 'expect'
2 |
3 | describe('Test should run', ()=>{
4 | it('should add 1 and 1', ()=>{
5 | expect(1+1).toBe(2);
6 | });
7 | });
8 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export AuthExample from './demo'
2 | export AuthReducer from './reducers/auth'
3 | export * as AuthMiddlewares from './middlewares'
4 | export AuthComponent from './component'
5 |
--------------------------------------------------------------------------------
/src/constants.js:
--------------------------------------------------------------------------------
1 | import consts from 'namespaced-constants'
2 |
3 | export const token = "auth.token"
4 | export const profile = "auth.profile"
5 | export const auth = consts('auth')('submitting', 'logout', 'signin', 'error', 'check');
6 |
--------------------------------------------------------------------------------
/src/dev.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { AuthExample } from './index';
4 |
5 | //Redux
6 | import {DevTools, store} from './redux-setup.js';
7 | import { Provider } from 'react-redux';
8 |
9 | ReactDOM.render(
10 |
11 |
15 |
16 | , document.getElementById('root')
17 | );
18 |
--------------------------------------------------------------------------------
/src/middlewares/hook.js:
--------------------------------------------------------------------------------
1 | import { auth } from '../constants'
2 | import { createAction as act } from 'redux-actions'
3 |
4 | /* [eventList]:
5 | * {
6 | * type: An event to check for (such as a route change),
7 | * func: (action.payload, AuthState, dispatch) //Callback with user info, state and dispatch
8 | * }
9 | */
10 | export default (eventList=[])=>{
11 | return store => next => action => {
12 | let result = next(action);
13 | var t, p;
14 | let { payload } = action;
15 |
16 | eventList.forEach((e)=>{
17 | const { type, func } = e;
18 | if(action.type == type){
19 | func(action.payload, store.getState(), store.dispatch);
20 | }
21 | });
22 |
23 | return result;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/index.tpl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | react-kickstart
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/reducers/auth.js:
--------------------------------------------------------------------------------
1 | import { handleActions } from 'redux-actions'
2 | import { auth } from '../constants'
3 |
4 | let fn = (obj={})=>{
5 | return Object.assign({}, {
6 | profile: null,
7 | token: null,
8 | id: null,
9 | submitting: false,
10 | error: false,
11 | newUser: false
12 | }, obj);
13 | }
14 |
15 | let obj = {};
16 |
17 | obj[auth.signin] = (state, action)=>{
18 | let { payload } = action;
19 | let { profile, token } = payload;
20 |
21 | return fn({
22 | id: profile.global_client_id,
23 | profile,
24 | token
25 | })
26 | }
27 |
28 | obj[auth.logout] = (state, action)=>{
29 | return fn();
30 | }
31 |
32 | obj[auth.error] = (state, action)=>{
33 | let { payload } = action;
34 | let { error } = payload;
35 |
36 | return fn({error});
37 | }
38 |
39 | export default handleActions(obj, fn());
40 |
--------------------------------------------------------------------------------
/src/demo.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactReduxAuth0 from './component'
3 | import { connect } from 'react-redux'
4 | import { auth, token, profile } from './constants'
5 | import { createAction as act } from 'redux-actions'
6 |
7 | class BaseComponent extends React.Component {
8 | componentDidMount(){
9 | let { props } = this;
10 | props.dispatch(act(auth.check)());
11 | }
12 |
13 | onAuthenticated(token, profile){ //if loginResult is null, it's likely because a token was already set
14 | console.log(`Login token ${JSON.stringify(token)},\n\nProfile\n ${JSON.stringify(profile)}`);
15 | }
16 |
17 | render(){
18 | let { auth } = this.props;
19 |
20 | return
21 | }
22 | }
23 |
24 | export default connect((state)=>{
25 | let { auth } = state;
26 | return { auth };
27 | })(BaseComponent);
28 |
--------------------------------------------------------------------------------
/src/middlewares/token.js:
--------------------------------------------------------------------------------
1 | import { auth, token, profile } from '../constants'
2 | import { createAction as act } from 'redux-actions'
3 |
4 | export default ()=>{
5 | return store => next => action => {
6 | let result = next(action);
7 | var t, p;
8 | let { payload } = action;
9 |
10 | if(action.type == auth.check){
11 | t = localStorage.getItem(token);
12 | if(t){
13 | t = JSON.parse(t);
14 | p = JSON.parse(localStorage.getItem(profile));
15 | store.dispatch(act(auth.signin)({profile: p, token: t}));
16 | }
17 | } else if(action.type == auth.signin){
18 | localStorage.setItem(token, JSON.stringify(payload.token));
19 | localStorage.setItem(profile, JSON.stringify(payload.profile));
20 | } else if(action.type == auth.logout){
21 | localStorage.removeItem(token);
22 | localStorage.removeItem(profile);
23 | }
24 |
25 | return result;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/devserver.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import express from 'express';
3 | import webpack from 'webpack';
4 | import webpackMiddleware from 'webpack-dev-middleware';
5 | import webpackHotMiddleware from 'webpack-hot-middleware';
6 | import config from './webpack.config.js';
7 |
8 | const port = process.env.PORT ? process.env.PORT : 3000;
9 | const app = express();
10 | const compiler = webpack(config);
11 | const middleware = webpackMiddleware(compiler, {
12 | publicPath: config.output.publicPath,
13 | contentBase: 'src',
14 | stats: {
15 | colors: true,
16 | hash: false,
17 | timings: true,
18 | chunks: false,
19 | chunkModules: false,
20 | modules: false
21 | }
22 | });
23 |
24 | app.use(middleware);
25 | app.use(webpackHotMiddleware(compiler));
26 | app.get('*', (req, res)=>{
27 | res.write(middleware.fileSystem.readFileSync(path.join(__dirname, 'dist/index.html')));
28 | res.end();
29 | });
30 |
31 | app.listen(port, '0.0.0.0', (err)=>{
32 | if (err) {
33 | console.log(err);
34 | }
35 | console.info('==> 🌎 Listening on port %s. Open up http://0.0.0.0:%s/ in your browser.', port, port);
36 | });
37 |
--------------------------------------------------------------------------------
/src/redux-setup.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | //Redux DevTools
4 | import { createDevTools } from 'redux-devtools';
5 | import LogMonitor from 'redux-devtools-log-monitor';
6 | import DockMonitor from 'redux-devtools-dock-monitor';
7 |
8 | //Redux
9 | import { applyMiddleware, compose, createStore, combineReducers } from 'redux';
10 |
11 | //Reducers
12 | import * as reducers from './reducers/index';
13 |
14 | //Set up Redux Middleware
15 | const reducer = combineReducers({
16 | ...reducers
17 | })
18 |
19 | //Set up Dev Tools
20 | const DevTools = createDevTools(
21 |
23 |
24 |
25 | )
26 |
27 | //Create the store
28 | import * as AuthMiddlewares from './middlewares'
29 | import { auth } from './constants'
30 |
31 | const finalCreateStore = compose(
32 | applyMiddleware(
33 | AuthMiddlewares.TokenMiddleware(),
34 | AuthMiddlewares.AuthMiddlewareHook([
35 | {
36 | type: auth.signin,
37 | func: (payload, state, dispatch)=>{
38 | console.log("I was called on signin!", payload, state, dispatch);
39 | }
40 | }
41 | ])
42 | ),
43 | DevTools.instrument()
44 | )(createStore);
45 |
46 | const store = finalCreateStore(reducer);
47 |
48 | //Exports
49 | export default store;
50 | export {DevTools, store}
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Use Auth0 with React + Redux
2 |
3 | ```
4 | import { AuthComponent, AuthMiddlewares, AuthReducer } from 'react-redux-auth0'
5 | ```
6 |
7 | ### When starting your app, include the following environment variables:
8 |
9 | ```
10 | AUTH0_CLIENTID=client-id-string AUTH0_DOMAIN=domain npm your-start-command
11 | ```
12 |
13 | Include [Auth0](https://auth0.com/) from CDN in your template (believe me, you don't want to build it):
14 |
15 | ```
16 |
17 |
18 | ```
19 |
20 | ### Usage with Webpack
21 |
22 | Make sure you have this webpack plugin so that webpack will compile in proper environment variables:
23 |
24 | ```
25 | new webpack.DefinePlugin({
26 | 'process.env.NODE_ENV': JSON.stringify(env),
27 | 'process.env.AUTH0_CLIENTID': JSON.stringify(AUTH0_CLIENTID),
28 | 'process.env.AUTH0_DOMAIN': JSON.stringify(AUTH0_DOMAIN)
29 | })
30 | ```
31 |
32 | ...here is an example of reading those env variables in webpack config:
33 |
34 | ```
35 | const env = process.env.NODE_ENV;
36 | const AUTH0_CLIENTID = process.env.AUTH0_CLIENTID;
37 | const AUTH0_DOMAIN = process.env.AUTH0_DOMAIN;
38 | ```
39 |
40 | # AuthComponent
41 |
42 | Can be used to render either a 'Sigup' or 'Login' button:
43 |
44 |
45 | ```
46 |
47 |
48 |
49 |
50 | ```
51 |
52 | ...or will render both:
53 |
54 | ```
55 |
56 | ```
57 |
58 | The component will automatically return a `Logout` button when the user is authenticated.
59 |
60 | ## Options
61 |
62 | `auth0`: auth0 lock customization options detailed here https://auth0.com/docs/libraries/lock/v10/customization
63 | `onAuthenticated (token, profile)`: A callback to receive when authentication has completed.
64 |
--------------------------------------------------------------------------------
/customize.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 |
3 | let { PROJECT_NAME, PROJECT_DESCRIPTION, GITHUB_USERNAME, AUTHOR_NAME, AUTHOR_EMAIL } = process.env;
4 |
5 | if(!PROJECT_NAME || !PROJECT_DESCRIPTION || !GITHUB_USERNAME || !AUTHOR_NAME || !AUTHOR_EMAIL){
6 | console.error('Must provide PROJECT_NAME, PROJECT_DESCRIPTION, GITHUB_USERNAME, AUTHOR_NAME, AUTHOR_EMAIL as environment variables!');
7 | process.exit();
8 | }
9 |
10 | RegExp.quote = function(str) {
11 | return str.replace(/([.?*+^$[\]\\(){}-])/g, "\\$1");
12 | };
13 |
14 | String.prototype.replaceAll = function(search, replace)
15 | {
16 | var re = new RegExp(RegExp.quote(search),"g");
17 | return this.replace(re, replace);
18 | };
19 |
20 | let oldName = 'react-redux-workbench';
21 | let packageJSON = fs.readFileSync('./.package.json').toString();
22 | let oldVersion = '"version": "'+JSON.parse(packageJSON).version+'"';
23 | let newVersion = '"version": "0.0.1"';
24 | let gitConfig = fs.readFileSync('./.gitconfig').toString();
25 | let webpackConfig = fs.readFileSync('./.webpack.config.js').toString();
26 | let projectName = PROJECT_NAME;
27 | let repo = [GITHUB_USERNAME, `${projectName}`].join('/');
28 | let gitConfigNew = gitConfig.replaceAll(`calvinfroedge/${oldName}`, repo);
29 | let file = projectName.replaceAll(' ', '-').toLowerCase();
30 | let packageJSONNEW = packageJSON.replaceAll(oldName, file).replaceAll('Calvin Froedge', AUTHOR_NAME).replaceAll('calvinfroedge@gmail.com', AUTHOR_EMAIL).replaceAll('description-customize-me', PROJECT_DESCRIPTION).replaceAll(oldVersion, newVersion);
31 | let webpackConfigNEW = webpackConfig.replaceAll('ReactReduxWorkbench', projectName.replaceAll(' ', '')).replaceAll(oldName, file);
32 | fs.writeFileSync('./.git/config', gitConfigNew);
33 | fs.writeFileSync('./package.json', packageJSONNEW);
34 | fs.writeFileSync('./webpack.config.js', webpackConfigNEW);
35 | console.info('Wrote updates to package.json, .git/config, and wepback.config.js.\n');
36 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var webpack = require('webpack')
4 | var path = require('path')
5 | var HtmlWebpackPlugin = require('html-webpack-plugin')
6 |
7 | const env = process.env.NODE_ENV;
8 | const AUTH0_CLIENTID = process.env.AUTH0_CLIENTID;
9 | const AUTH0_DOMAIN = process.env.AUTH0_DOMAIN;
10 |
11 | var config = {
12 | module: {
13 | loaders: [
14 | { test: /\.js$/, loaders: ['babel-loader'], exclude: /node_modules/ },
15 | { test: /\.json?$/, loader: 'json' },
16 | { test: /\.css$/, loader: 'style!css?modules&localIdentName=[name]---[local]---[hash:base64:5]' },
17 | { test: /\.less$/, loader: "style!css!less" }
18 | ]
19 | },
20 | plugins: [
21 | new webpack.optimize.OccurenceOrderPlugin(),
22 | new webpack.DefinePlugin({
23 | 'process.env.NODE_ENV': JSON.stringify(env),
24 | 'process.env.AUTH0_CLIENTID': JSON.stringify(AUTH0_CLIENTID),
25 | 'process.env.AUTH0_DOMAIN': JSON.stringify(AUTH0_DOMAIN)
26 | })
27 | ]
28 | };
29 |
30 | if(env === 'build'){
31 | config.output = {
32 | library: 'react-redux-auth0',
33 | libraryTarget: 'umd'
34 | }
35 | } else if(env === 'development'){
36 | config.devtool = 'eval-source-map';
37 |
38 | config.entry = [
39 | 'webpack-hot-middleware/client?reload=true',
40 | path.join(__dirname, 'src/dev.js')
41 | ];
42 |
43 | config.output = {
44 | path: path.join(__dirname, '/dist/'),
45 | filename: 'react-redux-auth0.js',
46 | publicPath: '/'
47 | };
48 |
49 | config.plugins = config.plugins.concat([
50 | new HtmlWebpackPlugin({
51 | template: 'index.tpl.html',
52 | inject: 'body',
53 | filename: 'index.html'
54 | }),
55 | new webpack.HotModuleReplacementPlugin(),
56 | new webpack.NoErrorsPlugin()
57 | ]);
58 | } else if (env === 'production') {
59 | config.plugins.push(
60 | new webpack.optimize.UglifyJsPlugin({
61 | compressor: {
62 | pure_getters: true,
63 | unsafe: true,
64 | unsafe_comps: true,
65 | screw_ie8: true,
66 | warnings: false
67 | }
68 | })
69 | )
70 | }
71 |
72 | module.exports = config
73 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-redux-auth0",
3 | "version": "0.0.9",
4 | "description": "React / redux / auth0",
5 | "main": "lib/index.js",
6 | "jsnext:main": "es/index.js",
7 | "scripts": {
8 | "clean": "rimraf lib dist es",
9 | "test": "cross-env NODE_ENV=build BABEL_ENV=commonjs mocha --compilers js:babel-register --recursive",
10 | "build:commonjs": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=commonjs ./node_modules/babel-cli/bin/babel.js src --out-dir lib",
11 | "build:es": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=es ./node_modules/babel-cli/bin/babel.js src --out-dir es",
12 | "build:umd": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=commonjs NODE_ENV=build ./node_modules/webpack/bin/webpack.js src/index.js dist/react-redux-auth0.js",
13 | "build:umd:min": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=commonjs NODE_ENV=production ./node_modules/webpack/bin/webpack.js src/index.js dist/react-redux-auth0.min.js",
14 | "build": "NODE_ENV=build npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min",
15 | "customize": "./node_modules/babel-cli/bin/babel-node.js customize.js",
16 | "development": "NODE_ENV=development nodemon devserver.js --ignore src/ --exec ./node_modules/babel-cli/bin/babel-node.js",
17 | "prepublish": "npm run clean && npm run build"
18 | },
19 | "repository": {
20 | "type": "git",
21 | "url": "git+https://github.com/calvinfroedge/react-redux-auth0.git"
22 | },
23 | "keywords": [
24 | "react",
25 | "redux",
26 | "helpers",
27 | "state",
28 | "modifiers"
29 | ],
30 | "author": "Calvin Froedge ",
31 | "license": "MIT",
32 | "bugs": {
33 | "url": "https://github.com/calvinfroedge/react-redux-auth0/issues"
34 | },
35 | "homepage": "https://github.com/calvinfroedge/react-redux-auth0#readme",
36 | "dependencies": {
37 | "auth0-lock": "^10",
38 | "cacheable": "^0.2.9",
39 | "html-webpack-plugin": "^2.16.0",
40 | "namespaced-constants": "0.0.1",
41 | "redux-modifiers": "0.0.5",
42 | "webpack-hot-middleware": "^2.10.0"
43 | },
44 | "devDependencies": {
45 | "babel-cli": "^6.7.5",
46 | "babel-core": "^6.7.4",
47 | "babel-loader": "^6.2.4",
48 | "babel-plugin-transform-runtime": "^6.6.0",
49 | "babel-preset-es2015": "^6.6.0",
50 | "babel-preset-react": "^6.5.0",
51 | "babel-preset-stage-0": "^6.5.0",
52 | "babel-register": "^6.7.2",
53 | "cross-env": "^1.0.7",
54 | "expect": "^1.16.0",
55 | "express": "^4.13.4",
56 | "jsdom": "^8.1.0",
57 | "json-loader": "^0.5.4",
58 | "mocha": "^2.4.5",
59 | "mocha-jsdom": "^1.1.0",
60 | "react": "^15.0.1",
61 | "react-dom": "^15.0.1",
62 | "react-redux": "^4.4.5",
63 | "redux": "^3.4.0",
64 | "redux-actions": "^0.9.1",
65 | "redux-devtools": "^3.2.0",
66 | "redux-devtools-dock-monitor": "^1.1.1",
67 | "redux-devtools-log-monitor": "^1.0.11",
68 | "rimraf": "^2.5.2",
69 | "transform-loader": "^0.2.3",
70 | "webpack": "^1.12.14",
71 | "webpack-dev-middleware": "^1.6.1"
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/component.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { auth } from './constants'
3 | import { createAction as act } from 'redux-actions'
4 | import { connect } from 'react-redux'
5 |
6 | class AuthComponent extends React.Component {
7 | constructor(props){
8 | super(props);
9 |
10 | if(props.signup && props.login) throw new Error('You may only pass "signup" or "login".');
11 | }
12 |
13 | hide(){
14 | this.lock.hide();
15 | }
16 |
17 | mountAuth0(options={}){
18 | try {
19 | this.lock = new Auth0Lock(
20 | process.env.AUTH0_CLIENTID || 'Set process.env.AUTH0_CLIENTID',
21 | process.env.AUTH0_DOMAIN || 'Set process.env.AUTH0_DOMAIN',
22 | Object.assign({}, options, this.props.auth0)
23 | );
24 |
25 | this.lock.on('authenticated', (authResult) => {
26 | this.lock.getUserInfo(authResult.accessToken, (error, profile) => {
27 | if (error) {
28 | // Handle error
29 | console.error(error);
30 | return;
31 | }
32 |
33 | const method = this.props.signup ? 'signup' : 'login';
34 | this.finish(method, error, profile, authResult);
35 | });
36 | });
37 |
38 | return this.lock;
39 | } catch(e){
40 | console.log('auth0 mount error', e);
41 | }
42 | }
43 |
44 | componentDidMount(){
45 | const { props } = this;
46 |
47 | let auth0 = props.auth0 || {};
48 | let authSettings = auth0.auth || {};
49 |
50 | if(authSettings.redirect){ //Because redirect restarts browser memory, auth0 needs to be mounted again in redirect mode for on.authenticated callback handler to be reached
51 | this.mountAuth0();
52 | }
53 | }
54 |
55 | componentWillReceiveProps(nextProps){
56 | const { props } = this;
57 | const {onAuthenticated, auth} = nextProps;
58 |
59 | if(auth.token && !this.props.auth.token && nextProps.onAuthenticated){
60 | nextProps.onAuthenticated(auth.token, auth.profile);
61 | }
62 | }
63 |
64 | componentWillUnmount(){
65 | this.lock = null;
66 | }
67 |
68 | show(event, opts, cb){
69 | event.preventDefault();
70 | let auth0 = this.mountAuth0(opts);
71 | auth0.show(cb);
72 | }
73 |
74 | showLoginModal(event){
75 | this.show(event, {initialScreen: 'login'});
76 | }
77 |
78 | showSignupModal(event){
79 | this.show(event, {initialScreen: 'signUp'});
80 | }
81 |
82 | finish(method, err, profile, token){
83 | let { props } = this;
84 | let action;
85 | let obj;
86 | let newUser = false;
87 |
88 | if(method == 'login'){ //These both do the same thing now, but that may not be the case later
89 | action = act(auth.signin);
90 | } else if(method == 'signup'){
91 | action = act(auth.signin);
92 | newUser = true;
93 | }
94 |
95 | if(err){
96 | action = act(auth.error);
97 | obj = { error: err };
98 | } else {
99 | obj = { profile, token, newUser };
100 | }
101 |
102 | props.dispatch(action(obj));
103 | }
104 |
105 | logout(){
106 | let { dispatch } = this.props;
107 | dispatch(act(auth.logout)());
108 | }
109 |
110 | render(){
111 | let { props } = this;
112 |
113 | const LOGGED_OUT = (
114 |
115 | {
116 | props.signup ? '' :
119 | }
120 | {props.login || props.signup ? '' :
or}
121 | {
122 | props.login ? '' :
125 | }
126 |
127 | );
128 |
129 | const LOGGED_IN = (
130 |
133 | );
134 |
135 | return props.auth.token ? LOGGED_IN : LOGGED_OUT;
136 | }
137 | }
138 |
139 | /*
140 | * Make redirect "false"
141 | */
142 | AuthComponent.defaultProps = {
143 | auth0: {
144 | auth: {
145 | redirect: true
146 | }
147 | }
148 | }
149 |
150 | AuthComponent.propTypes = {
151 | onAuthenticated: React.PropTypes.func
152 | };
153 |
154 | export default connect((state)=>{
155 | let { auth } = state;
156 | return { auth };
157 | })(AuthComponent);
158 |
--------------------------------------------------------------------------------