Socket
Socket
Sign inDemoInstall

autohost

Package Overview
Dependencies
172
Maintainers
4
Versions
110
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.0.0 to 3.0.0

6

.eslintrc.js

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

"use strict";
module.exports = {

@@ -7,3 +9,3 @@ extends: [ "leankit", "leankit/es6" ],

"global-require": 0,
"max-statements": [ "error", { "max": 35 } ]
"max-statements": [ "error", { max: 35 } ]
},

@@ -13,2 +15,2 @@ parserOptions: {

}
};
};

@@ -0,1 +1,20 @@

## 3.x
### 3.0.0
* Removed unused dependencies
* Updated multer
* Updated whistlepunk
* Updated passport and conditionally add passport session middleware based on changes to passport
* Updated socket.io
* Updated passport to 0.5.3
* Updated query-string dep
* Updated sinon/chai related deps
* Updated more dev deps
* Updated some dev deps
* Added a few updated dependencies
* Updated to latest semver versions
* Removed a couple of unneeded dependencies
* Updated node version
## 2.x

@@ -2,0 +21,0 @@

{
"name": "autohost",
"version": "2.0.0",
"version": "3.0.0",
"description": "Resource driven, transport agnostic host",
"main": "src/index.js",
"dependencies": {
"body-parser": "^1.14.1",
"cookie-parser": "^1.4.0",
"express": "~4.17.0",
"express-session": "^1.12.1",
"fount": "1.0.1",
"lodash": "^4.17.20",
"multer": "^1.1.0",
"body-parser": "^1.20.1",
"cookie-parser": "^1.4.6",
"express": "^4.18.2",
"express-session": "^1.17.3",
"fount": "^1.1.5",
"lodash": "^4.17.21",
"multer": "^1.4.5-lts.1",
"node-uuid": "~1.4.3",
"parseurl": "~1.3.0",
"passport": "^0.3.2",
"postal": "~1.0.2",
"query-string": "^3.0.0",
"passport": "^0.6.0",
"postal": "^2.0.6",
"query-string": "^7.1.1",
"request": "^2.88.2",
"socket.io": "^2.3.0",
"socket.io": "^4.5.3",
"websocket": "~1.0.22",
"when": "~3.7.2",
"whistlepunk": "^1.0.0"
"whistlepunk": "^2.0.0"
},
"devDependencies": {
"chai": "^3.4.1",
"chai-as-promised": "^5.1.0",
"connect-redis": "^3.0.1",
"debug": "^2.1.3",
"eslint": "^4.2.0",
"eslint-config-leankit": "^4.0.0",
"mocha": "^8.2.1",
"nodemon": "^1.11.0",
"chai": "^4.3.6",
"chai-as-promised": "^7.1.1",
"eslint-config-leankit": "^6.0.0",
"mocha": "^10.1.0",
"nodemon": "^2.0.20",
"nyc": "^15.1.0",

@@ -38,8 +35,6 @@ "passport-http": "^0.3.0",

"passport-strategy": "^1.0.0",
"proxyquire": "^1.8.0",
"redis": "^2.4.2",
"sinon": "^4.2.2",
"sinon-as-promised": "^4.0.0",
"sinon-chai": "^2.12.0",
"socket.io-client": "^2.3.1"
"proxyquire": "^2.1.3",
"sinon": "^14.0.1",
"sinon-chai": "^3.7.0",
"socket.io-client": "^4.5.3"
},

@@ -46,0 +41,0 @@ "scripts": {

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

var _ = require( 'lodash' );
var path = require( 'path' );
var _ = require('lodash');
var path = require('path');
var port = 8988;

@@ -10,14 +10,14 @@ var defaults = {

module.exports = function setup( config ) {
config = _.defaults( config, defaults );
require( './log' )( config.log );
module.exports = function setup(config) {
config = _.defaults(config, defaults);
require('./log')(config.log);
var authProvider;
var hasAuth = !config.noAuth;
if ( hasAuth ) {
authProvider = require( './mock/auth' )( config );
if ( config.defaultUser ) {
if (hasAuth) {
authProvider = require('./mock/auth')(config);
if (config.defaultUser) {
authProvider.tokens = { 'one': 'userone' };
authProvider.users = {
'userone': { name: 'userone', password: 'pass', roles: [ 'user' ] },
'userone': { name: 'userone', password: 'pass', roles: ['user'] },
};

@@ -27,5 +27,5 @@ }

var autohost = require( './index' );
var autohost = require('./index');
config.authProvider = authProvider;
var host = autohost( config );
var host = autohost(config);
var httpAdapter = host.transport.adapters.http;

@@ -36,10 +36,10 @@ var socketAdapter = host.transport.adapters.ws;

var middleware = host.middleware;
var actionRoles = function( action, roles ) {
if ( authProvider ) {
authProvider.actions[ action ] = { roles: roles };
var actionRoles = function (action, roles) {
if (authProvider) {
authProvider.actions[action] = { roles: roles };
}
};
var addAction = function( resourceName, actionName, handle, method, url, topic, resourceMiddleware, actionMiddleware ) {
var fqn = [ resourceName, actionName ].join( '.' );
var addAction = function (resourceName, actionName, handle, method, url, topic, resourceMiddleware, actionMiddleware) {
var fqn = [resourceName, actionName].join('.');
httpAdapter.action(

@@ -67,39 +67,39 @@ { name: resourceName, middleware: resourceMiddleware },

);
actionRoles( fqn, [] );
actionRoles(fqn, []);
};
var addMiddleware = function( url, mw, alias ) {
http.middleware( url, mw, alias );
var addMiddleware = function (url, mw, alias) {
http.middleware(url, mw, alias);
};
var addResource = function( resource, resourcePath ) {
httpAdapter.resource( resource, resourcePath || './', {} );
socketAdapter.resource( resource );
_.each( resource.actions, function( action, actionName ) {
actionRoles( [ resource.name, actionName ].join( '.' ), [] );
} );
var addResource = function (resource, resourcePath) {
httpAdapter.resource(resource, resourcePath || './', {});
socketAdapter.resource(resource);
_.each(resource.actions, function (action, actionName) {
actionRoles([resource.name, actionName].join('.'), []);
});
};
var addRoute = function( url, method, handle ) {
http.route( url, method, handle );
var addRoute = function (url, method, handle) {
http.route(url, method, handle);
};
var addPath = function( url, opts ) {
var addPath = function (url, opts) {
var options = typeof opts === 'string' ? { path: opts } : opts;
options.path = path.join( __dirname, options.path );
http.static( url, options );
options.path = path.join(__dirname, options.path);
http.static(url, options);
};
var addTopic = function( topic, handle ) {
socket.on( topic, handle );
var addTopic = function (topic, handle) {
socket.on(topic, handle);
};
var addUser = function( name, password, token, roles ) {
authProvider.users[ name ] = { name: name, password: password, roles: roles || [] };
authProvider.tokens[ token ] = name;
var addUser = function (name, password, token, roles) {
authProvider.users[name] = { name: name, password: password, roles: roles || [] };
authProvider.tokens[token] = name;
};
var clearUsers = function() {
var clearUsers = function () {
authProvider.users = {};
if ( httpAdapter.passport ) {
if (httpAdapter.passport) {
httpAdapter.passport.resetUserCheck();

@@ -109,7 +109,7 @@ }

var userRoles = function( user, roles ) {
if ( authProvider.users[ user ] ) {
authProvider.users[ user ].roles = roles;
var userRoles = function (user, roles) {
if (authProvider.users[user]) {
authProvider.users[user].roles = roles;
} else {
authProvider.users[ user ] = { roles: roles };
authProvider.users[user] = { roles: roles };
}

@@ -120,25 +120,25 @@ };

var ioClients = [];
var io = require( 'socket.io-client' );
var WebSocketClient = require( 'websocket' ).client;
var io = require('socket.io-client');
var WebSocketClient = require('websocket').client;
var getIOClient = function( address, opts ) {
var getIOClient = function (address, opts) {
opts = opts || {};
opts.multiplex = false;
var ioClient = io( address, opts );
ioClients.push( ioClient );
var ioClient = io(address, opts);
ioClients.push(ioClient);
return ioClient;
};
var getWSClient = function( address, opts ) {
var getWSClient = function (address, opts) {
var wsClient = new WebSocketClient();
wsClient.connect( address, 'echo-protocol', 'console', opts );
wsClient.connect(address, 'echo-protocol', 'console', opts);
return wsClient;
};
var start = function() {
var start = function () {
host.start();
};
var stop = function() {
if ( authProvider ) {
var stop = function () {
if (authProvider) {
authProvider.tokens = {};

@@ -148,12 +148,12 @@ authProvider.users = {};

}
_.each( ioClients, function( i ) {
if ( i && i.close ) {
_.each(ioClients, function (i) {
if (i && i.close) {
i.close();
}
} );
_.each( wsClients, function( w ) {
});
_.each(wsClients, function (w) {
w.close();
} );
});
if ( socket.websocket && socket.websocket.socketServer ) {
if (socket.websocket && socket.websocket.socketServer) {
socket.websocket.socketServer.pendingRequests = [];

@@ -160,0 +160,0 @@ }

var request;
var _ = require( 'lodash' );
var fs = require( 'fs' );
var path = require( 'path' );
var log = require( '../log' )( 'autohost.http.envelope' );
var _ = require('lodash');
var fs = require('fs');
var path = require('path');
var log = require('../log')('autohost.http.envelope');
function HttpEnvelope( req, res ) {
function HttpEnvelope(req, res) {
this.transport = 'http';

@@ -12,6 +12,6 @@ this.context = req.context;

this.data;
if( req.data ) {
if (req.data) {
this.data = req.data;
} else {
this.data = req.body ? _.cloneDeep( req.body ) : {};
this.data = req.body ? _.cloneDeep(req.body) : {};
}

@@ -24,4 +24,4 @@ this.body = req.body || {};

this.headers = req.headers || {};
this.logout = function() {
req.logout();
this.logout = function () {
req.logout(() => { });
};

@@ -38,24 +38,24 @@

};
this.version = req.context ? ( req.context.version || 1 ) : 1;
this.version = req.context ? (req.context.version || 1) : 1;
_.extend( this.data, req.params );
Object.keys( req.query ).forEach( function( key ) {
var val = req.query[ key ];
if ( !this.data.hasOwnProperty( key ) ) {
this.data[ key ] = val;
_.extend(this.data, req.params);
Object.keys(req.query).forEach(function (key) {
var val = req.query[key];
if (!this.data.hasOwnProperty(key)) {
this.data[key] = val;
}
if ( !this.params.hasOwnProperty( key ) ) {
this.params[ key ] = val;
if (!this.params.hasOwnProperty(key)) {
this.params[key] = val;
}
}.bind( this ) );
}.bind(this));
if ( req.extendHttp ) {
_.each( req.extendHttp, function( val, key ) {
this[ key ] = val;
}.bind( this ) );
if (req.extendHttp) {
_.each(req.extendHttp, function (val, key) {
this[key] = val;
}.bind(this));
}
}
HttpEnvelope.prototype.forwardTo = function( options ) {
if ( !this._original.req.readable ) {
HttpEnvelope.prototype.forwardTo = function (options) {
if (!this._original.req.readable) {
var req = this._original.req;

@@ -66,50 +66,50 @@ var original = {

};
if ( req.body ) {
if (req.body) {
original.body = req.body;
if ( _.isObject( req.body ) ) {
if (_.isObject(req.body)) {
original.json = true;
}
}
var forwarded = _.defaults( options, original );
return request( forwarded ).pipe( this._original.res );
var forwarded = _.defaults(options, original);
return request(forwarded).pipe(this._original.res);
} else {
return this._original.req.pipe( request( options ) ).pipe( this._original.res );
return this._original.req.pipe(request(options)).pipe(this._original.res);
}
};
HttpEnvelope.prototype.redirect = function( statusCode, url ) {
if ( url === undefined ) {
HttpEnvelope.prototype.redirect = function (statusCode, url) {
if (url === undefined) {
url = statusCode;
statusCode = 302;
}
this._original.res.redirect( statusCode, url );
this._original.res.redirect(statusCode, url);
};
HttpEnvelope.prototype.reply = function( envelope ) {
HttpEnvelope.prototype.reply = function (envelope) {
var code = envelope.statusCode || envelope.status || 200;
if ( envelope.headers ) {
_.each( envelope.headers, function( v, k ) {
this._original.res.set( k, v );
}.bind( this ) );
if (envelope.headers) {
_.each(envelope.headers, function (v, k) {
this._original.res.set(k, v);
}.bind(this));
}
if ( envelope.cookies ) {
_.each( envelope.cookies, function( v, k ) {
this._original.res.cookie( k, v.value, v.options );
}.bind( this ) );
if (envelope.cookies) {
_.each(envelope.cookies, function (v, k) {
this._original.res.cookie(k, v.value, v.options);
}.bind(this));
}
this._original.res.status( code ).send( envelope.data );
this._original.res.status(code).send(envelope.data);
};
HttpEnvelope.prototype.handleReturn = function( host, resource, action, result ) {
if ( result instanceof Error ) {
this.renderError( host, resource, action, result );
HttpEnvelope.prototype.handleReturn = function (host, resource, action, result) {
if (result instanceof Error) {
this.renderError(host, resource, action, result);
} else {
if ( result.file ) {
this.replyWithFile( result.file.type, result.file.name, result.file.stream, result.status );
} else if ( result.forward ) {
this.forwardTo( result.forward );
} else if ( result.redirect ) {
this.redirect( result.redirect.status || 302, result.redirect.url );
if (result.file) {
this.replyWithFile(result.file.type, result.file.name, result.file.stream, result.status);
} else if (result.forward) {
this.forwardTo(result.forward);
} else if (result.redirect) {
this.redirect(result.redirect.status || 302, result.redirect.url);
} else {
this.reply( this.render( host, resource, action, result ) );
this.reply(this.render(host, resource, action, result));
}

@@ -119,6 +119,6 @@ }

HttpEnvelope.prototype.render = function( host, resource, action, result ) {
HttpEnvelope.prototype.render = function (host, resource, action, result) {
var envelope = { status: 200 };
if ( result.data || result.status ) {
_.merge( envelope, result );
if (result.data || result.status) {
_.merge(envelope, result);
} else {

@@ -130,3 +130,3 @@ envelope.data = result;

HttpEnvelope.prototype.renderError = function( host, resource, action, error ) {
HttpEnvelope.prototype.renderError = function (host, resource, action, error) {
var defaultStrategy = {

@@ -136,5 +136,5 @@ status: 500,

};
var hostError = host.errors ? host.errors[ error.name ] : undefined;
var resourceError = resource.errors ? resource.errors[ error.name ] : undefined;
var actionError = action.errors ? action.errors[ error.name ] : undefined;
var hostError = host.errors ? host.errors[error.name] : undefined;
var resourceError = resource.errors ? resource.errors[error.name] : undefined;
var actionError = action.errors ? action.errors[error.name] : undefined;
var strategy = _.merge(

@@ -147,20 +147,20 @@ defaultStrategy,

if ( strategy.status >= 500 ) {
var user = _.isObject( this.user ) ? ( this.user.name || this.user.username || this.user.id ) : 'anonymous';
log.error( '%s [%s] %s\n%s', process.title, user, this.url || '', error.stack || error.name || '' );
if (strategy.status >= 500) {
var user = _.isObject(this.user) ? (this.user.name || this.user.username || this.user.id) : 'anonymous';
log.error('%s [%s] %s\n%s', process.title, user, this.url || '', error.stack || error.name || '');
}
var filePath = strategy.file ? path.resolve( host.static, strategy.file ) : '';
if ( fs.existsSync( filePath ) ) {
this.replyWithFile( 'text/html', undefined, fs.createReadStream( filePath ), strategy.status );
var filePath = strategy.file ? path.resolve(host.static, strategy.file) : '';
if (fs.existsSync(filePath)) {
this.replyWithFile('text/html', undefined, fs.createReadStream(filePath), strategy.status);
} else {
var reply = {
status: strategy.status,
data: strategy.reply ? strategy.reply( error, this ) : strategy.body
data: strategy.reply ? strategy.reply(error, this) : strategy.body
};
this.reply( this.render( host, resource, action, reply ) );
this.reply(this.render(host, resource, action, reply));
}
};
HttpEnvelope.prototype.replyWithFile = function( contentType, fileName, fileStream, status ) {
HttpEnvelope.prototype.replyWithFile = function (contentType, fileName, fileStream, status) {
status = status || 200;

@@ -170,13 +170,13 @@ var headers = {

};
if ( fileName ) {
headers[ 'Content-Disposition' ] = 'attachment; filename="' + fileName + '"';
if (fileName) {
headers['Content-Disposition'] = 'attachment; filename="' + fileName + '"';
}
this._original.res.status( status );
this._original.res.set( headers );
fileStream.pipe( this._original.res );
this._original.res.status(status);
this._original.res.set(headers);
fileStream.pipe(this._original.res);
};
module.exports = function( req ) {
module.exports = function (req) {
request = req;
return HttpEnvelope;
};

@@ -23,13 +23,16 @@ var _ = require( 'lodash' );

function getAuthMiddleware( state, uri ) {
var list = [
{ path: uri, fn: state.passportInitialize, alias: 'passport' },
{ path: uri, fn: state.passportSession, alias: 'passportSession' }
]
.concat( _.map( state.anonPaths, function( pattern ) {
return { path: pattern, fn: skipAuthentication, alias: 'skipAuth' };
} ) )
const list = [
{ path: uri, fn: state.passportInitialize, alias: "passport" }
];
if ( !state.config.noSession ) {
list.push( { path: uri, fn: state.passportSession, alias: "passportSession" } );
}
return list.concat( _.map( state.anonPaths, function ( pattern ) {
return { path: pattern, fn: skipAuthentication, alias: "skipAuth" };
} ) )
.concat( [ { path: uri, fn: whenNoUsers },
{ path: uri, fn: authConditionally.bind( undefined, state ), alias: 'conditionalAuth' },
{ path: uri, fn: getRoles.bind( undefined, state ), alias: 'userRoles' } ] );
return list;
{ path: uri, fn: authConditionally.bind( undefined, state ), alias: "conditionalAuth" },
{ path: uri, fn: getRoles.bind( undefined, state ), alias: "userRoles" } ] );
}

@@ -36,0 +39,0 @@

@@ -1,7 +0,7 @@

var _ = require( 'lodash' );
var socketio = require( 'socket.io' );
var log = require( '../log' )( 'autohost.socketio' );
var _ = require('lodash');
var socketio = require('socket.io');
var log = require('../log')('autohost.socketio');
function acceptSocket( state, socket ) {
log.debug( 'Processing socket.io connection attempt' );
function acceptSocket(state, socket) {
log.debug('Processing socket.io connection attempt');

@@ -21,18 +21,18 @@ var request = socket.request;

socket.cookies = {};
if ( request.headers.cookie ) {
_.each( request.headers.cookie.split( ';' ), function( cookie ) {
var crumbs = cookie.split( '=' );
socket.cookies[ crumbs[ 0 ].trim() ] = crumbs[ 1 ].trim();
} );
if (request.headers.cookie) {
_.each(request.headers.cookie.split(';'), function (cookie) {
var crumbs = cookie.split('=');
socket.cookies[crumbs[0].trim()] = crumbs[1].trim();
});
}
// attach roles to user on socket
if ( state.authProvider ) {
state.authProvider.getSocketRoles( socket.user )
.then( null, function( /* err */ ) {
if (state.authProvider) {
state.authProvider.getSocketRoles(socket.user)
.then(null, function ( /* err */) {
return [];
} )
.then( function( roles ) {
})
.then(function (roles) {
socket.user.roles = roles;
} );
});
}

@@ -44,17 +44,17 @@

// normalize socket publishing interface
socket.publish = function( topic, message ) {
socket.emit( topic, message );
socket.publish = function (topic, message) {
socket.emit(topic, message);
};
// add a way to close a socket
socket.close = function() {
log.debug( 'Closing socket.io client (user: %j)', socket.user );
socket.close = function () {
log.debug('Closing socket.io client (user: %j)', socket.user);
socket.removeAllListeners();
socket.disconnect( true );
state.registry.remove( socket );
socket.disconnect(true);
state.registry.remove(socket);
};
// add a way to end session
socket.logout = function() {
request.logout();
socket.logout = function () {
request.logout(() => { });
socket.close();

@@ -64,69 +64,73 @@ };

// if client identifies itself, register id
socket.on( 'client.identity', function( data ) {
log.debug( 'Client sent identity %j', data );
socket.on('client.identity', function (data) {
log.debug('Client sent identity %j', data);
socket.id = data.id;
state.registry.identified( data.id, socket );
} );
state.registry.identified(data.id, socket);
});
// add anonymous socket
state.registry.add( socket );
state.registry.add(socket);
// subscribe to registered topics
_.each( state.registry.topics, function( callback, topic ) {
if ( callback ) {
socket.on( topic, function( data ) {
callback( data, socket );
} );
_.each(state.registry.topics, function (callback, topic) {
if (callback) {
socket.on(topic, function (data) {
callback(data, socket);
});
}
} );
});
socket.publish( 'server.connected', { user: socket.user } );
socket.on( 'disconnect', function() {
log.debug( 'socket.io client disconnected (user: %j)', socket.user );
socket.publish('server.connected', { user: socket.user });
socket.on('disconnect', function () {
log.debug('socket.io client disconnected (user: %j)', socket.user);
socket.removeAllListeners();
state.registry.remove( socket );
} );
state.registry.remove(socket);
});
}
function authSocketIO( state, auth, req, allow ) {
if ( state.authProvider ) {
function authSocketIO(state, auth, req, allow) {
if (state.authProvider) {
auth
.handle( req, req.res, function( err ) {
if ( err ) {
log.debug( 'Error in authenticating socket.io connection %s', err.stack );
allow( err );
.handle(req, req.res, function (err) {
if (err) {
log.debug('Error in authenticating socket.io connection %s', err.stack);
allow(err);
} else {
log.debug( 'Authenticated socket.io connection as user %j', req.user );
allow( null, req.user );
log.debug('Authenticated socket.io connection as user %j', req.user);
allow(null, req.user);
}
} );
});
} else {
allow( null, { id: 'anonymous', name: 'anonymous', roles: [] } );
allow(null, { id: 'anonymous', name: 'anonymous', roles: [] });
}
}
function configureSocketIO( state, http ) {
var config = _.get( state, 'config.socketio', {} );
function configureSocketIO(state, http) {
var config = _.get(state, 'config.socketio', {});
var options = typeof config === 'boolean' ? {} : config;
var io = state.io = socketio( http.server, _.defaults( options, { destroyUpgrade: false } ) );
var authStack = http.getAuthMiddleware()
.use( '/', function( hreq, hres, next ) {
log.debug( 'Setting socket.io connection user to %j', hreq.user );
.use('/', function (hreq, hres, next) {
log.debug('Setting socket.io connection user to %j', hreq.user);
next();
} );
io.on( 'connection', acceptSocket.bind( undefined, state ) );
io.engine.allowRequest = authSocketIO.bind( undefined, state, authStack );
});
var io = state.io = socketio(http.server, _.defaults(options, {
allowRequest: authSocketIO.bind(undefined, state, authStack),
destroyUpgrade: false
}));
io.on('connection', acceptSocket.bind(undefined, state));
}
function handle( state, topic, callback ) {
_.each( state.registry.clients, function( client ) {
if ( client.type === 'socketio' ) {
client.on( topic, function( data ) {
callback( data, client );
} );
function handle(state, topic, callback) {
_.each(state.registry.clients, function (client) {
if (client.type === 'socketio') {
client.on(topic, function (data) {
callback(data, client);
});
}
} );
});
}
function stop( state ) {
function stop(state) {
state.io.engine.removeAllListeners();

@@ -136,3 +140,3 @@ state.io.engine.close();

module.exports = function( config, registry, authProvider ) {
module.exports = function (config, registry, authProvider) {
var state = {

@@ -143,8 +147,8 @@ authProvider: authProvider,

};
_.merge( state, {
configure: configureSocketIO.bind( undefined, state ),
on: handle.bind( undefined, state ),
stop: stop.bind( undefined, state )
} );
_.merge(state, {
configure: configureSocketIO.bind(undefined, state),
on: handle.bind(undefined, state),
stop: stop.bind(undefined, state)
});
return state;
};

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc