| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- import mongoose, {
- Schema, Model, Document,
- } from 'mongoose';
- import { addMinutes } from 'date-fns';
- import uniqueValidator from 'mongoose-unique-validator';
- import crypto from 'crypto';
- import { getOrCreateModel } from '@growi/core';
- const ObjectId = mongoose.Schema.Types.ObjectId;
- export interface IPasswordResetOrder {
- token: string,
- email: string,
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- relatedUser: any,
- isRevoked: boolean,
- createdAt: Date,
- expiredAt: Date,
- }
- export interface PasswordResetOrderDocument extends IPasswordResetOrder, Document {
- isExpired(): Promise<boolean>
- revokeOneTimeToken(): Promise<void>
- }
- export interface PasswordResetOrderModel extends Model<PasswordResetOrderDocument> {
- generateOneTimeToken(): string
- createPasswordResetOrder(email: string): PasswordResetOrderDocument
- }
- const expiredAt = (): Date => {
- return addMinutes(new Date(), 10);
- };
- const schema = new Schema<PasswordResetOrderDocument, PasswordResetOrderModel>({
- token: { type: String, required: true, unique: true },
- email: { type: String, required: true },
- relatedUser: { type: ObjectId, ref: 'User' },
- isRevoked: { type: Boolean, default: false, required: true },
- expiredAt: { type: Date, default: expiredAt, required: true },
- }, {
- timestamps: {
- createdAt: true,
- updatedAt: false,
- },
- });
- schema.plugin(uniqueValidator);
- schema.statics.generateOneTimeToken = function() {
- const buf = crypto.randomBytes(256);
- const token = buf.toString('hex');
- return token;
- };
- schema.statics.createPasswordResetOrder = async function(email) {
- let token;
- let duplicateToken;
- do {
- token = this.generateOneTimeToken();
- // eslint-disable-next-line no-await-in-loop
- duplicateToken = await this.findOne({ token });
- } while (duplicateToken != null);
- const passwordResetOrderData = await this.create({ token, email });
- return passwordResetOrderData;
- };
- schema.methods.isExpired = function() {
- return this.expiredAt.getTime() < Date.now();
- };
- schema.methods.revokeOneTimeToken = async function() {
- this.isRevoked = true;
- return this.save();
- };
- export default getOrCreateModel<PasswordResetOrderDocument, PasswordResetOrderModel>('PasswordResetOrder', schema);
|