mirror of
https://github.com/discourse/discourse.git
synced 2024-12-13 05:43:54 +08:00
d63f1826fe
We want to allow admins to make new required fields apply to existing users. In order for this to work we need to have a way to make those users fill up the fields on their next page load. This is very similar to how adding a 2FA requirement post-fact works. Users will be redirected to a page where they can fill up the remaining required fields, and until they do that they won't be able to do anything else.
131 lines
3.9 KiB
Ruby
131 lines
3.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class UsersEmailController < ApplicationController
|
|
requires_login only: %i[index update]
|
|
|
|
skip_before_action :check_xhr, only: %i[show_confirm_old_email show_confirm_new_email]
|
|
|
|
skip_before_action :redirect_to_login_if_required,
|
|
:redirect_to_profile_if_required,
|
|
only: %i[
|
|
show_confirm_old_email
|
|
show_confirm_new_email
|
|
confirm_old_email
|
|
confirm_new_email
|
|
]
|
|
|
|
def index
|
|
end
|
|
|
|
def create
|
|
return render json: failed_json, status: 410 if !SiteSetting.enable_secondary_emails
|
|
|
|
params.require(:email)
|
|
user = fetch_user_from_params
|
|
|
|
RateLimiter.new(user, "email-hr-#{request.remote_ip}", 6, 1.hour).performed!
|
|
RateLimiter.new(user, "email-min-#{request.remote_ip}", 3, 1.minute).performed!
|
|
|
|
updater = EmailUpdater.new(guardian: guardian, user: user)
|
|
updater.change_to(params[:email], add: true)
|
|
|
|
return render_json_error(updater.errors.full_messages) if updater.errors.present?
|
|
|
|
render body: nil
|
|
rescue RateLimiter::LimitExceeded
|
|
render_json_error(I18n.t("rate_limiter.slow_down"))
|
|
end
|
|
|
|
def update
|
|
params.require(:email)
|
|
user = fetch_user_from_params
|
|
|
|
RateLimiter.new(user, "email-hr-#{request.remote_ip}", 6, 1.hour).performed!
|
|
RateLimiter.new(user, "email-min-#{request.remote_ip}", 3, 1.minute).performed!
|
|
|
|
updater = EmailUpdater.new(guardian: guardian, user: user)
|
|
updater.change_to(params[:email])
|
|
|
|
return render_json_error(updater.errors.full_messages) if updater.errors.present?
|
|
|
|
render body: nil
|
|
rescue RateLimiter::LimitExceeded
|
|
render_json_error(I18n.t("rate_limiter.slow_down"))
|
|
end
|
|
|
|
def confirm_new_email
|
|
change_request = load_change_request(:new)
|
|
|
|
result =
|
|
run_second_factor!(SecondFactor::Actions::ConfirmEmail, target_user: change_request.user)
|
|
|
|
if result.no_second_factors_enabled? || result.second_factor_auth_completed?
|
|
updater = EmailUpdater.new
|
|
if updater.confirm(params[:token]) == :complete
|
|
updater.user.user_stat.reset_bounce_score!
|
|
render json: success_json
|
|
else
|
|
render json: { error: I18n.t("change_email.already_done") }, status: 400
|
|
end
|
|
end
|
|
end
|
|
|
|
def show_confirm_new_email
|
|
return render "default/empty" if request.format.html?
|
|
|
|
change_request = load_change_request(:new)
|
|
|
|
render json: {
|
|
new_email: change_request.new_email,
|
|
old_email: change_request.old_email,
|
|
token: params[:token],
|
|
}
|
|
end
|
|
|
|
def confirm_old_email
|
|
load_change_request(:old)
|
|
|
|
updater = EmailUpdater.new
|
|
if updater.confirm(params[:token]) == :authorizing_new
|
|
render json: success_json
|
|
else
|
|
render json: { error: I18n.t("change_email.already_done") }, status: 400
|
|
end
|
|
end
|
|
|
|
def show_confirm_old_email
|
|
return render "default/empty" if request.format.html?
|
|
|
|
change_request = load_change_request(:old)
|
|
|
|
render json: {
|
|
new_email: change_request.new_email,
|
|
old_email: change_request.old_email,
|
|
token: params[:token],
|
|
}
|
|
end
|
|
|
|
private
|
|
|
|
def load_change_request(type)
|
|
expires_now
|
|
|
|
token = EmailToken.confirmable(params[:token], scope: EmailToken.scopes[:email_update])
|
|
|
|
raise Discourse::NotFound if !token || !token.user
|
|
|
|
if current_user && token.user.id != current_user.id
|
|
raise Discourse::InvalidAccess.new "You are logged in, but this email change link belongs to another user account. Please log out and try again."
|
|
end
|
|
|
|
change_request_params =
|
|
if type == :old
|
|
{ old_email_token_id: token.id, change_state: EmailChangeRequest.states[:authorizing_old] }
|
|
elsif type == :new
|
|
{ new_email_token_id: token.id, change_state: EmailChangeRequest.states[:authorizing_new] }
|
|
end
|
|
|
|
token.user&.email_change_requests&.find_by!(**change_request_params)
|
|
end
|
|
end
|