Use hash-based flash objects to render complex flash messages
Since flash objects can only be String, Hash or Array (notably excluding SafeBuffers), then this approach is necessary to render complex html in a safe manner. Each local can be treated as an (unsafe) string, and therefore escaped normally when rendered into the template. The template (and translation strings) can contain html since they are no longer stored in the flash as a plain string. Fixes #3215
This commit is contained in:
parent
f6818bb2ed
commit
24f6aeda6a
6 changed files with 43 additions and 5 deletions
|
@ -66,7 +66,7 @@ class ConfirmationsController < ApplicationController
|
|||
flash[:error] = t "confirmations.confirm_resend.failure", :name => params[:display_name]
|
||||
else
|
||||
UserMailer.signup_confirm(user, user.tokens.create).deliver_later
|
||||
flash[:notice] = t "confirmations.confirm_resend.success_html", :email => user.email, :sender => Settings.email_from
|
||||
flash[:notice] = { :partial => "confirmations/resend_success_flash", :locals => { :email => user.email, :sender => Settings.email_from } }
|
||||
end
|
||||
|
||||
redirect_to login_path
|
||||
|
|
|
@ -68,4 +68,14 @@ module ApplicationHelper
|
|||
|
||||
data
|
||||
end
|
||||
|
||||
# If the flash is a hash, then it will be a partial with a hash of locals, so we can call `render` on that
|
||||
# This allows us to render html into a flash message in a safe manner.
|
||||
def render_flash(flash)
|
||||
if flash.is_a?(Hash)
|
||||
render flash.with_indifferent_access
|
||||
else
|
||||
flash
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
1
app/views/confirmations/_resend_success_flash.html.erb
Normal file
1
app/views/confirmations/_resend_success_flash.html.erb
Normal file
|
@ -0,0 +1 @@
|
|||
<%= t "confirmations.confirm_resend.success_html", :email => email, :sender => sender %>
|
|
@ -4,7 +4,7 @@
|
|||
<source srcset="<%= image_path "notice.svg" %>" type="image/svg+xml" />
|
||||
<%= image_tag("notice.png", :srcset => image_path("notice.svg"), :class => "small_icon", :border => 0) %>
|
||||
</picture>
|
||||
<div class="message"><%= flash[:error] %></div>
|
||||
<div class="message"><%= render_flash(flash[:error]) %></div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
|||
<source srcset="<%= image_path "notice.svg" %>" type="image/svg+xml"></source>
|
||||
<%= image_tag("notice.png", :srcset => image_path("notice.svg"), :class => "small_icon", :border => 0) %>
|
||||
</picture>
|
||||
<div class="message"><%= flash[:warning] %></div>
|
||||
<div class="message"><%= render_flash(flash[:warning]) %></div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
@ -24,6 +24,6 @@
|
|||
<source srcset="<%= image_path "notice.svg" %>" type="image/svg+xml"></source>
|
||||
<%= image_tag("notice.png", :srcset => image_path("notice.svg"), :class => "small_icon", :border => 0) %>
|
||||
</picture>
|
||||
<div class="message"><%= flash[:notice] %></div>
|
||||
<div class="message"><%= render_flash(flash[:notice]) %></div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -211,7 +211,8 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
|
|||
|
||||
assert_response :redirect
|
||||
assert_redirected_to login_path
|
||||
assert_match(/sent a new confirmation/, flash[:notice])
|
||||
assert_equal("confirmations/resend_success_flash", flash[:notice][:partial])
|
||||
assert_equal({ :email => user.email, :sender => Settings.email_from }, flash[:notice][:locals])
|
||||
|
||||
email = ActionMailer::Base.deliveries.last
|
||||
|
||||
|
|
26
test/system/confirmation_resend.rb
Normal file
26
test/system/confirmation_resend.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
require "application_system_test_case"
|
||||
|
||||
class ConfirmationResendSystemTest < ApplicationSystemTestCase
|
||||
def setup
|
||||
@user = build(:user)
|
||||
visit user_new_path
|
||||
|
||||
fill_in "Email", :with => @user.email
|
||||
fill_in "Email Confirmation", :with => @user.email
|
||||
fill_in "Display Name", :with => @user.display_name
|
||||
fill_in "Password", :with => "testtest"
|
||||
fill_in "Confirm Password", :with => "testtest"
|
||||
click_button "Sign Up"
|
||||
|
||||
check "I have read and agree to the above contributor terms"
|
||||
check "I have read and agree to the Terms of Use"
|
||||
click_button "Continue"
|
||||
end
|
||||
|
||||
test "flash message should not contain raw html" do
|
||||
visit user_confirm_resend_path(@user)
|
||||
|
||||
assert page.has_content?("sent a new confirmation")
|
||||
assert_not page.has_content?("<br />")
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue