Forem Creators and Builders 🌱

yheuhtozr
yheuhtozr

Posted on

Are confirmation instructions emails really sent with <html> tag?

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>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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;">
Enter fullscreen mode Exit fullscreen mode

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

  1. Go into rails console
  2. 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?

"Probably!"

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 %>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
alexgallacher profile image
Alex

I can confirm I have the same error with my own instances. This is an error that occurs out of the box.