Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
359 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"presets": ["es2015", "react", "stage-0"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
redux-auth-wrapper basic example | ||
================================= | ||
|
||
This is a basic example that demonstrates wrapping components | ||
with authentication and authorization checks. It shows how to handle | ||
nested checks and demonstrates redirect support. | ||
|
||
This example uses React-Router 2.x and React-Router-Redux 4.x. | ||
|
||
**To run, follow these steps:** | ||
|
||
1. Install dependencies with `npm install` in this directory (make sure it creates a local node_modules) | ||
2. By default, it uses the local version from `src` of redux-auth-wrapper, so you need to run `npm install` from there first. | ||
3. `npm start` | ||
4. `Browse to http://localhost:8080` | ||
|
||
Login as any user to access the protected page `foo`. | ||
Login with the admin box check to access the admin section. (Link is hidden until logging in as admin) | ||
Logout from any protected page to get redirect back to the login page. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import * as constants from '../constants' | ||
|
||
export function login(data) { | ||
return { | ||
type: constants.USER_LOGGED_IN, | ||
payload: data | ||
} | ||
} | ||
|
||
export function logout() { | ||
return { | ||
type: constants.USER_LOGGED_OUT | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { createDevTools } from 'redux-devtools' | ||
import LogMonitor from 'redux-devtools-log-monitor' | ||
import DockMonitor from 'redux-devtools-dock-monitor' | ||
|
||
import React from 'react' | ||
import ReactDOM from 'react-dom' | ||
import { createStore, combineReducers, applyMiddleware, compose } from 'redux' | ||
import { Provider } from 'react-redux' | ||
import { Route, Switch } from 'react-router-dom' | ||
import createHistory from 'history/createBrowserHistory' | ||
import { ConnectedRouter, routerReducer, routerMiddleware } from 'react-router-redux' | ||
|
||
import * as reducers from './reducers' | ||
import { App, Home, Foo, Admin, Login } from './components' | ||
import { UserIsAuthenticated, UserIsAdmin } from './util/wrappers.js' | ||
|
||
const baseHistory = createHistory() | ||
const routingMiddleware = routerMiddleware(baseHistory) | ||
const reducer = combineReducers(Object.assign({}, reducers, { | ||
router: routerReducer | ||
})) | ||
|
||
const DevTools = createDevTools( | ||
<DockMonitor toggleVisibilityKey="ctrl-h" | ||
changePositionKey="ctrl-q"> | ||
<LogMonitor theme="tomorrow" /> | ||
</DockMonitor> | ||
) | ||
|
||
const enhancer = compose( | ||
// Middleware you want to use in development: | ||
applyMiddleware(routingMiddleware), | ||
DevTools.instrument() | ||
) | ||
|
||
// Note: passing enhancer as the last argument requires redux@>=3.1.0 | ||
const store = createStore(reducer, enhancer) | ||
|
||
ReactDOM.render( | ||
<Provider store={store}> | ||
<ConnectedRouter history={baseHistory}> | ||
<div> | ||
<App> | ||
<Switch> | ||
<Route exact path="/" component={Home} /> | ||
<Route path="/login" component={Login}/> | ||
<Route path="/foo" component={UserIsAuthenticated(Foo)}/> | ||
<Route path="/admin" component={UserIsAuthenticated(UserIsAdmin(Admin))}/> | ||
</Switch> | ||
</App> | ||
<DevTools /> | ||
</div> | ||
</ConnectedRouter> | ||
</Provider>, | ||
document.getElementById('mount') | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import React from 'react' | ||
|
||
export default function Admin({ authData }) { | ||
return <div> | ||
<p>{`Welcome admin user: ${authData.name}`}</p> | ||
<p>Refreshing your page here will redirect you back to Login with a redirect back here once authenticated</p> | ||
<p>See the local storage example for an example that doesn't log you out on refresh</p> | ||
</div> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import React from 'react' | ||
import { NavLink, withRouter } from 'react-router-dom' | ||
import { connect } from 'react-redux' | ||
import { logout } from '../actions/user' | ||
import { VisibleOnlyAdmin } from '../util/wrappers' | ||
|
||
const OnlyAdminLink = VisibleOnlyAdmin(() => <NavLink to="/admin">{'Admin'}</NavLink>) | ||
|
||
function App({ children, logout }) { | ||
return ( | ||
<div> | ||
<header> | ||
Links: | ||
{' '} | ||
<NavLink to="/">Home</NavLink> | ||
{' '} | ||
<NavLink to="/foo">{'Foo (Login Required)'}</NavLink> | ||
{' '} | ||
<OnlyAdminLink /> | ||
{' '} | ||
<NavLink to="/login">Login</NavLink> | ||
{' '} | ||
<button onClick={() => logout()}>Logout</button> | ||
</header> | ||
<div style={{ marginTop: '1.5em' }}>{children}</div> | ||
</div> | ||
) | ||
} | ||
|
||
export default withRouter(connect(false, { logout })(App)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react' | ||
|
||
export default function Foo({ authData }) { | ||
return ( | ||
<div>{`I am Foo! Welcome ${authData.name}`}</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import React from 'react' | ||
|
||
export default function Home() { | ||
return ( | ||
<div> | ||
<h4>{"Welcome! Why dont you login and check out Foo? Or log in as an admin and click Admin"}</h4> | ||
<h4>{"Or just try to click Foo and you will be redirected"}</h4> | ||
<h4>{"The Administrator link is hidden until you log in as an admin"}</h4> | ||
<h4>{"Dont forget to try logging out on any page!"}</h4> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import 'url-search-params-polyfill' | ||
|
||
import React, { Component, PropTypes } from 'react' | ||
import { routerActions } from 'react-router-redux' | ||
import { connect } from 'react-redux' | ||
|
||
import { login } from '../actions/user' | ||
|
||
function select(state, ownProps) { | ||
const isAuthenticated = state.user.name || false | ||
// https://github.com/mjrussell/redux-auth-wrapper/issues/127 | ||
// https://github.com/ReactTraining/react-router/issues/4410 | ||
const query = new URLSearchParams(ownProps.location.search) | ||
const redirect = query.get('redirect') || '/' | ||
return { | ||
isAuthenticated, | ||
redirect | ||
} | ||
} | ||
|
||
class LoginContainer extends Component { | ||
|
||
static propTypes = { | ||
login: PropTypes.func.isRequired, | ||
replace: PropTypes.func.isRequired | ||
}; | ||
|
||
componentWillMount() { | ||
const { isAuthenticated, replace, redirect } = this.props | ||
if (isAuthenticated) { | ||
replace(redirect) | ||
} | ||
} | ||
|
||
componentWillReceiveProps(nextProps) { | ||
const { isAuthenticated, replace, redirect } = nextProps | ||
const { isAuthenticated: wasAuthenticated } = this.props | ||
|
||
if (!wasAuthenticated && isAuthenticated) { | ||
replace(redirect) | ||
} | ||
} | ||
|
||
onClick = (e) => { | ||
e.preventDefault() | ||
this.props.login({ | ||
name: this.refs.name.value, | ||
isAdmin: this.refs.admin.checked | ||
}) | ||
}; | ||
|
||
render() { | ||
return ( | ||
<div> | ||
<h2>Enter your name</h2> | ||
<input type="text" ref="name" /> | ||
<br/> | ||
{'Admin?'} | ||
<input type="checkbox" ref="admin" /> | ||
<br/> | ||
<button onClick={this.onClick}>Login</button> | ||
</div> | ||
) | ||
} | ||
|
||
} | ||
|
||
export default connect(select, { login, replace: routerActions.replace })(LoginContainer) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import App from './App' | ||
import Home from './Home' | ||
import Foo from './Foo' | ||
import Admin from './Admin' | ||
import Login from './Login' | ||
|
||
module.exports = { App, Home, Foo, Admin, Login } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export const USER_LOGGED_IN = 'USER_LOGGED_IN' | ||
export const USER_LOGGED_OUT = 'USER_LOGGED_OUT' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>redux-auth-wrapper basic example</title> | ||
<meta charset="utf8"/> | ||
</head> | ||
<body> | ||
<div id="mount"></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "raw-basic-example", | ||
"version": "0.0.0", | ||
"dependencies": { | ||
"react": "15.3.2", | ||
"react-dom": "15.3.2", | ||
"react-redux": "^5.0.3", | ||
"react-router": "^4.0.0", | ||
"react-router-dom": "^4.0.0", | ||
"react-router-redux": "next", | ||
"redux": "3.6.0", | ||
"url-search-params-polyfill": "^1.1.0" | ||
}, | ||
"devDependencies": { | ||
"babel-core": "6.18.2", | ||
"babel-loader": "6.2.7", | ||
"babel-preset-es2015": "6.18.0", | ||
"babel-preset-react": "6.16.0", | ||
"babel-preset-stage-0": "6.16.0", | ||
"eslint": "1.7.1", | ||
"eslint-config-rackt": "1.1.1", | ||
"eslint-plugin-react": "3.16.0", | ||
"html-webpack-plugin": "2.24.1", | ||
"redux-devtools": "3.3.1", | ||
"redux-devtools-dock-monitor": "1.1.1", | ||
"redux-devtools-log-monitor": "1.1.1", | ||
"webpack": "1.13.3", | ||
"webpack-dev-server": "1.16.2" | ||
}, | ||
"scripts": { | ||
"start": "webpack-dev-server --config webpack.config.babel.js --progress" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import user from './user' | ||
|
||
module.exports = { user } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import * as constants from '../constants' | ||
|
||
export default function userUpdate(state = {}, { type, payload }) { | ||
if(type === constants.USER_LOGGED_IN) { | ||
return payload | ||
} | ||
else if(type === constants.USER_LOGGED_OUT) { | ||
return {} | ||
} | ||
return state | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { UserAuthWrapper } from 'redux-auth-wrapper' | ||
import { routerActions } from 'react-router-redux' | ||
|
||
export const UserIsAuthenticated = UserAuthWrapper({ | ||
authSelector: state => state.user, | ||
redirectAction: routerActions.replace, | ||
wrapperDisplayName: 'UserIsAuthenticated' | ||
|
||
}) | ||
|
||
export const UserIsAdmin = UserAuthWrapper({ | ||
authSelector: state => state.user, | ||
redirectAction: routerActions.replace, | ||
failureRedirectPath: '/', | ||
wrapperDisplayName: 'UserIsAdmin', | ||
predicate: user => user.isAdmin, | ||
allowRedirectBack: false | ||
}) | ||
|
||
export const VisibleOnlyAdmin = UserAuthWrapper({ | ||
authSelector: state => state.user, | ||
wrapperDisplayName: 'VisibleOnlyAdmin', | ||
predicate: user => user.isAdmin, | ||
FailureComponent: null | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import path from 'path' | ||
import fs from 'fs' | ||
import HtmlWebpackPlugin from 'html-webpack-plugin' | ||
|
||
module.exports = { | ||
entry: './app.js', | ||
output: { | ||
path: path.join(__dirname, 'dist'), | ||
filename: 'bundle.js' | ||
}, | ||
devServer: { | ||
inline: true, | ||
historyApiFallback: true, | ||
stats: { | ||
colors: true, | ||
hash: false, | ||
version: false, | ||
chunks: false, | ||
children: false | ||
} | ||
}, | ||
module: { | ||
loaders: [ { | ||
test: /\.js$/, | ||
loaders: [ 'babel' ], | ||
exclude: /node_modules/, | ||
include: __dirname | ||
} ] | ||
}, | ||
plugins: [ | ||
new HtmlWebpackPlugin({ | ||
template: 'index.html', // Load a custom template | ||
inject: 'body' // Inject all scripts into the body | ||
}) | ||
] | ||
} | ||
|
||
// This will make the redux-auth-wrapper module resolve to the | ||
// latest src instead of using it from npm. Remove this if running | ||
// outside of the source. | ||
const src = path.join(__dirname, '..', '..', 'src') | ||
if (fs.existsSync(src)) { | ||
// Use the latest src | ||
module.exports.resolve = { alias: { 'redux-auth-wrapper': src } } | ||
module.exports.module.loaders.push({ | ||
test: /\.js$/, | ||
loaders: [ 'babel' ], | ||
include: src | ||
}) | ||
} |