user-registration-order.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import mongoose, {
  2. Schema, Model, Document,
  3. } from 'mongoose';
  4. import uniqueValidator from 'mongoose-unique-validator';
  5. import crypto from 'crypto';
  6. import { getOrCreateModel } from '@growi/core';
  7. export interface IUserRegistrationOrder {
  8. token: string,
  9. email: string,
  10. isRevoked: boolean,
  11. createdAt: Date,
  12. expiredAt: Date,
  13. }
  14. export interface UserRegistrationOrderDocument extends IUserRegistrationOrder, Document {
  15. isExpired(): Promise<boolean>
  16. revokeOneTimeToken(): Promise<void>
  17. }
  18. export interface UserRegistrationOrderModel extends Model<UserRegistrationOrderDocument> {
  19. generateOneTimeToken(): string
  20. createUserRegistrationOrder(email: string): UserRegistrationOrderDocument
  21. }
  22. const schema = new Schema<UserRegistrationOrderDocument, UserRegistrationOrderModel>({
  23. token: { type: String, required: true, unique: true },
  24. email: { type: String, required: true },
  25. isRevoked: { type: Boolean, default: false, required: true },
  26. createdAt: { type: Date, default: new Date(Date.now()), required: true },
  27. expiredAt: { type: Date, default: new Date(Date.now() + 600000), required: true },
  28. });
  29. schema.plugin(uniqueValidator);
  30. schema.statics.generateOneTimeToken = function() {
  31. const buf = crypto.randomBytes(256);
  32. const token = buf.toString('hex');
  33. return token;
  34. };
  35. schema.statics.createUserRegistrationOrder = async function(email) {
  36. let token;
  37. let duplicateToken;
  38. do {
  39. token = this.generateOneTimeToken();
  40. // eslint-disable-next-line no-await-in-loop
  41. duplicateToken = await this.findOne({ token });
  42. } while (duplicateToken != null);
  43. const userRegistrationOrderData = await this.create({ token, email });
  44. return userRegistrationOrderData;
  45. };
  46. schema.methods.isExpired = function() {
  47. return this.expiredAt.getTime() < Date.now();
  48. };
  49. schema.methods.revokeOneTimeToken = async function() {
  50. this.isRevoked = true;
  51. return this.save();
  52. };
  53. export default getOrCreateModel<UserRegistrationOrderDocument, UserRegistrationOrderModel>('UserRegistrationOrder', schema);