AuthenticationManager.coffee 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. Settings = require "settings-sharelatex"
  2. User = require("../../models/User").User
  3. {db, ObjectId} = require("../../infrastructure/mongojs")
  4. crypto = require 'crypto'
  5. bcrypt = require 'bcrypt'
  6. BCRYPT_ROUNDS = Settings?.security?.bcryptRounds or 12
  7. module.exports = AuthenticationManager =
  8. authenticate: (query, password, callback = (error, user) ->) ->
  9. # Using Mongoose for legacy reasons here. The returned User instance
  10. # gets serialized into the session and there may be subtle differences
  11. # between the user returned by Mongoose vs mongojs (such as default values)
  12. User.findOne query, (error, user) =>
  13. return callback(error) if error?
  14. if user?
  15. if user.hashedPassword?
  16. bcrypt.compare password, user.hashedPassword, (error, match) ->
  17. return callback(error) if error?
  18. if match
  19. AuthenticationManager.checkRounds user, user.hashedPassword, password, (err) ->
  20. return callback(err) if err?
  21. callback null, user
  22. else
  23. callback null, null
  24. else
  25. callback null, null
  26. else
  27. callback null, null
  28. setUserPassword: (user_id, password, callback = (error) ->) ->
  29. if (Settings.passwordStrengthOptions?.length?.max? and
  30. Settings.passwordStrengthOptions?.length?.max < password.length)
  31. return callback("password is too long")
  32. if (Settings.passwordStrengthOptions?.length?.min? and
  33. Settings.passwordStrengthOptions?.length?.min > password.length)
  34. return callback("password is too short")
  35. bcrypt.genSalt BCRYPT_ROUNDS, (error, salt) ->
  36. return callback(error) if error?
  37. bcrypt.hash password, salt, (error, hash) ->
  38. return callback(error) if error?
  39. db.users.update({
  40. _id: ObjectId(user_id.toString())
  41. }, {
  42. $set: hashedPassword: hash
  43. $unset: password: true
  44. }, callback)
  45. checkRounds: (user, hashedPassword, password, callback = (error) ->) ->
  46. # check current number of rounds and rehash if necessary
  47. currentRounds = bcrypt.getRounds hashedPassword
  48. if currentRounds < BCRYPT_ROUNDS
  49. AuthenticationManager.setUserPassword user._id, password, callback
  50. else
  51. callback()