fix: api key brevo

This commit is contained in:
DeathKaioken 2026-01-18 22:45:52 +01:00
parent 2296b521db
commit 7b06ea93c5
2 changed files with 84 additions and 12 deletions

View File

@ -40,7 +40,12 @@ class ReferralRegistrationController {
static async registerPersonalReferral(req, res) { static async registerPersonalReferral(req, res) {
const { refToken, lang, ...registrationData } = req.body; const { refToken, lang, ...registrationData } = req.body;
logger.info('ReferralRegistrationController:registerPersonalReferral:start', { refToken, lang, registrationData }); logger.info('ReferralRegistrationController:registerPersonalReferral:start', {
refToken,
lang,
email: registrationData.email
});
const unitOfWork = new UnitOfWork(); const unitOfWork = new UnitOfWork();
await unitOfWork.start(); await unitOfWork.start();
try { try {
@ -52,14 +57,24 @@ class ReferralRegistrationController {
res.json({ success: true, userId: user.id, email: user.email }); res.json({ success: true, userId: user.id, email: user.email });
} catch (error) { } catch (error) {
await unitOfWork.rollback(error); await unitOfWork.rollback(error);
logger.error('ReferralRegistrationController:registerPersonalReferral:error', { refToken, error }); logger.error('ReferralRegistrationController:registerPersonalReferral:error', {
refToken,
message: error?.message,
name: error?.name
});
res.status(400).json({ success: false, message: error.message }); res.status(400).json({ success: false, message: error.message });
} }
} }
static async registerCompanyReferral(req, res) { static async registerCompanyReferral(req, res) {
const { refToken, lang, ...registrationData } = req.body; const { refToken, lang, ...registrationData } = req.body;
logger.info('ReferralRegistrationController:registerCompanyReferral:start', { refToken, lang, registrationData }); logger.info('ReferralRegistrationController:registerCompanyReferral:start', {
refToken,
lang,
companyEmail: registrationData.companyEmail,
companyName: registrationData.companyName
});
const { const {
companyEmail, companyEmail,
password, password,
@ -68,6 +83,7 @@ class ReferralRegistrationController {
contactPersonName, contactPersonName,
contactPersonPhone contactPersonPhone
} = registrationData; } = registrationData;
const unitOfWork = new UnitOfWork(); const unitOfWork = new UnitOfWork();
await unitOfWork.start(); await unitOfWork.start();
try { try {
@ -85,7 +101,11 @@ class ReferralRegistrationController {
res.json({ success: true, userId: user.id, email: user.email }); res.json({ success: true, userId: user.id, email: user.email });
} catch (error) { } catch (error) {
await unitOfWork.rollback(error); await unitOfWork.rollback(error);
logger.error('ReferralRegistrationController:registerCompanyReferral:error', { refToken, error }); logger.error('ReferralRegistrationController:registerCompanyReferral:error', {
refToken,
message: error?.message,
name: error?.name
});
res.status(400).json({ success: false, message: error.message }); res.status(400).json({ success: false, message: error.message });
} }
} }

View File

@ -6,18 +6,27 @@ const { logger } = require('../../middleware/logger');
class MailService { class MailService {
constructor() { constructor() {
this.brevo = new brevo.TransactionalEmailsApi(); this.brevo = new brevo.TransactionalEmailsApi();
const rawApiKey = process.env.BREVO_API_KEY;
const apiKey = (rawApiKey || '').trim(); // helps catch whitespace/newline issues
this.brevo.setApiKey( this.brevo.setApiKey(
brevo.TransactionalEmailsApiApiKeys.apiKey, brevo.TransactionalEmailsApiApiKeys.apiKey,
process.env.BREVO_API_KEY apiKey
); );
logger.info('MailService:brevo_api_key_loaded', {
present: Boolean(apiKey),
length: apiKey.length,
last4: apiKey.length >= 4 ? apiKey.slice(-4) : null
});
this.sender = { this.sender = {
email: process.env.BREVO_SENDER_EMAIL, email: process.env.BREVO_SENDER_EMAIL,
name: process.env.BREVO_SENDER_NAME, name: process.env.BREVO_SENDER_NAME,
}; };
this.loginUrl = process.env.LOGIN_URL; this.loginUrl = process.env.LOGIN_URL;
// Use the single correct templates directory
this.templatesDir = path.join(__dirname, '..', '..', 'mailTemplates'); this.templatesDir = path.join(__dirname, '..', '..', 'mailTemplates');
} }
@ -49,6 +58,18 @@ class MailService {
return template; return template;
} }
_extractBrevoErrorDetails(error) {
const status = error?.response?.status;
const data = error?.response?.data;
let dataSafe;
try {
dataSafe = typeof data === 'string' ? data.slice(0, 2000) : JSON.parse(JSON.stringify(data));
} catch (_) {
dataSafe = '[unserializable_response_data]';
}
return { status, data: dataSafe };
}
async sendRegistrationEmail({ email, firstName, lastName, userType, companyName, lang }) { async sendRegistrationEmail({ email, firstName, lastName, userType, companyName, lang }) {
logger.info('MailService.sendRegistrationEmail:start', { email, userType, lang }); logger.info('MailService.sendRegistrationEmail:start', { email, userType, lang });
let subject, text; let subject, text;
@ -90,13 +111,21 @@ class MailService {
logger.info('MailService.sendRegistrationEmail:email_sent', { email, userType, lang: chosenLang }); logger.info('MailService.sendRegistrationEmail:email_sent', { email, userType, lang: chosenLang });
return data; return data;
} catch (error) { } catch (error) {
logger.error('MailService.sendRegistrationEmail:error', { email, error: error.message }); const brevo = this._extractBrevoErrorDetails(error);
logger.error('MailService.sendRegistrationEmail:error', {
email,
userType,
lang: chosenLang,
message: error?.message,
brevoStatus: brevo.status,
brevoData: brevo.data
});
throw error; throw error;
} }
} }
async sendVerificationCodeEmail({ email, code, expiresAt, lang }) { async sendVerificationCodeEmail({ email, code, expiresAt, lang }) {
logger.info('MailService.sendVerificationCodeEmail:start', { email, code, expiresAt, lang }); logger.info('MailService.sendVerificationCodeEmail:start', { email, expiresAt, lang }); // don't log code
const chosenLang = lang || 'en'; const chosenLang = lang || 'en';
const subject = chosenLang === 'de' const subject = chosenLang === 'de'
? 'Ihr ProfitPlanet E-Mail-Verifizierungscode' ? 'Ihr ProfitPlanet E-Mail-Verifizierungscode'
@ -114,10 +143,17 @@ class MailService {
payload.textContent = text; payload.textContent = text;
const data = await this.brevo.sendTransacEmail(payload); const data = await this.brevo.sendTransacEmail(payload);
logger.info('MailService.sendVerificationCodeEmail:email_sent', { email, code, lang: chosenLang }); logger.info('MailService.sendVerificationCodeEmail:email_sent', { email, lang: chosenLang }); // don't log code
return data; return data;
} catch (error) { } catch (error) {
logger.error('MailService.sendVerificationCodeEmail:error', { email, error: error.message }); const brevo = this._extractBrevoErrorDetails(error);
logger.error('MailService.sendVerificationCodeEmail:error', {
email,
lang: chosenLang,
message: error?.message,
brevoStatus: brevo.status,
brevoData: brevo.data
});
throw error; throw error;
} }
} }
@ -146,7 +182,15 @@ class MailService {
logger.info('MailService.sendLoginNotificationEmail:email_sent', { email, ip, lang: chosenLang }); logger.info('MailService.sendLoginNotificationEmail:email_sent', { email, ip, lang: chosenLang });
return data; return data;
} catch (error) { } catch (error) {
logger.error('MailService.sendLoginNotificationEmail:error', { email, error: error.message }); const brevo = this._extractBrevoErrorDetails(error);
logger.error('MailService.sendLoginNotificationEmail:error', {
email,
ip,
lang: chosenLang,
message: error?.message,
brevoStatus: brevo.status,
brevoData: brevo.data
});
throw error; throw error;
} }
} }
@ -175,7 +219,15 @@ class MailService {
logger.info('MailService.sendPasswordResetEmail:email_sent', { email, token, lang: chosenLang }); logger.info('MailService.sendPasswordResetEmail:email_sent', { email, token, lang: chosenLang });
return data; return data;
} catch (error) { } catch (error) {
logger.error('MailService.sendPasswordResetEmail:error', { email, error: error.message }); const brevo = this._extractBrevoErrorDetails(error);
logger.error('MailService.sendPasswordResetEmail:error', {
email,
token,
lang: chosenLang,
message: error?.message,
brevoStatus: brevo.status,
brevoData: brevo.data
});
throw error; throw error;
} }
} }