Permalink
Browse files

1.0 Pre-release (#336)

* cleaning up dependencies

* removing auth redirects and exposing middleware

* expanding express middleware

* moving what I can in services to setup method

* updating dependencies

* cleaning up middleware and adding debug logs

* cleaning up services and adding debug logs

* changing options for populate user hook to conform with other options

* cleaning up main index file

* fixing lint errors

* getting example app working

* fixing options for populate user middlware

* fixing socket logout emitting

* restructuring so you can set hooks to construct your token payload if you want to customize it

* Default to a session cookie instead of 1 day

* Switch to "user" instead of "data" for the response from auth

* Make sure we clear the user out of locals so that you don't end up in a weird state.

* Allow passing options when creating a JWT.

Used to customize the type of token we want to generate (ie. confirmation, password reset, etc.)

* setting version

* don't throw an error in the decode token middleware

* bump version

* clearing cookie if use not found. Setting cookie age to same as JWT

* bump version

* Don’t mix options when signing tokens (#255)

Fixes #254.

* Attempt to get token right away. (#252)

* Attempt to get token right away.

This makes it so that we don’t have to wait for an async response in order to start making authenticated requests.

* Also set up localStorage.

* fix restrict to owner hook methods. Closes #228

* bump version

* cookies should get set regardless of whether it was an xhr request if enabled

* bumping version

* adding migration guide

* reorganizing middleware, hooks and services

* updaing mocha

* updating migration doc of things left to doc/complete

* fixing a bunch of the tests and adding tests for all new middleware

* cleaning up client side tests. Still failing

* getting all tests passing

* updating all middleware to not have default and pull from global config

* finished consolidating options

* bumping version

* adding more details to migration guide

* fix typo missing 'd'

* Fix typo and simplify wording.

* normalize the callbackURL

If the callbackURL doesn’t begin with a slash, the Passport `authenticate()` call will mess up the URL depending on the referrer’s url.  So if the page is `domain.com/auth/github`, the callback URL will become `domain.com/auth/auth/github`.  This normalizes the URL so that relative URLs always begin with a leading slash and absolute URLs don’t get touched.

* Make sure the provider plugin name doesn't overwrite the OAuth provider name

* consistency: `callbackUrl` should be `callbackURL`

* Normalize comparison URL & fix typo

This performs the same normalization to the comparison URL for the callback (as is done for the callbackURL).  Also fixes typo in callbackUrl, updates it to callbackURL.

* Always use service lookup.

Previously, we were setting up this._tokenService and this._userService in the `setup` function.  This was a problem because not all services are registered by the time `setup` runs.  In order to continue to allow the passing of either strings or an actual service object, this PR checks if we only have a string reference to the service stored.  If so, it uses the `app.service` method of service lookup before attempting to use the service.  This also fixes a problem that was occurring when trying to call this._userService or this._tokenService when this was undefined inside the middleware callbacks.

* DRY up the dynamic token and user service lookup.

This moves the dynamic service lookup to a function to be a bit more DRY.

* OAuth require successRedirect with default successHandler

If a successHandler hasn’t been passed, then the default `successHandler` will be used.  The `successRedirect` will now be required in that scenario.

* First cut for authentication middleware (#305)

* First cut for authentication middleware

* Fix service methods

* Allow passing user service and service name

* First cut for authentication middleware (#305)

* First cut for authentication middleware

* Fix service methods

* Allow passing user service and service name

* Cookies will match jwt expiry by default. (#308)

* Cookies will match jwt expiry by default.

* Add missing makeExpiry function.

* Store config at `app.config` (#312)

* Store config at `app.config`

* Use app.set to store config.

* Add test.

* adding instanbul code coverage

* Remove permissions hooks and middleware which will be put into feathers-permissions (#307)

* Started implementation of more modularized module structure

* Some reorganization

* Implement Socket new authentication

* More reorganization and start of integration tests

* eslint fix

* More integration tests and cleanup

* reogranizing

* Applying latest changes and merging with dev other branch

* Socket.io authentication tests and login logout event

* Improving socket tests and adding Primus

* Some cleanup

* Better error verification tests

* Implement login and logout events for REST authentication (#325)

* Fix tests

* wip

* first cut of auth working with passport. Clean up and tests to do

* fixing event middleware resolution

* Keep github together

* Keep twitter together

* getting tests passing. Still a couple more to do

* removing unused hooks for now. May bring some back later

* fixing lint errors

* removing hashPassword hook. It now lives in feathers-authentication-local

* adding a migration guide and new features docs

* adding more detail to migration doc

* cleaning up dependencies

* getting tests passing again

* adding some more tests. Implementing chained strategies

* cleaning up dependencies

* finishing integration tests and handling socket logout timeout

* cleaning up example app

* fixing up example

* updating README

* updating API docs
1 parent 69cd5f2 commit 97f8004ddf0abc802c218500fdbdffd7e2de1ade @ekryski ekryski committed on GitHub Nov 16, 2016
Showing with 4,712 additions and 6,508 deletions.
  1. +4 −1 .gitignore
  2. +2 −1 .jshintrc
  3. +1 −0 .npmignore
  4. +1 −0 .travis.yml
  5. +138 −37 README.md
  6. +208 −0 docs/migrating.md
  7. +203 −0 docs/new-1.0-features.md
  8. +12 −0 example/README.md
  9. +71 −76 example/app.js
  10. +0 −37 example/client.js
  11. +0 −185 example/public/index.html
  12. +1 −1 mocha.opts
  13. +31 −30 package.json
  14. +0 −20 src/client/hooks.js
  15. +0 −115 src/client/index.js
  16. +0 −109 src/client/utils.js
  17. +68 −0 src/express/authenticate.js
  18. +31 −0 src/express/emit-events.js
  19. +12 −0 src/express/expose-cookies.js
  20. +12 −0 src/express/expose-headers.js
  21. +23 −0 src/express/failure-redirect.js
  22. +17 −0 src/express/index.js
  23. +72 −0 src/express/set-cookie.js
  24. +18 −0 src/express/success-redirect.js
  25. +0 −41 src/hooks/associate-current-user.js
  26. +84 −0 src/hooks/authenticate.js
  27. +0 −146 src/hooks/has-role-or-restrict.js
  28. +0 −62 src/hooks/hash-password.js
  29. +3 −25 src/hooks/index.js
  30. +0 −104 src/hooks/populate-or-restrict.js
  31. +0 −46 src/hooks/populate-user.js
  32. +0 −30 src/hooks/query-with-current-user.js
  33. +0 −14 src/hooks/restrict-to-authenticated.js
  34. +0 −73 src/hooks/restrict-to-owner.js
  35. +0 −99 src/hooks/restrict-to-roles.js
  36. +0 −83 src/hooks/verify-or-restrict.js
  37. +0 −52 src/hooks/verify-token.js
  38. +48 −136 src/index.js
  39. +0 −140 src/middleware/express.js
  40. +0 −16 src/middleware/index.js
  41. +0 −86 src/middleware/sockets.js
  42. +28 −0 src/options.js
  43. +116 −0 src/passport/authenticate.js
  44. +21 −0 src/passport/index.js
  45. +21 −0 src/passport/initialize.js
  46. +0 −74 src/public/auth-fail.html
  47. +0 −87 src/public/auth-success.html
  48. +61 −0 src/service.js
  49. +0 −136 src/services/local.js
  50. +0 −205 src/services/oauth2.js
  51. +0 −160 src/services/token.js
  52. +194 −0 src/socket/handler.js
  53. +39 −0 src/socket/index.js
  54. +86 −0 src/utils.js
  55. +0 −226 test/client/index.test.js
  56. +243 −0 test/express/authenticate.test.js
  57. +76 −0 test/express/emit-events.test.js
  58. +34 −0 test/express/expose-cookies.test.js
  59. +34 −0 test/express/expose-headers.test.js
  60. +88 −0 test/express/failure-redirect.test.js
  61. +40 −0 test/express/index.test.js
  62. +161 −0 test/express/set-cookie.test.js
  63. +63 −0 test/express/success-redirect.test.js
  64. +97 −0 test/fixtures/server.js
  65. +37 −0 test/fixtures/strategy.js
  66. +254 −0 test/hooks/authenticate.test.js
  67. +16 −0 test/hooks/index.test.js
  68. +168 −0 test/index.test.js
  69. +292 −192 test/integration/primus.test.js
  70. +420 −295 test/integration/rest.test.js
  71. +0 −291 test/integration/socket-io.test.js
  72. +380 −0 test/integration/socketio.test.js
  73. +104 −0 test/options.test.js
  74. +223 −0 test/passport/authenticate.test.js
  75. +25 −0 test/passport/index.test.js
  76. +8 −0 test/passport/initialize.test.js
  77. +108 −0 test/service.test.js
  78. +21 −0 test/socket/index.test.js
  79. +0 −150 test/src/hooks/associate-current-user.test.js
  80. +0 −346 test/src/hooks/has-role-or-restrict.test.js
  81. +0 −174 test/src/hooks/hash-password.test.js
  82. +0 −56 test/src/hooks/index.test.js
  83. +0 −129 test/src/hooks/populate-or-restrict.test.js
  84. +0 −176 test/src/hooks/populate-user.test.js
  85. +0 −117 test/src/hooks/query-with-current-user.test.js
  86. +0 −77 test/src/hooks/restrict-to-authenticated.test.js
  87. +0 −204 test/src/hooks/restrict-to-owner.test.js
  88. +0 −287 test/src/hooks/restrict-to-roles.test.js
  89. +0 −208 test/src/hooks/verify-token-or-restrict.test.js
  90. +0 −176 test/src/hooks/verify-token.test.js
  91. +0 −534 test/src/index.test.js
  92. +0 −377 test/src/middleware.test.js
  93. +0 −66 test/test-server.js
  94. +194 −0 test/utils.test.js
View
@@ -28,4 +28,7 @@ node_modules
.lock-wscript
lib/
-data.db
+coverage/
+data.db
+_backup/
+yarn.lock
View
@@ -13,12 +13,13 @@
"quotmark": "single",
"regexp": true,
"undef": true,
- "unused": true,
+ "unused": false,
"strict": false,
"trailing": true,
"smarttabs": true,
"white": false,
"node": true,
+ "expr": true,
"globals": {
"window": true,
"it": true,
View
@@ -1,5 +1,6 @@
.editorconfig
.jshintrc
+.istanbul.yml
.travis.yml
.babelrc
.idea/
View
@@ -1,3 +1,4 @@
+sudo: false
language: node_js
node_js:
- node
View
@@ -9,7 +9,7 @@
> Add Authentication to your FeathersJS app.
-`feathers-authentication` adds shared [PassportJS](http://passportjs.org/) authentication for Feathers HTTP REST and WebSockets services using [JSON Web Tokens](http://jwt.io/).
+`feathers-authentication` adds shared [PassportJS](http://passportjs.org/) authentication for Feathers HTTP REST and WebSockets transports using [JSON Web Tokens](http://jwt.io/).
## Installation
@@ -20,55 +20,156 @@ npm install feathers-authentication --save
## Documentation
-Please refer to the [Authentication documentation](http://docs.feathersjs.com/authentication/readme.html) for more details:
+<!-- Please refer to the [Authentication documentation](http://docs.feathersjs.com/authentication/readme.html) for more details. -->
-- [Local Auth Tutorial](http://docs.feathersjs.com/authentication/local.html) - How to implement a username and password-based authentication.
-- [Use Hooks for Authorization](http://docs.feathersjs.com/authorization/readme.html) - Learn about the bundled hooks.
+## API
+This module contains:
-## Complete Example
+1. The main entry function
+2. An `authenticate` hook
+3. The authentication `service`
+4. Socket listeners
+5. Express middleware
+6. A [Passport](http://passportjs.org/) adapter
+
+### Hooks
-Here's an example of a Feathers server that uses `feathers-authentication` for local auth. It includes a `users` service that uses `feathers-mongoose`. *Note that it does NOT implement any authorization.*
+There is just 1 hook now called `authenticate`. This can be used to authenticate a service method with a given strategy.
```js
-import feathers from 'feathers';
-import hooks from 'feathers-hooks';
-import bodyParser from 'body-parser';
-import authentication from 'feathers-authentication';
-import { hooks as authHooks } from 'feathers-authentication';
-import mongoose from 'mongoose';
-import service from 'feathers-mongoose';
-
-const port = 3030;
-const Schema = mongoose.Schema;
-const UserSchema = new Schema({
- email: {type: String, required: true, unique: true},
- password: {type: String, required: true },
- createdAt: {type: Date, 'default': Date.now},
- updatedAt: {type: Date, 'default': Date.now}
+app.service('authentication').hooks({
+ before: {
+ create: [
+ // You can chain multiple strategies
+ auth.hooks.authenticate(['jwt', 'local']),
+ ],
+ remove: [
+ auth.hooks.authenticate('jwt')
+ ]
+ }
});
-let UserModel = mongoose.model('User', UserSchema);
+```
+
+
+### Express Middleware
+
+Just like hooks there is an `authenticate` middleware. It is used the exact same way you would the regular passport express middleware.
+
+```js
+app.post('/login', auth.express.authenticate('local', { successRedirect: '/app', failureRedirect: '/login' }));
+```
+
+The other middleware are included but typically you don't need to worry about them.
+
+- `emitEvents` - emit `login` and `logout` events
+- `exposeCookies` - expose cookies to Feathers so they are available to hooks and services
+- `exposeHeaders` - expose headers to Feathers so they are available to hooks and services
+- `failureRedirect` - support redirecting on auth failure. Only triggered if `hook.redirect` is set.
+- `successRedirect` - support redirecting on auth success. Only triggered if `hook.redirect` is set.
+- `setCookie` - support setting the JWT access token in a cookie. Only enabled if cookies are enabled.
+
+### Default Options
-mongoose.Promise = global.Promise;
-mongoose.connect('mongodb://localhost:27017/feathers');
+The following default options will be mixed in with your global `auth` object from your config file. It will set the mixed options back to to the app so that they are available at any time by `app.get('auth')`. They can all be overridden and are depended upon by some of the authentication plugins.
-let app = feathers()
- .configure(feathers.rest())
- .configure(feathers.socketio())
+```js
+{
+ path: '/authentication', // the authentication service path
+ header: 'Authorization', // the header to use when using JWT auth
+ entity: 'user', // the entity that will be added to the request, socket, and hook.params. (ie. req.user, socket.user, hook.params.user)
+ service: 'users', // the service to look up the entity
+ passReqToCallback: true, // whether the request object should be passed to the strategies `verify` function
+ session: false, // whether to use sessions
+ cookie: {
+ enabled: false, // whether the cookie should be enabled
+ name: 'feathers-jwt', // the cookie name
+ httpOnly: false, // whether the cookie should not be available to client side JavaScript
+ secure: true // whether cookies should only be available over HTTPS
+ },
+ jwt: {
+ header: { typ: 'access' }, // by default is an access token but can be any type
+ audience: 'https://yourdomain.com', // The resource server where the token is processed
+ subject: 'anonymous', // Typically the entity id associated with the JWT
+ issuer: 'feathers', // The issuing server, application or resource
+ algorithm: 'HS256', // the algorithm to use
+ expiresIn: '1d' // the access token expiry
+ }
+}
+```
+
+## Complementary Plugins
+
+The following plugins are complementary but entirely optional:
+
+- [feathers-authentication-client](https://github.com/feathersjs/feathers-authentication-client)
+- [feathers-authentication-local](https://github.com/feathersjs/feathers-authentication-local)
+- [feathers-authentication-jwt](https://github.com/feathersjs/feathers-authentication-jwt)
+- [feathers-authentication-oauth1](https://github.com/feathersjs/feathers-authentication-oauth1)
+- [feathers-authentication-oauth2](https://github.com/feathersjs/feathers-authentication-oauth2)
+- [feathers-permissions](https://github.com/feathersjs/feathers-permissions)
+
+## Migrating to 1.0
+Refer to [the migration guide](./docs/migrating.md).
+
+## Complete Example
+Here's an example of a Feathers server that uses `feathers-authentication` for local auth.
+
+**Note:** This does NOT implement any authorization. Use [feathers-permissions](https://github.com/feathersjs/feathers-permissions) for that.
+
+```js
+const feathers = require('feathers');
+const rest = require('feathers-rest');
+const socketio = require('feathers-socketio');
+const hooks = require('feathers-hooks');
+const memory = require('feathers-memory');
+const bodyParser = require('body-parser');
+const errors = require('feathers-errors');
+const errorHandler = require('feathers-errors/handler');
+const local = require('feathers-authentication-local');
+const jwt = require('feathers-authentication-jwt');
+const auth = require('feathers-authentication');
+
+const app = feathers();
+app.configure(rest())
+ .configure(socketio())
.configure(hooks())
.use(bodyParser.json())
.use(bodyParser.urlencoded({ extended: true }))
- // Configure feathers-authentication
- .configure(authentication());
-
-app.use('/users', new service('user', {Model: UserModel}))
+ .configure(auth({ secret: 'supersecret' }))
+ .configure(local())
+ .configure(jwt())
+ .use('/users', memory())
+ .use('/', feathers.static(__dirname + '/public'))
+ .use(errorHandler());
+
+app.service('authentication').hooks({
+ before: {
+ create: [
+ // You can chain multiple strategies
+ auth.hooks.authenticate(['jwt', 'local']),
+ customizeJWTPayload()
+ ],
+ remove: [
+ auth.hooks.authenticate('jwt')
+ ]
+ }
+});
-let userService = app.service('users');
-userService.before({
- create: [authHooks.hashPassword('password')]
+// Add a hook to the user service that automatically replaces
+// the password with a hash of the password before saving it.
+app.service('users').hooks({
+ before: {
+ find: [
+ auth.hooks.authenticate('jwt')
+ ],
+ create: [
+ local.hooks.hashPassword({ passwordField: 'password' })
+ ]
+ }
});
-let server = app.listen(port);
+let server = app.listen(3030);
server.on('listening', function() {
console.log(`Feathers application started on localhost:${port}`);
});
@@ -84,7 +185,7 @@ import feathers from 'feathers/client';
import hooks from 'feathers-hooks';
import socketio from 'feathers-socketio/client';
import localstorage from 'feathers-localstorage';
-import authentication from 'feathers-authentication/client';
+import authentication from 'feathers-authentication-client';
const socket = io('http://localhost:3030/');
const app = feathers()
@@ -93,7 +194,7 @@ const app = feathers()
.configure(authentication({ storage: window.localStorage }));
app.authenticate({
- type: 'local',
+ strategy: 'local',
'email': 'admin@feathersjs.com',
'password': 'admin'
}).then(function(result){
Oops, something went wrong.

0 comments on commit 97f8004

Please sign in to comment.