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

feathers-authentication-client

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

feathers-authentication-client - npm Package Compare versions

Comparing version 0.1.0 to 0.1.1

6

example/primus-client.js

@@ -0,3 +1,9 @@

// This is an example of using the client on the server with Node.js.
// Most of the code is the same for the browser with the exception
// of how modules are imported and configured. It depends on how you choose
// to load them. Refer to the client section of docs.feathersjs.com for more detail.
// NOTE (EK): You need to uncomment the primus setup
// and comment out the socket.io setup inside app.js
// in order for this to work with the example app.

@@ -4,0 +10,0 @@ const feathers = require('feathers/client');

@@ -0,1 +1,6 @@

// This is an example of using the client on the server with Node.js.
// Most of the code is the same for the browser with the exception
// of how modules are imported and configured. It depends on how you choose
// to load them. Refer to the client section of docs.feathersjs.com for more detail.
//
const feathers = require('feathers/client');

@@ -2,0 +7,0 @@ const rest = require('feathers-rest/client');

@@ -0,1 +1,6 @@

// This is an example of using the client on the server with Node.js.
// Most of the code is the same for the browser with the exception
// of how modules are imported and configured. It depends on how you choose
// to load them. Refer to the client section of docs.feathersjs.com for more detail.
const feathers = require('feathers/client');

@@ -2,0 +7,0 @@ const socketio = require('feathers-socketio/client');

2

lib/hooks/populate-entity.js

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

return app.authentication.verifyJWT(hook.result.accessToken).then(function (payload) {
return app.passport.verifyJWT(hook.result.accessToken).then(function (payload) {
var id = payload[options.field];

@@ -38,0 +38,0 @@

@@ -6,4 +6,24 @@ 'use strict';

});
exports.default = init;
exports.default = function () {
var _hooks = require('./hooks');
var _hooks2 = _interopRequireDefault(_hooks);
var _passport = require('./passport');
var _passport2 = _interopRequireDefault(_passport);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var defaults = {
header: 'authorization',
cookie: 'feathers-jwt',
storageKey: 'feathers-jwt',
path: '/authentication',
entity: 'user',
service: 'users'
};
function init() {
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

@@ -38,23 +58,5 @@

};
};
}
var _hooks = require('./hooks');
var _hooks2 = _interopRequireDefault(_hooks);
var _passport = require('./passport');
var _passport2 = _interopRequireDefault(_passport);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var defaults = {
header: 'authorization',
cookie: 'feathers-jwt',
storageKey: 'feathers-jwt',
path: '/authentication',
entity: 'user',
service: 'users'
};
init.defaults = defaults;
module.exports = exports['default'];

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

var _utils = require('./utils');
var _jwtDecode = require('jwt-decode');
var _jwtDecode2 = _interopRequireDefault(_jwtDecode);
var _debug = require('debug');
var _debug2 = _interopRequireDefault(_debug);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -20,2 +26,4 @@

var debug = (0, _debug2.default)('feathers-authentication-client');
var Passport = function () {

@@ -27,32 +35,116 @@ function Passport(app, options) {

this.app = app;
this.storage = app.get('storage') || this.getStorage(options.storage);
if (!app.get('storage')) {
var storage = (0, _utils.getStorage)(options.storage);
app.set('storage', storage);
}
this.setJWT = this.setJWT.bind(this);
this.getJWT().then(function (accessToken) {
if (accessToken) {
app.set('accessToken', accessToken);
app.get('storage').setItem(options.storageKey, accessToken);
}
});
app.set('storage', this.storage);
this.getJWT().then(this.setJWT);
}
_createClass(Passport, [{
key: 'connected',
value: function connected() {
var _this = this,
_arguments = arguments;
var app = this.app;
return new Promise(function (resolve, reject) {
if (app.rest) {
return resolve();
}
var socket = app.io || app.primus;
if (!socket) {
return reject(new Error('It looks like your client connection has not been configured.'));
}
// If the socket is not connected yet we have to wait for the `connect` event
if (app.io && !socket.connected || app.primus && socket.readyState !== 3) {
var connected = app.primus ? 'open' : 'connect';
debug('Waiting for socket connection');
socket.on(connected, function () {
debug('Socket connected');
var emit = app.io ? 'emit' : 'send';
var disconnect = app.io ? 'disconnect' : 'end';
var reconnecting = app.io ? 'reconnecting' : 'reconnect';
var reconnected = app.io ? 'reconnect' : 'reconnected';
// If one of those events happens before `connect` the promise will be rejected
// If it happens after, it will do nothing (since Promises can only resolve once)
socket.on(disconnect, function () {
debug('Socket disconnected');
socket.authenticated = false;
socket.removeAllListeners();
});
socket.on(reconnecting, function () {
debug('Socket reconnecting');
});
socket.on(reconnected, function () {
debug('Socket reconnected');
// If socket was already authenticated then re-authenticate
// it with the server automatically.
if (socket.authenticated) {
var data = {
strategy: 'jwt',
accessToken: app.get('accessToken')
};
_this.authenticateSocket(data, socket, emit).then(_this.setJWT).catch(function (error) {
debug('Error re-authenticating after socket upgrade', error);
socket.authenticated = false;
app.emit('reauthentication-error', error);
});
}
});
if (socket.io) {
socket.io.engine.on('upgrade', function () {
debug('Socket upgrading', _arguments);
// If socket was already authenticated then re-authenticate
// it with the server automatically.
if (socket.authenticated) {
var data = {
strategy: 'jwt',
accessToken: app.get('accessToken')
};
_this.authenticateSocket(data, socket, emit).then(_this.setJWT).catch(function (error) {
debug('Error re-authenticating after socket upgrade', error);
socket.authenticated = false;
app.emit('reauthentication-error', error);
});
}
});
}
resolve(socket);
});
} else {
debug('Socket already connected');
resolve(socket);
}
});
}
}, {
key: 'authenticate',
value: function authenticate() {
var _this = this;
var _this2 = this;
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var credentials = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var app = this.app;
var getData = Promise.resolve(data);
var getCredentials = Promise.resolve(credentials);
// If no strategy was given let's try to authenticate with a stored JWT
if (!data.strategy) {
if (data.accessToken) {
data.strategy = 'jwt';
if (!credentials.strategy) {
if (credentials.accessToken) {
credentials.strategy = 'jwt';
} else {
getData = this.getJWT().then(function (accessToken) {
getCredentials = this.getJWT().then(function (accessToken) {
if (!accessToken) {

@@ -66,40 +158,46 @@ return Promise.reject(new _feathersErrors2.default.NotAuthenticated('Could not find stored JWT and no authentication strategy was given'));

var handleResponse = function handleResponse(response) {
if (response.accessToken) {
app.set('accessToken', response.accessToken);
app.get('storage').setItem(_this.options.storageKey, response.accessToken);
}
return Promise.resolve(response);
};
return getData.then(function (data) {
return (0, _utils.connected)(app).then(function (socket) {
return getCredentials.then(function (credentials) {
return _this2.connected(app).then(function (socket) {
if (app.rest) {
return app.service(_this.options.path).create(data).then(handleResponse);
return app.service(_this2.options.path).create(credentials).then(_this2.setJWT);
}
var method = app.io ? 'emit' : 'send';
return (0, _utils.authenticateSocket)(data, socket, method).then(handleResponse);
var emit = app.io ? 'emit' : 'send';
return _this2.authenticateSocket(credentials, socket, emit).then(_this2.setJWT);
});
});
}
// Returns a promise that authenticates a socket
}, {
key: 'getJWT',
value: function getJWT() {
var _this2 = this;
key: 'authenticateSocket',
value: function authenticateSocket(credentials, socket, emit) {
return new Promise(function (resolve, reject) {
debug('Attempting to authenticate socket');
socket[emit]('authenticate', credentials, function (error, data) {
if (error) {
return reject(error);
}
var app = this.app;
return new Promise(function (resolve) {
var accessToken = app.get('accessToken');
if (accessToken) {
return resolve(accessToken);
}
(0, _utils.retrieveJWT)(_this2.options.storageKey, _this2.options.cookie, app.get('storage')).then(resolve);
socket.authenticated = true;
debug('Socket authenticated!');
resolve(data);
});
});
}
}, {
key: 'verifyJWT',
value: function verifyJWT(data) {
return (0, _utils.verifyJWT)(data);
key: 'logoutSocket',
value: function logoutSocket(socket, emit) {
return new Promise(function (resolve, reject) {
socket[emit]('logout', function (error) {
if (error) {
reject(error);
}
socket.authenticated = false;
resolve();
});
});
}

@@ -109,6 +207,8 @@ }, {

value: function logout() {
var _this3 = this;
var app = this.app;
app.set('accessToken', null);
(0, _utils.clearCookie)(this.options.cookie);
this.clearCookie(this.options.cookie);

@@ -122,6 +222,119 @@ // remove the accessToken from localStorage

return (0, _utils.logoutSocket)(socket, method);
return _this3.logoutSocket(socket, method);
}
});
}
}, {
key: 'setJWT',
value: function setJWT(data) {
var accessToken = data && data.accessToken ? data.accessToken : data;
if (accessToken) {
this.app.set('accessToken', accessToken);
this.app.get('storage').setItem(this.options.storageKey, accessToken);
}
return Promise.resolve(data);
}
}, {
key: 'getJWT',
value: function getJWT() {
var _this4 = this;
var app = this.app;
return new Promise(function (resolve) {
var accessToken = app.get('accessToken');
if (accessToken) {
return resolve(accessToken);
}
return Promise.resolve(_this4.storage.getItem(_this4.options.storageKey)).then(function (jwt) {
var token = jwt || _this4.getCookie(_this4.options.cookie);
if (token && token !== 'null' && !_this4.payloadIsValid((0, _jwtDecode2.default)(token))) {
token = undefined;
}
return resolve(token);
});
});
}
// Pass a jwt token, get back a payload if it's valid.
}, {
key: 'verifyJWT',
value: function verifyJWT(token) {
if (typeof token !== 'string') {
return Promise.reject(new Error('Token provided to verifyJWT is missing or not a string'));
}
try {
var payload = (0, _jwtDecode2.default)(token);
if (this.payloadIsValid(payload)) {
return Promise.resolve(payload);
}
return Promise.reject(new Error('Invalid token: expired'));
} catch (error) {
return Promise.reject(new Error('Cannot decode malformed token.'));
}
}
// Pass a decoded payload and it will return a boolean based on if it hasn't expired.
}, {
key: 'payloadIsValid',
value: function payloadIsValid(payload) {
return payload && payload.exp * 1000 > new Date().getTime();
}
}, {
key: 'getCookie',
value: function getCookie(name) {
if (typeof document !== 'undefined') {
var value = '; ' + document.cookie;
var parts = value.split('; ' + name + '=');
if (parts.length === 2) {
return parts.pop().split(';').shift();
}
}
return null;
}
}, {
key: 'clearCookie',
value: function clearCookie(name) {
if (typeof document !== 'undefined') {
document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}
return null;
}
// Returns a storage implementation
}, {
key: 'getStorage',
value: function getStorage(storage) {
if (storage) {
return storage;
}
return {
store: {},
getItem: function getItem(key) {
return this.store[key];
},
setItem: function setItem(key, value) {
return this.store[key] = value;
},
removeItem: function removeItem(key) {
delete this.store[key];
return this;
}
};
}
}]);

@@ -128,0 +341,0 @@

{
"name": "feathers-authentication-client",
"description": "The authentication plugin for feathers-client",
"version": "0.1.0",
"version": "0.1.1",
"homepage": "https://github.com/feathersjs/feathers-authentication-client",

@@ -6,0 +6,0 @@ "main": "lib/",

@@ -41,2 +41,22 @@ # feathers-authentication-client

### Handling the special re-authentication errors
In the event that your server goes down or the client loses connectivity, it will automatically handle attempting to re-authenticate the socket when the client regains connectivity with the server. In order to handle an authentication failure during automatic re-authentication you need to implement the following event listener:
```js
const errorHandler = error => {
app.authenticate({
strategy: 'local',
email: 'admin@feathersjs.com',
password: 'admin'
}).then(response => {
// You are now authenticated again
});
};
// Handle when auth fails during a reconnect or a transport upgrade
app.on('reauthentication-error', errorHandler)
```
### Default Options

@@ -43,0 +63,0 @@

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