1
0
forked from noxious/server

Improved error message to client for password reset request, delete PasswordTokenReset after changing password

This commit is contained in:
Dennis Postma 2024-11-05 01:00:11 +01:00
parent 881e3375ab
commit 44cfbd6ee8
3 changed files with 72 additions and 33 deletions

View File

@ -0,0 +1,32 @@
import prisma from '../utilities/prisma'
import passwordResetTokenRepository from '../repositories/passwordResetTokenRepository'
import { appLogger } from '../utilities/logger'
class PasswordResetTokenService {
/**
* Delete token
* @param token
*/
public async delete(token: string): Promise<boolean> {
try {
const tokenData = await passwordResetTokenRepository.getByToken(token)
if (!tokenData) {
return false
}
prisma.passwordResetToken.delete({
where: {
token
}
})
return true
} catch (error: any) {
appLogger.error(`Error deleting password reset token: ${error instanceof Error ? error.message : String(error)}`)
return false
}
}
}
export default PasswordResetTokenService

View File

@ -6,6 +6,7 @@ import { User } from '@prisma/client'
import config from '../utilities/config'
import NodeMailer from 'nodemailer'
import { httpLogger } from '../utilities/logger'
import PasswordResetTokenService from './passwordResetTokenService'
/**
* User service
@ -76,15 +77,16 @@ class UserService {
* @param email
*/
async requestPasswordReset(email: string): Promise<boolean> {
try {
const user = await UserRepository.getByEmail(email)
if (!user) return false
const token = await bcrypt.hash(new Date().getTime().toString(), 10)
const latestToken = await PasswordResetTokenRepository.getByUserId(user.id)
//Check if password reset has been requested recently
// Check if password reset has been requested recently
if (latestToken) {
const tokenExpiryDate = new Date(Date.now() - 24 * 60 * 60 * 1000)
const tokenExpiryDate = new Date(Date.now() - 24 * 60 * 60 * 1000) // 24 hours
const isTokenExpired = latestToken.createdAt < tokenExpiryDate
if (!isTokenExpired) return false
@ -113,7 +115,6 @@ class UserService {
}
})
try {
await transporter.sendMail({
from: config.SMTP_USER,
to: email,
@ -134,7 +135,7 @@ class UserService {
* @param urlToken
* @param password
*/
async resetPassword(urlToken: string, password: string): Promise<boolean | User> {
async resetPassword(urlToken: string, password: string): Promise<boolean> {
try {
const tokenData = await PasswordResetTokenRepository.getByToken(urlToken)
if (!tokenData) {
@ -142,12 +143,18 @@ class UserService {
}
const hashedPassword = await bcrypt.hash(password, 10)
return prisma.user.update({
prisma.user.update({
where: { id: tokenData.userId },
data: {
password: hashedPassword
}
})
// Delete the token
const passwordResetTokenService = new PasswordResetTokenService()
await passwordResetTokenService.delete(urlToken)
return true
} catch (error: any) {
httpLogger.error(`Error setting new password: ${error instanceof Error ? error.message : String(error)}`)
return false

View File

@ -82,7 +82,7 @@ async function addHttpRoutes(app: Application) {
return res.status(200).json({ message: 'Email has been sent' })
}
return res.status(400).json({ message: 'Failed to send password reset request' })
return res.status(400).json({ message: 'Failed to send password reset request. Perhaps one has already been sent recently, check your spam folder.' })
})
/**