Guest User

Untitled

a guest
Dec 8th, 2018
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.84 KB | None | 0 0
  1. 'use strict'
  2. const bcrypt = require('bcrypt')
  3. const jwt = require('jsonwebtoken')
  4. const Joi = require('joi')
  5. const credentialsSchema = require('../schema/credentials')
  6.  
  7. module.exports = (database) => {
  8. const collectionName = process.env.DB_USERS_COLLECTION_NAME
  9. const secret = process.env.JWT_SECRET
  10. const saltRounds = Number(process.env.PASSWORD_SALT_ROUNDS)
  11. const collection = database.collection(collectionName)
  12.  
  13. /**
  14. * Creates a new user, returns a promise which resolves into JWT token
  15. * @param {*} credentials an object with {username:String, password: String}
  16. */
  17. function create(credentials) {
  18. return new Promise((resolve, reject) => {
  19. const result = Joi.validate(credentials, credentialsSchema)
  20. if (result.error) {
  21. return reject(result.error)
  22. }
  23.  
  24. try {
  25. const token = createUserInternal(collection, credentials, secret, saltRounds)
  26. return resolve(token)
  27. } catch (error) {
  28. return reject(error)
  29. }
  30. })
  31. }
  32.  
  33. /**
  34. * Performs user login, returns a promise which resolves into JWT token, or throws an error
  35. * @param {*} credentials an object with {username:String, password: String}
  36. */
  37. function login(credentials) {
  38. return new Promise((resolve, reject) => {
  39. const result = Joi.validate(credentials, credentialsSchema)
  40. if (result.error) {
  41. return reject(result.error)
  42. }
  43.  
  44. try {
  45. const token = loginInternal(collection, credentials, secret)
  46. return resolve(token)
  47. } catch (error) {
  48. return reject(error)
  49. }
  50. })
  51. }
  52.  
  53. async function loginInternal(collection, credentials, secret) {
  54. const user = await collection.findOne({
  55. name: credentials.name
  56. })
  57.  
  58. if (!user) {
  59. throw 'invalid user name'
  60. }
  61.  
  62. const isPasswordOk = await bcrypt.compare(credentials.password, user.passwordHash)
  63. if (!isPasswordOk) {
  64. throw 'invalid password'
  65. }
  66.  
  67. return sign(credentials, secret)
  68. }
  69.  
  70. async function createUserInternal(collection, credentials, secret, saltRounds) {
  71. const hashedPassword = await bcrypt.hash(credentials.password, saltRounds)
  72. const user = {
  73. name: credentials.name,
  74. passwordHash: hashedPassword
  75. }
  76.  
  77. await collection.insertOne(user)
  78.  
  79. return sign(credentials, secret)
  80. }
  81.  
  82. function sign(credentials, secret) {
  83. return jwt.sign({
  84. exp: Math.floor(Date.now() / 1000) + (60 * 60), // 1 hour from now
  85. data: {
  86. name: credentials.name
  87. }
  88. }, secret)
  89. }
  90.  
  91. return Object.assign({}, {
  92. create,
  93. login
  94. })
  95. }
Add Comment
Please, Sign In to add comment