github Notifuse/notifuse v30.0

latest release: latest
15 hours ago

Breaking Changes

  • Webhooks: Signatures now conform to the Standard Webhooks specification and match the published verification code in the docs (#318)
    • Stored secrets are now prefixed with whsec_ and the 32 random bytes after the prefix are base64-decoded before use as the HMAC key (previously the 44-char base64 string was used directly as raw bytes, making the published Python/JS/Go/PHP verification snippets always fail)
    • V30 migration rotates every existing webhook secret to the new format. Subscriptions, URLs, event filters, enabled state, and delivery history are preserved; only the secret value changes
    • Consumer action required: copy the new whsec_… secret from the console into your environment and update your verification code to the spec-compliant form shown in the docs. Deliveries that fire during the gap will retry automatically once the consumer's secret is updated

Data migration

  • Timezone: Europe/Kiev is rewritten to the IANA-canonical Europe/Kyiv across workspaces.settings, contacts.timezone, segments.timezone, and broadcasts.schedule.timezone. Stored Europe/Kiev continued to resolve at runtime via Go's tzdata alias, but the console dropdown (which no longer lists the obsolete name) showed an empty selection for affected rows. The contacts triggers are briefly disabled around the rename so it does not emit contact.updated webhook events or fill contact_timeline with rename entries.

Other changes

  • Task dispatch no longer swallowed by auth proxies (#320, #317): The scheduler's internal POST /api/tasks.execute client now refuses to follow redirects (CheckRedirect = http.ErrUseLastResponse). Previously, an auth-walling reverse proxy (Cloudflare Access, Authelia, oauth2-proxy, Traefik Forward Auth, etc.) sitting in front of the API could respond with a 302 to its login page; Go's default http.Client followed the redirect as a GET, the login page returned 200 OK HTML, and the dispatcher logged "dispatched successfully" while the task never ran. The 302 is now surfaced in the non-200 branch (with the Location header logged) so the misconfiguration is loud instead of silent. Operator note: if your ingress performs an HTTP→HTTPS redirect on the API path, set $API_ENDPOINT to the final HTTPS URL — the dispatch client will no longer silently upgrade it.
  • Task scheduler: Scheduler tick no longer waits on in-flight HTTP dispatches, so one slow recurring task can't delay dispatch of others on the same tick. Stale tasks left in running with an expired timeout_after are now reclaimed by MarkAsRunningTx on a subsequent tick instead of looping on 409 indefinitely (#317).
  • Task dispatch observability: The scheduler-side "Task execution request dispatched successfully" log now includes the HTTP status_code, and tasks.execute logs an entry line on the handler side. Diffing the two streams makes any remaining silent-interception failure mode visible.
  • Feature: Added AWS region eu-central-2 (Europe, Zurich) to the S3 provider and integrations region selectors (#316).

Don't miss a new notifuse release

NewReleases is sending notifications on new releases.