AuthenticationManager.coffee 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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. EmailHelper = require("../Helpers/EmailHelper")
  7. BCRYPT_ROUNDS = Settings?.security?.bcryptRounds or 12
  8. module.exports = AuthenticationManager =
  9. authenticate: (query, password, callback = (error, user) ->) ->
  10. # Using Mongoose for legacy reasons here. The returned User instance
  11. # gets serialized into the session and there may be subtle differences
  12. # between the user returned by Mongoose vs mongojs (such as default values)
  13. User.findOne query, (error, user) =>
  14. return callback(error) if error?
  15. if user?
  16. if user.hashedPassword?
  17. bcrypt.compare password, user.hashedPassword, (error, match) ->
  18. return callback(error) if error?
  19. if match
  20. AuthenticationManager.checkRounds user, user.hashedPassword, password, (err) ->
  21. return callback(err) if err?
  22. callback null, user
  23. else
  24. callback null, null
  25. else
  26. callback null, null
  27. else
  28. callback null, null
  29. validateEmail: (email) ->
  30. parsed = EmailHelper.parseEmail(email)
  31. if !parsed?
  32. return { message: 'email not valid' }
  33. return null
  34. validatePassword: (password) ->
  35. if !password?
  36. return { message: 'password not set' }
  37. if (Settings.passwordStrengthOptions?.length?.max? and
  38. password.length > Settings.passwordStrengthOptions?.length?.max)
  39. return { message: "password is too long" }
  40. if (Settings.passwordStrengthOptions?.length?.min? and
  41. password.length < Settings.passwordStrengthOptions?.length?.min)
  42. return { message: 'password is too short' }
  43. return null
  44. setUserPassword: (user_id, password, callback = (error) ->) ->
  45. validation = @validatePassword(password)
  46. return callback(validation.message) if validation?
  47. bcrypt.genSalt BCRYPT_ROUNDS, (error, salt) ->
  48. return callback(error) if error?
  49. bcrypt.hash password, salt, (error, hash) ->
  50. return callback(error) if error?
  51. db.users.update({
  52. _id: ObjectId(user_id.toString())
  53. }, {
  54. $set: hashedPassword: hash
  55. $unset: password: true
  56. }, callback)
  57. checkRounds: (user, hashedPassword, password, callback = (error) ->) ->
  58. # check current number of rounds and rehash if necessary
  59. currentRounds = bcrypt.getRounds hashedPassword
  60. if currentRounds < BCRYPT_ROUNDS
  61. AuthenticationManager.setUserPassword user._id, password, callback
  62. else
  63. callback()