├── .codeclimate.yml
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .npmignore
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── package.json
├── src
└── index.js
├── test
└── null_spec.js
└── webpack.config.js
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | languages:
2 | JavaScript: true
3 | # exclude_paths:
4 | # - lib/*
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 |
2 | ### Specific to project ##########
3 |
4 | # Results of builds
5 | lib
6 | dist
7 |
8 | ### Standard .gitignore ##########
9 |
10 | ## Dependency directory
11 |
12 | # Deployed apps should consider commenting this line out:
13 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
14 | node_modules/
15 | bower_components/
16 | jspm_packages/
17 |
18 | ## Node
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 | # Compiled binary addons (http://nodejs.org/api/addons.html)
23 | build/Release
24 | # Optional npm cache directory
25 | .npm
26 | # Optional REPL history
27 | .node_repl_history
28 |
29 | ## Apple
30 |
31 |
32 | ## Git
33 | .git/
34 |
35 | ## Temporary storage
36 | temp/
37 | tmp/
38 | unused/
39 |
40 | ## Logs
41 | logs/
42 | *.log
43 | npm-debug.log*
44 |
45 | ## Runtime data
46 | pids
47 | *.pid
48 | *.seed
49 |
50 | ## WebStorm editor
51 | .idea/
52 | # IntelliJ
53 | /out/
54 |
55 | ## Build
56 |
57 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
58 | .grunt
59 |
60 | ## Testing coverage
61 |
62 | # Directory for instrumented libs generated by jscoverage/JSCover
63 | lib-cov
64 | # Coverage directory used by tools like istanbul
65 | coverage
66 | # nyc test coverage
67 | .nyc_output
68 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "airbnb",
3 | "parser": "babel-eslint",
4 | "env": {
5 | "browser": true,
6 | "es6": true,
7 | "node": true,
8 | "mocha": true,
9 | },
10 | "plugins": [
11 | "jsdoc",
12 | ],
13 | "rules": { // override airbnb rules, add other rules
14 | "func-names": 0,
15 | "import/no-extraneous-dependencies": 0,
16 | "import/no-named-as-default": 0,
17 | "import/no-unresolved": ["error", { "ignore": ["^redux-form-material-ui"] }], // why complaints?
18 | "linebreak-style": 0,
19 | "max-statements": ["warn", 100],
20 | "no-use-before-define": ["off", {
21 | "functions": false, "classes": false
22 | }],
23 | "react/jsx-filename-extension": 0,
24 | "react/jsx-first-prop-new-line": 0,
25 | "jsdoc/check-param-names": 2,
26 | "jsdoc/check-tag-names": 2,
27 | "jsdoc/check-types": 2, // {type} starting with upper case letter is always OK
28 | "jsdoc/newline-after-description": [2, "always"],
29 | "jsdoc/require-description-complete-sentence": 0, // 2 prevents code in comments
30 | "jsdoc/require-hyphen-before-param-description": 2,
31 | "jsdoc/require-param": 2,
32 | "jsdoc/require-param-description": 2,
33 | "jsdoc/require-param-type": 2,
34 | "jsdoc/require-returns-description": 2,
35 | "jsdoc/require-returns-type": 2,
36 | },
37 | "settings": {
38 | "jsdoc": {
39 | "tagNamePreference": {
40 | "param": "param",
41 | "returns": "returns",
42 | }
43 | }
44 | },
45 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | ### Specific to project ##########
3 |
4 | # build
5 | lib/
6 | # checklists
7 | docs-secure/
8 | # Authentication information
9 | *.secure.js
10 |
11 | ### Standard .gitignore ##########
12 |
13 | ## Dependency directory
14 |
15 | # Deployed apps should consider commenting this line out:
16 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
17 | node_modules/
18 | bower_components/
19 | jspm_packages/
20 |
21 | ## Node
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 | # Compiled binary addons (http://nodejs.org/api/addons.html)
26 | build/Release
27 | # Optional npm cache directory
28 | .npm
29 | # Optional REPL history
30 | .node_repl_history
31 |
32 | ## Apple
33 |
34 |
35 | ## Git
36 | .git/
37 |
38 | ## Temporary storage
39 | temp/
40 | tmp/
41 | unused/
42 |
43 | ## Logs
44 | logs/
45 | *.log
46 | npm-debug.log*
47 |
48 | ## Runtime data
49 | pids
50 | *.pid
51 | *.seed
52 |
53 | ## WebStorm editor
54 | .idea/
55 | # IntelliJ
56 | /out/
57 |
58 | ## VSCode
59 | .vscode/
60 |
61 | ## Build
62 |
63 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
64 | .grunt
65 |
66 | ## Testing coverage
67 |
68 | # Directory for instrumented libs generated by jscoverage/JSCover
69 | lib-cov
70 | # Coverage directory used by tools like istanbul
71 | coverage
72 | # nyc test coverage
73 | .nyc_output
74 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # npm will use .gitignore if .npmignore does not exist. we don't want this.
2 | # npm modules
3 | node_modules/
4 | # ES6 source
5 | src/
6 | # example
7 | example/
8 | # coverage report
9 | coverage/
10 | # checklists and standard files
11 | docs-secure/
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - stable
5 |
6 | install:
7 | - npm install
8 |
9 | script:
10 | - npm run cover
11 |
12 | # Send coverage data to Coveralls
13 | after_script: "cat coverage/lcov.info | node_modules/coveralls/bin/coveralls.js"
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Notable changes to feathers-reduxify-authentication
2 |
3 | ## 0.1.1
4 | - Released package as it works with feathers-starter-react-redux-login-roles.
5 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to feathers-reduxify-authentication
2 |
3 | We would love for you to contribute code and help make Feathersjs even more productive than it is
4 | today! Here are some guidelines we would like you to follow:
5 |
6 | - [Question or Problem?](#question)
7 | - [Submission Guidelines](#submit)
8 | - [Coding Rules](#rules)
9 |
10 | ## Got a Question or Problem?
11 |
12 | If you have questions about how to *use* Feathersjs, you are likely to get effective help from
13 | the community here on [Slack](https://feathersjs.slack.com/messages/general/).
14 |
15 | ## Pull Requests (PR)
16 |
17 | ### Submitting a Pull Request
18 | Before you submit your Pull Request (PR) consider the following guidelines:
19 |
20 | * Search [GitHub](https://github.com/eddyystop/feathers-reduxify-authentication) for an open or closed PR
21 | that relates to your submission. You don't want to duplicate effort.
22 | * Make your changes in a new git branch:
23 |
24 | ```shell
25 | git checkout -b my-fix-branch master
26 | ```
27 |
28 | * Create your patch, **including appropriate test cases**.
29 | * Follow our [Coding Rules](#rules).
30 | * Run the full test suite with `npm test` and ensure that all tests pass.
31 | * Commit your changes using a descriptive commit message.
32 |
33 | ```shell
34 | git commit -a
35 | ```
36 | Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
37 |
38 | * Push your branch to GitHub:
39 |
40 | ```shell
41 | git push origin my-fix-branch
42 | ```
43 |
44 | * In GitHub, send a pull request.
45 | * If a change is suggested then:
46 | * Make the required updates.
47 | * Re-run the test suite to ensure tests are still passing.
48 | * Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
49 |
50 | ```shell
51 | git rebase master -i
52 | git push -f
53 | ```
54 |
55 | That's it! Thank you for your contribution!
56 |
57 | ### After your pull request is merged
58 |
59 | After your pull request is merged, you can safely delete your branch and pull the changes
60 | from the main (upstream) repository:
61 |
62 | * Delete the remote branch on GitHub:
63 |
64 | ```shell
65 | git push origin --delete my-fix-branch
66 | ```
67 |
68 | * Check out the master branch:
69 |
70 | ```shell
71 | git checkout master -f
72 | ```
73 |
74 | * Delete the local branch:
75 |
76 | ```shell
77 | git branch -D my-fix-branch
78 | ```
79 |
80 | * Update your master with the latest upstream version:
81 |
82 | ```shell
83 | git pull --ff upstream master
84 | ```
85 |
86 | ## Code
87 |
88 | The most important need is that all code changes and contributions have unit tests.
89 |
90 | * Place unit tests in `/test`. They should require their code from `/lib`.
91 | * Unit tests should not require a build step. Feel free to use the latest Nodejs syntax.
92 | * The repo is set up to use Mocha and Chai.
93 | You can use any assertion style but most tests are presently using the assert style.
94 | * `npm test` will build, lint and test.
95 | This command needs to complete successfully before you submit a PR.
96 | * `npm run test:build` will build and test.
97 | * `npm run test:only` will just run the tests.
98 |
99 | The build:
100 |
101 | * Add your code to `/src`. The build step expands it into `/lib`.
102 | * Babel is set up to use plugin babel-preset-es2015. Add others if your really have to.
103 |
104 | Linting and docs:
105 |
106 | * The lint step uses ESLint with the AirBnB rule set.
107 | ESLint is the most popular JavaScript linting tool right now,
108 | and AirBnB’s style guide is the most widely-used style guide.
109 | * `npm run eslint` runs the linting.
110 | * Feel free to add JSDoc blocks for your new hooks as that helps us write documentation.
111 | * The code should immediately follow any JSDoc blocks.
112 | * JSDoc blocks are linted.
113 | Follow them by a blank line if you have linting issues, as that stops the block from being linted.
114 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Eddyystop
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # feathers-reduxify-authentication
2 | Wrap feathers-client.authentication so it works transparently with Redux, as well as authentication, authorization packages for React-Router.
3 |
4 | [](https://travis-ci.org/eddyystop/feathers-reduxify-authentication)
5 |
6 | - Work with standard `feathers-client.authentication` on the client.
7 | - Dispatch feathers authentication and logout to Redux.
8 | - Integrate with `react-router` and `react-router-redux`.
9 | - Use popular Redux, React-Router authentication and authorization packages for React routing.
10 |
11 | ## Code Examples
12 |
13 | - [What we want to be able to do](#todo)
14 | - [Making feathers-client.authentication work with Redux](#reduxifying)
15 | - [Working example](#workingexample)
16 |
17 | ### What we want to be able to do
18 |
19 | This is typical code for React routing and permissions.
20 |
21 | ```javascript
22 | import { UserAuthWrapper } from 'redux-auth-wrapper';
23 |
24 | // Define permissions
25 | const UserIsAuthenticated = UserAuthWrapper({
26 | authSelector: (state) => state.auth.user, // BEING ABLE TO DO THIS IS ONE REASON TO USE THIS REPO
27 | predicate: user => user && user.isVerified,
28 | ...
29 | });
30 | const UserIsAdmin = UserAuthWrapper({
31 | authSelector: (state) => state.auth.user, // BEING ABLE TO DO THIS IS ONE REASON TO USE THIS REPO
32 | predicate: user => user && user.isVerified && user.roles && user.roles.indexOf('admin') !== -1,
33 | ...
34 | });
35 |
36 | // React routing
37 |
38 |
39 |
40 |
43 |
46 |
47 |
48 |
49 | ```
50 |
51 | `require('feathers-client').authentication` cannot be used as-is in this scenario
52 | or other scenarios involving Redux-based projects.
53 |
54 | `feathers-reduxify-authentication` wraps feathers-client.authentication
55 | so it behaves transparently as 100% compatible Redux code.
56 |
57 | ### Making feathers-client.authentication work with Redux
58 |
59 | You wrap `require('feathers-client').authentication`, insert the wrapper's reducer
60 | into Redux's `combineReducers`, and use the wrapper's action creators with Redux's `dispatch`.
61 |
62 | Voila, 100% Redux compatible with the current user retained in Redux's `store`.
63 |
64 | ```javascript
65 | import feathers from 'feathers-client';
66 | import feathersReduxifyAuthentication from 'feathers-reduxify-authentication';
67 |
68 | // Configure feathers-client
69 | const app = feathers(). ... .configure(feathers.authentication({ ... });
70 |
71 | // Reduxify feathers-client.authentication
72 | feathersAuthentication = reduxifyAuthentication(app,
73 | { isUserAuthorized: (user) => user.isVerified } // WE INSIST USER IS 'verified' TO AUTHENTICATE
74 | );
75 |
76 | // Add to Redux reducer
77 | const rootReducer = combineReducers({ ..., auth: feathersAuthentication.reducer, ...});
78 |
79 | // Dispatch actions as needed. Params are the same as for feathers.authentication().
80 | dispatch(feathersAuthentication.authenticate({ type: 'local', email, password })).then().catch();
81 | dispatch(feathersAuthentication.logout());
82 | ```
83 |
84 | ### Working Example
85 |
86 | This package is used in
87 | [feathers-starter-react-redux-login-roles](https://github.com/eddyystop/feathers-starter-react-redux-login-roles)
88 | which implements full featured local authentication with user roles, email verification,
89 | forgotten passwords, etc.
90 |
91 | You can review how that project uses `feathers-reduxify-authentication`:
92 | - `client/feathers/index.js` configures feathers and reduxifies feathers-client.authentication.
93 | - `client/reducers/index.js` adds our authentication to Redux's reducers.
94 | Our current user will be stored at `state.auth.user`.
95 | - `client/index.js` sets up React routing and permissions.
96 | - `client/screens/Users/UserSignIn/FormContainer.js`
97 | both authenticates users and logs them out.
98 |
99 | ## Motivation
100 |
101 | - Feathers is a great real-time client-server framework.
102 | - Redux is a great state container for the front-end.
103 | - React is a great declarative UI.
104 | - React-Router is a complete routing library for React by React.
105 | - There are several packages
106 | which handle authentication and authorization for React-Router and Redux.
107 |
108 | This repo let's everyone work together easily.
109 |
110 | ## Installation
111 |
112 | Install [Nodejs](https://nodejs.org/en/).
113 |
114 | Run `npm install --save-dev feathers-reduxify-authentication` in your project folder.
115 |
116 | You can then:
117 |
118 | ```javascript
119 | // ES6
120 | import feathersReduxifyAuthentication from 'feathers-reduxify-authentication';
121 | // ES5
122 | const feathersReduxifyAuthentication = require('feathers-reduxify-authentication');
123 | ```
124 |
125 | `/src` on GitHub contains the ES6 source.
126 |
127 | ## API Reference
128 |
129 | Each module is fully documented.
130 |
131 | Also see [Working example](#workingexample) above.
132 |
133 | ## Build
134 |
135 | `npm test` to transpile the ES6 code in `/src` to ES5 in `/lib`.
136 |
137 | ## Contributing
138 |
139 | [Contribute to this repo.](./CONTRIBUTING.md)
140 |
141 | [Guide to ideomatic contributing.](https://github.com/jonschlinkert/idiomatic-contributing)
142 |
143 | ## Change Log
144 |
145 | [List of notable changes.](./CHANGELOG.md)
146 |
147 | ## License
148 |
149 | MIT. See LICENSE.
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "feathers-reduxify-authentication",
3 | "version": "1.0.0",
4 | "description": "Wrap feathers-client.authentication so it works with Redux, as well as authentication, authorization packages for React-Router.",
5 | "files": [
6 | "index.js",
7 | "test"
8 | ],
9 | "main": "lib/",
10 | "directories": {
11 | "lib": "lib"
12 | },
13 | "scripts": {
14 | "copy": "rm -rf lib/ && mkdir lib && cp -r src/ lib/",
15 | "babel": "babel src/ --out-dir lib --presets babel-preset-es2015,babel-preset-stage-0",
16 | "babel:watch": "babel src/ --watch --out-dir lib --presets babel-preset-es2015,babel-preset-stage-0",
17 | "mocha": "mocha test/ --reporter spec --compilers js:babel-core/register",
18 | "mocha:only": "mocha test/ --reporter spec",
19 | "eslint": "eslint src/. test/. --ext .js,.jsx .",
20 | "build": "npm run copy && npm run babel",
21 | "test": "npm run build && npm run eslint && npm run mocha",
22 | "test:build": "npm run build && npm run mocha",
23 | "test:only": "npm run eslint && npm run mocha:only",
24 | "cover": "node_modules/istanbul/lib/cli.js cover node_modules/mocha/bin/_mocha -- --reporter spec test/*",
25 | "watch": "npm run copy && npm run babel:watch",
26 | "git:push": "npm run build && git push origin && git push origin --tags",
27 | "npm:patch": "npm version patch && npm publish",
28 | "npm:minor": "npm version minor && npm publish",
29 | "npm:major": "npm version major && npm publish",
30 | "npm:updates": "npm-check-updates"
31 | },
32 | "repository": {
33 | "type": "git",
34 | "url": "git+https://github.com/eddyystop/feathers-reduxify-authentication.git"
35 | },
36 | "keywords": [
37 | "feathers",
38 | "feathersjs",
39 | "authentication",
40 | "react-router",
41 | "redux"
42 | ],
43 | "author": "John Szwaronek ",
44 | "license": "MIT",
45 | "bugs": {
46 | "url": "https://github.com/eddyystop/feathers-reduxify-authentication/issues"
47 | },
48 | "homepage": "https://github.com/eddyystop/feathers-reduxify-authentication#readme",
49 | "dependencies": {
50 | "debug": "^2.2.0",
51 | "object.assign": "^4.0.4"
52 | },
53 | "devDependencies": {
54 | "babel-cli": "^6.14.0",
55 | "babel-core": "^6.14.0",
56 | "babel-eslint": "^6.1.2",
57 | "babel-loader": "^6.2.5",
58 | "babel-plugin-add-module-exports": "^0.2.1",
59 | "babel-plugin-transform-es2015-destructuring": "^6.9.0",
60 | "babel-plugin-transform-object-rest-spread": "^6.8.0",
61 | "babel-plugin-transform-runtime": "^6.15.0",
62 | "babel-preset-es2015": "^6.14.0",
63 | "babel-preset-stage-0": "^6.5.0",
64 | "chai": "^3.5.0",
65 | "coveralls": "^2.11.12",
66 | "eslint": "^3.5.0",
67 | "eslint-config-airbnb": "^10.0.0",
68 | "eslint-plugin-import": "^1.15.0",
69 | "eslint-plugin-jsdoc": "^2.3.1",
70 | "eslint-plugin-jsx-a11y": "^2.2.2",
71 | "eslint-plugin-react": "^6.2.1",
72 | "istanbul": "^0.4.5",
73 | "mocha": "^3.0.2",
74 | "redux-actions": "0.12.0"
75 | },
76 | "engines": {
77 | "node": ">=5.0.0",
78 | "npm": ">=3.8.0"
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 |
2 | import { createAction, handleActions } from 'redux-actions';
3 | import makeDebug from 'debug';
4 |
5 | // handles situation where a logout is dispatched while an authentication is in progress
6 |
7 | export default (app, options = {}) => {
8 | const debug = makeDebug('reducer:authentication');
9 | debug('instantiate');
10 |
11 | const defaults = {
12 | isError: 'isError',
13 | isLoading: 'isLoading', // s/b compatible with feathers-reduxify-service::getServicesStatus
14 | isSignedIn: 'isSignedIn',
15 | user: 'user',
16 | token: 'token',
17 | PENDING: 'PENDING',
18 | FULFILLED: 'FULFILLED',
19 | REJECTED: 'REJECTED',
20 | isUserAuthorized: (/* user */) => true,
21 | assign: {
22 | verifyExpires: undefined,
23 | verifyToken: undefined,
24 | resetExpires: undefined,
25 | resetToken: undefined,
26 | },
27 | };
28 | const opts = Object.assign({}, defaults, options);
29 |
30 | const reducer = {
31 | [`SERVICES_AUTHENTICATION_AUTHENTICATE_${opts.PENDING}`]: (state, action) => {
32 | debug(`redux:SERVICES_AUTHENTICATION_AUTHENTICATE_${opts.PENDING}`, action);
33 | return ({
34 | ...state,
35 | [opts.isError]: null,
36 | [opts.isLoading]: true,
37 | [opts.isSignedIn]: false,
38 | [opts.user]: null,
39 | [opts.token]: null,
40 | ignorePendingAuth: false,
41 | });
42 | },
43 |
44 | [`SERVICES_AUTHENTICATION_AUTHENTICATE_${opts.FULFILLED}`]: (state, action) => {
45 | debug(`redux:SERVICES_AUTHENTICATION_AUTHENTICATE_${opts.FULFILLED}`, action);
46 | const user = action.payload.data;
47 |
48 | if (state.ignorePendingAuth) {
49 | // A logout was dispatched between the authentication being started and completed
50 | app.logout();
51 |
52 | return {
53 | ...state,
54 | [opts.isError]: null,
55 | [opts.isLoading]: false,
56 | [opts.isSignedIn]: false,
57 | [opts.data]: null,
58 | [opts.token]: null,
59 | ignorePendingAuth: false,
60 | };
61 | }
62 |
63 | if (!opts.isUserAuthorized(user)) {
64 | // feathers authenticated the user but the app is rejecting
65 | app.logout();
66 |
67 | return {
68 | ...state,
69 | [opts.isError]: new Error('User is not verified.'),
70 | [opts.isLoading]: false,
71 | [opts.isSignedIn]: false,
72 | [opts.data]: null,
73 | [opts.token]: null,
74 | ignorePendingAuth: false,
75 | };
76 | }
77 |
78 | return {
79 | ...state,
80 | [opts.isError]: null,
81 | [opts.isLoading]: false,
82 | [opts.isSignedIn]: true,
83 | [opts.user]: Object.assign({}, user, opts.assign),
84 | [opts.token]: action.payload[opts.token],
85 | ignorePendingAuth: false,
86 | };
87 | },
88 |
89 | [`SERVICES_AUTHENTICATION_AUTHENTICATE_${opts.REJECTED}`]: (state, action) => {
90 | debug(`redux:SERVICES_AUTHENTICATION_AUTHENTICATE_${opts.REJECTED}`, action);
91 | return {
92 | ...state,
93 | // action.payload = { name: "NotFound", message: "No record found for id 'G6HJ45'",
94 | // code:404, className: "not-found" }
95 | [opts.isError]: action.payload,
96 | [opts.isLoading]: false,
97 | [opts.isSignedIn]: false,
98 | [opts.data]: null,
99 | [opts.token]: null,
100 | ignorePendingAuth: false,
101 | };
102 | },
103 |
104 | SERVICES_AUTHENTICATION_LOGOUT: (state, action) => {
105 | debug('redux:SERVICES_AUTHENTICATION_LOGOUT', action);
106 | app.logout();
107 |
108 | return ({
109 | ...state,
110 | [opts.isError]: null,
111 | [opts.isLoading]: null,
112 | [opts.isSignedIn]: false,
113 | [opts.user]: null,
114 | [opts.token]: null,
115 | // Ignore the result if an authentication has been started
116 | ignorePendingAuth: state.isLoading,
117 | });
118 | },
119 |
120 | SERVICES_AUTHENTICATION_USER: (state, action) => {
121 | debug('redux:SERVICES_AUTHENTICATION_USER', action);
122 |
123 | let user = state[opts.user];
124 | if (user) {
125 | user = { ...user, ...action.payload };
126 | }
127 |
128 | return ({
129 | ...state,
130 | [opts.isError]: null,
131 | [opts.isLoading]: null,
132 | [opts.isSignedIn]: false,
133 | [opts.user]: user,
134 | // A logout may be dispatched between the authentication being started and completed
135 | ignorePendingAuth: false,
136 | });
137 | },
138 | };
139 |
140 | // ACTION TYPES
141 |
142 | const AUTHENTICATE = 'SERVICES_AUTHENTICATION_AUTHENTICATE';
143 | const LOGOUT = 'SERVICES_AUTHENTICATION_LOGOUT';
144 | const USER = 'SERVICES_AUTHENTICATION_USER';
145 |
146 | return {
147 | // ACTION CREATORS
148 | // Note: action.payload in reducer will have the value of .data below
149 | authenticate: createAction(
150 | AUTHENTICATE, (p) => ({ promise: app.authenticate(p), data: undefined })
151 | ),
152 | logout: createAction(LOGOUT),
153 | user: createAction(USER),
154 |
155 | // REDUCER
156 | reducer: handleActions(
157 | reducer,
158 | {
159 | [opts.isError]: null,
160 | [opts.isLoading]: false,
161 | [opts.isSignedIn]: false,
162 | [opts.user]: null,
163 | ignorePendingAuth: false,
164 | }
165 | ),
166 | };
167 | };
168 |
--------------------------------------------------------------------------------
/test/null_spec.js:
--------------------------------------------------------------------------------
1 |
2 | /* eslint no-shadow: 0, no-var: 0 */
3 |
4 | describe('feathers-reduxify-authentication', () => {
5 | it('no tests yet', () => {});
6 | });
7 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 |
2 | const webpack = require('webpack'); // eslint-disable-line import/no-unresolved
3 | const path = require('path');
4 |
5 | module.exports = {
6 | context: path.join(__dirname, './client'),
7 | entry: './index.js',
8 | output: {
9 | path: path.join(__dirname, './public/dist'),
10 | filename: 'bundle.js',
11 | },
12 | module: {
13 | loaders: [
14 | {
15 | test: /\.(js|jsx)$/,
16 | exclude: /node_modules/,
17 | loaders: [
18 | 'babel-loader',
19 | ],
20 | },
21 | ],
22 | },
23 | resolve: {
24 | extensions: ['', '.js', '.jsx'],
25 | },
26 | plugins: [
27 | new webpack.DefinePlugin({
28 | 'process.env': { NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development') },
29 | }),
30 | ],
31 | };
32 |
--------------------------------------------------------------------------------