Switch email service from Brevo to Legacy API

- Add sendEmailViaLegacyAPI() function in legacyAPI.js
- Update email.js to use Legacy API instead of Brevo
- All emails (OTP, password reset, invitations) now go through
  eluxnetworks.net/function/well-api/api with send_message method
- Fix syntax errors in alarm.js, beneficiaries.js, invitations.js
  (missing console.log statements)

Brevo API is no longer used - credentials can be removed from .env

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Sergei 2026-02-04 13:03:52 -08:00
parent 20aacb4044
commit 0c82e05617
5 changed files with 60 additions and 31 deletions

View File

@ -94,7 +94,7 @@ exports.sendWalarm = async (req, res) => {
try { try {
// TODO: Implement alarm sending (push notifications, SMS, etc.) // TODO: Implement alarm sending (push notifications, SMS, etc.)
// For now, log the alarm and return success // For now, log the alarm and return success
console.log('[ALARM]', {
deployment_id, deployment_id,
location, location,
method, method,

View File

@ -657,6 +657,7 @@ router.patch('/:id',
} }
beneficiary = updatedBeneficiary; beneficiary = updatedBeneficiary;
console.log('[BENEFICIARY] Updated:', {
id: beneficiary.id, id: beneficiary.id,
name: beneficiary.name, name: beneficiary.name,
phone: beneficiary.phone, phone: beneficiary.phone,
@ -733,6 +734,7 @@ router.delete('/:id', async (req, res) => {
.single(); .single();
if (accessError || !access || access.role !== 'custodian') { if (accessError || !access || access.role !== 'custodian') {
console.log('[DELETE BENEFICIARY] Access denied:', {
userId, userId,
beneficiaryId, beneficiaryId,
role: access?.role || 'none' role: access?.role || 'none'
@ -1001,6 +1003,7 @@ router.post('/:id/activate', async (req, res) => {
const normalizedSerial = validation.normalized; const normalizedSerial = validation.normalized;
const isDemoMode = isDemoSerial(normalizedSerial); const isDemoMode = isDemoSerial(normalizedSerial);
console.log('[ACTIVATE] Serial validation:', {
original: serialNumber, original: serialNumber,
normalized: normalizedSerial, normalized: normalizedSerial,
format: validation.format, format: validation.format,
@ -1038,6 +1041,7 @@ router.post('/:id/activate', async (req, res) => {
return res.status(500).json({ error: 'Failed to activate equipment' }); return res.status(500).json({ error: 'Failed to activate equipment' });
} }
console.log('[ACTIVATE] Equipment activated:', {
beneficiaryId, beneficiaryId,
equipmentStatus, equipmentStatus,
isDemoMode, isDemoMode,
@ -1127,6 +1131,7 @@ router.post('/:id/transfer', async (req, res) => {
return res.status(500).json({ error: 'Failed to transfer rights' }); return res.status(500).json({ error: 'Failed to transfer rights' });
} }
console.log('[TRANSFER] Custodian rights transferred:', {
from: userId, from: userId,
to: newCustodianId, to: newCustodianId,
beneficiaryId beneficiaryId

View File

@ -290,6 +290,7 @@ router.post('/',
.single(); .single();
if (accessError || !access || !['custodian', 'guardian'].includes(access.role)) { if (accessError || !access || !['custodian', 'guardian'].includes(access.role)) {
console.log('[INVITATIONS] Access denied:', {
userId, userId,
beneficiaryId, beneficiaryId,
accessError: accessError?.message, accessError: accessError?.message,

View File

@ -1,42 +1,22 @@
const BREVO_API_URL = 'https://api.brevo.com/v3/smtp/email'; const { sendEmailViaLegacyAPI } = require('./legacyAPI');
/** /**
* Send email via Brevo API * Send email via Legacy API (eluxnetworks.net)
* Replaces Brevo API with the centralized WellNuo email service
*/ */
async function sendEmail({ to, subject, htmlContent, textContent }) { async function sendEmail({ to, subject, htmlContent, textContent }) {
const apiKey = process.env.BREVO_API_KEY; // Use HTML content if available, fallback to text
const content = htmlContent || textContent;
if (!apiKey) { if (!content) {
throw new Error('Email service not configured'); throw new Error('Email content is required');
} }
const payload = { return sendEmailViaLegacyAPI({
sender: { to,
name: process.env.BREVO_SENDER_NAME || 'WellNuo',
email: process.env.BREVO_SENDER_EMAIL || 'noreply@wellnuo.com'
},
to: [{ email: to }],
subject, subject,
htmlContent, content
textContent
};
const response = await fetch(BREVO_API_URL, {
method: 'POST',
headers: {
'accept': 'application/json',
'api-key': apiKey,
'content-type': 'application/json'
},
body: JSON.stringify(payload)
}); });
if (!response.ok) {
const error = await response.text();
throw new Error('Failed to send email');
}
return await response.json();
} }
/** /**

View File

@ -298,6 +298,48 @@ async function findDeploymentByUsername(adminUsername, adminToken, beneficiaryUs
} }
} }
/**
* Send email via Legacy API (eluxnetworks.net)
* Uses the send_message function with method=email
*
* @param {object} params - Email parameters
* @param {string} params.to - Recipient email address
* @param {string} params.subject - Email subject
* @param {string} params.content - Email content (HTML supported)
* @returns {Promise<boolean>} Success status
*/
async function sendEmailViaLegacyAPI({ to, subject, content }) {
const username = process.env.LEGACY_API_USERNAME;
const password = process.env.LEGACY_API_PASSWORD;
if (!username || !password) {
throw new Error('Legacy API credentials not configured');
}
// Get fresh token
const token = await getLegacyToken(username, password);
const formData = new URLSearchParams({
function: 'send_message',
token: token,
user_name: username,
user_id_or_recepient: to,
method: 'email',
subject: subject,
content: content
});
const response = await axios.post(LEGACY_API_BASE, formData, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
if (response.data.ok !== true && response.data.status !== '200 OK') {
throw new Error(`Failed to send email via Legacy API: ${JSON.stringify(response.data)}`);
}
return true;
}
module.exports = { module.exports = {
getLegacyToken, getLegacyToken,
createLegacyDeployment, createLegacyDeployment,
@ -306,6 +348,7 @@ module.exports = {
updateDeviceLocation, updateDeviceLocation,
getDeploymentDevices, getDeploymentDevices,
rebootDevice, rebootDevice,
sendEmailViaLegacyAPI,
ROOM_LOCATIONS, ROOM_LOCATIONS,
LOCATION_NAMES LOCATION_NAMES
}; };