2019-04-29 19:27:42 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
require "rotp"
|
2016-03-07 12:45:33 -06:00
|
|
|
|
2022-07-27 21:27:38 -05:00
|
|
|
RSpec.describe UsersEmailController do
|
2023-11-09 16:47:59 -06:00
|
|
|
fab!(:user)
|
2021-11-25 01:34:39 -06:00
|
|
|
let!(:email_token) { Fabricate(:email_token, user: user) }
|
2023-11-09 16:47:59 -06:00
|
|
|
fab!(:moderator)
|
2019-11-20 01:31:25 -06:00
|
|
|
|
|
|
|
describe "#confirm-new-email" do
|
2023-01-09 05:18:21 -06:00
|
|
|
it "does not redirect to login for signed out accounts, this route works fine as anon user" do
|
2021-11-25 01:34:39 -06:00
|
|
|
get "/u/confirm-new-email/invalidtoken"
|
2019-11-20 01:31:25 -06:00
|
|
|
|
2020-10-06 22:02:24 -05:00
|
|
|
expect(response.status).to eq(200)
|
2019-11-20 01:31:25 -06:00
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "does not redirect to login for signed out accounts on login_required sites, this route works fine as anon user" do
|
2021-01-19 18:52:25 -06:00
|
|
|
SiteSetting.login_required = true
|
2021-11-25 01:34:39 -06:00
|
|
|
get "/u/confirm-new-email/invalidtoken"
|
2021-01-19 18:52:25 -06:00
|
|
|
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "errors out for invalid tokens" do
|
2019-11-20 01:31:25 -06:00
|
|
|
sign_in(user)
|
|
|
|
|
2024-01-30 04:32:42 -06:00
|
|
|
get "/u/confirm-new-email/invalidtoken.json"
|
2017-08-30 23:06:56 -05:00
|
|
|
|
2024-01-30 04:32:42 -06:00
|
|
|
expect(response.status).to eq(404)
|
2016-03-07 13:40:11 -06:00
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "does not change email if accounts mismatch for a signed in user" do
|
2020-02-19 17:52:21 -06:00
|
|
|
updater = EmailUpdater.new(guardian: user.guardian, user: user)
|
2023-01-09 05:18:21 -06:00
|
|
|
updater.change_to("bubblegum@adventuretime.ooo")
|
2016-03-07 13:40:11 -06:00
|
|
|
|
2019-11-20 01:31:25 -06:00
|
|
|
old_email = user.email
|
2016-03-07 13:40:11 -06:00
|
|
|
|
2019-11-20 01:31:25 -06:00
|
|
|
sign_in(moderator)
|
2017-08-30 23:06:56 -05:00
|
|
|
|
2024-01-30 04:32:42 -06:00
|
|
|
put "/u/confirm-new-email/#{email_token.token}.json"
|
|
|
|
expect(response.status).to eq(404)
|
2021-11-25 01:34:39 -06:00
|
|
|
expect(user.reload.email).to eq(old_email)
|
2016-03-07 13:40:11 -06:00
|
|
|
end
|
|
|
|
|
2019-11-20 01:31:25 -06:00
|
|
|
context "with a valid user" do
|
2020-02-19 17:52:21 -06:00
|
|
|
let(:updater) { EmailUpdater.new(guardian: user.guardian, user: user) }
|
2016-03-07 13:40:11 -06:00
|
|
|
|
|
|
|
before do
|
2019-11-20 01:31:25 -06:00
|
|
|
sign_in(user)
|
2023-01-09 05:18:21 -06:00
|
|
|
updater.change_to("bubblegum@adventuretime.ooo")
|
2016-03-07 13:40:11 -06:00
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "confirms with a correct token" do
|
2017-02-20 03:37:01 -06:00
|
|
|
user.user_stat.update_columns(bounce_score: 42, reset_bounce_score_after: 1.week.from_now)
|
|
|
|
|
2024-01-30 04:32:42 -06:00
|
|
|
put "/u/confirm-new-email/#{updater.change_req.new_email_token.token}.json"
|
2017-06-01 03:19:42 -05:00
|
|
|
|
2024-01-30 04:32:42 -06:00
|
|
|
expect(response.status).to eq(200)
|
2017-02-20 03:37:01 -06:00
|
|
|
user.reload
|
|
|
|
expect(user.user_stat.bounce_score).to eq(0)
|
|
|
|
expect(user.user_stat.reset_bounce_score_after).to eq(nil)
|
2023-01-09 05:18:21 -06:00
|
|
|
expect(user.email).to eq("bubblegum@adventuretime.ooo")
|
2018-05-08 14:23:45 -05:00
|
|
|
end
|
2016-03-07 13:40:11 -06:00
|
|
|
end
|
2023-01-04 16:08:55 -06:00
|
|
|
|
|
|
|
it "destroys email tokens associated with the old email after the new email is confirmed" do
|
|
|
|
SiteSetting.enable_secondary_emails = true
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
email_token =
|
|
|
|
user.email_tokens.create!(email: user.email, scope: EmailToken.scopes[:password_reset])
|
2023-01-04 16:08:55 -06:00
|
|
|
|
|
|
|
updater = EmailUpdater.new(guardian: user.guardian, user: user)
|
2023-01-09 05:18:21 -06:00
|
|
|
updater.change_to("bubblegum@adventuretime.ooo")
|
2023-01-04 16:08:55 -06:00
|
|
|
|
|
|
|
sign_in(user)
|
2024-01-30 04:32:42 -06:00
|
|
|
put "/u/confirm-new-email/#{updater.change_req.new_email_token.token}.json"
|
|
|
|
expect(response.status).to eq(200)
|
2023-01-04 16:08:55 -06:00
|
|
|
|
|
|
|
new_password = SecureRandom.hex
|
2023-01-09 05:18:21 -06:00
|
|
|
put "/u/password-reset/#{email_token.token}.json", params: { password: new_password }
|
2023-01-04 16:08:55 -06:00
|
|
|
expect(response.parsed_body["success"]).to eq(false)
|
2023-01-09 05:18:21 -06:00
|
|
|
expect(response.parsed_body["message"]).to eq(
|
|
|
|
I18n.t("password_reset.no_token", base_url: Discourse.base_url),
|
|
|
|
)
|
2023-01-04 16:08:55 -06:00
|
|
|
expect(user.reload.confirm_password?(new_password)).to eq(false)
|
|
|
|
end
|
2016-03-07 13:40:11 -06:00
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
describe "#confirm-old-email" do
|
|
|
|
it "errors out for invalid tokens" do
|
2019-11-20 01:31:25 -06:00
|
|
|
sign_in(user)
|
|
|
|
|
2024-01-30 04:32:42 -06:00
|
|
|
get "/u/confirm-old-email/invalidtoken.json"
|
2019-11-20 01:31:25 -06:00
|
|
|
|
2024-01-30 04:32:42 -06:00
|
|
|
expect(response.status).to eq(404)
|
2019-11-20 01:31:25 -06:00
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "bans change when accounts do not match" do
|
2019-11-20 01:31:25 -06:00
|
|
|
sign_in(user)
|
2020-02-19 17:52:21 -06:00
|
|
|
updater = EmailUpdater.new(guardian: moderator.guardian, user: moderator)
|
2023-01-09 05:18:21 -06:00
|
|
|
email_change_request = updater.change_to("bubblegum@adventuretime.ooo")
|
2019-11-20 01:31:25 -06:00
|
|
|
|
2024-01-30 04:32:42 -06:00
|
|
|
get "/u/confirm-old-email/#{email_change_request.old_email_token.token}.json"
|
2019-11-20 01:31:25 -06:00
|
|
|
|
2024-01-30 04:32:42 -06:00
|
|
|
expect(response.status).to eq(403)
|
2019-11-20 01:31:25 -06:00
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
context "with valid old token" do
|
|
|
|
it "confirms with a correct token" do
|
2019-11-20 01:31:25 -06:00
|
|
|
sign_in(moderator)
|
2020-02-19 17:52:21 -06:00
|
|
|
updater = EmailUpdater.new(guardian: moderator.guardian, user: moderator)
|
2023-01-09 05:18:21 -06:00
|
|
|
email_change_request = updater.change_to("bubblegum@adventuretime.ooo")
|
2019-11-20 01:31:25 -06:00
|
|
|
|
2024-01-30 04:32:42 -06:00
|
|
|
get "/u/confirm-old-email/#{email_change_request.old_email_token.token}.json"
|
2019-11-20 01:31:25 -06:00
|
|
|
|
|
|
|
expect(response.status).to eq(200)
|
2024-01-30 04:32:42 -06:00
|
|
|
expect(response.parsed_body["old_email"]).to eq(moderator.email)
|
|
|
|
expect(response.parsed_body["new_email"]).to eq("bubblegum@adventuretime.ooo")
|
2019-11-20 01:31:25 -06:00
|
|
|
|
2024-01-30 04:32:42 -06:00
|
|
|
put "/u/confirm-old-email/#{email_change_request.old_email_token.token}.json"
|
2019-11-20 01:31:25 -06:00
|
|
|
|
2024-01-30 04:32:42 -06:00
|
|
|
expect(response.status).to eq(200)
|
2019-11-20 01:31:25 -06:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
describe "#create" do
|
|
|
|
it "has an email token" do
|
2020-06-10 11:11:49 -05:00
|
|
|
sign_in(user)
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
expect {
|
|
|
|
post "/u/#{user.username}/preferences/email.json",
|
|
|
|
params: {
|
|
|
|
email: "bubblegum@adventuretime.ooo",
|
|
|
|
}
|
|
|
|
}.to change(EmailChangeRequest, :count)
|
2020-06-10 11:11:49 -05:00
|
|
|
|
|
|
|
emailChangeRequest = EmailChangeRequest.last
|
|
|
|
expect(emailChangeRequest.old_email).to eq(nil)
|
2023-01-09 05:18:21 -06:00
|
|
|
expect(emailChangeRequest.new_email).to eq("bubblegum@adventuretime.ooo")
|
2020-06-10 11:11:49 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
describe "#update" do
|
2016-03-07 12:45:33 -06:00
|
|
|
it "requires you to be logged in" do
|
2023-01-09 05:18:21 -06:00
|
|
|
put "/u/#{user.username}/preferences/email.json",
|
|
|
|
params: {
|
|
|
|
email: "bubblegum@adventuretime.ooo",
|
|
|
|
}
|
2018-01-11 21:15:10 -06:00
|
|
|
expect(response.status).to eq(403)
|
2016-03-07 12:45:33 -06:00
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
context "when logged in" do
|
|
|
|
before { sign_in(user) }
|
2016-03-07 12:45:33 -06:00
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "raises an error without an email parameter" do
|
2018-01-11 21:15:10 -06:00
|
|
|
put "/u/#{user.username}/preferences/email.json"
|
|
|
|
expect(response.status).to eq(400)
|
2016-03-07 12:45:33 -06:00
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "raises an error without an invalid email" do
|
2018-08-20 20:54:34 -05:00
|
|
|
put "/u/#{user.username}/preferences/email.json", params: { email: "sam@not-email.com'" }
|
|
|
|
expect(response.status).to eq(422)
|
2020-06-02 21:13:25 -05:00
|
|
|
expect(response.body).to include("Email is invalid")
|
2018-08-20 20:54:34 -05:00
|
|
|
end
|
|
|
|
|
2016-03-07 12:45:33 -06:00
|
|
|
it "raises an error if you can't edit the user's email" do
|
2021-11-25 01:34:39 -06:00
|
|
|
SiteSetting.email_editable = false
|
2017-08-30 23:06:56 -05:00
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
put "/u/#{user.username}/preferences/email.json",
|
|
|
|
params: {
|
|
|
|
email: "bubblegum@adventuretime.ooo",
|
|
|
|
}
|
2016-03-07 12:45:33 -06:00
|
|
|
expect(response).to be_forbidden
|
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
context "when the new email address is taken" do
|
2019-05-06 22:12:20 -05:00
|
|
|
fab!(:other_user) { Fabricate(:coding_horror) }
|
2017-08-30 23:06:56 -05:00
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
context "when hide_email_address_taken is disabled" do
|
|
|
|
before { SiteSetting.hide_email_address_taken = false }
|
2017-10-04 10:41:08 -05:00
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "raises an error" do
|
2021-11-25 01:34:39 -06:00
|
|
|
put "/u/#{user.username}/preferences/email.json", params: { email: other_user.email }
|
2018-06-05 02:29:17 -05:00
|
|
|
expect(response).to_not be_successful
|
2017-10-04 10:41:08 -05:00
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "raises an error if there is whitespace too" do
|
|
|
|
put "/u/#{user.username}/preferences/email.json",
|
|
|
|
params: {
|
|
|
|
email: "#{other_user.email} ",
|
|
|
|
}
|
2018-06-05 02:29:17 -05:00
|
|
|
expect(response).to_not be_successful
|
2017-10-04 10:41:08 -05:00
|
|
|
end
|
2016-03-07 12:45:33 -06:00
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
context "when hide_email_address_taken is enabled" do
|
|
|
|
before { SiteSetting.hide_email_address_taken = true }
|
2017-08-30 23:06:56 -05:00
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "responds with success" do
|
2021-11-25 01:34:39 -06:00
|
|
|
put "/u/#{user.username}/preferences/email.json", params: { email: other_user.email }
|
2018-06-07 03:11:09 -05:00
|
|
|
expect(response.status).to eq(200)
|
2017-10-04 10:41:08 -05:00
|
|
|
end
|
2016-03-07 12:45:33 -06:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
context "when new email is different case of existing email" do
|
|
|
|
fab!(:other_user) { Fabricate(:user, email: "case.insensitive@gmail.com") }
|
2016-03-07 12:45:33 -06:00
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "raises an error" do
|
|
|
|
put "/u/#{user.username}/preferences/email.json",
|
|
|
|
params: {
|
|
|
|
email: other_user.email.upcase,
|
|
|
|
}
|
2018-06-05 02:29:17 -05:00
|
|
|
expect(response).to_not be_successful
|
2016-03-07 12:45:33 -06:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "raises an error when new email domain is present in blocked_email_domains site setting" do
|
2020-07-26 19:23:54 -05:00
|
|
|
SiteSetting.blocked_email_domains = "mailinator.com"
|
2017-08-30 23:06:56 -05:00
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
put "/u/#{user.username}/preferences/email.json",
|
|
|
|
params: {
|
|
|
|
email: "not_good@mailinator.com",
|
|
|
|
}
|
2018-06-05 02:29:17 -05:00
|
|
|
expect(response).to_not be_successful
|
2016-03-07 12:45:33 -06:00
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
it "raises an error when new email domain is not present in allowed_email_domains site setting" do
|
2020-07-26 19:23:54 -05:00
|
|
|
SiteSetting.allowed_email_domains = "discourse.org"
|
2017-08-30 23:06:56 -05:00
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
put "/u/#{user.username}/preferences/email.json",
|
|
|
|
params: {
|
|
|
|
email: "bubblegum@adventuretime.ooo",
|
|
|
|
}
|
2018-06-05 02:29:17 -05:00
|
|
|
expect(response).to_not be_successful
|
2016-03-07 12:45:33 -06:00
|
|
|
end
|
|
|
|
|
2023-01-09 05:18:21 -06:00
|
|
|
context "with success" do
|
|
|
|
it "has an email token" do
|
2017-08-30 23:06:56 -05:00
|
|
|
expect do
|
2023-01-09 05:18:21 -06:00
|
|
|
put "/u/#{user.username}/preferences/email.json",
|
|
|
|
params: {
|
|
|
|
email: "bubblegum@adventuretime.ooo",
|
|
|
|
}
|
2017-08-30 23:06:56 -05:00
|
|
|
end.to change(EmailChangeRequest, :count)
|
2016-03-07 12:45:33 -06:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|