diff --git a/app/models/card/eventable/system_commenter.rb b/app/models/card/eventable/system_commenter.rb
index 0e76700b3..5c7defc29 100644
--- a/app/models/card/eventable/system_commenter.rb
+++ b/app/models/card/eventable/system_commenter.rb
@@ -1,4 +1,6 @@
class Card::Eventable::SystemCommenter
+ include ERB::Util
+
attr_reader :card, :event
def initialize(card, event)
@@ -15,25 +17,53 @@ class Card::Eventable::SystemCommenter
def comment_body
case event.action
when "card_assigned"
- "#{event.creator.name} assigned this to #{event.assignees.pluck(:name).to_sentence}."
+ "#{creator_name} assigned this to #{assignee_names}."
when "card_unassigned"
- "#{event.creator.name} unassigned from #{event.assignees.pluck(:name).to_sentence}."
+ "#{creator_name} unassigned from #{assignee_names}."
when "card_closed"
- "Moved to “Done” by #{event.creator.name}"
+ "Moved to “Done” by #{creator_name}"
when "card_reopened"
- "Reopened by #{event.creator.name}"
+ "Reopened by #{creator_name}"
when "card_postponed"
- "#{event.creator.name} moved this to “Not Now”"
+ "#{creator_name} moved this to “Not Now”"
when "card_auto_postponed"
"Moved to “Not Now” due to inactivity"
when "card_title_changed"
- "#{event.creator.name} changed the title from “#{event.particulars.dig('particulars', 'old_title')}” to “#{event.particulars.dig('particulars', 'new_title')}”."
+ "#{creator_name} changed the title from “#{old_title}” to “#{new_title}”."
when "card_board_changed"
- "#{event.creator.name} moved this from “#{event.particulars.dig('particulars', 'old_board')}” to “#{event.particulars.dig('particulars', 'new_board')}”."
+ "#{creator_name} moved this from “#{old_board}” to “#{new_board}”."
when "card_triaged"
- "#{event.creator.name} moved this to “#{event.particulars.dig('particulars', 'column')}”"
+ "#{creator_name} moved this to “#{column}”"
when "card_sent_back_to_triage"
- "#{event.creator.name} moved this back to “Maybe?”"
+ "#{creator_name} moved this back to “Maybe?”"
end
end
+
+ def creator_name
+ h event.creator.name
+ end
+
+ def assignee_names
+ h event.assignees.pluck(:name).to_sentence
+ end
+
+ def old_title
+ h event.particulars.dig("particulars", "old_title")
+ end
+
+ def new_title
+ h event.particulars.dig("particulars", "new_title")
+ end
+
+ def old_board
+ h event.particulars.dig("particulars", "old_board")
+ end
+
+ def new_board
+ h event.particulars.dig("particulars", "new_board")
+ end
+
+ def column
+ h event.particulars.dig("particulars", "column")
+ end
end
diff --git a/test/models/card/eventable/system_commenter_test.rb b/test/models/card/eventable/system_commenter_test.rb
index 57bef880b..012dd4a45 100644
--- a/test/models/card/eventable/system_commenter_test.rb
+++ b/test/models/card/eventable/system_commenter_test.rb
@@ -33,6 +33,20 @@ class Card::Eventable::SystemCommenterTest < ActiveSupport::TestCase
end
end
+ test "escapes html in comment body" do
+ users(:david).update! name: "Injected"
+ Current.session = sessions(:david)
+
+ assert_difference -> { @card.comments.count }, 1 do
+ @card.toggle_assignment users(:kevin)
+ end
+
+ comment = @card.comments.last
+ html = comment.body.body.to_html
+ assert_includes html, "<em>Injected</em> assigned this to Kevin."
+ refute_includes html, "Injected"
+ end
+
test "don't notify on system comments" do
@card.watch_by(users(:david))