- Fix missing imports and dependencies in email verification tests - Update email verification service implementation - Resolve test reference errors that were causing failures - Improve error handling and test reliability This fixes the 3 failing database service tests mentioned in the improvement summary.
95 lines
2.7 KiB
TypeScript
95 lines
2.7 KiB
TypeScript
import { v4 as uuidv4 } from 'uuid';
|
|
import { EmailVerificationToken, AuthenticatedUser } from './auth.types';
|
|
import { mailgunService } from '../mailgun.service';
|
|
import { AccountStatus } from './auth.constants';
|
|
import { databaseService } from '../database';
|
|
|
|
const TOKEN_EXPIRY_HOURS = 24;
|
|
|
|
export class EmailVerificationService {
|
|
async generateVerificationToken(
|
|
user: AuthenticatedUser
|
|
): Promise<EmailVerificationToken> {
|
|
const token = uuidv4().replace(/-/g, ''); // Generate a random token using UUID
|
|
const expiresAt = new Date();
|
|
expiresAt.setHours(expiresAt.getHours() + TOKEN_EXPIRY_HOURS);
|
|
|
|
const verificationToken: EmailVerificationToken = {
|
|
userId: user._id,
|
|
email: user.email || '',
|
|
token,
|
|
expiresAt,
|
|
};
|
|
|
|
// Store token in localStorage for demo (in production, save to database)
|
|
const tokens = JSON.parse(
|
|
localStorage.getItem('verification_tokens') || '[]'
|
|
);
|
|
tokens.push(verificationToken);
|
|
localStorage.setItem('verification_tokens', JSON.stringify(tokens));
|
|
|
|
// Send verification email via Mailgun
|
|
if (user.email) {
|
|
const emailSent = await mailgunService.sendVerificationEmail(
|
|
user.email,
|
|
token
|
|
);
|
|
if (!emailSent) {
|
|
console.warn('Failed to send verification email');
|
|
}
|
|
}
|
|
|
|
return verificationToken;
|
|
}
|
|
|
|
async validateVerificationToken(
|
|
token: string
|
|
): Promise<AuthenticatedUser | null> {
|
|
// Get tokens from localStorage
|
|
const tokens = JSON.parse(
|
|
localStorage.getItem('verification_tokens') || '[]'
|
|
);
|
|
const verificationToken = tokens.find(
|
|
(t: EmailVerificationToken) => t.token === token
|
|
);
|
|
|
|
if (!verificationToken) {
|
|
return null;
|
|
}
|
|
|
|
// Check if token is expired
|
|
if (new Date() > new Date(verificationToken.expiresAt)) {
|
|
return null;
|
|
}
|
|
|
|
// Find the user (in production, this would be a proper database lookup)
|
|
const user = await databaseService.findUserByEmail(verificationToken.email);
|
|
|
|
return user as AuthenticatedUser;
|
|
}
|
|
|
|
async markEmailVerified(user: AuthenticatedUser): Promise<void> {
|
|
// Update user in database
|
|
const updatedUser = {
|
|
...user,
|
|
emailVerified: true,
|
|
status: AccountStatus.ACTIVE,
|
|
};
|
|
|
|
await databaseService.updateUser(updatedUser);
|
|
|
|
// Remove used token
|
|
const tokens = JSON.parse(
|
|
localStorage.getItem('verification_tokens') || '[]'
|
|
);
|
|
const filteredTokens = tokens.filter(
|
|
(t: EmailVerificationToken) => t.userId !== user._id
|
|
);
|
|
localStorage.setItem('verification_tokens', JSON.stringify(filteredTokens));
|
|
}
|
|
|
|
async sendPasswordResetEmail(email: string, token: string): Promise<boolean> {
|
|
return mailgunService.sendPasswordResetEmail(email, token);
|
|
}
|
|
}
|