| import type { QueryOptions } from 'mongoose'; |
| import { IToken, TokenCreateData, TokenQuery, TokenUpdateData, TokenDeleteResult } from '~/types'; |
| import logger from '~/config/winston'; |
|
|
| |
| export function createTokenMethods(mongoose: typeof import('mongoose')) { |
| |
| |
| |
| async function createToken(tokenData: TokenCreateData): Promise<IToken> { |
| try { |
| const Token = mongoose.models.Token; |
| const currentTime = new Date(); |
| const expiresAt = new Date(currentTime.getTime() + tokenData.expiresIn * 1000); |
|
|
| const newTokenData = { |
| ...tokenData, |
| createdAt: currentTime, |
| expiresAt, |
| }; |
|
|
| return await Token.create(newTokenData); |
| } catch (error) { |
| logger.debug('An error occurred while creating token:', error); |
| throw error; |
| } |
| } |
|
|
| |
| |
| |
| async function updateToken( |
| query: TokenQuery, |
| updateData: TokenUpdateData, |
| ): Promise<IToken | null> { |
| try { |
| const Token = mongoose.models.Token; |
|
|
| const dataToUpdate = { ...updateData }; |
| if (updateData?.expiresIn !== undefined) { |
| dataToUpdate.expiresAt = new Date(Date.now() + updateData.expiresIn * 1000); |
| } |
|
|
| return await Token.findOneAndUpdate(query, dataToUpdate, { new: true }); |
| } catch (error) { |
| logger.debug('An error occurred while updating token:', error); |
| throw error; |
| } |
| } |
|
|
| |
| |
| |
| |
| async function deleteTokens(query: TokenQuery): Promise<TokenDeleteResult> { |
| try { |
| const Token = mongoose.models.Token; |
| const conditions = []; |
|
|
| if (query.userId !== undefined) { |
| conditions.push({ userId: query.userId }); |
| } |
| if (query.token !== undefined) { |
| conditions.push({ token: query.token }); |
| } |
| if (query.email !== undefined) { |
| conditions.push({ email: query.email.trim().toLowerCase() }); |
| } |
| if (query.identifier !== undefined) { |
| conditions.push({ identifier: query.identifier }); |
| } |
|
|
| |
| |
| |
| if (conditions.length === 0) { |
| throw new Error('At least one query parameter must be provided'); |
| } |
|
|
| return await Token.deleteMany({ |
| $or: conditions, |
| }); |
| } catch (error) { |
| logger.debug('An error occurred while deleting tokens:', error); |
| throw error; |
| } |
| } |
|
|
| |
| |
| |
| |
| async function findToken(query: TokenQuery, options?: QueryOptions): Promise<IToken | null> { |
| try { |
| const Token = mongoose.models.Token; |
| const conditions = []; |
|
|
| if (query.userId) { |
| conditions.push({ userId: query.userId }); |
| } |
| if (query.token) { |
| conditions.push({ token: query.token }); |
| } |
| if (query.email) { |
| conditions.push({ email: query.email.trim().toLowerCase() }); |
| } |
| if (query.identifier) { |
| conditions.push({ identifier: query.identifier }); |
| } |
|
|
| const token = await Token.findOne({ $and: conditions }, null, options).lean(); |
|
|
| return token as IToken | null; |
| } catch (error) { |
| logger.debug('An error occurred while finding token:', error); |
| throw error; |
| } |
| } |
|
|
| |
| return { |
| findToken, |
| createToken, |
| updateToken, |
| deleteTokens, |
| }; |
| } |
|
|
| export type TokenMethods = ReturnType<typeof createTokenMethods>; |
|
|