streamflix-api / src /shared /modules /email /email.service.ts
Akshar2325
✨ feat(super-admin-2fa): introduce two-factor authentication
add3ead
Raw
History Blame
6.04 kB
import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { EmailConfig } from './email.config';
@Injectable()
export class EmailService {
private readonly logger = new Logger(EmailService.name);
private readonly config: EmailConfig;
constructor(configService: ConfigService) {
this.config = new EmailConfig(configService);
}
async sendOtpEmail(
email: string,
otp: string,
firstName?: string,
): Promise<void> {
try {
this.logger.log(`πŸ“§ Attempting to send OTP email to: ${email}`);
const greeting = firstName ? `Hi ${firstName}` : 'Hello';
const payload = {
sender: {
email: this.config.otpEmail,
name: 'StreamFlix',
},
to: [{ email, name: firstName || email }],
templateId: this.config.otpTemplateId,
params: {
GREETING: greeting,
OTP: otp,
},
};
this.logger.log('πŸ“§ OTP Email payload:', {
sender: payload.sender,
to: payload.to,
templateId: payload.templateId,
params: payload.params,
});
const response = await fetch('https://api.brevo.com/v3/smtp/email', {
method: 'POST',
headers: {
'api-key': this.config.apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
const responseText = await response.text();
this.logger.log(`πŸ“§ Raw Response: ${responseText}`);
if (!response.ok) {
let error;
try {
error = JSON.parse(responseText);
} catch {
error = responseText;
}
this.logger.error('πŸ“§ Failed to send OTP email:', error);
throw new Error('Failed to send OTP email');
}
this.logger.log(`πŸ“§ βœ… OTP email sent successfully to ${email}`);
} catch (error) {
this.logger.error('πŸ“§ ❌ Error sending OTP email:', error);
throw error;
}
}
async sendWelcomeEmail(
email: string,
firstName: string,
lastName: string,
): Promise<void> {
try {
this.logger.log(`πŸ“§ Attempting to send welcome email to: ${email}`);
const fullName = `${firstName} ${lastName}`.trim();
const payload = {
sender: {
email: this.config.welcomeEmail,
name: 'StreamFlix',
},
to: [{ email, name: fullName || email }],
templateId: this.config.welcomeTemplateId,
params: {
FIRSTNAME: fullName || firstName || 'User',
},
};
this.logger.log('πŸ“§ Welcome Email payload:', {
sender: payload.sender,
to: payload.to,
templateId: payload.templateId,
params: payload.params,
});
const response = await fetch('https://api.brevo.com/v3/smtp/email', {
method: 'POST',
headers: {
'api-key': this.config.apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
const responseText = await response.text();
this.logger.log(`πŸ“§ Raw Response: ${responseText}`);
if (!response.ok) {
let error;
try {
error = JSON.parse(responseText);
} catch {
error = responseText;
}
this.logger.error('πŸ“§ Failed to send welcome email:', error);
throw new Error('Failed to send welcome email');
}
this.logger.log(`πŸ“§ βœ… Welcome email sent successfully to ${email}`);
} catch (error) {
this.logger.error('πŸ“§ ❌ Error sending welcome email:', error);
throw error;
}
}
async send2FACode(
email: string,
name: string,
code: string,
ipAddress?: string,
userAgent?: string,
location?: string,
): Promise<void> {
try {
this.logger.log(`πŸ“§ Attempting to send 2FA code to: ${email}`);
const payload = {
sender: {
email: this.config.otpEmail,
name: 'StreamFlix Security',
},
to: [{ email, name: name || email }],
templateId: parseInt(process.env.BREVO_2FA_CODE_TEMPLATE_ID || '4', 10),
params: {
adminName: name,
verificationCode: code,
expiryMinutes: process.env.TWO_FA_CODE_EXPIRY_MINUTES || '10',
location: location || 'Unknown Location',
ipAddress: ipAddress || 'Unknown',
deviceInfo: userAgent || 'Unknown device',
timestamp: new Date().toLocaleString('en-US', {
dateStyle: 'long',
timeStyle: 'short',
}),
supportUrl: process.env.SUPPORT_URL || '#',
securityUrl: process.env.SECURITY_URL || '#',
privacyUrl: process.env.PRIVACY_URL || '#',
currentYear: new Date().getFullYear().toString(),
companyAddress: process.env.COMPANY_ADDRESS || '',
},
};
this.logger.log('πŸ“§ 2FA Code Email payload:', {
sender: payload.sender,
to: payload.to,
templateId: payload.templateId,
params: { ...payload.params, verificationCode: '******' }, // Hide code in logs
});
const response = await fetch('https://api.brevo.com/v3/smtp/email', {
method: 'POST',
headers: {
'api-key': this.config.apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
const responseText = await response.text();
this.logger.log(`πŸ“§ Raw Response: ${responseText}`);
if (!response.ok) {
let error;
try {
error = JSON.parse(responseText);
} catch {
error = responseText;
}
this.logger.error('πŸ“§ Failed to send 2FA code email:', error);
throw new Error('Failed to send 2FA code email');
}
this.logger.log(`πŸ“§ βœ… 2FA code sent successfully to ${email}`);
} catch (error) {
this.logger.error('πŸ“§ ❌ Error sending 2FA code:', error);
throw error;
}
}
}