New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

feathers-authentication

Package Overview
Dependencies
Maintainers
3
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

feathers-authentication - npm Package Compare versions

Comparing version 1.0.0-beta to 1.0.0-beta-1

docs/examples/username-and-email.md

213

docs/migrating.md

@@ -30,3 +30,26 @@ # Migrating to 1.0

// feathers-authentication < v0.8.0
// In your config files
{
"auth": {
"token": {
"secret": "xxxx"
},
"local": {},
"facebook": {
"clientID": "<your client id>",
"clientSecret": "<your client secret>",
"permissions": {
"scope": ["public_profile","email"]
}
}
}
}
// In your authentication service
const authentication = require('feathers-authentication');
const FacebookStrategy = require('passport-facebook').Strategy;
let config = app.get('auth');
config.facebook.strategy = FacebookStrategy;
app.configure(authentication(config))

@@ -40,2 +63,16 @@ .use('/users', memory()) // this use to be okay to be anywhere

// feathers-authentication >= v1.0.0
// In your config files
{
"auth": {
"secret": "xxxx"
"facebook": {
"clientID": "<your client id>",
"clientSecret": "<your client secret>",
"scope": ["public_profile","email"]
}
}
}
// In your app or authentication service, wherever you would like
const authentication = require('feathers-authentication');

@@ -46,10 +83,25 @@ const local = require('feathers-authentication-local');

const oauth2 = require('feathers-authentication-oauth2');
const FacebookStrategy = require('passport-facebook').Strategy;
// The services you are setting the `entity` param for need to be registered before authentication
app.use('/users', memory())
.configure(authentication(config))
.configure(jwt(config))
.configure(local(config))
.configure(oauth1(config))
.configure(oauth2(config))
.configure(authentication(app.get('auth')))
.configure(jwt())
.configure(local())
.configure(oauth1())
.configure(oauth2({
name: 'facebook', // if the name differs from your config key you need to pass your config options explicitly
Strategy: FacebookStrategy
}));
// Authenticate the user using the a JWT or
// email/password strategy and if successful
// return a new JWT access token.
app.service('authentication').hooks({
before: {
create: [
auth.hooks.authenticate(['jwt', 'local'])
]
}
});
```

@@ -63,3 +115,3 @@

- Move `auth.token.secret` -> `auth.secret`
- `auth.token.payload` option has been removed. See [customizing JWT payload]() for how to do this.
- `auth.token.payload` option has been removed. See [customizing JWT payload](#customizing-jwt-payload) for how to do this.
- `auth.idField` has been removed. It is now included in all services so we can pull it internally without you needing to specify it.

@@ -72,3 +124,33 @@ - `auth.shouldSetupSuccessRoute` has been removed. Success redirect middleware is registered automatically but only triggers if you explicitly set a redirect. [See redirecting]() for more details.

- Cookies are now disabled by default. If you need cookie support (ie. OAuth, Server Side Rendering, Redirection) then you need to explicitly enable it by setting `auth.cookie.enable = true`.
- When setting up an OAuth strategy it used to be `strategy: FacebookStrategy` and is now capitalized `Strategy: FacebookStrategy`.
- Any passport strategy options are flattened. So previously you would have had this in your config:
```json
{
"auth": {
"facebook": {
"clientID": "<your client id>",
"clientSecret": "<your client secret>",
"permissions": {
"scope": ["public_profile","email"]
}
}
}
}
```
and now you have:
```json
{
"auth": {
"facebook": {
"clientID": "<your client id>",
"clientSecret": "<your client secret>",
"scope": ["public_profile","email"]
}
}
}
```
## Setting up authentication on the client

@@ -111,9 +193,19 @@

password: 'admin'
}).then(function(result){
console.log('Authenticated!', result);
return app.service('users').get(result.payload.id).then(user => {
app.set('user', user);
});
}).catch(function(error){
})
.then(response => {
console.log('Authenticated!', response);
// By this point your accessToken has been stored in
// localstorage
return app.passport.verifyJWT(response.accessToken);
})
.then(payload => {
console.log('JWT Payload', payload);
return app.service('users').get(payload.id);
})
.then(user => {
app.set('user', user);
console.log('User', client.get('user'));
// Do whatever you want now
})
.catch(function(error){
console.error('Error authenticating!', error);

@@ -132,15 +224,40 @@ });

We previously made the poor assumption that you are always authenticating a user. This is not always be the case, or your app may not care about the current user as you have their id or can encode some details in the JWT. Therefore, if you need to get the current user you need to request it explicitly after authentication or populate it yourself in an after hook.
We previously made the poor assumption that you are always authenticating a user. This is not always the case, or your app may not care about the current user as you already have their id in the accessToken payload or can encode some additional details in the JWT accessToken. Therefore, if you need to get the current user you need to request it explicitly after authentication or populate it yourself in an after hook server side. See the new usage above for how to fetch your user.
### Fetching User Explicitly
## Customizing JWT Payload
TODO
By default the payload for your JWT is simply your entity id (ie. `{ userId }`). However, you can customize your JWT payloads however you wish by adding a `before` hook to the authentication service. For example:
### Populating User Explicitly
```js
// This hook customizes your payload.
function customizeJWTPayload() {
return function(hook) {
console.log('Customizing JWT Payload');
hook.data.payload = {
// You need to make sure you have the right id.
// You can put whatever you want to be encoded in
// the JWT access token.
customId: hook.params.user.id
};
TODO
return Promise.resolve(hook);
};
}
// Authenticate the user using the a JWT or
// email/password strategy and if successful
// return a new JWT access token.
app.service('authentication').hooks({
before: {
create: [
auth.hooks.authenticate(['jwt', 'local']),
customizeJWTPayload()
]
}
});
```
## JWT Parsing
The JWT is only parsed from the header and body by default now. It is no longer pulled from the query string.
The JWT is only parsed from the header and body by default now. It is no longer pulled from the query string unless you explicitly tell `feathers-authentication-jwt` to do so.

@@ -178,3 +295,3 @@ You can customize the header and body keys like so:

- `restrictToAuthenticated` -> use new `feathers-permissions` plugin
- `hashPassword` -> has been moved to `feathers-authentication-local`
- `hashPassword` -> has been moved to `feathers-authentication-local` **This is important.**
- `populateUser` -> use new `populate` hook in `feathers-hooks-common`

@@ -191,2 +308,3 @@ - `verifyToken` -> use new `feathers-authentication-jwt` plugin to easily validate a JWT access token. You can also now call `app.passport.verifyJWT` anywhere in your app to do it explicitly.

// feathers-authentication < v0.8.0
// Users service
const auth = require('feathers-authentication').hooks;

@@ -206,3 +324,18 @@ exports.before = {

auth.restrictToOwner({ ownerField: '_id' })
]
],
create: [
auth.hashPassword()
],
update: [
auth.verifyToken(),
auth.populateUser(),
auth.restrictToAuthenticated(),
auth.hashPassword()
],
patch: [
auth.verifyToken(),
auth.populateUser(),
auth.restrictToAuthenticated(),
auth.hashPassword()
],
}

@@ -216,13 +349,41 @@ ```

const authentication = require('feathers-authentication');
const local = require('feathers-authentication-local');
const permissions = require('feathers-permissions');
const myCustomQueryWithCurrentUser = function(options ={}) {
return function(hook) {
hook.params.query.userId = hook.params.user._id;
return Promise.resolve(hook);
};
};
exports.before = {
all: [
all: [],
find: [
authentication.hooks.authenticate('jwt'),
permissions.hooks.checkPermissions({service: 'users', on: 'user', field: 'permissions'}),
permissions.hooks.checkPermissions({ service: 'users' }),
permissions.hooks.isPermitted(),
myCustomQueryWithCurrentUser() // instead of auth.queryWithCurrentUser()
],
get: [
authentication.hooks.authenticate('jwt'),
permissions.hooks.checkPermissions({ service: 'users' }),
permissions.hooks.isPermitted()
],
find: [
myCustomQueryWithCurrentUser() // instead of auth.queryWithCurrentUser()
]
create: [
local.hooks.hashPassword()
],
update: [
authentication.hooks.authenticate('jwt'),
permissions.hooks.checkPermissions({ service: 'users' }),
permissions.hooks.isPermitted(),
local.hooks.hashPassword()
],
patch: [
authentication.hooks.authenticate('jwt'),
permissions.hooks.checkPermissions({ service: 'users' }),
permissions.hooks.isPermitted(),
local.hooks.hashPassword()
],
}
```

28

docs/new-1.0-features.md

@@ -9,15 +9,15 @@ # New 1.0 Features

```js
// when calling from hooks
auth.hooks.authenticate('local', { assignProperty: 'custom' })
// when calling from middleware
auth.express.authenticate('local', { assignProperty: 'custom' })
// For sockets and all other methods you can have it in your main
// config or pass explicitly when initializing auth.
app.configure(authentication({
local: {
assignProperty: 'custom'
}
}))
```
```js
// when calling from hooks
auth.hooks.authenticate('local', { assignProperty: 'custom' })
// when calling from middleware
auth.express.authenticate('local', { assignProperty: 'custom' })
// For sockets and all other methods you can have it in your main
// config or pass explicitly when initializing auth.
app.configure(authentication({
local: {
assignProperty: 'custom'
}
}))
```

@@ -204,2 +204,2 @@ ## More warnings and debugging

### In Hooks/Services
If you need this information in a hook or service you can access the current currently authenticated entity (ie. user) and whether they are authenticated by inspecting `hook.params.<entity>` (ie. `hook.params.user`) and `hooks.params.authenticated` respectively.
If you need this information in a hook or service you can access the current currently authenticated entity (ie. user) and whether they are authenticated by inspecting `hook.params.<entity>` (ie. `hook.params.user`) and `hooks.params.authenticated` respectively.

@@ -13,12 +13,2 @@ const feathers = require('feathers');

function customizeJWTPayload() {
return function(hook) {
hook.data.payload = {
id: hook.params.user.id
};
return Promise.resolve(hook);
};
}
const app = feathers();

@@ -40,4 +30,3 @@ app.configure(rest())

// You can chain multiple strategies
auth.hooks.authenticate(['jwt', 'local']),
customizeJWTPayload()
auth.hooks.authenticate(['jwt', 'local'])
],

@@ -44,0 +33,0 @@ remove: [

@@ -35,4 +35,2 @@ 'use strict';

debug('passport.authenticate called with the following options', passport, name, strategyOptions, callback);
// This is called by the feathers middleware, hook or socket. The request object

@@ -50,3 +48,3 @@ // is a mock request derived from an http request, socket object, or hook.

var failures = [];
var strategies = [name];
var strategies = void 0;

@@ -63,4 +61,8 @@ // Cast `name` to an array, allowing authentication to pass through a chain of

// redirect will halt the chain.
if (Array.isArray(name)) {
if (request.strategy) {
strategies = [request.strategy];
} else if (Array.isArray(name)) {
strategies = name;
} else {
strategies = [name];
}

@@ -115,9 +117,9 @@

strategy.success = function (data, info) {
strategy.success = function (data, payload) {
var _data;
debug('\'' + layer + '\' authentication strategy succeeded', data, info);
debug('\'' + layer + '\' authentication strategy succeeded', data, payload);
resolve({
success: true,
data: (_data = {}, _defineProperty(_data, entity, data), _defineProperty(_data, 'info', info), _data)
data: (_data = {}, _defineProperty(_data, entity, data), _defineProperty(_data, 'payload', payload), _data)
});

@@ -124,0 +126,0 @@ };

@@ -32,6 +32,21 @@ 'use strict';

// Expose our JWT util functions globally
passport._feathers = {};
passport.createJWT = _utils.createJWT;
passport.verifyJWT = _utils.verifyJWT;
passport.options = function (name, strategyOptions) {
if (!name) {
return passport._feathers;
}
if (typeof name === 'string' && !strategyOptions) {
return passport._feathers[name];
}
if (typeof name === 'string' && strategyOptions) {
debug('Setting ' + name + ' strategy options', strategyOptions);
passport._feathers[name] = Object.assign({}, strategyOptions);
}
};
};
}
module.exports = exports['default'];

@@ -37,4 +37,8 @@ 'use strict';

key: 'create',
value: function create(data, params) {
value: function create() {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var defaults = this.app.get('auth');
var payload = (0, _lodash2.default)(data.payload, params.payload);

@@ -45,3 +49,3 @@ // create accessToken

// TODO (EK): This service can be datastore backed to support blacklists :)
return this.passport.createJWT(data.payload, (0, _lodash2.default)(defaults, params)).then(function (accessToken) {
return this.passport.createJWT(payload, (0, _lodash2.default)(defaults, params)).then(function (accessToken) {
return { accessToken: accessToken };

@@ -48,0 +52,0 @@ });

@@ -113,3 +113,5 @@ 'use strict';

var promise = app.authenticate(strategy, options[strategy])(socket._feathers).then(function (result) {
var stategyOptions = app.passport.options(strategy);
var promise = app.authenticate(strategy, stategyOptions)(socket._feathers).then(function (result) {
if (result.success) {

@@ -119,7 +121,7 @@ // NOTE (EK): I don't think we need to support

// and let the client redirect.
// if (options.successRedirect) {
// if (stategyOptions.successRedirect) {
// return {
// redirect: true,
// status: 302,
// url: options.successRedirect
// url: stategyOptions.successRedirect
// };

@@ -134,7 +136,7 @@ // }

// and let the client redirect.
// if (options.failureRedirect) {
// if (stategyOptions.failureRedirect) {
// return {
// redirect: true,
// status: 302,
// url: options.failureRedirect
// url: stategyOptions.failureRedirect
// };

@@ -145,3 +147,3 @@ // }

var message = options.failureMessage || challenge && challenge.message;
var message = stategyOptions.failureMessage || challenge && challenge.message;

@@ -148,0 +150,0 @@ return Promise.reject(new _feathersErrors2.default[401](message, challenge));

@@ -17,2 +17,6 @@ 'use strict';

var _lodash3 = require('lodash.omit');
var _lodash4 = _interopRequireDefault(_lodash3);
var _jsonwebtoken = require('jsonwebtoken');

@@ -43,3 +47,3 @@

// TODO (EK): Support jwtids. Maybe auto-generate a uuid
_jsonwebtoken2.default.sign(payload, secret, (0, _lodash2.default)(settings, VALID_KEYS), function (error, token) {
_jsonwebtoken2.default.sign((0, _lodash4.default)(payload, VALID_KEYS), secret, (0, _lodash2.default)(settings, VALID_KEYS), function (error, token) {
if (error) {

@@ -46,0 +50,0 @@ debug('Error signing JWT', error);

{
"name": "feathers-authentication",
"description": "Add Authentication to your FeathersJS app.",
"version": "1.0.0-beta",
"version": "1.0.0-beta-1",
"homepage": "https://github.com/feathersjs/feathers-authentication",

@@ -86,5 +86,5 @@ "main": "lib/",

"socket.io-client": "^1.4.8",
"superagent": "^2.3.0",
"superagent": "^3.0.0",
"ws": "^1.1.1"
}
}

@@ -150,4 +150,3 @@ # feathers-authentication

// You can chain multiple strategies
auth.hooks.authenticate(['jwt', 'local']),
customizeJWTPayload()
auth.hooks.authenticate(['jwt', 'local'])
],

@@ -154,0 +153,0 @@ remove: [

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc