(options)
| 27 | } |
| 28 | |
| 29 | function buildMiddleware(options) { |
| 30 | var challenge = options.challenge != undefined ? !!options.challenge : false |
| 31 | var users = options.users || {} |
| 32 | var authorizer = options.authorizer || staticUsersAuthorizer |
| 33 | var isAsync = options.authorizeAsync != undefined ? !!options.authorizeAsync : false |
| 34 | var getResponseBody = ensureFunction(options.unauthorizedResponse, '') |
| 35 | var realm = ensureFunction(options.realm) |
| 36 | |
| 37 | assert(typeof users == 'object', 'Expected an object for the basic auth users, found ' + typeof users + ' instead') |
| 38 | assert(typeof authorizer == 'function', 'Expected a function for the basic auth authorizer, found ' + typeof authorizer + ' instead') |
| 39 | |
| 40 | function staticUsersAuthorizer(username, password) { |
| 41 | for(var i in users) |
| 42 | if(safeCompare(username, i) & safeCompare(password, users[i])) |
| 43 | return true |
| 44 | |
| 45 | return false |
| 46 | } |
| 47 | |
| 48 | return function authMiddleware(req, res, next) { |
| 49 | var authentication = auth(req) |
| 50 | |
| 51 | if(!authentication) |
| 52 | return unauthorized() |
| 53 | |
| 54 | req.auth = { |
| 55 | user: authentication.name, |
| 56 | password: authentication.pass |
| 57 | } |
| 58 | |
| 59 | if(isAsync) |
| 60 | return authorizer(authentication.name, authentication.pass, authorizerCallback) |
| 61 | else if(!authorizer(authentication.name, authentication.pass)) |
| 62 | return unauthorized() |
| 63 | |
| 64 | return next() |
| 65 | |
| 66 | function unauthorized() { |
| 67 | if(challenge) { |
| 68 | var challengeString = 'Basic' |
| 69 | var realmName = realm(req) |
| 70 | |
| 71 | if(realmName) |
| 72 | challengeString += ' realm="' + realmName + '"' |
| 73 | |
| 74 | res.set('WWW-Authenticate', challengeString) |
| 75 | } |
| 76 | |
| 77 | //TODO: Allow response body to be JSON (maybe autodetect?) |
| 78 | const response = getResponseBody(req) |
| 79 | |
| 80 | if(typeof response == 'string') |
| 81 | return res.status(401).send(response) |
| 82 | |
| 83 | return res.status(401).json(response) |
| 84 | } |
| 85 | |
| 86 | function authorizerCallback(err, approved) { |
nothing calls this directly
no test coverage detected
searching dependent graphs…