* fix(notifications): harden alert dispatch crash-safety and redact webhook secrets in logs
Make NotificationService.dispatchAlert never reject so the many
fire-and-forget callers (monitors, event streams, policy and image-update
paths) cannot trigger an unhandledRejection on an unhealthy database. The
whole dispatch body now sits inside a guard covering node resolution, the
history insert, channel-table reads, and the WebSocket broadcast; a
failure logs and drops the notification instead of crashing the process.
An inner guard still splits the write-success and write-failure metrics.
Also:
- Redact webhook URLs in diagnostic logs via a new maskWebhookUrl helper;
Discord/Slack/custom webhook URLs embed their token in the path, so only
the origin is safe to emit.
- Add error logging to four notification-history route handlers that
previously swallowed database errors silently before returning 500.
- Snapshot the subscriber set before broadcasting so a close/error handler
firing mid-send cannot mutate the set during iteration.
- Sanitize the admin-supplied route name in dispatch log lines.
Adds tests for dispatch crash-safety (write failure, post-write routing
failure, broadcast send failure), the success-path write metric, webhook
URL masking, and history-route error logging.
* fix(notifications): sanitize route name and patterns in create logs
Apply sanitizeForLog to the admin-supplied route name and stack patterns
in the route-creation log lines, matching the dispatch-site sanitization
and closing the remaining log-injection path on this feature.
Also extend tests: userinfo-stripping in maskWebhookUrl, subscriber-set
snapshot behavior under an unsubscribe-during-send, and error logging on
the mark-read, delete-one, and clear-all notification-history handlers.