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.

70 lines
1.6 KiB

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