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 {
// TODO: Implement alarm sending (push notifications, SMS, etc.)
// For now, log the alarm and return success
console.log('[ALARM]', {
deployment_id,
location,
method,

View File

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

View File

@ -290,6 +290,7 @@ router.post('/',
.single();
if (accessError || !access || !['custodian', 'guardian'].includes(access.role)) {
console.log('[INVITATIONS] Access denied:', {
userId,
beneficiaryId,
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 }) {
const apiKey = process.env.BREVO_API_KEY;
// Use HTML content if available, fallback to text
const content = htmlContent || textContent;
if (!apiKey) {
throw new Error('Email service not configured');
if (!content) {
throw new Error('Email content is required');
}
const payload = {
sender: {
name: process.env.BREVO_SENDER_NAME || 'WellNuo',
email: process.env.BREVO_SENDER_EMAIL || 'noreply@wellnuo.com'
},
to: [{ email: to }],
return sendEmailViaLegacyAPI({
to,
subject,
htmlContent,
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)
content
});
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 = {
getLegacyToken,
createLegacyDeployment,
@ -306,6 +348,7 @@ module.exports = {
updateDeviceLocation,
getDeploymentDevices,
rebootDevice,
sendEmailViaLegacyAPI,
ROOM_LOCATIONS,
LOCATION_NAMES
};