diff --git a/artifacts/api-server/src/routes/executive-meetings.ts b/artifacts/api-server/src/routes/executive-meetings.ts index 936e8a3d..5624331f 100644 --- a/artifacts/api-server/src/routes/executive-meetings.ts +++ b/artifacts/api-server/src/routes/executive-meetings.ts @@ -814,6 +814,24 @@ router.get( res.status(400).json({ error: "Invalid date", code: "invalid_date" }); return; } + // The 5-minute upcoming-meeting alert is, by definition, a "what is + // about to start in the next 5 minutes" widget — it has no semantic + // use for past or future dates. Restrict reads to the server's + // current local date so callers can't accidentally (or + // intentionally) enumerate other days' state via this endpoint. + const today = (() => { + const d = new Date(); + const y = d.getFullYear(); + const m = String(d.getMonth() + 1).padStart(2, "0"); + const day = String(d.getDate()).padStart(2, "0"); + return `${y}-${m}-${day}`; + })(); + if (dateRaw !== today) { + res + .status(400) + .json({ error: "Date must be today", code: "date_not_today" }); + return; + } const userId = req.session.userId; const rows = await db .select({