Release history
notifuse releases
Notifuse is an open-source & modern emailing platform
All releases
48 shown
- Webhook signatures conform to Standard Webhooks spec
- Stored secrets now prefixed with whsec_
- V30 migration rotates webhook secrets to new format
- Task scheduler improvements
- AWS region eu-central-2 support
Full changelog
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
- Stored secrets are now prefixed with
Data migration
- Timezone:
Europe/Kievis rewritten to the IANA-canonicalEurope/Kyivacrossworkspaces.settings,contacts.timezone,segments.timezone, andbroadcasts.schedule.timezone. StoredEurope/Kievcontinued 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. Thecontactstriggers are briefly disabled around the rename so it does not emitcontact.updatedwebhook events or fillcontact_timelinewith rename entries.
Other changes
- Task dispatch no longer swallowed by auth proxies (#320, #317): The scheduler's internal
POST /api/tasks.executeclient 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 defaulthttp.Clientfollowed 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 theLocationheader 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_ENDPOINTto 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
runningwith an expiredtimeout_afterare now reclaimed byMarkAsRunningTxon 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, andtasks.executelogs 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).
- Broadcasts can be paused, resumed, or canceled mid-delivery, even after the orchestrator finishes enqueueing; cancel now allowed from Processing state
- In-table bulk actions for contacts: multi-select delete, add to list, remove from list, unsubscribe, with progress modal and 'Skipped' tagging for no-op cases
Full changelog
- Feature: Pause, resume, and cancel broadcasts mid-delivery — even after the orchestrator has finished enqueueing — and cancel is now allowed from the Processing state (#303)
- Contacts: Added in-table bulk actions (multi-select delete, add to list, remove from list, unsubscribe) with progress modal and "Skipped" tagging for no-op cases (#299)
- Blog RSS 2.0 and JSON Feed 1.1 syndication with per-workspace/category feeds, ETag, gzip, and XSS sanitization
- SMTP_BRIDGE_TLS setting for reverse proxy and SMTPS mode support
Full changelog
- Feature: Added
SMTP_BRIDGE_TLSsetting (off/starttls/implicit) to let operators run the SMTP bridge behind a TLS-terminating reverse proxy or in implicit-TLS (SMTPS) mode (#314) - Feature: Blog RSS 2.0 and JSON Feed 1.1 syndication — automatic
/feed.xmland/feed.jsonendpoints per workspace, per-category feeds, conditional GET with ETag, gzip, XSS-sanitized content, autodiscovery<link>tags, and admin-configurable feed settings
**Fix**: Double opt-in confirmation link now correctly transitions contacts from Pending to Active instead of resending the confirmation email in a loop (#313)
- New MAX_WORKSPACES env var controls workspace creation limits (0 = unlimited); review and set this value explicitly if workspace cap enforcement is desired
- Tracking pixel URLs now use encrypted /t/ and /r/ paths — verify any firewall or proxy rules that inspect these paths are updated accordingly
- Updated liquidjs to 10.25.5 (console) to remediate Dependabot-reported vulnerabilities
- Updated vitest to 3.2.4 (notification center) to remediate Dependabot-reported vulnerabilities
- Total of 5 Dependabot vulnerabilities addressed across both packages
- OpenAI-compatible LLM provider support with full streaming and tool use, including custom base URL for OpenRouter, Ollama, vLLM, LiteLLM, and Azure
- System Settings drawer for root admins to view and edit system configuration from the dashboard
- Email open tracking now operates independently of click tracking with proxy-cache prevention and pixel-blocker evasion
- Fixed arbitrary file read via WebSocket (CVE-2026-39363) by upgrading Vite to 7.3.2
Full changelog
- Security: Upgraded Vite to 7.3.2 in console and notification center to fix arbitrary file read via WebSocket (CVE-2026-39363)
- Fix: Removed invalid
visibilityattribute from MJML section output that caused template compilation errors (#305) - Fix: Automation now exits when contact is unsubscribed/bounced/complained for marketing emails, while still allowing transactional emails to be sent (#304)
- Fix: Social media buttons now link directly to pages by default instead of wrapping URLs in share prompts; added "Share link" toggle to social element settings (#306)
- Renamed SMTP Relay to SMTP Bridge, affecting environment variables, API fields, routes, UI labels, and migrating database settings
- Enforced workspace team member limits via MAX_USERS environment variable, with checks on invite, accept invitation, and direct add, excluding API key users from the count
- Changed SMTP EHLO hostname default from SMTP host to from-email domain for improved compatibility with strict providers
- Fixed SSRF vulnerability in /api/detect-favicon endpoint by adding a safe HTTP client with private IP blocking, DNS rebinding protection, scheme validation, and response size limits
- Updated lodash/lodash-es to 4.18.x, brace-expansion to 5.0.5, and yaml to 2.8.3 to fix prototype pollution, code injection, ReDoS, and stack overflow vulnerabilities
- SMTP EHLO hostname now defaults to the from-email domain, improving compatibility with strict providers
- Upgraded happy-dom to 20.8.9 and picomatch to 4.0.4, enhancing stability in notification center and console
- **Security**: Upgraded google.golang.org/grpc to v1.79.3 - **Security**: Upgraded fast-xml-parser to v5.5.8
- Postmark Message Stream support
- Partial email search in Contacts API
- MJML code mode broadcast support
- Upgraded liquidjs to 10.25.0
- Dynamic preheader text override
- Language selection for test/preview
- mj-liquid block for dynamic MJML
- Visual or MJML editor selection for templates
- Template translation to all workspace languages
- Configurable SMTP EHLO hostname
- Upgraded rollup and minimatch
- Template filter for email activity conditions
- Upgraded fast-xml-parser to 5.3.6
- Anthropic Sonnet model updated
- Upgraded markdown-it to 14.1.1
- Per-email provider selection in automations
- Database migration adds data_feed column to broadcasts table
- Global and per-recipient data feeds
- SSRF protection for URLs
- Real-time feed testing
Fixed email builder buttons with HTML content like <strong> rendering as default 'Button' text instead of displaying the custom content provided.
- Card-based transactional notification dashboard
- Delivery stats (sent/delivered/failed/bounced)
- 8-language internationalization support
Fixed URL corruption in emails caused by dots being stripped after quoted-printable line breaks by implementing proper SMTP dot-stuffing per RFC 5321. Fixed broadcast page crashes when variations field is null instead of empty array.
- Warning modal for large images
- All template categories visible
- MJML engine switched to gomjml
- CSV export with filter support
- Broadcast progress bar with ETA
- File manager bulk operations
- Browser history sync for folders
- SMTP OAuth2 for M365 and Gmail
- Twilio SendGrid integration
Fixed Supabase integration webhook URL mismatch for 'Before User Created' hook causing HTTP 405 errors. Fixed email editor image width handling so images properly fill column width instead of generating invalid MJML.
Fixed email editor columns displaying with zero width causing text to wrap character-by-character vertically. Properly set parent table cell widths and column inner div to 100% width.
Fixed an issue where the Reply-To email address configured in email templates was not being used when sending emails through automations or broadcast queues.
Fixed Supabase integration failing to parse new email address in email_change webhook due to incorrect JSON field name mapping from email_new to new_email.
- List status changed from 'subscribed' to 'active' via migration
Fixed automation execution of child nodes in workflows. Added comprehensive full end-to-end tests for automation functionality.
- automation_enroll_contact function signature changed from 5 to 4 parameters
Fixed automation enrollment failure caused by stats field being stored as JSONB scalar instead of object. Ensured stats field is always initialized as empty object to support atomic increment operations.
- Event kind names changed from legacy to semantic format
Fixed an error where SMTP connections were rejected with code 220 when interacting with servers that send multi-line greeting banners.
Fixed the date picker in segment creation to use RFC3339/ISO8601 format instead of YYYY-MM-DD HH:mm:ss. This ensures compatibility with contact property date ranges, timeline timeframes, and custom events goal timeframes.
Fixed regressions in the email queue system that prevented system template variables like {{ unsubscribe_url }} and {{ notification_center_url }} from rendering in broadcast emails. Resolved an issue where template data was missing from message history for queue-based sends.
Fixed an issue in the Automation Flow Editor where nodes disappeared when adding children to ListStatusBranch handles.