userKeys.mjs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /* global WIKI */
  2. import { Model } from 'objection'
  3. import { DateTime } from 'luxon'
  4. import { nanoid } from 'nanoid'
  5. import { User } from './users.mjs'
  6. /**
  7. * Users model
  8. */
  9. export class UserKey extends Model {
  10. static get tableName() { return 'userKeys' }
  11. static get jsonSchema () {
  12. return {
  13. type: 'object',
  14. required: ['kind', 'token', 'validUntil'],
  15. properties: {
  16. id: {type: 'string'},
  17. kind: {type: 'string'},
  18. token: {type: 'string'},
  19. createdAt: {type: 'string'},
  20. validUntil: {type: 'string'}
  21. }
  22. }
  23. }
  24. static get relationMappings() {
  25. return {
  26. user: {
  27. relation: Model.BelongsToOneRelation,
  28. modelClass: User,
  29. join: {
  30. from: 'userKeys.userId',
  31. to: 'users.id'
  32. }
  33. }
  34. }
  35. }
  36. async $beforeInsert(context) {
  37. await super.$beforeInsert(context)
  38. this.createdAt = DateTime.utc().toISO()
  39. }
  40. static async generateToken ({ userId, kind, meta }, context) {
  41. WIKI.logger.debug(`Generating ${kind} token for user ${userId}...`)
  42. const token = await nanoid()
  43. await WIKI.db.userKeys.query().insert({
  44. kind,
  45. token,
  46. meta,
  47. validUntil: DateTime.utc().plus({ days: 1 }).toISO(),
  48. userId
  49. })
  50. return token
  51. }
  52. static async validateToken ({ kind, token, skipDelete }, context) {
  53. const res = await WIKI.db.userKeys.query().findOne({ kind, token }).withGraphJoined('user')
  54. if (res) {
  55. if (skipDelete !== true) {
  56. await WIKI.db.userKeys.query().deleteById(res.id)
  57. }
  58. if (DateTime.utc() > DateTime.fromISO(res.validUntil)) {
  59. throw new Error('ERR_EXPIRED_VALIDATION_TOKEN')
  60. }
  61. return {
  62. ...res.meta,
  63. user: res.user
  64. }
  65. } else {
  66. throw new Error('ERR_INVALID_VALIDATION_TOKEN')
  67. }
  68. }
  69. static async destroyToken ({ token }) {
  70. return WIKI.db.userKeys.query().findOne({ token }).delete()
  71. }
  72. }