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.

74 lines
1.7 KiB

  1. /* global WIKI */
  2. const _ = require('lodash')
  3. const securityHelper = require('../helpers/security')
  4. const Model = require('objection').Model
  5. const moment = require('moment')
  6. const nanoid = require('nanoid')
  7. /**
  8. * Users model
  9. */
  10. module.exports = class UserKey extends Model {
  11. static get tableName() { return 'userKeys' }
  12. static get jsonSchema () {
  13. return {
  14. type: 'object',
  15. required: ['kind', 'token', 'validUntil'],
  16. properties: {
  17. id: {type: 'integer'},
  18. kind: {type: 'string'},
  19. token: {type: 'string'},
  20. createdAt: {type: 'string'},
  21. validUntil: {type: 'string'}
  22. }
  23. }
  24. }
  25. static get relationMappings() {
  26. return {
  27. user: {
  28. relation: Model.BelongsToOneRelation,
  29. modelClass: require('./users'),
  30. join: {
  31. from: 'userKeys.userId',
  32. to: 'users.id'
  33. }
  34. }
  35. }
  36. }
  37. async $beforeInsert(context) {
  38. await super.$beforeInsert(context)
  39. this.createdAt = moment.utc().toISOString()
  40. }
  41. static async generateToken ({ userId, kind }, context) {
  42. const token = await nanoid()
  43. await WIKI.models.userKeys.query().insert({
  44. kind,
  45. token,
  46. validUntil: moment.utc().add(1, 'days').toISOString(),
  47. userId
  48. })
  49. return token
  50. }
  51. static async validateToken ({ kind, token }, context) {
  52. const res = await WIKI.models.userKeys.query().findOne({ kind, token }).eager('user')
  53. if (res) {
  54. await WIKI.models.userKeys.query().deleteById(res.id)
  55. if (moment.utc().isAfter(moment.utc(res.validUntil))) {
  56. throw new WIKI.Error.AuthValidationTokenInvalid()
  57. }
  58. return res.user
  59. } else {
  60. throw new WIKI.Error.AuthValidationTokenInvalid()
  61. }
  62. return token
  63. }
  64. }