Skip to content

Commit

Permalink
AO3-6772 Create reset_password_instructions mailer preview (#4895)
Browse files Browse the repository at this point in the history
* AO3-6772 Create reset_password_instructions mailer preview

* AO3-6772 Remove useless html_safe call

The url is in the form of "https://archiveofourown.org/users/password/edit?reset_password_token=Token"

Nothing in this url could become mangled by getting html escaped, it's a
standard url and the Token is generated with SecureRandom.urlsafe_base64
without padding, so can only contain A-Z, a-z, 0-9, - and _.
So it does not need to be marked as html_safe.

Additionally, the admin version of this mail also doesn't call html_safe
on the url, neither does devise's own implementation of it.
  • Loading branch information
Bilka2 committed Sep 8, 2024
1 parent d4a8dfa commit 927ca65
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 18 deletions.
20 changes: 8 additions & 12 deletions app/mailers/archive_devise_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,14 @@ class ArchiveDeviseMailer < Devise::Mailer
def reset_password_instructions(record, token, options = {})
@user = record
@token = token
if @user.is_a?(Admin)
subject = t("admin.mailer.reset_password_instructions.subject",
subject = if @user.is_a?(Admin)
t("admin.mailer.reset_password_instructions.subject",
app_name: ArchiveConfig.APP_SHORT_NAME)
devise_mail(record, :reset_password_instructions,
options.merge(subject: subject))
else
I18n.with_locale(@user.preference.locale.iso) do
subject = t("users.mailer.reset_password_instructions.subject",
app_name: ArchiveConfig.APP_SHORT_NAME)
devise_mail(record, :reset_password_instructions,
options.merge(subject: subject))
end
end
else
t("users.mailer.reset_password_instructions.subject",
app_name: ArchiveConfig.APP_SHORT_NAME)
end
devise_mail(record, :reset_password_instructions,
options.merge(subject: subject))
end
end
13 changes: 11 additions & 2 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,18 @@ def prevent_password_resets?
end

protected
def first_save?
self.new_record?

def first_save?
self.new_record?
end

# Override of Devise method for email sending to set I18n.locale
# Based on https://github.com/heartcombo/devise/blob/v4.9.3/lib/devise/models/authenticatable.rb#L200
def send_devise_notification(notification, *args)
I18n.with_locale(preference.locale.iso) do
devise_mailer.send(notification, self, *args).deliver_now
end
end

public

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<% content_for :message do %>
<p><%= t("mailer.general.greeting.formal_html", name: style_bold(@resource.login)) %></p>
<p><%= t(".intro") %></p>
<p><%= style_link t(".link_title"), edit_user_password_url(reset_password_token: @token).html_safe %></p>
<p><%= style_link t(".link_title"), edit_user_password_url(reset_password_token: @token) %></p>
<p><%= t(".expiration") %></p>
<p><%= t(".unrequested") %></p>
<% end %>
3 changes: 2 additions & 1 deletion features/step_definitions/email_custom_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

Given "a locale with translated emails" do
FactoryBot.create(:locale, iso: "new")
# The footer keys are used in all emails
# The footer keys are used in most emails
I18n.backend.store_translations(:new, { mailer: { general: { footer: { general: { about: { html: "Translated footer", text: "Translated footer" } } } } } })
I18n.backend.store_translations(:new, { kudo_mailer: { batch_kudo_notification: { subject: "Translated subject" } } })
I18n.backend.store_translations(:new, { users: { mailer: { reset_password_instructions: { subject: "Translated subject" } } } })
end

Given "the user {string} enables translated emails" do |user|
Expand Down
20 changes: 20 additions & 0 deletions features/users/authenticate_users.feature
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,26 @@ Feature: User Authentication
And I press "Log In"
Then I should not see "Hi, sam"

Scenario: Translated reset password email
Given a locale with translated emails
And the following activated users exist
| login | email | password |
| sam | sam@example.com | password |
| notsam | notsam@example.com | password |
And the user "sam" enables translated emails
And all emails have been delivered
When I request a password reset for "sam@example.com"
Then I should see "Check your email for instructions on how to reset your password."
And 1 email should be delivered to "sam@example.com"
And the email should have "Translated subject" in the subject
And the email to "sam" should be translated
# notsam didn't enable translated emails
When I request a password reset for "notsam@example.com"
Then I should see "Check your email for instructions on how to reset your password."
And 1 email should be delivered to "notsam@example.com"
And the email should have "Reset your password" in the subject
And the email to "notsam" should be non-translated

Scenario: Forgot password, logging in with email address
Given I have no users
And the following activated user exists
Expand Down
9 changes: 9 additions & 0 deletions test/mailers/previews/archive_devise_mailer_preview.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

class ArchiveDeviseMailerPreview < ApplicationMailerPreview
# Sent when a user requests a password reset
def reset_password_instructions
user = create(:user, :for_mailer_preview)
ArchiveDeviseMailer.reset_password_instructions(user, "fakeToken")
end
end
4 changes: 2 additions & 2 deletions test/mailers/previews/kudo_mailer_preview.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ def batch_kudo_notification
user = create(:user)
work = create(:work)
guest_count = params[:guest_count] || 1
user_count = params[:user_count].to_i || 1
names = Array.new(user_count) { "User#{Faker::Alphanumeric.alpha(number: 8)}" }
user_count = params[:user_count] || 1
names = Array.new(user_count.to_i) { "User#{Faker::Alphanumeric.alpha(number: 8)}" }
hash = { "Work_#{work.id}": { guest_count:, names: } }
KudoMailer.batch_kudo_notification(user.id, hash.to_json)
end
Expand Down

0 comments on commit 927ca65

Please sign in to comment.