Phases (d) and (e) of docs/NOTIFICATIONS.md, after #9 and #10.
d: automatic sources
AlertsNotices: newSignIn, apiKeyCreated, apiKeyExpiring (one per key, refreshed), permissionChanged (SECURITY, never mutable), shared (SHARE: notebook shares, record locks, approvals) and release (RELEASE to all users). Core has no sign-in or API key events today, so hosts call these from their authentication customizer and API key screens. A core hook is follow-up work (spec Q5).
Marketing and other announcements: admin-authored notifications, or sink().notify with an audience.
Alerts home: a link-only Notifications line for authors (scheduled, sent this week, drafts). The home stays the one dashboard.
e: email
NotificationEmailer in the delivery job: opt-in per user and category from My Notification Settings.
IMMEDIATE: at or above the minimum severity.
DAILY_DIGEST: one email at the user's digest hour, in their time zone (My Alert Settings), listing that day's unread notifications.
Inert without a messaging provider and From address.
ALERT notifications are not emailed here, because alert subscriptions already email them.
SECURITY emails carry the title and link only.
Recipient emailStatus: SENT, DIGESTED, SKIPPED or FAILED.
Security (open-redirect fix from the review)
NotificationService.safeLink refuses backslashes, whitespace and control characters, and a second leading /.
It allows only app paths with one leading slash, or https URLs with a host.
It is used when a notification is saved (the table customizer), on output, and in emails.
Tests cover //evil.com, /\evil.com, \\evil.com, javascript:, data: and http:.
Tests:NotificationEmailAndNoticesTest (immediate, severity floor, digest hour, digest contents, notices, no security body) with a capturing messaging provider. ./mvnw verify: 67 tests, coverage gate met, checkstyle 0 violations.
Phases (d) and (e) of docs/NOTIFICATIONS.md, after #9 and #10.
**d: automatic sources**
- `AlertsNotices`: `newSignIn`, `apiKeyCreated`, `apiKeyExpiring` (one per key, refreshed), `permissionChanged` (SECURITY, never mutable), `shared` (SHARE: notebook shares, record locks, approvals) and `release` (RELEASE to all users). Core has no sign-in or API key events today, so hosts call these from their authentication customizer and API key screens. A core hook is follow-up work (spec Q5).
- Marketing and other announcements: admin-authored notifications, or `sink().notify` with an audience.
- Alerts home: a link-only Notifications line for authors (scheduled, sent this week, drafts). The home stays the one dashboard.
**e: email**
- `NotificationEmailer` in the delivery job: opt-in per user and category from My Notification Settings.
- IMMEDIATE: at or above the minimum severity.
- DAILY_DIGEST: one email at the user's digest hour, in their time zone (My Alert Settings), listing that day's unread notifications.
- Inert without a messaging provider and From address.
- ALERT notifications are not emailed here, because alert subscriptions already email them.
- SECURITY emails carry the title and link only.
- Recipient `emailStatus`: SENT, DIGESTED, SKIPPED or FAILED.
**Security (open-redirect fix from the review)**
- `NotificationService.safeLink` refuses backslashes, whitespace and control characters, and a second leading `/`.
- It allows only app paths with one leading slash, or https URLs with a host.
- It is used when a notification is saved (the table customizer), on output, and in emails.
- Tests cover `//evil.com`, `/\evil.com`, `\\evil.com`, `javascript:`, `data:` and `http:`.
**Tests:** `NotificationEmailAndNoticesTest` (immediate, severity floor, digest hour, digest contents, notices, no security body) with a capturing messaging provider. `./mvnw verify`: 67 tests, coverage gate met, checkstyle 0 violations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Phases (d) and (e) of docs/NOTIFICATIONS.md, after #9 and #10.
d: automatic sources
AlertsNotices:newSignIn,apiKeyCreated,apiKeyExpiring(one per key, refreshed),permissionChanged(SECURITY, never mutable),shared(SHARE: notebook shares, record locks, approvals) andrelease(RELEASE to all users). Core has no sign-in or API key events today, so hosts call these from their authentication customizer and API key screens. A core hook is follow-up work (spec Q5).sink().notifywith an audience.e: email
NotificationEmailerin the delivery job: opt-in per user and category from My Notification Settings.emailStatus: SENT, DIGESTED, SKIPPED or FAILED.Security (open-redirect fix from the review)
NotificationService.safeLinkrefuses backslashes, whitespace and control characters, and a second leading/.//evil.com,/\evil.com,\\evil.com,javascript:,data:andhttp:.Tests:
NotificationEmailAndNoticesTest(immediate, severity floor, digest hour, digest contents, notices, no security body) with a capturing messaging provider../mvnw verify: 67 tests, coverage gate met, checkstyle 0 violations.🤖 Generated with Claude Code