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 0.8.0-beta-1 to 0.8.0-beta-2

lib/base.js

2

lib/client/hooks.js

@@ -25,3 +25,3 @@ 'use strict';

function populateHeader() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -28,0 +28,0 @@ return function (hook) {

@@ -8,5 +8,5 @@ 'use strict';

exports.default = function () {
var opts = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var config = Object.assign({}, defaults, opts);
var options = Object.assign({}, defaults, opts);

@@ -16,82 +16,6 @@ return function () {

if (!app.get('storage')) {
var storage = (0, _utils.getStorage)(config.storage);
app.set('storage', storage);
}
app.authentication = new _authentication2.default(app, options);
app.authenticate = app.authentication.authenticate.bind(app.authentication);
app.logout = app.authentication.logout.bind(app.authentication);
// load any pre-existing JWT from localStorage
(0, _utils.getJWT)(config.tokenKey, config.cookie, app.get('storage')).then(function (token) {
app.set('token', token);
app.get('storage').setItem(config.tokenKey, token);
});
app.authenticate = function () {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var getOptions = Promise.resolve(options);
// If no type was given let's try to authenticate with a stored JWT
if (!options.type) {
getOptions = (0, _utils.getJWT)(config.tokenKey, config.cookie, app.get('storage')).then(function (token) {
if (!token) {
return Promise.reject(new _feathersErrors2.default.NotAuthenticated('Could not find stored JWT and no authentication type was given'));
}
return { type: 'token', token: token };
});
}
var handleResponse = function handleResponse(response) {
app.set('token', response.token);
app.set('user', response.user);
return Promise.resolve(app.get('storage').setItem(config.tokenKey, response.token)).then(function () {
return response;
});
};
return getOptions.then(function (options) {
var endPoint = void 0;
if (options.type === 'local') {
endPoint = config.localEndpoint;
} else if (options.type === 'token') {
endPoint = config.tokenEndpoint;
} else {
throw new Error('Unsupported authentication \'type\': ' + options.type);
}
return (0, _utils.connected)(app).then(function (socket) {
// TODO (EK): Handle OAuth logins
// If we are using a REST client
if (app.rest) {
return app.service(endPoint).create(options).then(handleResponse);
}
var method = app.io ? 'emit' : 'send';
return (0, _utils.authenticateSocket)(options, socket, method).then(handleResponse);
});
});
};
// Set our logout method with the correct socket context
app.logout = function () {
app.set('user', null);
app.set('token', null);
(0, _utils.clearCookie)(config.cookie);
// remove the token from localStorage
return Promise.resolve(app.get('storage').removeItem(config.tokenKey)).then(function () {
// If using sockets de-authenticate the socket
if (app.io || app.primus) {
var method = app.io ? 'emit' : 'send';
var socket = app.io ? app.io : app.primus;
return (0, _utils.logoutSocket)(socket, method);
}
});
};
// Set up hook that adds token and user to params so that

@@ -110,3 +34,3 @@ // it they can be accessed by client side hooks and services

app.mixins.push(function (service) {
service.before(hooks.populateHeader(config));
service.before(hooks.populateHeader(options));
});

@@ -117,6 +41,2 @@ }

var _feathersErrors = require('feathers-errors');
var _feathersErrors2 = _interopRequireDefault(_feathersErrors);
var _hooks = require('./hooks');

@@ -126,8 +46,10 @@

var _utils = require('./utils');
var _authentication = require('./authentication');
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
var _authentication2 = _interopRequireDefault(_authentication);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
var defaults = {

@@ -134,0 +56,0 @@ cookie: 'feathers-jwt',

@@ -11,4 +11,13 @@ 'use strict';

exports.clearCookie = clearCookie;
exports.getJWT = getJWT;
exports.verifyJWT = verifyJWT;
exports.payloadIsValid = payloadIsValid;
exports.retrieveJWT = retrieveJWT;
exports.getStorage = getStorage;
var _jwtDecode = require('jwt-decode');
var _jwtDecode2 = _interopRequireDefault(_jwtDecode);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Returns a promise that resolves when the socket is connected

@@ -90,12 +99,36 @@ function connected(app) {

// Tries the JWT from the given key either from a storage or the cookie
function getJWT(tokenKey, cookieKey, storage) {
// Pass a jwt token, get back a payload if it's valid.
function verifyJWT(data) {
return new Promise(function (resolve, reject) {
var token = typeof data === 'string' ? data : data.token;
if (token) {
try {
var payload = (0, _jwtDecode2.default)(token);
if (payloadIsValid(payload)) {
resolve(payload);
} else {
reject(new Error('Invalid token: expired'));
}
} catch (error) {
reject(new Error('Cannot decode malformed token.'));
}
} else {
reject(new Error('No token provided to verifyJWT'));
}
});
}
// Pass a decoded payload and it will return a boolean based on if it hasn't expired.
function payloadIsValid(payload) {
return payload && payload.exp * 1000 > new Date().getTime();
}
// Tries the JWT from the given key either from a storage or the cookie.
function retrieveJWT(tokenKey, cookieKey, storage) {
return Promise.resolve(storage.getItem(tokenKey)).then(function (jwt) {
var cookieToken = getCookie(cookieKey);
if (cookieToken) {
return cookieToken;
var token = jwt || getCookie(cookieKey);
if (token && token !== 'null' && !payloadIsValid((0, _jwtDecode2.default)(token))) {
token = undefined;
}
return jwt;
return token;
});

@@ -102,0 +135,0 @@ }

@@ -27,3 +27,3 @@ 'use strict';

function associateAuthenticated() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -30,0 +30,0 @@ return function (hook) {

@@ -21,3 +21,3 @@ 'use strict';

function hashPassword() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -24,0 +24,0 @@ return function (hook) {

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

var _isPermitted = require('./is-permitted');
var _isPermitted2 = _interopRequireDefault(_isPermitted);
var _parseToken = require('./parse-token');

@@ -36,6 +32,2 @@

var _checkPermissions = require('./check-permissions');
var _checkPermissions2 = _interopRequireDefault(_checkPermissions);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -49,5 +41,3 @@

isAuthenticated: _isAuthenticated2.default,
isPermitted: _isPermitted2.default,
parseToken: _parseToken2.default,
checkPermissions: _checkPermissions2.default
parseToken: _parseToken2.default
};

@@ -54,0 +44,0 @@

@@ -25,3 +25,3 @@ 'use strict';

function loadAuthenticated() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -28,0 +28,0 @@ return function (hook) {

@@ -21,3 +21,3 @@ 'use strict';

function parseToken() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -24,0 +24,0 @@ return function (hook) {

@@ -21,3 +21,3 @@ 'use strict';

function queryWithAuthenticated() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -24,0 +24,0 @@ return function (hook) {

@@ -6,3 +6,3 @@ 'use strict';

});
exports.default = auth;
exports.default = init;

@@ -17,6 +17,2 @@ var _debug = require('debug');

var _lodash = require('lodash.merge');
var _lodash2 = _interopRequireDefault(_lodash);
var _hooks = require('./hooks');

@@ -42,2 +38,10 @@

var _options = require('./options');
var _options2 = _interopRequireDefault(_options);
var _base = require('./base');
var _base2 = _interopRequireDefault(_base);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

@@ -49,57 +53,11 @@

// Options that apply to any provider
// Exposed modules
function init() {
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var middleware = [];
// Exposed modules
var defaults = {
header: 'Authorization',
setupMiddleware: true, // optional - to setup middleware yourself set to false.
cookie: { // Used for redirects, server side rendering and OAuth
enabled: false, // Set to true to enable all cookies
name: 'feathers-jwt',
httpOnly: true,
maxAge: '1d',
secure: true
},
token: {
name: 'token', // optional
service: '/auth/token', // optional string or Service
subject: 'auth', // optional
issuer: 'feathers', // optional
algorithm: 'HS256', // optional
expiresIn: '1d', // optional
secret: null, // required
successRedirect: null, // optional - no default. If set the default success handler will redirect to location
failureRedirect: null, // optional - no default. If set the default success handler will redirect to location
successHandler: null // optional - a middleware to handle things once authentication succeeds
},
local: {
service: '/auth/local', // optional string or Service
successRedirect: null, // optional - no default. If set the default success handler will redirect to location
failureRedirect: null, // optional - no default. If set the default success handler will redirect to location
successHandler: null, // optional - a middleware to handle things once authentication succeeds
passReqToCallback: true, // optional - whether request should be passed to callback
session: false // optional - whether we should use a session
},
user: {
service: '/users', // optional string or Service
idField: '_id', // optional
usernameField: 'email', // optional
passwordField: 'password' // optional
},
oauth2: {
// service: '/auth/facebook', // required - the service path or initialized service
passReqToCallback: true, // optional - whether request should be passed to callback
// callbackUrl: 'callback', // optional - the callback url, by default this gets set to /<service>/callback
permissions: {
state: true,
session: false
}
}
};
function authentication() {
var _app$authentication;
function auth() {
var config = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
return function () {
var app = this;

@@ -109,3 +67,3 @@ var _super = app.setup;

// Merge and flatten options
var authOptions = (0, _lodash2.default)({}, defaults, app.get('auth'), config);
var authOptions = (0, _options2.default)(app.get('auth'), config);

@@ -115,4 +73,4 @@ // NOTE (EK): Currently we require token based auth so

// provider then we'll set up a sane default for them.
if (!authOptions.token.secret) {
throw new Error('You must provide a token secret in your config via \'auth.token.secret\'.');
if (!authOptions.secret && !authOptions.token.secret) {
throw new Error('You must provide a \'secret\' in your authentication configuration');
}

@@ -142,3 +100,3 @@

app.use(mw.tokenParser(authOptions));
// Verify and decode a JWT if it is present
// Verify and decode a JWT if it is present
app.use(mw.verifyToken(authOptions));

@@ -177,11 +135,22 @@ // Make the Passport user available for REST services.

};
app.authentication = new _base2.default(app, authOptions);
(_app$authentication = app.authentication).use.apply(_app$authentication, middleware);
}
authentication.use = function () {
middleware.push.apply(middleware, arguments);
return authentication;
};
return authentication;
}
// Exposed Modules
auth.hooks = _hooks2.default;
auth.middleware = mw;
auth.LocalService = _local2.default;
auth.TokenService = _token2.default;
auth.OAuth2Service = _oauth2.default;
init.hooks = _hooks2.default;
init.middleware = mw;
init.LocalService = _local2.default;
init.TokenService = _token2.default;
init.OAuth2Service = _oauth2.default;
module.exports = exports['default'];

@@ -45,10 +45,2 @@ 'use strict';

var _isPermitted = require('./rest/is-permitted');
var _isPermitted2 = _interopRequireDefault(_isPermitted);
var _checkPermissions = require('./rest/check-permissions');
var _checkPermissions2 = _interopRequireDefault(_checkPermissions);
var _logout = require('./rest/logout');

@@ -71,4 +63,2 @@

isAuthenticated: _isAuthenticated2.default,
isPermitted: _isPermitted2.default,
checkPermissions: _checkPermissions2.default,
logout: _logout2.default,

@@ -75,0 +65,0 @@ setupSocketIOAuthentication: _sockets.setupSocketIOAuthentication,

@@ -17,3 +17,3 @@ 'use strict';

function logout() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -20,0 +20,0 @@ debug('Registering logout middleware');

@@ -17,3 +17,3 @@ 'use strict';

function notAuthenticated() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -20,0 +20,0 @@ debug('Registering notAuthenticated middleware');

@@ -23,3 +23,3 @@ 'use strict';

function populateUser() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -26,0 +26,0 @@ debug('Registering populateUser middleware');

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

function setCookie() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
debug('Registering setCookie middleware');
function makeExpiry(timeframe) {
return new Date(Date.now() + (0, _ms2.default)(timeframe));
}
return function (req, res, next) {

@@ -63,6 +67,10 @@ var app = req.app;

if (options.expires === undefined && options.maxAge) {
var expiry = new Date(Date.now() + (0, _ms2.default)(options.maxAge));
options.expires = expiry;
options.expires = makeExpiry(options.maxAge);
}
// By default, the cookie will expire with the token.
if (options.expires === undefined && options.maxAge === undefined) {
options.expires = makeExpiry(options.token.expiresIn);
}
if (options.expires && !(options.expires instanceof Date)) {

@@ -69,0 +77,0 @@ throw new Error('cookie.expires must be a valid Date object');

@@ -17,3 +17,3 @@ 'use strict';

function successRedirect() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -20,0 +20,0 @@ debug('Registering successRedirect middleware');

@@ -25,3 +25,3 @@ 'use strict';

function tokenParser() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -28,0 +28,0 @@ debug('Registering tokenParser middleware');

@@ -20,3 +20,3 @@ 'use strict';

module.exports = function verifyToken() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -23,0 +23,0 @@ debug('Registering verifyToken middleware');

@@ -89,3 +89,3 @@ 'use strict';

socket.on('logout', function () {
var callback = arguments.length <= 0 || arguments[0] === undefined ? function () {} : arguments[0];
var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};

@@ -119,3 +119,3 @@ // TODO (EK): Blacklist token

function setupSocketIOAuthentication(app) {
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

@@ -130,3 +130,3 @@ debug('Setting up Socket.io authentication middleware with options:', options);

function setupPrimusAuthentication(app) {
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

@@ -133,0 +133,0 @@ debug('Setting up Primus authentication middleware with options:', options);

@@ -46,3 +46,3 @@ 'use strict';

function LocalService() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -49,0 +49,0 @@ _classCallCheck(this, LocalService);

@@ -10,2 +10,3 @@ 'use strict';

exports.normalizeCallbackURL = normalizeCallbackURL;
exports.default = init;

@@ -31,2 +32,8 @@

var _url = require('url');
var _url2 = _interopRequireDefault(_url);
var _feathersCommons = require('feathers-commons');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -42,3 +49,3 @@

function OAuth2Service() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -78,2 +85,3 @@ _classCallCheck(this, OAuth2Service);

var id = user[idField];
var userService = this.getUserService();

@@ -86,3 +94,3 @@ debug('Updating user: ' + id);

// TODO (EK): Handle paginated services?
return this._userService.patch(id, data, { oauth: true });
return userService.patch(id, data, { oauth: true });
}

@@ -94,5 +102,6 @@ }, {

var id = data[provider + 'Id'];
var userService = this.getUserService();
debug('Creating new user with ' + provider + 'Id: ' + id);
return this._userService.create(data, { oauth: true });
return userService.create(data, { oauth: true });
}

@@ -107,5 +116,6 @@ }, {

var query = _defineProperty({}, options.provider + 'Id', profile.id);
var userService = this.getUserService();
// Find or create the user since they could have signed up via facebook.
this._userService.find({ query: query }).then(this.getFirstUser).then(function (user) {
userService.find({ query: query }).then(this.getFirstUser).then(function (user) {
var _Object$assign;

@@ -132,2 +142,12 @@

}
}, {
key: 'getUserService',
value: function getUserService() {
return typeof this._userService === 'string' ? this.app.service(this._userService) : this._userService;
}
}, {
key: 'getTokenService',
value: function getTokenService() {
return typeof this._tokenService === 'string' ? this.app.service(this._tokenService) : this._tokenService;
}

@@ -148,5 +168,8 @@ // GET /auth/facebook

value: function get(id, params) {
// Make sure the provider plugin name doesn't overwrite the OAuth provider name.
delete params.provider;
var tokenService = this.getTokenService();
var options = Object.assign({}, this.options, params);
if (options.service + '/' + id !== options.callbackUrl) {
if ('/' + (0, _feathersCommons.stripSlashes)(options.service) + '/' + id !== options.callbackURL) {
return Promise.reject(new _feathersErrors2.default.NotFound());

@@ -170,3 +193,3 @@ }

// Get a new JWT and the associated user from the Auth token service and send it back to the client.
return this._tokenService.create(tokenPayload, { user: user }).then(resolve).catch(reject);
return tokenService.create(tokenPayload, { user: user }).then(resolve).catch(reject);
});

@@ -185,2 +208,3 @@

var options = this.options;
var tokenService = this.getTokenService();

@@ -206,4 +230,4 @@ if (!options.tokenStrategy) {

// Get a new JWT and the associated user from the Auth token service and send it back to the client.
return this._tokenService.create(tokenPayload, { user: user }).then(resolve).catch(reject);
});
return tokenService.create(tokenPayload, { user: user }).then(resolve).catch(reject);
}).bind(this);

@@ -220,8 +244,5 @@ middleware(params.req, params.res);

var tokenService = this.options.token.service;
var userService = this.options.user.service;
this._tokenService = this.options.token.service;
this._userService = this.options.user.service;
this._tokenService = typeof tokenService === 'string' ? app.service(tokenService) : tokenService;
this._userService = typeof userService === 'string' ? app.service(userService) : userService;
// Register our Passport auth strategy and get it to use our passport callback function

@@ -251,2 +272,19 @@ var Strategy = this.options.strategy;

/*
* Make sure the callbackURL is an absolute URL or relative to the root.
*/
function normalizeCallbackURL(callbackURL, servicePath) {
if (callbackURL) {
var parsed = _url2.default.parse(callbackURL);
if (!parsed.protocol) {
callbackURL = '/' + (0, _feathersCommons.stripSlashes)(callbackURL);
}
} else {
callbackURL = callbackURL || '/' + (0, _feathersCommons.stripSlashes)(servicePath) + '/callback';
}
return callbackURL;
}
function init(options) {

@@ -258,5 +296,9 @@ if (!options.provider) {

if (!options.service) {
throw new Error('You need to provide an \'service\' for your ' + options.provider + ' provider. This can either be a string or an initialized service.');
throw new Error('You need to provide an \'service\' for your ' + options.provider + ' OAuth provider. This can either be a string or an initialized service.');
}
if (!options.successHandler && !options.successRedirect) {
throw new Error('You need to provide a \'successRedirect\' URL for your ' + options.provider + ' OAuth provider when using the default successHandler.');
}
if (!options.strategy) {

@@ -277,3 +319,3 @@ throw new Error('You need to provide a Passport \'strategy\' for your ' + options.provider + ' provider');

options = (0, _lodash2.default)({ user: {} }, app.get('auth'), app.get('auth').oauth2, options);
options.callbackURL = options.callbackURL || options.service + '/callback';
options.callbackURL = normalizeCallbackURL(options.callbackURL, options.service);

@@ -280,0 +322,0 @@ if (options.token === undefined) {

@@ -45,3 +45,3 @@ 'use strict';

var _verifyToken = function _verifyToken() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -79,3 +79,3 @@ var secret = options.token.secret;

function TokenService() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -82,0 +82,0 @@ _classCallCheck(this, TokenService);

@@ -56,3 +56,3 @@ # Migrating from 0.7 to 0.8

auth.isAuthenticated(),
auth.checkPermissions({entity: 'user', has: 'users', field: 'permissions'}),
auth.checkPermissions({namespace: 'users', on: 'user', field: 'permissions'}),
auth.isPermitted()

@@ -71,4 +71,3 @@ ]

mw.checkPermissions({
entity: 'user',
has: 'admin',
on: 'user',
field: 'permissions',

@@ -91,3 +90,3 @@ permissions

auth.isAuthenticated(),
auth.hasPermissions('admin', { field: 'role'})
auth.checkPermissions({namespace: 'admin', on: 'user', field: 'role'})
]

@@ -207,4 +206,23 @@ });

TODO
TODO (EK): We currently set them up automatically by default but may enforce middleware to be registered explicitly.
### All cookies are httpOnly
There is no longer a JS accessible cookie. in most cases this is an implementation detail and not something you were likely aware of. However, if you were relying on accessing the JWT access token inside the JS accessible cookie then it is no more.
We've found that all authentication can happen using an `httpOnly` cookie instead of having the short lived JS accessible cookie. This is not only more secure as you are no longer susceptible to XSS attacks but are also more flexible.
Scenarios where you need to use a cookie:
- OAuth
- Universal app server side rendering
- Old school server side template rendering
- Redirects to other domains or apps after authentication
To support all of these use cases we needed to encode the auth token a cookie. The other option is to put the token in the query string (which is insecure).
Previously we had the feathers client parse the token from a short lived JS accessible cookie. However, we've since realized that if you make an ajax call the cookie will be sent along in the header and we can verify it on the server side. If you make a socket call the initial socket connection will also have the cookie and we can verify it. So in all cases we can simply use an `httpOnly` cookie and parse the token out of it server side.
If you are doing your authentication over AJAX or sockets in the first place then there is no need for a cookie at all and the client will just store the token in localstorage and use it until logged out or expired.
### You no longer register some hooks

@@ -243,5 +261,5 @@

### Response to `app.uthenticate()` returns `user`
### Response to `app.authenticate()` does not return `user`
The authenticate call is not a typical service call. It doesn't support batch calls as you can't authenticate multiple users and it returns both the token and the authenticated user. Assigning the user object to `response.data` doesn't makes it harder for you to add your own custom data to the authentication response. For those reasons and to make it easier for people to find the logged in `user` in the response, `response.data` is now `response.user` when authenticating.
We previously made the assumption that you are always authenticating a user. This may 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.

@@ -252,5 +270,4 @@ ### Removed Configuration Options

We've changed up some of the possible authentication options.
We've changed up some of the possible authentication options. You can view all the available options in the main [`index.js`](./src/index.js) file.
- `cookie`
-

@@ -264,3 +281,3 @@

The following hooks have been remove:
The following hooks have been removed:

@@ -274,2 +291,2 @@ - `restrictToOwner`

You should now use single `checkPermissions` and `isPermitted` hook (or middleware) as shown above.
You should now use single `checkPermissions` and `isPermitted` hook (or middleware) as shown above.
{
"name": "feathers-authentication",
"description": "Add Authentication to your FeathersJS app.",
"version": "0.8.0-beta-1",
"version": "0.8.0-beta-2",
"homepage": "https://github.com/feathersjs/feathers-authentication",

@@ -39,4 +39,5 @@ "main": "lib/",

"jshint": "jshint src/. test/. --config",
"mocha": "mocha --recursive test/ --compilers js:babel-core/register",
"test": "npm run compile && npm run jshint && npm run mocha && nsp check"
"mocha": "mocha --opts mocha.opts",
"coverage": "istanbul cover _mocha -- --opts mocha.opts",
"test": "npm run compile && npm run jshint && npm run coverage && nsp check"
},

@@ -53,4 +54,6 @@ "directories": {

"debug": "^2.2.0",
"feathers-commons": "^0.7.5",
"feathers-errors": "^2.4.0",
"jsonwebtoken": "^7.1.9",
"jwt-decode": "^2.1.0",
"lodash.intersection": "^4.4.0",

@@ -77,2 +80,3 @@ "lodash.isplainobject": "^4.0.6",

"feathers-socketio": "^1.3.2",
"istanbul": "^1.1.0-alpha.1",
"jshint": "^2.9.3",

@@ -79,0 +83,0 @@ "localstorage-memory": "^1.0.2",

# feathers-authentication
[![Build Status](https://travis-ci.org/feathersjs/feathers-authentication.png?branch=master)](https://travis-ci.org/feathersjs/feathers-authentication)
[![Code Climate](https://codeclimate.com/github/feathersjs/feathers-authentication/badges/gpa.svg)](https://codeclimate.com/github/feathersjs/feathers-authentication)
[![Test Coverage](https://codeclimate.com/github/feathersjs/feathers-authentication/badges/coverage.svg)](https://codeclimate.com/github/feathersjs/feathers-authentication/coverage)
[![Issue Count](https://codeclimate.com/github/feathersjs/feathers-authentication/badges/issue_count.svg)](https://codeclimate.com/github/feathersjs/feathers-authentication)

@@ -5,0 +8,0 @@ > Add Authentication to your FeathersJS app.

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