I'd like to know whether a confirmation instructions email (which is sent when a new user creates account using email address) sent from a vanilla Forem instance is wrapped by <html>...</html>
.
I have run into a possible bug, but because I only have a customized Forem instance online and no other testing environment that can send email outbound, I am not able to decide whether it is a Forem bug or mine.
Situation
Whenever I tried to browse any user's "Confirmation instructions" emails from the admin Member Manager UI (i.e. /admin/member_manager/users/****/email_messages/****
), the page crashed with the following error:
ActionView::Template::Error (undefined method `+' for nil:NilClass):
40: <h2>Email content</h2>
41: <p><em>The content is previewed below without formatting</em></p>
42: <div class="crayons-card my-5 p-5">
43: <%= @email.html_content.html_safe %>
44: </div>
45: </div>
46: </div>
It apparently comes from app/views/admin/email_messages/show.html.erb, and the source of the error is in the following method of app/models/email_message.rb:
def html_content
html_index = content.index("<html")
closing_html_index = content.index("</html>") + 7
content[html_index..closing_html_index]
end
It turns out that "Confirmation instructions" emails my instance sending out contain no <html>
tags and content.index("</html>")
returns nil.
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii"><p>Welcome [your_address]!</p>
<p>You can confirm your account email through the link below:</p>
<p><a href="[omitted]">Confirm my account</a></p>
<img src="[omitted]" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;">
The email_message.rb logic above seems to have been implemented in this PR:
Look for <html> tags instead of <body> for email viewing #14547
What type of PR is this? (check all applicable)
- [x] Bug Fix
Description
When looking for the closing </body>
tag for rendering email messages within the app, it sometimes fails, specifically for the Devise-generated confirmation email. This should fix that, since it grabs the entire <html>
of the email.
Related Tickets & Documents
https://app.honeybadger.io/fault/66984/0032f7edebb6170a8eb849a0abb390a1
QA Instructions, Screenshots, Recordings
- Go into
rails console
-
EmailMessage.last.html_content
should render something
UI accessibility concerns?
Nope
Added/updated tests?
- [x] No, and this is why: Not sure how to test this view -- unfortunately testing in production
😬
[Forem core team only] How will this change be communicated?
- [x] Will communicate with the appropriate teams
[optional] Are there any post deployment tasks we need to perform?
No
[optional] What gif best describes this PR or how it makes you feel?
but whether the solution works as intended is not clear, because it says:
Added/updated tests?
- [X] No, and this is why: Not sure how to test this view -- unfortunately testing in production 😬
Since the controller seems to read template from app/views/devise/mailer/confirmation_instructions.html.erb:
<% if @user.creator? %>
<%= render partial: "creator_confirmation_instructions", locals: { url: confirmation_url(@resource, confirmation_token: @token) } %>
<% else %>
<p>Welcome <%= @email %>!</p>
<p>You can confirm your account email through the link below:</p>
<p><%= link_to "Confirm my account", confirmation_url(@resource, confirmation_token: @token) %></p>
<% end %>
Judging from that the partial creator_confirmation_instructions
contains a complete <html>
structure, it is strongly suspected that DeviseMailer just sends out the bare paragraphs shown above when @user.creator?
is false, thus the same error as mine should happen on a vanilla Forem too, though I have no definite proof.
Workaround
FWIW I have currently modified app/models/email_message.rb as follows to avoid errors:
def html_content
if html_index = content.index("<html")
closing_html_index = content.index("</html>") + 7
content[html_index..closing_html_index]
else
content[content.index("\r\n\r\n")..-1]
end
end
Top comments (1)
I can confirm I have the same error with my own instances. This is an error that occurs out of the box.