I'm building a white-label service and we need a logic where users should have a chance to authenticate with the same email through different domains (example1.com, example2.com).
I'm using ruby-on-rails 6.1.7, ruby 2.7.0p0 and device 4.8.1
I have tried to do that by using this documentation and I have added to my devise initializer this line config.authentication_keys = [ :email, :domain ]
. After that, I created a migrations file where I'm adding indexes:
add_column :users, :domain, :string, null: false, default: 'example.com'
remove_index :users, :email
add_index :users, [:email, :domain], unique: true
also added to Users model:
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, authentication_keys: [:domain, :email]
def self.find_for_authentication
where(domain: warden_conditions[:domain], email: warden_conditions[:email]).first
end
and registration controller where I create a new account looks like this:
def create
build_resource(sign_up_params)
resource.domain = request.domain
puts
puts '*' * 100
p resource
puts '*' * 100
puts
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
sign_up(resource_name, resource)
else
render json: { success: true, location: '/registrations/success' }
end
else
render json: { errors: resource.errors.messages }, status: 422
end
end
now I am faced with a problem. In the database, I have an account with the email [email protected] and the domain example1.com, so now when I'm trying to create a new account for the same person with the same email, but from a different domain example2.com I'm getting an error that user with this email exists. I see that devise does the wrong query to the database and this query looks like this User Exists? (1.6ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "[email protected]"], ["LIMIT", 1]]
, but it should look like this User Exists? (1.6ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 AND "users"."domain" = $2 LIMIT $3 [["email", "[email protected]"], ["domain", "example.com"], ["LIMIT", 1]]
That I've missed? Thanks for any help.
CodePudding user response:
From the linked page
Check that you do not have :validatable in the devise call on the Model
If you do, :validatable will prevent more than one record having the same email, even in different subdomains.
CodePudding user response:
I think this link would help. https://dev.to/casseylottman/adding-a-field-to-your-sign-up-form-with-devise-10i1
You need to override the create
function.