Files
rxminder/services/auth/emailVerification.service.ts
William Valentin 2e3fbaf1e6 fix(auth): resolve service import and dependency issues
- Replace dynamic imports with static imports for better test compatibility
- Fix circular dependency issues between auth service and CouchDB factory
- Use correct CouchDB service methods (createUserWithPassword, etc.)
- Remove unused imports and improve code organization
- Fix email verification service to work properly with mocked dependencies
- Ensure proper error handling and service interaction patterns
2025-09-07 16:14:25 -07:00

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 { dbService } from '../couchdb.factory';
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 dbService.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 dbService.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);
}
}