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.

user.js 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. 'use strict';
  2. const Util = require('util');
  3. const Jwt = require('@hapi/jwt');
  4. const Schmervice = require('@hapipal/schmervice');
  5. const SecurePassword = require('secure-password');
  6. module.exports = class UserService extends Schmervice.Service {
  7. constructor(...args) {
  8. super(...args)
  9. const pwd = new SecurePassword()
  10. this.pwd = {
  11. hash: Util.promisify(pwd.hash.bind(pwd)),
  12. verify: Util.promisify(pwd.verify.bind(pwd))
  13. }
  14. }
  15. async findById(id, txn) {
  16. const { User } = this.server.models()
  17. return await User.query(txn).throwIfNotFound().findById(id)
  18. }
  19. async findByUsername(username, txn) {
  20. const { User } = this.server.models()
  21. return await User.query(txn).throwIfNotFound().first().where({ username })
  22. }
  23. async signup({ password, ...userInfo }, txn) {
  24. const { User } = this.server.models()
  25. const { id } = await User.query(txn).insert(userInfo)
  26. await this.changePassword(id, password, txn)
  27. return id
  28. }
  29. async update(id, { password, ...userInfo }, txn) {
  30. const { User } = this.server.models()
  31. if (Object.keys(userInfo).length > 0) {
  32. await User.query(txn).throwIfNotFound().where({ id }).patch(userInfo)
  33. }
  34. if (password) {
  35. await this.changePassword(id, password, txn)
  36. }
  37. return id
  38. }
  39. async login({ email, password }, txn) {
  40. const { User } = this.server.models()
  41. console.log('user service attempting login...')
  42. const user = await User.query(txn).throwIfNotFound().first().where({
  43. email: User.raw('? collate nocase', email)
  44. })
  45. const passwordCheck = await this.pwd.verify(Buffer.from(password), user.password)
  46. if (passwordCheck === SecurePassword.VALID_NEEDS_REHASH) {
  47. await this.changePassword(user.id, password, txn)
  48. }
  49. else if (passwordCheck !== SecurePassword.VALID) {
  50. throw User.createNotFoundError()
  51. }
  52. return user
  53. }
  54. createToken(id) {
  55. return Jwt.token.generate({ id }, {
  56. key: this.options.jwtKey,
  57. algorithm: 'HS256'
  58. }, {
  59. ttlSec: 7 * 24 * 60 * 60 // 7 days
  60. })
  61. }
  62. async changePassword(id, password, txn) {
  63. const { User } = this.server.models()
  64. await User.query(txn).throwIfNotFound().where({ id }).patch({
  65. password: await this.pwd.hash(Buffer.from(password))
  66. })
  67. return id
  68. }
  69. }