feat: new accounts controller for signup+onboarding (#8804)
* feat: add v2 accounts controller * feat: allow empty account and user name * feat: ensure and is present for v1 signup * test: remove validation checks * chore: apply suggestions * chore: revert en.yml formatting * chore: line at EOF * fix: routes --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
class AccountBuilder
|
||||
include CustomExceptions::Account
|
||||
pattr_initialize [:account_name!, :email!, :confirmed, :user, :user_full_name, :user_password, :super_admin, :locale]
|
||||
pattr_initialize [:account_name, :email!, :confirmed, :user, :user_full_name, :user_password, :super_admin, :locale]
|
||||
|
||||
def perform
|
||||
if @user.nil?
|
||||
@@ -21,6 +21,16 @@ class AccountBuilder
|
||||
|
||||
private
|
||||
|
||||
def user_full_name
|
||||
# the empty string ensures that not-null constraint is not violated
|
||||
@user_full_name || ''
|
||||
end
|
||||
|
||||
def account_name
|
||||
# the empty string ensures that not-null constraint is not violated
|
||||
@account_name || ''
|
||||
end
|
||||
|
||||
def validate_email
|
||||
address = ValidEmail2::Address.new(@email)
|
||||
if address.valid? # && !address.disposable?
|
||||
@@ -39,7 +49,7 @@ class AccountBuilder
|
||||
end
|
||||
|
||||
def create_account
|
||||
@account = Account.create!(name: @account_name, locale: I18n.locale)
|
||||
@account = Account.create!(name: account_name, locale: I18n.locale)
|
||||
Current.account = @account
|
||||
end
|
||||
|
||||
@@ -64,7 +74,7 @@ class AccountBuilder
|
||||
@user = User.new(email: @email,
|
||||
password: user_password,
|
||||
password_confirmation: user_password,
|
||||
name: @user_full_name)
|
||||
name: user_full_name)
|
||||
@user.type = 'SuperAdmin' if @super_admin
|
||||
@user.confirm if @confirmed
|
||||
@user.save!
|
||||
|
||||
@@ -5,11 +5,13 @@ class Api::V1::AccountsController < Api::BaseController
|
||||
skip_before_action :authenticate_user!, :set_current_user, :handle_with_exception,
|
||||
only: [:create], raise: false
|
||||
before_action :check_signup_enabled, only: [:create]
|
||||
before_action :ensure_account_name, only: [:create]
|
||||
before_action :validate_captcha, only: [:create]
|
||||
before_action :fetch_account, except: [:create]
|
||||
before_action :check_authorization, except: [:create]
|
||||
|
||||
rescue_from CustomExceptions::Account::InvalidEmail,
|
||||
CustomExceptions::Account::InvalidParams,
|
||||
CustomExceptions::Account::UserExists,
|
||||
CustomExceptions::Account::UserErrors,
|
||||
with: :render_error_response
|
||||
@@ -53,6 +55,17 @@ class Api::V1::AccountsController < Api::BaseController
|
||||
|
||||
private
|
||||
|
||||
def ensure_account_name
|
||||
# ensure that account_name and user_full_name is present
|
||||
# this is becuase the account builder and the models validations are not triggered
|
||||
# this change is to align the behaviour with the v2 accounts controller
|
||||
# since these values are not required directly there
|
||||
return if account_params[:account_name].present?
|
||||
return if account_params[:user_full_name].present?
|
||||
|
||||
raise CustomExceptions::Account::InvalidParams.new({})
|
||||
end
|
||||
|
||||
def get_cache_keys
|
||||
{
|
||||
label: fetch_value_for_key(params[:id], Label.name.underscore),
|
||||
|
||||
48
app/controllers/api/v2/accounts_controller.rb
Normal file
48
app/controllers/api/v2/accounts_controller.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
class Api::V2::AccountsController < Api::BaseController
|
||||
include AuthHelper
|
||||
|
||||
skip_before_action :authenticate_user!, :set_current_user, :handle_with_exception,
|
||||
only: [:create], raise: false
|
||||
before_action :check_signup_enabled, only: [:create]
|
||||
before_action :validate_captcha, only: [:create]
|
||||
before_action :fetch_account, except: [:create]
|
||||
before_action :check_authorization, except: [:create]
|
||||
|
||||
rescue_from CustomExceptions::Account::InvalidEmail,
|
||||
CustomExceptions::Account::UserExists,
|
||||
CustomExceptions::Account::UserErrors,
|
||||
with: :render_error_response
|
||||
|
||||
def create
|
||||
@user, @account = AccountBuilder.new(
|
||||
email: account_params[:email],
|
||||
user_password: account_params[:password],
|
||||
user: current_user
|
||||
).perform
|
||||
if @user
|
||||
send_auth_headers(@user)
|
||||
render 'api/v1/accounts/create', format: :json, locals: { resource: @user }
|
||||
else
|
||||
render_error_response(CustomExceptions::Account::SignupFailed.new({}))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fetch_account
|
||||
@account = current_user.accounts.find(params[:id])
|
||||
@current_account_user = @account.account_users.find_by(user_id: current_user.id)
|
||||
end
|
||||
|
||||
def account_params
|
||||
params.permit(:account_name, :email, :name, :password, :locale, :domain, :support_email, :auto_resolve_duration, :user_full_name)
|
||||
end
|
||||
|
||||
def check_signup_enabled
|
||||
raise ActionController::RoutingError, 'Not Found' if GlobalConfigService.load('ENABLE_ACCOUNT_SIGNUP', 'false') == 'false'
|
||||
end
|
||||
|
||||
def validate_captcha
|
||||
raise ActionController::InvalidAuthenticityToken, 'Invalid Captcha' unless ChatwootCaptcha.new(params[:h_captcha_client_response]).valid?
|
||||
end
|
||||
end
|
||||
@@ -32,7 +32,6 @@ class Account < ApplicationRecord
|
||||
check_for_column: false
|
||||
}.freeze
|
||||
|
||||
validates :name, presence: true
|
||||
validates :auto_resolve_duration, numericality: { greater_than_or_equal_to: 1, less_than_or_equal_to: 999, allow_nil: true }
|
||||
validates :domain, length: { maximum: 100 }
|
||||
|
||||
|
||||
@@ -68,8 +68,7 @@ class User < ApplicationRecord
|
||||
# work because :validatable in devise overrides this.
|
||||
# validates_uniqueness_of :email, scope: :account_id
|
||||
|
||||
validates :email, :name, presence: true
|
||||
validates_length_of :name, minimum: 1, maximum: 255
|
||||
validates :email, presence: true
|
||||
|
||||
has_many :account_users, dependent: :destroy_async
|
||||
has_many :accounts, through: :account_users
|
||||
|
||||
Reference in New Issue
Block a user