mirror of
https://github.com/wekan/wekan.git
synced 2026-11-07 02:52:33 -05:00
Two source bugs kept due-date reminder mail from reaching people. (1) The reminder hour was parsed as parseInt(NOTIFY_DUE_AT_HOUR_OF_DAY, 10) || 8, so a configured hour of 0 (midnight) silently became 8 (0 is falsy) and out-of-range hours were accepted; parseNotifyDueHour now keeps 0 and rejects anything outside 0..23. (2) A due-card activity's notification participants were only the card CREATOR and its MEMBERS (server/models/activities.js) -- a user ASSIGNED a card but not a member was never notified about it, including its due date; card.assignees are now included too (still gated downstream by the board tracking level, so nobody who is not tracking is newly emailed). The NOTIFY_DUE_* parsing is extracted to a pure, unit-tested models/lib/dueNotificationConfig.js. Note: the built-in reminder still requires NOTIFY_DUE_DAYS_BEFORE_AND_AFTER to be set, and members/assignees are emailed per their board watch/tracking level. Tests: tests/dueNotificationConfig.test.cjs (12 checks) covers the midnight-hour case, valid/invalid/out-of-range hours, the day-offset window parsing and negatives, plus source guards that cards.js uses parseNotifyDueHour and that assignees are in the notification participants. Thanks to SirConfigMgr and xet7 ! Fixes #3192,
39 lines
1.6 KiB
JavaScript
39 lines
1.6 KiB
JavaScript
'use strict';
|
|
|
|
// Pure parsers for the due-date reminder configuration (NOTIFY_DUE_* env vars),
|
|
// extracted from models/cards.js so they are unit-testable without Meteor.
|
|
// Related to #3192 (due-date reminder mail).
|
|
|
|
// Parse NOTIFY_DUE_DAYS_BEFORE_AND_AFTER: a comma-separated list of day offsets
|
|
// (positive = days before due, 0 = due today, negative = days past due). Each is
|
|
// validated to the -14..14 window; invalid/out-of-range entries are dropped.
|
|
// Returns an array of integers (possibly empty).
|
|
function parseNotifyDueDays(envValue) {
|
|
if (!envValue || typeof envValue !== 'string') return [];
|
|
return envValue
|
|
.split(',')
|
|
.map(value => {
|
|
const iValue = parseInt(value, 10);
|
|
if (Number.isNaN(iValue) || iValue < -14 || iValue > 14) return false;
|
|
return iValue;
|
|
})
|
|
.filter(v => v !== false);
|
|
}
|
|
|
|
// Parse NOTIFY_DUE_AT_HOUR_OF_DAY: the hour of day (0..23) at which to send the
|
|
// reminders. Returns the parsed hour, or `defaultHour` when the value is missing,
|
|
// non-numeric, or out of range.
|
|
//
|
|
// #3192: the previous `parseInt(env, 10) || defaultHour` silently turned a valid
|
|
// hour of 0 (midnight) into the default (8), because 0 is falsy — so midnight
|
|
// reminders were impossible. It also accepted out-of-range hours (e.g. 25, -1).
|
|
// Number.isNaN + a 0..23 range check fixes both while keeping the "parse error ->
|
|
// default" behaviour.
|
|
function parseNotifyDueHour(envValue, defaultHour = 8) {
|
|
const hour = parseInt(envValue, 10);
|
|
if (Number.isNaN(hour) || hour < 0 || hour > 23) return defaultHour;
|
|
return hour;
|
|
}
|
|
|
|
module.exports = { parseNotifyDueDays, parseNotifyDueHour };
|