password-reset-order.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. const mongoose = require('mongoose');
  2. const uniqueValidator = require('mongoose-unique-validator');
  3. const crypto = require('crypto');
  4. const ObjectId = mongoose.Schema.Types.ObjectId;
  5. const schema = new mongoose.Schema({
  6. token: { type: String, required: true, unique: true },
  7. email: { type: String, required: true },
  8. relatedUser: { type: ObjectId, ref: 'User' },
  9. isRevoked: { type: Boolean, default: false, required: true },
  10. createdAt: { type: Date, default: Date.now, required: true },
  11. expiredAt: { type: Date, default: Date.now() + 600000, required: true },
  12. });
  13. schema.plugin(uniqueValidator);
  14. class PasswordResetOrder {
  15. static generateOneTimeToken() {
  16. const buf = crypto.randomBytes(256);
  17. const token = buf.toString('hex');
  18. return token;
  19. }
  20. static async createPasswordResetOrder(email) {
  21. let token;
  22. let duplicateToken;
  23. do {
  24. token = this.generateOneTimeToken();
  25. // eslint-disable-next-line no-await-in-loop
  26. duplicateToken = await this.findOne({ token });
  27. } while (duplicateToken != null);
  28. const passwordResetOrderData = await this.create({ token, email });
  29. return passwordResetOrderData;
  30. }
  31. isExpired() {
  32. return this.expiredAt.getTime() < Date.now();
  33. }
  34. async revokeOneTimeToken() {
  35. this.isRevoked = true;
  36. return this.save();
  37. }
  38. }
  39. module.exports = function(crowi) {
  40. PasswordResetOrder.crowi = crowi;
  41. schema.loadClass(PasswordResetOrder);
  42. const model = mongoose.model('PasswordResetOrder', schema);
  43. return model;
  44. };