Files
rxminder/services/auth/emailVerification.service.ts
William Valentin e48adbcb00 Initial commit: Complete NodeJS-native setup
- Migrated from Python pre-commit to NodeJS-native solution
- Reorganized documentation structure
- Set up Husky + lint-staged for efficient pre-commit hooks
- Fixed Dockerfile healthcheck issue
- Added comprehensive documentation index
2025-09-06 01:42:48 -07:00

96 lines
2.8 KiB
TypeScript

import { v4 as uuidv4 } from 'uuid';
import { EmailVerificationToken, AuthenticatedUser } from './auth.types';
import { mailgunService } from '../mailgun.service';
import { AccountStatus } from './auth.constants';
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 { dbService } = await import('../couchdb');
const user = await dbService.findUserByEmail(verificationToken.email);
return user as AuthenticatedUser;
}
async markEmailVerified(user: AuthenticatedUser): Promise<void> {
// Update user in database
const { dbService } = await import('../couchdb');
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);
}
}