From 2d92ec1e100d2db8d98c791258b8ea115044975d Mon Sep 17 00:00:00 2001 From: sarken Date: Wed, 1 Feb 2023 02:18:33 -0500 Subject: [PATCH] AO3-6440 Configure admin and user reset token expiry separately (#4447) AO3-6440 Configure admin and user reset token expiry separately --- app/models/admin.rb | 1 + .../reset_password_instructions.html.erb | 2 +- .../reset_password_instructions.text.erb | 2 +- .../set_password_notification.html.erb | 1 + .../set_password_notification.text.erb | 2 ++ config/config.yml | 3 ++ config/locales/mailers/en.yml | 13 ++++++-- features/admins/authenticate_admins.feature | 33 +++++++++++++++++++ features/step_definitions/admin_steps.rb | 5 +++ 9 files changed, 58 insertions(+), 4 deletions(-) diff --git a/app/models/admin.rb b/app/models/admin.rb index 480691a79d8..ffb697411a4 100644 --- a/app/models/admin.rb +++ b/app/models/admin.rb @@ -8,6 +8,7 @@ class Admin < ApplicationRecord :recoverable, :validatable, password_length: ArchiveConfig.ADMIN_PASSWORD_LENGTH_MIN..ArchiveConfig.ADMIN_PASSWORD_LENGTH_MAX, + reset_password_within: ArchiveConfig.DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES.days, lock_strategy: :none, unlock_strategy: :none diff --git a/app/views/admin/mailer/reset_password_instructions.html.erb b/app/views/admin/mailer/reset_password_instructions.html.erb index 8aa4bd97658..6e873b60dd0 100644 --- a/app/views/admin/mailer/reset_password_instructions.html.erb +++ b/app/views/admin/mailer/reset_password_instructions.html.erb @@ -2,6 +2,6 @@

<%= t("mailer.general.greeting.formal", name: style_bold(@resource.login)).html_safe %>

<%= t(".intro") %>

<%= style_link t(".link_title_html"), edit_admin_password_url(reset_password_token: @token) %>

-

<%= t(".expiration") %>

+

<%= t(".expiration", count: ArchiveConfig.DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES) %>

<%= t(".unrequested") %>

<% end %> diff --git a/app/views/admin/mailer/reset_password_instructions.text.erb b/app/views/admin/mailer/reset_password_instructions.text.erb index 7523e8f5813..233dac358d6 100644 --- a/app/views/admin/mailer/reset_password_instructions.text.erb +++ b/app/views/admin/mailer/reset_password_instructions.text.erb @@ -5,7 +5,7 @@ <%= edit_admin_password_url(reset_password_token: @token) %> -<%= t(".expiration") %> +<%= t(".expiration", count: ArchiveConfig.DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES) %> <%= t(".unrequested") %> diff --git a/app/views/admin_mailer/set_password_notification.html.erb b/app/views/admin_mailer/set_password_notification.html.erb index d40ad65aa8f..ac5054537b7 100644 --- a/app/views/admin_mailer/set_password_notification.html.erb +++ b/app/views/admin_mailer/set_password_notification.html.erb @@ -4,4 +4,5 @@

<%= style_work_metadata_label(t(".username")) %><%= @admin.login %>

<%= style_work_metadata_label(t(".url")) %><%= style_link(new_admin_session_url, new_admin_session_url) %>

<%= t(".finish_html", set_password_link: style_link(t(".set_password"), edit_admin_password_url(reset_password_token: @token))) %>

+

<%= t(".expiration_html", count: ArchiveConfig.DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES, request_reset_link: style_link(t(".request_reset"), new_admin_password_url)) %>

<% end %> diff --git a/app/views/admin_mailer/set_password_notification.text.erb b/app/views/admin_mailer/set_password_notification.text.erb index 15018d0cec4..b3571b87561 100644 --- a/app/views/admin_mailer/set_password_notification.text.erb +++ b/app/views/admin_mailer/set_password_notification.text.erb @@ -7,4 +7,6 @@ <%= work_metadata_label(t(".url")) %><%= new_admin_session_url %> <%= t(".finish", set_password_url: edit_admin_password_url(reset_password_token: @token)) %> + +<%= t(".expiration", count: ArchiveConfig.DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES, request_reset_url: new_admin_password_url) %> <% end %> diff --git a/config/config.yml b/config/config.yml index 693c6e50ece..dca7fee0bbc 100644 --- a/config/config.yml +++ b/config/config.yml @@ -19,6 +19,9 @@ REMEMBERED_SESSION_LENGTH_IN_MONTHS: 3 # also change the message (and vice versa). DAYS_UNTIL_RESET_PASSWORD_LINK_EXPIRES: 7 +# This also affects the link included in the admin account creation email. +DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES: 5 + # email addresses RETURN_ADDRESS: 'do-not-reply@example.org' SPAM_ALERT_ADDRESS: 'abuse-discuss@example.org' diff --git a/config/locales/mailers/en.yml b/config/locales/mailers/en.yml index 97648de90ea..1fd73f667ca 100644 --- a/config/locales/mailers/en.yml +++ b/config/locales/mailers/en.yml @@ -40,9 +40,16 @@ en: created: Your AO3 admin account has been created. username: Admin username url: Admin login URL - finish: "Please follow this link to set your password so you can log in: %{set_password_url}" + finish: "Please follow this link to set your password so you can log in: %{set_password_url}." finish_html: "Please %{set_password_link} so you can log in." set_password: "follow this link to set your password" + request_reset: request a password reset + expiration_html: + one: "The link to set your password is good for %{count} day. If it no longer works, you can %{request_reset_link} and use the link that will be emailed to you instead." + other: "The link to set your password is good for %{count} days. If it no longer works, you can %{request_reset_link} and use the link that will be emailed to you instead." + expiration: + one: "The link to set your password is good for %{count} day. If it no longer works, you can request a password reset and use the link that will be emailed to you instead: %{request_reset_url}." + other: "The link to set your password is good for %{count} days. If it no longer works, you can request a password reset and use the link that will be emailed to you instead: %{request_reset_url}." kudo_mailer: batch_kudo_notification: subject: "[%{app_name}] You've got kudos!" @@ -346,5 +353,7 @@ en: subject: "[%{app_name}] Reset your admin password" intro: "Someone has requested a password reset for your account. You can change your account password by following the link below and entering your new password:" link_title_html: "Change my password." - expiration: "If you do not use this link to reset your password within a week, it will expire, and you will have to request a new one." + expiration: + one: "If you do not use this link to reset your password within %{count} day, it will expire, and you will have to request a new one." + other: "If you do not use this link to reset your password within %{count} days, it will expire, and you will have to request a new one." unrequested: "If you did not request this password reset, you may ignore this email and your previous password will continue to work." diff --git a/features/admins/authenticate_admins.feature b/features/admins/authenticate_admins.feature index 9f38c60519e..4cb266d1bab 100644 --- a/features/admins/authenticate_admins.feature +++ b/features/admins/authenticate_admins.feature @@ -36,6 +36,19 @@ Feature: Authenticate Admin Users Then I should see "Your password has been changed successfully. You are now signed in." And I should see "Hi, admin!" + Scenario: Set password link expires. + Given the following admin exists + | login | password | email | + | admin | testpassword | admin@example.com | + Then 1 email should be delivered to "admin@example.com" + When it is past the admin password reset token's expiration date + And I follow "follow this link to set your password" in the email + Then I should see "Set My Admin Password" + When I fill in "New password" with "newpassword" + And I fill in "Confirm new password" with "newpassword" + And I press "Set Admin Password" + Then I should see "Reset password token has expired, please request a new one" + Scenario: Admin can log in. Given I have no users And the following admin exists @@ -88,6 +101,26 @@ Feature: Authenticate Admin Users Then I should see "Your password has been changed successfully. You are now signed in." And I should see "Hi, admin!" + Scenario: Reset password link expires. + Given the following admin exists + | login | password | email | + | admin | testpassword | admin@example.com | + And all emails have been delivered + When I go to the admin login page + And I follow "Forgot admin password?" + Then I should see "Forgotten your admin password?" + When I fill in "Admin user name" with "admin" + And I press "Reset Admin Password" + Then I should see "Check your email for instructions on how to reset your password." + And 1 email should be delivered to "admin@example.com" + When it is past the admin password reset token's expiration date + And I follow "Change my password" in the email + Then I should see "Set My Admin Password" + When I fill in "New password" with "newpassword" + And I fill in "Confirm new password" with "newpassword" + And I press "Set Admin Password" + Then I should see "Reset password token has expired, please request a new one" + Scenario: Locked admin cannot sign in. Given the admin "admin" is locked When I go to the admin login page diff --git a/features/step_definitions/admin_steps.rb b/features/step_definitions/admin_steps.rb index f32604486f4..48cfb160da3 100644 --- a/features/step_definitions/admin_steps.rb +++ b/features/step_definitions/admin_steps.rb @@ -298,6 +298,11 @@ fill_in("user_id", with: user_id) end +When "it is past the admin password reset token's expiration date" do + days = ArchiveConfig.DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES + 1 + step "it is currently #{days} days from now" +end + ### THEN Then (/^the translation information should still be filled in$/) do