From 5d9f76f8fd9e68932fdd7951b9b8db28d3f36c5a Mon Sep 17 00:00:00 2001 From: Renganath Chokkalingam Date: Thu, 14 May 2026 17:18:46 +0530 Subject: [PATCH 1/2] fix (email): replace hardcoded sender domains with env variables and fallbacks --- packages/common/src/utils/emailService.js | 42 ++++++++++++++++++----- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/packages/common/src/utils/emailService.js b/packages/common/src/utils/emailService.js index 5f90edc8..bf7922d6 100644 --- a/packages/common/src/utils/emailService.js +++ b/packages/common/src/utils/emailService.js @@ -6,6 +6,24 @@ const dotenv = require('dotenv'); dotenv.config(); const resend = new Resend(process.env.RESEND_API_KEY_2 || process.env.RESEND_API_KEY || 're_dummy_key_for_testing'); +const formatFromAddress = (value) => { + if (!value) { + return 'urBackend '; + } + + const trimmed = value.trim(); + const angleMatch = trimmed.match(/^(.*)<(.+)>$/); + if (angleMatch) { + const email = angleMatch[2].trim(); + return `urBackend <${email}>`; + } + + return `urBackend <${trimmed}>`; +}; + +const defaultFromAddress = formatFromAddress(process.env.EMAIL_FROM); +const replyToAddress = process.env.EMAIL_REPLY_TO || "urbackend@apps.bitbros.in"; + async function sendOtp(email, otp, { subject = "Verify your urBackend account", customContent = null } = {}) { try { const htmlContent = customContent || ` @@ -43,11 +61,11 @@ async function sendOtp(email, otp, { subject = "Verify your urBackend account", `; const { data, error } = await resend.emails.send({ - from: 'urBackend ', + from: defaultFromAddress, to: email, subject: subject, html: htmlContent, - replyTo: 'urbackend@apps.bitbros.in', + replyTo: replyToAddress, }); if (error) { @@ -120,11 +138,11 @@ async function sendReleaseEmail(email, { version, title, content, changelogUrl } `; const { data, error } = await resend.emails.send({ - from: 'urBackend ', + from: defaultFromAddress, to: email, subject: `Release: ${version} - ${title}`, html: htmlContent, - replyTo: 'urbackend@apps.bitbros.in', + replyTo: replyToAddress, }); if (error) { @@ -200,11 +218,17 @@ async function sendAuthOtpEmail(email, { otp, type, pname, byokKey, byokFrom }) let mailClient = resend; - let fromAddress = `${finalDisplayName} <${safeEmailHandle}.urbackend@apps.bitbros.in>`; + let fromAddress = process.env.EMAIL_FROM + ? formatFromAddress(process.env.EMAIL_FROM) + : `${finalDisplayName} <${safeEmailHandle}.urbackend@apps.bitbros.in>`; if (byokKey) { mailClient = new Resend(byokKey); - fromAddress = byokFrom || "onboarding@resend.dev"; + fromAddress = byokFrom + ? formatFromAddress(byokFrom) + : process.env.EMAIL_FROM + ? formatFromAddress(process.env.EMAIL_FROM) + : "onboarding@resend.dev"; } const { data, error } = await mailClient.emails.send({ @@ -212,7 +236,7 @@ async function sendAuthOtpEmail(email, { otp, type, pname, byokKey, byokFrom }) to: email, subject: subject, html: htmlContent, - replyTo: fromAddress, + replyTo: replyToAddress, }); if (error) { @@ -259,11 +283,11 @@ async function sendProRequestConfirmationEmail(email) { `; const { data, error } = await resend.emails.send({ - from: 'urBackend ', + from: defaultFromAddress, to: email, subject: "Pro Access Requested - urBackend ⚡", html: htmlContent, - replyTo: 'urbackend@apps.bitbros.in', + replyTo: replyToAddress, }); if (error) { From 7d832824da5aafb3253c1ca5f17c4cbabac45170 Mon Sep 17 00:00:00 2001 From: Renganath Chokkalingam Date: Fri, 15 May 2026 07:32:20 +0530 Subject: [PATCH 2/2] fix: trim email param values and remove regex-based sender parsing --- packages/common/src/utils/emailService.js | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/common/src/utils/emailService.js b/packages/common/src/utils/emailService.js index bf7922d6..a37e7b57 100644 --- a/packages/common/src/utils/emailService.js +++ b/packages/common/src/utils/emailService.js @@ -6,23 +6,21 @@ const dotenv = require('dotenv'); dotenv.config(); const resend = new Resend(process.env.RESEND_API_KEY_2 || process.env.RESEND_API_KEY || 're_dummy_key_for_testing'); -const formatFromAddress = (value) => { - if (!value) { - return 'urBackend '; - } +const FALLBACK_FROM_ADDRESS = 'urBackend '; - const trimmed = value.trim(); - const angleMatch = trimmed.match(/^(.*)<(.+)>$/); - if (angleMatch) { - const email = angleMatch[2].trim(); - return `urBackend <${email}>`; +const formatFromAddress = (email_address) => { + const trimmed = email_address?.trim(); + if (!trimmed) { + return FALLBACK_FROM_ADDRESS; } + // simplified the sender formatting logic and removed the regex based parsing to avoid the CodeQL warning + return `urBackend <${trimmed}>`; }; - + const defaultFromAddress = formatFromAddress(process.env.EMAIL_FROM); -const replyToAddress = process.env.EMAIL_REPLY_TO || "urbackend@apps.bitbros.in"; +const replyToAddress = process.env.EMAIL_REPLY_TO?.trim() || "urbackend@apps.bitbros.in"; async function sendOtp(email, otp, { subject = "Verify your urBackend account", customContent = null } = {}) { try {