fixed reminder encryption
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
This commit is contained in:
parent
46b66df823
commit
5536bb3bc9
@ -4075,11 +4075,17 @@ app.post('/api/premium/tasks', authenticatePremiumUser, async (req, res) => {
|
|||||||
[req.id]
|
[req.id]
|
||||||
);
|
);
|
||||||
if (profile?.sms_reminders_opt_in && profile.phone_verified_at && profile.phone_e164) {
|
if (profile?.sms_reminders_opt_in && profile.phone_verified_at && profile.phone_e164) {
|
||||||
|
// 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({
|
await createReminder({
|
||||||
userId : req.id,
|
userId : req.id,
|
||||||
phone : profile.phone_e164,
|
phone : profile.phone_e164,
|
||||||
body : `🔔 AptivaAI: “${title}” is due ${due_date.slice(0,10)}`,
|
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);
|
console.log('[reminder] queued for task', title);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
// cron‑job doesn’t need its own UPDATE logic.
|
// cron‑job doesn’t need its own UPDATE logic.
|
||||||
|
|
||||||
import twilio from 'twilio';
|
import twilio from 'twilio';
|
||||||
|
import { decrypt } from '../shared/crypto/encryption.js';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import db from '../config/mysqlPool.js';
|
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 }) {
|
export async function sendSMS ({ reminderId = null, to, body }) {
|
||||||
try {
|
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({
|
const msg = await client.messages.create({
|
||||||
to,
|
to: toE164,
|
||||||
body,
|
body: bodyPlain,
|
||||||
messagingServiceSid: TWILIO_MESSAGING_SERVICE_SID
|
messagingServiceSid: TWILIO_MESSAGING_SERVICE_SID
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -50,9 +61,10 @@ export async function sendSMS ({ reminderId = null, to, body }) {
|
|||||||
`UPDATE reminders
|
`UPDATE reminders
|
||||||
SET status = 'failed',
|
SET status = 'failed',
|
||||||
sent_at = UTC_TIMESTAMP(),
|
sent_at = UTC_TIMESTAMP(),
|
||||||
error_code = ?
|
error_code = ?,
|
||||||
|
error_message = ?
|
||||||
WHERE id = ?`,
|
WHERE id = ?`,
|
||||||
[err.code || null, reminderId]
|
[err.code || null, err.message || null, reminderId]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
throw err; // propagate so cron can log
|
throw err; // propagate so cron can log
|
||||||
|
Loading…
Reference in New Issue
Block a user