This commit is contained in:
65
src/schema/token.ts
Normal file
65
src/schema/token.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { InferSchemaType, Model, Schema, StringSchemaDefinition, Types } from 'mongoose';
|
||||
|
||||
import { TokenType } from '../constants/tokens';
|
||||
import { getDefaultExpiresFor } from '../utils/getDefaultExpiresFor';
|
||||
import { sign, verify } from '../utils/jwt';
|
||||
|
||||
export interface Token {
|
||||
auth: StringSchemaDefinition;
|
||||
expires?: number;
|
||||
type: TokenType;
|
||||
}
|
||||
|
||||
export interface TokenModel extends Model<Token> {
|
||||
cleanupExpiredTokens(): { success: boolean; deletedCount: number };
|
||||
getToken(type: TokenType, auth: Types.ObjectId, expires?: number): string;
|
||||
validateResetToken(token: string): Types.ObjectId | false;
|
||||
}
|
||||
|
||||
export const TokenSchema = new Schema<Token, TokenModel>(
|
||||
{
|
||||
auth: { type: Types.ObjectId, index: true },
|
||||
expires: { type: Number, required: true },
|
||||
type: { type: String, enum: TokenType, required: true },
|
||||
},
|
||||
{
|
||||
minimize: true,
|
||||
timestamps: true,
|
||||
},
|
||||
);
|
||||
|
||||
TokenSchema.statics = {
|
||||
async cleanupExpiredTokens() {
|
||||
const { acknowledged, deletedCount } = await this.deleteMany({ expires: { $lte: Date.now() } });
|
||||
return { success: acknowledged, deletedCount };
|
||||
},
|
||||
|
||||
async getToken(type: TokenType, auth: StringSchemaDefinition, expires?: number) {
|
||||
const existing = await this.findOne({ type, auth });
|
||||
if (existing) {
|
||||
await existing.deleteOne();
|
||||
}
|
||||
|
||||
const doc = await this.create({ type, auth, expires: expires || getDefaultExpiresFor(type) });
|
||||
return sign({
|
||||
sub: `${doc._id}`,
|
||||
exp: doc.expires,
|
||||
});
|
||||
},
|
||||
|
||||
async validateResetToken(token: string) {
|
||||
const { sub } = verify(token);
|
||||
|
||||
if (sub) {
|
||||
const record = await this.findById(sub);
|
||||
if (record) {
|
||||
await record.deleteOne();
|
||||
return !!record?.expires && record.expires >= Date.now() && record.auth;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
export type TokenSchema = InferSchemaType<typeof TokenSchema>;
|
||||
Reference in New Issue
Block a user