Closer/functions/dist/notifications/quietHours.js

55 lines
2.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.recipientInQuietHours = recipientInQuietHours;
/**
* Quiet-hours suppression for partner-action pushes.
*
* The Settings UI promises "10 PM 8 AM, no notifications". The client stores the window in local
* DataStore AND mirrors it to the recipient's `users/{uid}` doc (quietHoursEnabled / *StartMinutes /
* *EndMinutes / timezone). Because a partner push carries a `notification` block, the OS shows it
* directly when the recipient app is backgrounded/killed — so the only place the promise can be kept
* is server-side, here, before the push is sent (M-001).
*
* FAIL-OPEN by design: if quiet hours is not explicitly enabled, or any field (window/timezone) is
* missing or malformed, we return `false` (do NOT suppress). A bug here can therefore only ever fall
* back to today's behavior (notification delivered) — it can never wrongly drop a notification, and
* existing installs keep delivering exactly as before until the client backfills the fields.
*/
function recipientInQuietHours(userData, now = new Date()) {
var _a, _b;
if (!userData || userData.quietHoursEnabled !== true)
return false;
const start = userData.quietHoursStartMinutes;
const end = userData.quietHoursEndMinutes;
const tz = userData.timezone;
if (typeof start !== 'number' || typeof end !== 'number' || typeof tz !== 'string' || !tz) {
return false;
}
let nowMinutes;
try {
const parts = new Intl.DateTimeFormat('en-US', {
timeZone: tz,
hour: '2-digit',
minute: '2-digit',
hour12: false,
}).formatToParts(now);
const hour = Number((_a = parts.find((p) => p.type === 'hour')) === null || _a === void 0 ? void 0 : _a.value) % 24;
const minute = Number((_b = parts.find((p) => p.type === 'minute')) === null || _b === void 0 ? void 0 : _b.value);
if (Number.isNaN(hour) || Number.isNaN(minute))
return false;
nowMinutes = hour * 60 + minute;
}
catch (_c) {
// Unknown/invalid timezone id → fail open.
return false;
}
// Start == end means "no window" (nothing suppressed) — kept in lockstep with the client's
// QuietHoursManager.isInQuietHours so both decide identically.
if (start === end)
return false;
// Window may cross midnight (e.g. 22:00 → 08:00).
return start < end
? nowMinutes >= start && nowMinutes <= end
: nowMinutes >= start || nowMinutes <= end;
}
//# sourceMappingURL=quietHours.js.map