UNPKG

gereji

Version:

A non-restrictive web application framework for creating multi-site web applications focused on security and performance.

156 lines (154 loc) 4.94 kB
"use strict"; var self = function(){ return { init: function(context){ this.context = context; this.context.get("broker").on(['authenticator.error'], function(){ var publisher = context.get("publisher"); publisher.push("gereji", "authenticator", "Not authorised."); if(context.get("route").type == "html") context.redirect("/signin"); else publisher.statusCode(401) && publisher.write(context); }); return this; }, execute: function(){ var uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; var _id = this.getUserID(); if(uuid.test(_id)) return this.findUserByID(_id); var token = this.getTokenID(); if(token) return this.findUserByToken(token); return this.createGuest(); }, getUserID: function(){ var name = this.context.get("settings").cookie.name; var cookie = this.context.get("cookies").find(name); var encryption = this.context.get("encryption"); return cookie ? encryption.decrypt(cookie) : null; }, getTokenID: function(){ var header = this.context.get('request').headers['authorization'] || ""; var token = header.split(/\s+/).pop() || ''; var auth = new Buffer(token, 'base64').toString(); return auth.split(/:/)[0]; }, findUserByID: function(_id){ var that = this; this.context.get("storage").get("global").collection("user").find({"_id" : _id}).toArray(function(error, items){ if(error) return that.error(error); else return items.length ? that.setUser(items[0]) : that.setGuest(_id); }); return this; }, findUserByToken: function(token){ var that = this; this.context.get("storage").get("global").collection("user").find({"token" : token}).toArray(function(error, items){ if(error) that.error(error); else return items.length ? that.setUser(items[0]) : that.error('The provided token is not valid'); }); return this; }, error: function(){ this.context.log(2, arguments[0]); this.context.broker.emit({type : "authenticator.error", data : this.context}); }, setUser: function(user){ for(var i in user){ this.context.get('user').set(i, user[i]); } this.findPermissions(this.context); return this; }, createGuest: function(){ var _id = this.context.get("storage").uuid(); var value = this.context.get("encryption").encrypt(_id); var name = this.context.get("settings").cookie.name; var age = this.context.get("settings").cookie.age; var expires = (new Date((new Date()).valueOf() + (age*1000))).toUTCString(); var secure = this.context.get("settings").server.secure; var cookie = { name: name, value: value, path: "/", expires: expires, secure: secure, httpOnly: true }; this.context.get("cookies").push(cookie); this.setGuest(_id); return this; }, setGuest: function(_id){ this.context.get('user').set("_id", _id); this.context.get('user').set("guest", true); this.context.get('user').set("permissions", ["public.permission"]); this.secure(this.context); return this; }, findPermissions: function(){ var roles = this.context.get('user').get("roles"); if(!roles) return this.setPermissions([{permissions: ["public.permission", "user.permission"]}]); var that = this; var site_id = this.context.get('site')._id; this.context.get("storage").get("global").collection("role").find({$and :[{"_id" : {$in : roles}}, {"site_id": site_id}]}).toArray(function(error, items){ return error ? that.error(error) : that.setPermissions(items); }); }, setPermissions: function(roles){ var permissions = []; for(var i in roles){ for(var j in roles[i].permissions){ permissions.push(roles[i].permissions[j]); } } this.context.get('user').set('permissions', permissions); this.secure(); }, secure: function(){ var modules = this.modules(); if(!modules.length) return this.error('There are no authorised modules on the route.'); this.context.set('modules', modules); this.context.set("queue", modules.length); this.context.get("broker").emit({type : "authenticator.end", data : this.context}); }, modules: function(){ var route = this.context.get('route'); var assigned = this.context.get("user").get("permissions"); var modules = []; if(!this.test(assigned, route.permissions)) return modules; for(var i in route.modules){ var module = route.modules[i]; var required = module.permissions; if(this.test(assigned, required)){ modules.push(module); } } return modules; }, test : function(assigned, required){ for(var i in required){ if(assigned.indexOf(required[i]) != -1){ return true; } } return false; } }; }; module.exports = { init: function(context){ context.get("broker").on(['routing.end'], function(){ (new self()).init(context).execute(); }); } };