diff --git a/README.md b/README.md index 150cab6..f3af915 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ var express = require('express'), app = express(), cs = require('cansecurity'), // only authorized if logged in, or as certain roles, or some combination app.get("/secure/loggedin",cansec.restrictToLoggedIn,send200); + app.get("/secure/customloggedin",cansec.setUnauthenticatedCode({code:302,location:"/login"}),cansec.restrictToLoggedIn,send200); app.get("/secure/user/:user",cansec.restrictToSelf,send200); app.get("/secure/roles/admin",cansec.restrictToRoles("admin"),send200); app.get("/secure/roles/adminOrSuper",cansec.restrictToRoles(["admin","super"]),send200); diff --git a/lib/authorization.js b/lib/authorization.js index 09ffcfd..541b5ad 100644 --- a/lib/authorization.js +++ b/lib/authorization.js @@ -1,16 +1,23 @@ /*jslint node:true, nomen:false, unused:vars */ const errors = require('./errors'), rparams = require('./param'), sender = require('./sender'), - constants = require('./constants').get(), + constants = require('./constants').get(), HttpStatus = require('http-status-codes'), csauth = constants.header.AUTH, fields = {}, params = {}; const checkLoggedIn = (req, res, next) => { // If our user is authenticated // then everything is fine :) - let logged = true; + let logged = true, + unauthenticatedResponse = req.unauthenticatedResponse || {} + unauthCode = unauthenticatedResponse.code || HttpStatus.UNAUTHORIZED; + unauthLocation = unauthenticatedResponse.location || null; + rparams(req); if (!req[csauth]) { - sender(res,401,errors.unauthenticated()); + if (unauthLocation != null) { + res.header("location", unauthLocation); + } + sender(res,unauthCode,errors.unauthenticated()); logged = false; } return (logged); @@ -101,6 +108,12 @@ const checkLoggedIn = (req, res, next) => { } }, indirect: { + setUnauthenticatedCode: (unauthenticatedResponse) => { + return (req, res, next) => { + req.unauthenticatedResponse = unauthenticatedResponse; + next() + }; + }, // valid if user is logged in *and* the logged-in user has at least one of the given roles restrictToRoles: (roles) => { roles = roles ? [].concat(roles) : []; diff --git a/package.json b/package.json index 33fbabe..ca75424 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cansecurity", "description": "cansecurity is your all-in-one security library for user authentication, authorization and management in node expressjs apps", - "version": "3.1.0", + "version": "3.2.0", "license": "MIT", "url": "http://github.com/deitch/cansecurity", "author": "Avi Deitcher ", @@ -17,6 +17,7 @@ "main": "./lib/index.js", "dependencies": { "async": "^2.5.0", + "http-status-codes": "^1.3.0", "jsonwebtoken": "^7.4.3", "lodash": "^4.17.4" }, diff --git a/test/test-authorization.js b/test/test-authorization.js index 6985fcb..23cda64 100644 --- a/test/test-authorization.js +++ b/test/test-authorization.js @@ -12,6 +12,15 @@ getCheckObject = function(req,res) { return({owner:"2",recipient:"4"}); }, alltests = function () { + describe('Authorization', function(){ + before(function(){ + path = '/secure/customloggedin'; + location = '/login'; + }); + it('should reject with custom HTTP code when not logged in',function (done) { + r.get(path).set('Accept', 'text/plain').expect('location', location).expect(302,unauthenticated,done); + }); + }); describe('logged in path', function(){ before(function(){ path = '/secure/loggedin'; @@ -309,6 +318,7 @@ alltests = function () { setpaths = function () { app.get('/secure/fieldOrRole',cansec.restrictToFieldOrRoles("owner","admin",getCheckObject),send200); app.get("/secure/loggedin",cansec.restrictToLoggedIn,send200); + app.get("/secure/customloggedin",cansec.setUnauthenticatedCode({code:302,location:"/login"}),cansec.restrictToLoggedIn,send200); app.get("/secure/user/:user",cansec.restrictToSelf,send200); app.get("/secure/roles/admin",cansec.restrictToRoles("admin"),send200); app.get("/secure/roles/adminOrSuper",cansec.restrictToRoles(["admin","super"]),send200);