Skip to content

Commit

Permalink
Send email to current email address on request to update email
Browse files Browse the repository at this point in the history
This would ensure unintended email address update don't go unnoticed.
  • Loading branch information
sonalkr132 committed Jun 16, 2020
1 parent 004752f commit 36a8012
Show file tree
Hide file tree
Showing 15 changed files with 119 additions and 5 deletions.
2 changes: 1 addition & 1 deletion app/controllers/email_confirmations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def create
# used to resend confirmation mail for unconfirmed_email validation
def unconfirmed
if current_user.generate_confirmation_token && current_user.save
Mailer.delay.email_reset(current_user)
Mailer.delay.email_reset(current_user.id)
flash[:notice] = t("profiles.update.confirmation_mail_sent")
else
flash[:notice] = t("try_again")
Expand Down
7 changes: 6 additions & 1 deletion app/controllers/profiles_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def update
@user = current_user.clone
if @user.update(params_user)
if @user.unconfirmed_email
Mailer.delay.email_reset(current_user)
send_reset_emails
flash[:notice] = t(".confirmation_mail_sent")
else
flash[:notice] = t(".updated")
Expand Down Expand Up @@ -58,4 +58,9 @@ def set_cache_headers
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end

def send_reset_emails
Mailer.delay.email_reset_update(current_user.id)
Mailer.delay.email_reset(current_user.id)
end
end
10 changes: 8 additions & 2 deletions app/mailers/mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@ class Mailer < ApplicationMailer
default_url_options[:host] = Gemcutter::HOST
default_url_options[:protocol] = Gemcutter::PROTOCOL

def email_reset(user)
@user = User.find(user["id"])
def email_reset(user_id)
@user = User.find(user_id)
mail to: @user.unconfirmed_email,
subject: I18n.t("mailer.confirmation_subject",
default: "Please confirm your email address with RubyGems.org")
end

def email_reset_update(user_id)
@user = User.find(user_id)
mail to: @user.email,
subject: I18n.t("mailer.email_reset_update.subject")
end

def email_confirmation(user)
@user = User.find(user["id"])
mail to: @user.email,
Expand Down
45 changes: 45 additions & 0 deletions app/views/mailer/email_reset_update.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<% @title = t(".title") %>
<% @sub_title = "Hi #{@user.handle}" %>

<!-- Body -->
<table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#ffffff">
<tr>
<td class="content-spacing" style="font-size:0pt; line-height:0pt; text-align:left" width="20"></td>
<td>
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="spacer" style="font-size:0pt; line-height:0pt; text-align:center; width:100%; min-width:100%"><tr><td height="35" class="spacer" style="font-size:0pt; line-height:0pt; text-align:center; width:100%; min-width:100%">&nbsp;</td></tr></table>

<div class="h3-1-center" style="color:#1e1e1e; font-family:Georgia, serif; min-width:auto !important; font-size:20px; line-height:26px;">
<p>
You have requested email update on RubyGems.org. Once you click on confirmation link sent to your new email address, your account will be disassociated from
<%= @user.email %>.
</p>
<p>
New email address: <strong><%= @user.unconfirmed_email %></strong>
</p>
<br/>
<p>If this email update is expected, you do not need to take further action.</p>
<p>
<strong>Only if this email update is unexpected</strong>
please take immediate steps to secure your account and gems:
</p>
<ol>
<li>If you suspect your account was compromised:
<ul>
<li><%= link_to("Change your password", new_password_url) %></li>
<li><%= link_to("Reset your API key", edit_profile_url) %></li>
<li><%= link_to("Enable multifactor authentication", edit_profile_url) %></li>
</ul>
</li>
<li><%= link_to("Report this", page_url("security")) %> incident to RubyGems.org</li>
</ol>
</div>

<table width="100%" border="0" cellspacing="0" cellpadding="0" class="spacer" style="font-size:0pt; line-height:0pt; text-align:center; width:100%; min-width:100%"><tr><td height="30" class="spacer" style="font-size:0pt; line-height:0pt; text-align:center; width:100%; min-width:100%">&nbsp;</td></tr></table>

<table width="100%" border="0" cellspacing="0" cellpadding="0" class="spacer" style="font-size:0pt; line-height:0pt; text-align:center; width:100%; min-width:100%"><tr><td height="35" class="spacer" style="font-size:0pt; line-height:0pt; text-align:center; width:100%; min-width:100%">&nbsp;</td></tr></table>

</td>
<td class="content-spacing" style="font-size:0pt; line-height:0pt; text-align:left" width="20"></td>
</tr>
</table>
<!-- END Body -->
3 changes: 3 additions & 0 deletions config/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ de:
gem_yanked:
subject:
title:
email_reset_update:
subject:
title:
news:
show:
title:
Expand Down
3 changes: 3 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ en:
gem_yanked:
subject: Gem %{gem} yanked from RubyGems.org
title: GEM YANKED
email_reset_update:
subject: You have requested email address update on RubyGems.org
title: EMAIL UPDATE REQUESTED
news:
show:
title: New Releases — All Gems
Expand Down
3 changes: 3 additions & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ es:
gem_yanked:
subject:
title:
email_reset_update:
subject:
title:
news:
show:
title: Nuevos lanzamientos — Todas las Gemas
Expand Down
3 changes: 3 additions & 0 deletions config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ fr:
gem_yanked:
subject:
title:
email_reset_update:
subject:
title:
news:
show:
title: Nouvelles Versions - Toutes les Gems
Expand Down
3 changes: 3 additions & 0 deletions config/locales/ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ ja:
gem_yanked:
subject:
title:
email_reset_update:
subject:
title:
news:
show:
title: 新しくリリースされたGem
Expand Down
3 changes: 3 additions & 0 deletions config/locales/nl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ nl:
gem_yanked:
subject:
title:
email_reset_update:
subject:
title:
news:
show:
title:
Expand Down
3 changes: 3 additions & 0 deletions config/locales/pt-BR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ pt-BR:
gem_yanked:
subject:
title:
email_reset_update:
subject:
title:
news:
show:
title: Novos Releases - Todas as Gems
Expand Down
3 changes: 3 additions & 0 deletions config/locales/zh-CN.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ zh-CN:
gem_yanked:
subject:
title:
email_reset_update:
subject:
title:
news:
show:
title: 全部新发布 Gems
Expand Down
3 changes: 3 additions & 0 deletions config/locales/zh-TW.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ zh-TW:
gem_yanked:
subject:
title:
email_reset_update:
subject:
title:
news:
show:
title: 最新發佈
Expand Down
27 changes: 27 additions & 0 deletions test/functional/profiles_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,33 @@ class ProfilesControllerTest < ActionController::TestCase
refute_equal "cannotchange@tothis.com", @user.unconfirmed_email
end
end

context "updating email" do
setup do
@current_email = "john@doe.com"
@user = create(:user, email: @current_email)
sign_in_as(@user)
@new_email = "change@tothis.com"
end

should "set unconfirmed email and confirmation token" do
put :update, params: { user: { email: @new_email, password: @user.password } }
assert_equal @new_email, @user.unconfirmed_email
assert @user.confirmation_token
end

should "not update the current email" do
put :update, params: { user: { email: @new_email, password: @user.password } }
assert_equal @current_email, @user.email
end

should "send email reset mails to new and current email addresses" do
Mailer.expects(:email_reset).times(1)
Mailer.expects(:email_reset_update).times(1)
put :update, params: { user: { email: @new_email, password: @user.password } }
Delayed::Worker.new.work_off
end
end
end
context "on DELETE to destroy" do
context "correct password" do
Expand Down
6 changes: 5 additions & 1 deletion test/mailers/previews/mailer_preview.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
class MailerPreview < ActionMailer::Preview
def email_reset
Mailer.email_reset(User.last)
Mailer.email_reset(User.last.id)
end

def email_reset_update
Mailer.email_reset_update(User.last.id)
end

def email_confirmation
Expand Down

0 comments on commit 36a8012

Please sign in to comment.