From 11419f99140e13688a9613cab3ee03f8d3cbae45 Mon Sep 17 00:00:00 2001 From: Adam Cooke Date: Sun, 1 Feb 2026 14:48:54 +0000 Subject: [PATCH 1/3] fix(deliveries): escape delivery details to prevent HTML injection --- app/helpers/application_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c6acf4563..52106ad60 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -3,6 +3,7 @@ module ApplicationHelper def format_delivery_details(server, text) + text = h(text) text.gsub!(//) do id = ::Regexp.last_match(1).to_i link_to("message ##{id}", organization_server_message_path(server.organization, server, id), class: "u-link") From d532922ff7f51e096a69fd97a2f0a37386e60243 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 1 Feb 2026 14:55:42 +0000 Subject: [PATCH 2/3] chore(main): release 3.3.5 (#3208) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 931d27504..63d74733e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "3.3.4" + ".": "3.3.5" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b78a9257..9b74885d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,33 @@ This file contains all the latest changes and updates to Postal. +## [3.3.5](https://github.com/postalserver/postal/compare/3.3.4...3.3.5) (2026-02-01) + + +### Bug Fixes + +* **deliveries:** escape delivery details to prevent HTML injection ([11419f9](https://github.com/postalserver/postal/commit/11419f99140e13688a9613cab3ee03f8d3cbae45)) +* **health_server:** use rackup handler instead of rack handler ([7c47422](https://github.com/postalserver/postal/commit/7c47422c865e738c4d6af0fed1cca4405288341f)) +* oidc scopes are invalid when concatenated ([#3332](https://github.com/postalserver/postal/issues/3332)) ([9c5f96a](https://github.com/postalserver/postal/commit/9c5f96ae90cf06dcd5db776806865752f667bd95)) +* typo in process logging ([#3212](https://github.com/postalserver/postal/issues/3212)) ([b7e5232](https://github.com/postalserver/postal/commit/b7e5232e077b3c9b7a999dcb6676fba0ec61458e)) +* typo in the credentials page ([fd3c7cc](https://github.com/postalserver/postal/commit/fd3c7ccdf6dc4ee0a76c9523cbd735159e4b8000)) +* update url for v2 config ([#3225](https://github.com/postalserver/postal/issues/3225)) ([e00098b](https://github.com/postalserver/postal/commit/e00098b8003cf37f2708f536871b3ade377aed2d)) + + +### Documentation + +* **process.rb:** add help about time unit used by metric ([#3339](https://github.com/postalserver/postal/issues/3339)) ([f5325c4](https://github.com/postalserver/postal/commit/f5325c49ff1152ad53eaaec98717ad3412d379ae)) + + +### Miscellaneous Chores + +* **deps:** upgrade puma, net-imap and other deps ([c03c44b](https://github.com/postalserver/postal/commit/c03c44b442a29aa9881c1e1aae60bead9776a6b6)) +* **dockerfile:** reduce container size ([86de372](https://github.com/postalserver/postal/commit/86de372382bd62bdd5d1372254f8817b0360bd56)) +* remove version from docker-compose.yml ([c78000c](https://github.com/postalserver/postal/commit/c78000ca8f2998aa04648f465060768db6467de6)) +* upgrade resolv to 0.6.2 ([d00d978](https://github.com/postalserver/postal/commit/d00d978872a96369544303d08f6a9d11cdf56b62)) +* upgrade to rails 7.1 and ruby 3.4 ([#3457](https://github.com/postalserver/postal/issues/3457)) ([ab6d443](https://github.com/postalserver/postal/commit/ab6d4430baa33a05f1aa66e776cc2a5bcaa0ede8)) +* upgrade uri gem to 1.0.3 ([f193b8e](https://github.com/postalserver/postal/commit/f193b8e77fc096382ab7aaa6a2c29641b4cb12df)) + ## [3.3.4](https://github.com/postalserver/postal/compare/3.3.3...3.3.4) (2024-06-20) From 33ba9ef3f654aab7f919ec55e2c71cd4e579ed5f Mon Sep 17 00:00:00 2001 From: Reouven Mimoun Date: Tue, 17 Mar 2026 13:15:49 +0200 Subject: [PATCH 3/3] fix(webhooks): add scheduled task to unlock stale webhook request locks When a worker process crashes or is killed (common in Kubernetes with rolling updates, OOM kills, etc.), locks held on webhook_requests are never released. Unlike QueuedMessage which has TidyQueuedMessagesTask to clean up stale locks, WebhookRequest had no equivalent mechanism, causing webhook delivery to be permanently blocked. This adds: - A `with_stale_lock` scope on WebhookRequest (locks older than 1 hour) - A TidyWebhookRequestsTask scheduled task that runs hourly to unlock stale webhook requests so they can be retried Co-Authored-By: Claude Opus 4.6 --- app/lib/worker/process.rb | 1 + app/models/webhook_request.rb | 2 ++ .../tidy_webhook_requests_task.rb | 16 ++++++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 app/scheduled_tasks/tidy_webhook_requests_task.rb diff --git a/app/lib/worker/process.rb b/app/lib/worker/process.rb index e2058bc0a..5b27e83ec 100644 --- a/app/lib/worker/process.rb +++ b/app/lib/worker/process.rb @@ -42,6 +42,7 @@ class Process PruneWebhookRequestsScheduledTask, SendNotificationsScheduledTask, TidyQueuedMessagesTask, + TidyWebhookRequestsTask, ].freeze # @param [Integer] thread_count The number of worker threads to run in this process diff --git a/app/models/webhook_request.rb b/app/models/webhook_request.rb index dfbf63e57..895e0cd18 100644 --- a/app/models/webhook_request.rb +++ b/app/models/webhook_request.rb @@ -36,6 +36,8 @@ class WebhookRequest < ApplicationRecord serialize :payload, type: Hash + scope :with_stale_lock, -> { where("locked_at IS NOT NULL AND locked_at < ?", 1.hour.ago) } + class << self def trigger(server, event, payload = {}) diff --git a/app/scheduled_tasks/tidy_webhook_requests_task.rb b/app/scheduled_tasks/tidy_webhook_requests_task.rb new file mode 100644 index 000000000..54c0b6389 --- /dev/null +++ b/app/scheduled_tasks/tidy_webhook_requests_task.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class TidyWebhookRequestsTask < ApplicationScheduledTask + + def call + WebhookRequest.with_stale_lock.find_each do |request| + logger.info "unlocking stale webhook request #{request.id} (locked at #{request.locked_at} by #{request.locked_by})" + request.unlock + end + end + + def self.next_run_after + quarter_to_each_hour + end + +end