Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.js 3.1KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. const auth = require('basic-auth')
  2. const assert = require('assert')
  3. const timingSafeEqual = require('crypto').timingSafeEqual
  4. // Credits for the actual algorithm go to github/@Bruce17
  5. // Thanks to github/@hraban for making me implement this
  6. function safeCompare(userInput, secret) {
  7. const userInputLength = Buffer.byteLength(userInput)
  8. const secretLength = Buffer.byteLength(secret)
  9. const userInputBuffer = Buffer.alloc(userInputLength, 0, 'utf8')
  10. userInputBuffer.write(userInput)
  11. const secretBuffer = Buffer.alloc(userInputLength, 0, 'utf8')
  12. secretBuffer.write(secret)
  13. return !!(timingSafeEqual(userInputBuffer, secretBuffer) & userInputLength === secretLength)
  14. }
  15. function ensureFunction(option, defaultValue) {
  16. if(option == undefined)
  17. return function() { return defaultValue }
  18. if(typeof option != 'function')
  19. return function() { return option }
  20. return option
  21. }
  22. function buildMiddleware(options) {
  23. var challenge = options.challenge != undefined ? !!options.challenge : false
  24. var users = options.users || {}
  25. var authorizer = options.authorizer || staticUsersAuthorizer
  26. var isAsync = options.authorizeAsync != undefined ? !!options.authorizeAsync : false
  27. var getResponseBody = ensureFunction(options.unauthorizedResponse, '')
  28. var realm = ensureFunction(options.realm)
  29. assert(typeof users == 'object', 'Expected an object for the basic auth users, found ' + typeof users + ' instead')
  30. assert(typeof authorizer == 'function', 'Expected a function for the basic auth authorizer, found ' + typeof authorizer + ' instead')
  31. function staticUsersAuthorizer(username, password) {
  32. for(var i in users)
  33. if(safeCompare(username, i) & safeCompare(password, users[i]))
  34. return true
  35. return false
  36. }
  37. return function authMiddleware(req, res, next) {
  38. var authentication = auth(req)
  39. if(!authentication)
  40. return unauthorized()
  41. req.auth = {
  42. user: authentication.name,
  43. password: authentication.pass
  44. }
  45. if(isAsync)
  46. return authorizer(authentication.name, authentication.pass, authorizerCallback)
  47. else if(!authorizer(authentication.name, authentication.pass))
  48. return unauthorized()
  49. return next()
  50. function unauthorized() {
  51. if(challenge) {
  52. var challengeString = 'Basic'
  53. var realmName = realm(req)
  54. if(realmName)
  55. challengeString += ' realm="' + realmName + '"'
  56. res.set('WWW-Authenticate', challengeString)
  57. }
  58. //TODO: Allow response body to be JSON (maybe autodetect?)
  59. const response = getResponseBody(req)
  60. if(typeof response == 'string')
  61. return res.status(401).send(response)
  62. return res.status(401).json(response)
  63. }
  64. function authorizerCallback(err, approved) {
  65. assert.ifError(err)
  66. if(approved)
  67. return next()
  68. return unauthorized()
  69. }
  70. }
  71. }
  72. buildMiddleware.safeCompare = safeCompare
  73. module.exports = buildMiddleware