mirror of
https://github.com/manyfold3d/manyfold.git
synced 2026-10-22 03:32:18 -05:00
226 lines
6.5 KiB
Ruby
226 lines
6.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class Users::RegistrationsController < Devise::RegistrationsController
|
|
rate_limit to: 3, within: 2.minutes, only: :create
|
|
|
|
before_action :random_delay, only: [:create, :cancel]
|
|
before_action :configure_sign_up_params, only: [:create]
|
|
before_action :detect_if_first_use, only: [:edit, :update]
|
|
before_action :load_languages, only: [:edit, :update]
|
|
before_action :configure_account_update_params, only: [:update]
|
|
skip_before_action :check_for_first_use, only: [:edit, :update]
|
|
|
|
respond_to :html, :json
|
|
|
|
# GET /resource/sign_up
|
|
def new
|
|
authorize User
|
|
super
|
|
end
|
|
|
|
# GET /resource/edit
|
|
def edit
|
|
authorize current_user
|
|
if @first_use
|
|
render "first_use"
|
|
else
|
|
super
|
|
end
|
|
end
|
|
|
|
# POST /users
|
|
def create
|
|
authorize User
|
|
if AltchaSolution.verify_and_save(params.permit(:altcha)[:altcha])
|
|
super do |user|
|
|
opts = {}
|
|
opts [:approved] = false if SiteSettings.approve_signups
|
|
if SiteSettings.autocreate_creator_for_new_users
|
|
creator_username = params.dig(:user, :creators_attributes, "0", :slug).presence || params.dig(:user, :creators_attributes, "0", :name)&.parameterize
|
|
opts[:username] ||= "u;#{creator_username}" if creator_username
|
|
end
|
|
opts.compact!
|
|
user.update(opts) unless opts.empty?
|
|
end
|
|
if @user.persisted?
|
|
ModeratorMailer.with(user: @user).new_approval.deliver_later if SiteSettings.approve_signups && SiteSettings.email_configured?
|
|
end
|
|
else
|
|
build_resource
|
|
clean_up_passwords(resource)
|
|
flash[:alert] = t(".altcha_failed")
|
|
render :new, status: :unprocessable_content
|
|
end
|
|
end
|
|
|
|
# PUT /resource
|
|
def update
|
|
authorize current_user
|
|
if @first_use
|
|
if current_user.update(account_update_params.merge(reset_password_token: nil))
|
|
bypass_sign_in current_user
|
|
redirect_to root_path, notice: t("devise.registrations.update.setup_complete")
|
|
else
|
|
render "first_use", status: :unprocessable_content
|
|
end
|
|
else
|
|
super
|
|
end
|
|
end
|
|
|
|
# DELETE /resource
|
|
def destroy
|
|
authorize current_user
|
|
super
|
|
end
|
|
|
|
# GET /resource/cancel
|
|
# Forces the session data which is usually expired after sign
|
|
# in to be expired now. This is useful if the user wants to
|
|
# cancel oauth signing in/up in the middle of the process,
|
|
# removing all OAuth session data.
|
|
def cancel
|
|
authorize :"users/registrations"
|
|
super
|
|
end
|
|
|
|
protected
|
|
|
|
def configure_sign_up_params
|
|
devise_parameter_sanitizer.permit(:sign_up, keys: [:username, creators_attributes: [:slug, :name]])
|
|
end
|
|
|
|
def configure_account_update_params
|
|
devise_parameter_sanitizer.permit(:account_update) do |user|
|
|
user.permit(
|
|
:email,
|
|
:username,
|
|
:password,
|
|
:password_confirmation,
|
|
:current_password,
|
|
:interface_language,
|
|
:sensitive_content_handling,
|
|
:sort_order,
|
|
pagination_settings: [
|
|
:per_page
|
|
],
|
|
tag_cloud_settings: [
|
|
:threshold,
|
|
:heatmap,
|
|
:keypair,
|
|
:sorting
|
|
],
|
|
file_list_settings: [
|
|
:hide_presupported_versions
|
|
],
|
|
renderer_settings: [
|
|
:grid_width,
|
|
:grid_depth,
|
|
:show_grid,
|
|
:enable_pan_zoom,
|
|
:background_colour,
|
|
:object_colour,
|
|
:render_style,
|
|
:auto_load_max_size
|
|
],
|
|
problem_settings: Problem::CATEGORIES,
|
|
tour_state: {
|
|
completed: {
|
|
add: []
|
|
}
|
|
}
|
|
)
|
|
end
|
|
end
|
|
|
|
def detect_if_first_use
|
|
if current_user.first_use?
|
|
@first_use = true
|
|
devise_parameter_sanitizer.permit(:account_update, keys: [:username])
|
|
end
|
|
end
|
|
|
|
# The path used after sign up.
|
|
def after_sign_up_path_for(resource)
|
|
SiteSettings.approve_signups ? root_path : welcome_path
|
|
end
|
|
|
|
# The path used after sign up for inactive accounts.
|
|
# def after_inactive_sign_up_path_for(resource)
|
|
# super(resource)
|
|
# end
|
|
|
|
# The path used after edit/update
|
|
def after_update_path_for(resource)
|
|
edit_user_registration_path
|
|
end
|
|
|
|
def pagination_json(settings)
|
|
return nil unless settings
|
|
{
|
|
"per_page" => settings[:per_page].to_i
|
|
}
|
|
end
|
|
|
|
def tag_cloud_json(settings)
|
|
return nil unless settings
|
|
{
|
|
"threshold" => settings[:threshold].to_i,
|
|
"heatmap" => settings[:heatmap] == "1",
|
|
"keypair" => settings[:keypair] == "1",
|
|
"sorting" => settings[:sorting].to_s
|
|
}
|
|
end
|
|
|
|
def file_list_json(settings)
|
|
return nil unless settings
|
|
{
|
|
"hide_presupported_versions" => settings[:hide_presupported_versions] == "1"
|
|
}
|
|
end
|
|
|
|
def renderer_json(settings)
|
|
return nil unless settings
|
|
{
|
|
"grid_width" => settings[:grid_width].to_i,
|
|
"grid_depth" => settings[:grid_width].to_i, # Store width in both for now. See #834
|
|
"show_grid" => settings[:show_grid] == "1",
|
|
"enable_pan_zoom" => settings[:enable_pan_zoom] == "1",
|
|
"background_colour" => settings[:background_colour],
|
|
"object_colour" => settings[:object_colour],
|
|
"render_style" => settings[:render_style],
|
|
"auto_load_max_size" => settings[:auto_load_max_size].to_i
|
|
}
|
|
end
|
|
|
|
def tour_state_json(current_state, data)
|
|
current_state ||= User::DEFAULT_TOUR_STATE
|
|
return current_state unless data
|
|
{
|
|
"completed" => (current_state["completed"] + data.dig("completed", "add")).uniq # Merge in added completions
|
|
}
|
|
end
|
|
|
|
def load_languages
|
|
@languages = [[t("devise.registrations.general_settings.interface_language.autodetect"), nil]].concat(
|
|
I18n.available_locales.map { |locale| [I18nData.languages(locale)[locale.to_s.first(2).upcase.to_s]&.capitalize, locale] }
|
|
)
|
|
end
|
|
|
|
def update_resource(resource, data)
|
|
# Transform form data to correct types
|
|
data[:pagination_settings] = pagination_json(data[:pagination_settings])
|
|
data[:renderer_settings] = renderer_json(data[:renderer_settings])
|
|
data[:tag_cloud_settings] = tag_cloud_json(data[:tag_cloud_settings])
|
|
data[:file_list_settings] = file_list_json(data[:file_list_settings])
|
|
data[:tour_state] = tour_state_json(resource.tour_state, data[:tour_state])
|
|
data.compact!
|
|
# Require password if important details have changed
|
|
if (data[:email] && (data[:email] != resource.email)) || data[:password].present?
|
|
resource.update_with_password(data)
|
|
else
|
|
resource.update_without_password(data.except(:email, :password, :password_confirmation, :current_password))
|
|
end
|
|
end
|
|
end
|