userKeys.mjs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. const token = await nanoid()
  42. await WIKI.db.userKeys.query().insert({
  43. kind,
  44. token,
  45. meta,
  46. validUntil: DateTime.utc().plus({ days: 1 }).toISO(),
  47. userId
  48. })
  49. return token
  50. }
  51. static async validateToken ({ kind, token, skipDelete }, context) {
  52. const res = await WIKI.db.userKeys.query().findOne({ kind, token }).withGraphJoined('user')
  53. if (res) {
  54. if (skipDelete !== true) {
  55. await WIKI.db.userKeys.query().deleteById(res.id)
  56. }
  57. if (DateTime.utc() > DateTime.fromISO(res.validUntil)) {
  58. throw new WIKI.Error.AuthValidationTokenInvalid()
  59. }
  60. return {
  61. ...res.meta,
  62. user: res.user
  63. }
  64. } else {
  65. throw new WIKI.Error.AuthValidationTokenInvalid()
  66. }
  67. }
  68. static async destroyToken ({ token }) {
  69. return WIKI.db.userKeys.query().findOne({ token }).delete()
  70. }
  71. }