UNPKG

sterling-session

Version:

Basic authentication and presence for sterling

193 lines (189 loc) 8.49 kB
(function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['sterling', 'async-arrays', 'squalor', 'uuid'], factory); } else if (typeof module === 'object' && module.exports) { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = factory(require('sterling'), require('async-arrays'), require('squalor'), require('uuid')); } else { // Browser globals (root is window) root.Sterling.Session = factory(root.Sterling, root.AsyncArrays, root.Squalor, root.UUID); } }(this, function (Sterling, arrays, SQL, uuid) { //todo: cookie support var SterlingSession = { allowGet : false, loginVars : [ 'phone' ], failCode : 401, serve : function(sterlingInstance, datasource, authFunction){ var controls = { handleRequest : function(id, req, res, cb){ var query = 'SELECT * from Session where session = "'+id+'"'; datasource.query( query, function(error, results, fields){ if(error || (!results) || (!results[0])){ return cb(new Error('No User, No Session')); }else{ var session = results[0]; req.session = {}; //eventually session storage, for now falsey var user; req.user = function(cb){ if(user) return cb(undefined, user); //try{ authFunction({id:session.userid}, function(err, user){ cb(err, user) }); //}catch(ex){ //cb(ex); //} }; cb(undefined); } } ); }, deleteSession : function(id, cb){ datasource.query( 'DELETE from Session where session = "'+id+'"', function(error, results, fields){ cb(error); } ); }, createSession : function(u, cb){ if(!u) return cb(new Error('User not supplied')) var act = function(user){ var id = uuid.v4(); if(!user.id) return cb(new Error('User has no ID')); datasource.query(SQL.save('Session', { userid:user.id, session:id }), function (err, results, fields) { if(err) throw err; datasource.query( 'SELECT * from Session where session ="'+id+'"', function (err, results, fields){ cb(undefined, results[0]); } ); }); } if(authFunction){ authFunction(u, function(err, user){ if(err) return cb(new Error('User not supplied')); act(user); }); }else{ act(u); } } }; var secureRoute = function(route, handler, method){ //console.log('SR-a', route); sterlingInstance.addRoute(route, function(){ //console.log('SR-e', arguments); //the session token is the first arg on the url var args = Array.prototype.slice.call(arguments); var session = arguments[0]; var ob = this; if((method || 'get').toUpperCase() !== this.req.method) return; if(this.req.routed){ console.log('DOUBLE FETCHED', this.req.routed, new Error().stack); return; } this.req.routed = new Error().stack; controls.handleRequest(session, ob.res, ob.req, function(err){ if(err) return sterlingInstance.error(ob.res, err, SterlingSession.failCode); if(!ob.res.user){ return sterlingInstance.error( ob.res, new Error('No Authentication Methods'), SterlingSession.failCode ); } handler.apply(ob, args); }); }, method); } sterlingInstance.addSecureRoute = function(route, handler){ if(typeof handler == 'function'){ secureRoute(route, handler); }else{ Object.keys(handler).forEach(function(method){ var lowerMethod = method.toLowerCase(); secureRoute(route, handler[lowerMethod], method); }); } } var prefix = sterlingInstance.prefix || ''; sterlingInstance.addRoute(prefix+'session/:session', {get:function(session){ var ob = this; controls.handleRequest(session, ob.req, ob.res, function(err){ if(err){ ob.res.end(JSON.stringify({ success: false, data: req.session, error: err.message })); }else{ ob.res.end(JSON.stringify({ success: true })); } }); }}); sterlingInstance.addRoute(prefix+'login', {post:function(session){ var ob = this; var cleaned = {}; SterlingSession.loginVars.forEach(function(key){ cleaned[key] = ob.req.post[key]; }); authFunction(cleaned, function(err, user){ controls.createSession(function(err, id){ if(err){ ob.res.end(JSON.stringify({ success: false, error: err.message })); }else{ ob.res.end(JSON.stringify({ success: true, session: id })); } }); }); }}); sterlingInstance.addRoute(prefix+'logout/:session/', {get:function(session){ var ob = this; controls.deleteSession(session, ob.res, ob.req, function(err){ if(err){ ob.res.end(JSON.stringify({ success: false, error: err.message })); }else{ ob.res.end(JSON.stringify({ success: true })); } }); }}); return controls; }, universal : function(tableName){ return function(data, cb){ database.query(SQL.select(tableName, data), function (err, results, fields) { if(err) return error(err, ob.res); if(!results[0]) return error(new Error('Unknown User'), ob.res); var user = results[0]; cb(undefined, user); }); } } }; return SterlingSession; }));