class RegistrationsController < Devise::RegistrationsController # Needed to have Current.tenant available in Devise's controllers prepend_before_action :load_tenant_data before_action :load_oauths, only: [:new] before_action :set_page_title_new, only: [:new] before_action :set_page_title_edit, only: [:edit] # Override create to check whether email registration is possible def create ts = Current.tenant.tenant_setting email = sign_up_params[:email] # Handle invitations is_invitation = sign_up_params[:invitation_token].present? is_invitation_valid = true invitation = nil if is_invitation invitation = Invitation.find_by(email: email) if invitation.nil? || invitation.token_digest != Digest::SHA256.hexdigest(sign_up_params[:invitation_token]) || invitation.accepted_at.present? flash[:alert] = t('errors.unauthorized') redirect_to new_user_registration_path and return end ActiveRecord::Base.transaction do invitation.accepted_at = Time.now invitation.save! # Sign up user without confirmation email and log them in user = User.new(email: email, full_name: sign_up_params[:full_name], password: sign_up_params[:password], password_confirmation: sign_up_params[:password], status: "active") user.skip_confirmation user.save! sign_in(user) flash[:notice] = t('devise.registrations.signed_up') redirect_to root_path end return end # ... if not an invitation, continue with normal registration ... # Check if email registration is allowed if ts.email_registration_policy == "none_allowed" || (ts.email_registration_policy == "custom_domains_allowed" && !allowed_domain?(email)) flash[:alert] = t('errors.email_domain_not_allowed') redirect_to new_user_registration_path and return end super end # Override update to check whether provided email is allowed def update ts = Current.tenant.tenant_setting email = account_update_params[:email] if ts.email_registration_policy == "custom_domains_allowed" && !allowed_domain?(email) flash[:alert] = t('errors.email_domain_not_allowed') redirect_to edit_user_registration_path and return end super end # Override destroy to soft delete def destroy resource.status = "deleted" resource.email = "#{SecureRandom.alphanumeric(16)}@deleted.com" resource.full_name = t('defaults.deleted_user_full_name') resource.skip_confirmation resource.save Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name) set_flash_message :notice, :destroyed yield resource if block_given? respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) } end def send_set_password_instructions user = User.find_by_email(params[:email]) if user.present? user.send_reset_password_instructions end render json: { success: true } # always return true, even if user not found end protected def after_inactive_sign_up_path_for(resource) if Current.tenant.tenant_setting.is_private # Redirect to log in page, since root page only visible to logged in users new_user_session_path else super end end private def allowed_domain?(email) allowed_email_domains = Current.tenant.tenant_setting.allowed_email_domains return false unless email.count('@') == 1 return true if allowed_email_domains.blank? registering_domain = email.split('@').last allowed_domains = allowed_email_domains.split(',') allowed_domains.include?(registering_domain) end def set_page_title_new @page_title = t('common.forms.auth.sign_up') end def set_page_title_edit @page_title = t('common.forms.auth.profile_settings') end end