| | 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>; |
| |
|