From 8fac8cc3cb16f0476ea5a7d1e96b5f57851065e8 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 4 Mar 2026 10:44:54 +1100 Subject: [PATCH] DEV: Refund flag is truthy-parsed, causing unintended refunds (#38223) The `refund` parameter in the admin subscription destroy action was truthy-parsed, causing unintended refunds when `refund=false` or `refund=""` was sent as a string. extra protection for refunds issued via api --- .../admin/subscriptions_controller.rb | 2 +- .../admin/subscriptions_controller.rb.lock | 0 .../requests/admin/subscriptions_controller_spec.rb | 11 +++++++++++ .../admin/subscriptions_controller_spec.rb.lock | 0 4 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 plugins/discourse-subscriptions/app/controllers/discourse_subscriptions/admin/subscriptions_controller.rb.lock create mode 100644 plugins/discourse-subscriptions/spec/requests/admin/subscriptions_controller_spec.rb.lock diff --git a/plugins/discourse-subscriptions/app/controllers/discourse_subscriptions/admin/subscriptions_controller.rb b/plugins/discourse-subscriptions/app/controllers/discourse_subscriptions/admin/subscriptions_controller.rb index a4250b539e2..18984c36e12 100644 --- a/plugins/discourse-subscriptions/app/controllers/discourse_subscriptions/admin/subscriptions_controller.rb +++ b/plugins/discourse-subscriptions/app/controllers/discourse_subscriptions/admin/subscriptions_controller.rb @@ -52,7 +52,7 @@ module DiscourseSubscriptions def destroy params.require(:id) begin - refund_subscription(params[:id]) if params[:refund] + refund_subscription(params[:id]) if ActiveModel::Type::Boolean.new.cast(params[:refund]) subscription = ::Stripe::Subscription.cancel(params[:id]) customer = diff --git a/plugins/discourse-subscriptions/app/controllers/discourse_subscriptions/admin/subscriptions_controller.rb.lock b/plugins/discourse-subscriptions/app/controllers/discourse_subscriptions/admin/subscriptions_controller.rb.lock new file mode 100644 index 00000000000..e69de29bb2d diff --git a/plugins/discourse-subscriptions/spec/requests/admin/subscriptions_controller_spec.rb b/plugins/discourse-subscriptions/spec/requests/admin/subscriptions_controller_spec.rb index 36b4b55ad12..d0be1ec9cb3 100644 --- a/plugins/discourse-subscriptions/spec/requests/admin/subscriptions_controller_spec.rb +++ b/plugins/discourse-subscriptions/spec/requests/admin/subscriptions_controller_spec.rb @@ -123,6 +123,17 @@ RSpec.describe DiscourseSubscriptions::Admin::SubscriptionsController do } end + it "does not refund when refund param is the string 'false'" do + ::Stripe::Subscription + .expects(:cancel) + .with("sub_12345") + .returns(plan: { product: "pr_34578" }, customer: "c_123") + ::Stripe::Subscription.expects(:retrieve).with("sub_12345").never + ::Stripe::Refund.expects(:create).never + + delete "/s/admin/subscriptions/sub_12345.json", params: { refund: "false" } + end + it "refunds if params[:refund] present" do ::Stripe::Subscription .expects(:cancel) diff --git a/plugins/discourse-subscriptions/spec/requests/admin/subscriptions_controller_spec.rb.lock b/plugins/discourse-subscriptions/spec/requests/admin/subscriptions_controller_spec.rb.lock new file mode 100644 index 00000000000..e69de29bb2d