Releases: Notifuse/notifuse
Releases · Notifuse/notifuse
Release list
v30.2
- Improvement: SES
4.4.7 Message expired(retry-exhaustion) now suppresses on the first event, and any recipient that accumulates 5 consecutive soft bounces with no successful delivery in between is also suppressed;MessageTooLarge/ContentRejected/AttachmentRejectednever count (#323). - Fix: Email AI Assistant
setEmailTreetool now declaresitemson itschildrenarray schema, so OpenAI-compatible providers no longer reject the request witharray schema missing items(#324). Anthropic was already lenient about this; only OpenAI-compatible endpoints surfaced the error. - Improvement:
/api/templates.compilenow accepts and returnssubjectandsubject_preview, rendered through the same Liquid engine used at send time. Previously the API only returnedmjml/html, so the console preview drawer rendered the subject in-browser withliquidjs, which could diverge from the Go-sideliquidgooutput used by the send pipeline. Any API consumer can now retrieve the rendered subject directly (#329). - Deps: Bumped
liquidjsto 10.25.7,postcssto 8.5.14,fast-xml-parseroverride to ≥5.8.0 (+ newfast-xml-builder≥1.1.7 override), andgithub.qkg1.top/prometheus/prometheusto v0.311.3.
v30.1
- Security: Bumped
go.opentelemetry.io/otelto v1.41.0 intelemetry/go.mod(CVE-2026-29181). - Deps: Bumped
gomjmlto v0.12.0.
Breaking Changes
- SMTP auth with
SMTP_USE_TLS=false: When TLS is explicitly disabled, the SMTP client now usesPLAIN-NOENC(go-mail'sSMTPAuthPlainNoEnc) explicitly instead ofSMTPAuthAutoDiscover. Previously, go-mail's auto-discover refusedPLAIN/LOGINover an unencrypted connection (onlySCRAM-SHA-*andCRAM-MD5were tried), andSMTPAuthPlainitself also refused unencrypted connections at the AUTH step.PLAIN-NOENCbypasses both gates while sending the standardAUTH PLAINcommand on the wire, so any server that advertisesAUTH PLAIN(e.g. local maddy/Mailpit relays) accepts it. Operators who have setSMTP_USE_TLS=falsehave already accepted plaintext credential transit, so forcingPLAINaligns with their stated intent. Action: none if your relay acceptsPLAIN. If your relay only acceptsSCRAM/CRAM-MD5, you must enable TLS (SMTP_USE_TLS=true) — auto-discover continues to apply when TLS is on.
v30.0
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).
v29.5
- 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)
v29.4
- 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 - i18n: Notification center confirmation banner (subscribe/unsubscribe result) is now translated in all supported languages instead of always showing English (#315)
v29.3
v29.2
- Feature: Added OpenAI as LLM provider alongside Anthropic — supports any OpenAI-compatible endpoint (OpenRouter, Ollama, vLLM, LiteLLM, Azure, etc.) via custom base URL, with full streaming and tool use support
- Security: Updated liquidjs to 10.25.5 in console and vitest to 3.2.4 in notification center to fix 5 Dependabot vulnerabilities
- Deps: Updated @vitejs/plugin-react to 5.2.0 in console and notification center
- Feature: Added System Settings drawer for root admin to view and edit system configuration from the dashboard
- Workspace: Enforce workspace creation limits via
MAX_WORKSPACESenv var (0 = unlimited), with "upgrade your plan" messaging in the console - Improvement: Email open tracking now works independently of click tracking — added Cache-Control headers to prevent proxy caching, encrypted tracking URLs (
/t/,/r/) to avoid pixel blocker detection, and padded tracking pixel (#307) - i18n: Added Polish language support to the notification center
v29.1
- 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)
v29.0
[29.0] - 2026-04-04
Breaking Changes
- Rename: "SMTP Relay" renamed to "SMTP Bridge" throughout the application
- Environment variables:
SMTP_RELAY_*renamed toSMTP_BRIDGE_*(old names still accepted for backward compatibility) - Database settings keys migrated automatically via V29 migration
- JSON API:
smtp_relay_*fields renamed tosmtp_bridge_*in setup endpoints - Frontend routes:
/settings/smtp-relaychanged to/settings/smtp-bridge - UI labels: "SMTP Relay" changed to "SMTP Bridge"
- Environment variables:
- Workspace: Enforce team member limits via
MAX_USERSenv var (0 = unlimited), with checks on invite, accept invitation, and direct add — API key users are excluded from the count - Security: Fixed SSRF vulnerability in
/api/detect-faviconendpoint by adding a safe HTTP client with private IP blocking, DNS rebinding protection, scheme validation, and response size limits - Security: Upgraded happy-dom to 20.8.9 in notification center and picomatch to 4.0.4 in console
- Improvement: SMTP EHLO hostname now defaults to the from-email domain instead of the SMTP host, improving compatibility with strict providers (#301)
- Security: 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
v28.4
- Security: Upgraded picomatch to 4.0.4 in notification center
- Contacts: Fixed dropdown menu becoming unresponsive after deleting contacts, and pagination state now persists in URL across page refreshes (#294)
- Templates: Test emails now load the full contact record, so Liquid variables like
{{ contact.first_name }}render correctly