SECURITY: Disable access to "activate-account" route for existing users

This commit is contained in:
Penar Musaraj 2024-12-27 13:42:03 -05:00 committed by Roman Rizzi
parent 17116c440b
commit b89cf9b443
No known key found for this signature in database
GPG Key ID: 64024A71CE7330D3
5 changed files with 39 additions and 9 deletions

View File

@ -17,11 +17,15 @@ import { i18n } from "discourse-i18n";
export default RouteTemplate(
class extends Component {
@service siteSettings;
@service currentUser;
@tracked accountActivated = false;
@tracked isLoading = false;
@tracked needsApproval = false;
@tracked errorMessage = null;
@tracked
errorMessage = this.currentUser
? i18n("user.activate_account.already_done")
: null;
get signupStep() {
if (this.needsApproval) {

View File

@ -1105,6 +1105,8 @@ class UsersController < ApplicationController
def activate_account
expires_now
raise Discourse::NotFound if current_user.present?
respond_to do |format|
format.html { render "default/empty" }
format.json { render json: success_json }
@ -1113,6 +1115,7 @@ class UsersController < ApplicationController
def perform_account_activation
raise Discourse::InvalidAccess.new if honeypot_or_challenge_fails?(params)
raise Discourse::NotFound if current_user.present?
if @user = EmailToken.confirm(params[:token], scope: EmailToken.scopes[:signup])
# Log in the user unless they need to be approved

View File

@ -597,11 +597,17 @@ Discourse::Application.routes.draw do
format: "json",
}
put "#{root_path}/password-reset/:token" => "users#password_reset_update"
get "#{root_path}/activate-account/:token" => "users#activate_account"
get "#{root_path}/activate-account/:token" => "users#activate_account",
:constraints => {
token: /[0-9a-f]+/,
}
put(
{ "#{root_path}/activate-account/:token" => "users#perform_account_activation" }.merge(
index == 1 ? { as: "perform_activate_account" } : {},
),
{
"#{root_path}/activate-account/:token" => "users#perform_account_activation",
:constraints => {
token: /[0-9a-f]+/,
},
}.merge(index == 1 ? { as: "perform_activate_account" } : {}),
)
get "#{root_path}/confirm-old-email/:token" => "users_email#show_confirm_old_email"

View File

@ -60,13 +60,20 @@ RSpec.describe UsersController do
before { UsersController.any_instance.stubs(:honeypot_or_challenge_fails?).returns(false) }
context "with invalid token" do
it "return success" do
put "/u/activate-account/invalid-token"
context "with inexistent token" do
it "return 404" do
put "/u/activate-account/123abc"
expect(response.status).to eq(422)
end
end
context "with invalid token" do
it "return 404" do
put "/u/activate-account/123%2f%252e"
expect(response.status).to eq(404)
end
end
context "with valid token" do
context "with welcome message" do
it "enqueues a welcome message if the user object indicates so" do
@ -158,6 +165,16 @@ RSpec.describe UsersController do
expect(response.status).to eq(200)
end
end
context "when user is already logged in" do
it "returns 404" do
sign_in(user1)
get "/u/activate-account/some-token"
expect(response.status).to eq(404)
end
end
end
context "when cookies contains a destination URL" do

View File

@ -67,7 +67,7 @@ shared_examples "login scenarios" do |login_page_object|
login_form.open.fill(username: "john", password: "supersecurepassword").click_login
expect(page).to have_css(".not-activated-modal")
visit "/u/activate-account/invalid"
visit "/u/activate-account/123abc"
activate_account.click_activate_account
expect(activate_account).to have_error