From 5536bb3bc9513a0396c1907c100735a83400f340 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 18 Sep 2025 16:08:34 +0000 Subject: [PATCH] fixed reminder encryption --- backend/server3.js | 12 +++++++++--- backend/utils/smsService.js | 20 ++++++++++++++++---- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/backend/server3.js b/backend/server3.js index dbffa5d..029168d 100644 --- a/backend/server3.js +++ b/backend/server3.js @@ -3439,7 +3439,7 @@ app.post('/api/premium/financial-profile', authenticatePremiumUser, async (req, if (!req.body || Object.keys(req.body).length === 0) { return res.json({ message: 'No changes' }); } - + // ---- Normalize split: numbers, clamp, complement, 50/50 fallback ---- function normalizeSplit(eIn, rIn) { let e = Number(eIn), r = Number(rIn); @@ -4075,11 +4075,17 @@ app.post('/api/premium/tasks', authenticatePremiumUser, async (req, res) => { [req.id] ); if (profile?.sms_reminders_opt_in && profile.phone_verified_at && profile.phone_e164) { - await createReminder({ + // If due_date is just YYYY-MM-DD, schedule at 14:00:00Z that day + const isoSend = + /^\d{4}-\d{2}-\d{2}$/.test(String(finalDue)) + ? `${finalDue}T14:00:00.000Z` + : new Date(finalDue).toISOString(); + + await createReminder({ userId : req.id, phone : profile.phone_e164, body : `🔔 AptivaAI: “${title}” is due ${due_date.slice(0,10)}`, - sendAtUtc: new Date(due_date).toISOString() // UTC ISO + sendAtUtc: isoSend // UTC ISO }); console.log('[reminder] queued for task', title); } diff --git a/backend/utils/smsService.js b/backend/utils/smsService.js index 70e293e..4c36315 100644 --- a/backend/utils/smsService.js +++ b/backend/utils/smsService.js @@ -4,6 +4,7 @@ // cron‑job doesn’t need its own UPDATE logic. import twilio from 'twilio'; +import { decrypt } from '../shared/crypto/encryption.js'; import { v4 as uuid } from 'uuid'; import db from '../config/mysqlPool.js'; @@ -24,9 +25,19 @@ const client = twilio(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN); ------------------------------------------------------------------ */ export async function sendSMS ({ reminderId = null, to, body }) { try { + // decrypt-at-send (DB stores encrypted) + const toPlain = typeof to === 'string' && to.startsWith('gcm:') ? decrypt(to) : to; + const bodyPlain = typeof body === 'string' && body.startsWith('gcm:') ? decrypt(body) : body; + // normalize to E.164 + const toE164 = (() => { + const s = String(toPlain || '').trim(); + if (!s) return s; + if (s.startsWith('+')) return s.replace(/[^\d+]/g, ''); + return '+' + s.replace(/\D/g, ''); + })(); const msg = await client.messages.create({ - to, - body, + to: toE164, + body: bodyPlain, messagingServiceSid: TWILIO_MESSAGING_SERVICE_SID }); @@ -50,9 +61,10 @@ export async function sendSMS ({ reminderId = null, to, body }) { `UPDATE reminders SET status = 'failed', sent_at = UTC_TIMESTAMP(), - error_code = ? + error_code = ?, + error_message = ? WHERE id = ?`, - [err.code || null, reminderId] + [err.code || null, err.message || null, reminderId] ); } throw err; // propagate so cron can log