mirror of https://github.com/docusealco/docuseal
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
2.0 KiB
69 lines
2.0 KiB
# frozen_string_literal: true
|
|
|
|
# Bridges Clerk's apex-cookie SSO into Devise. When a request arrives with a
|
|
# valid Clerk session JWT belonging to the Bloombilt Staff org, find or
|
|
# auto-provision the matching Devise User and call sign_in so the rest of the
|
|
# app (which authorizes via Devise + CanCanCan) sees the request as
|
|
# authenticated. Devise's password login at /users/sign_in is preserved as
|
|
# emergency access.
|
|
module ClerkDeviseBridge
|
|
extend ActiveSupport::Concern
|
|
|
|
STAFF_ORG_SLUG = 'bloombilt-staff'
|
|
|
|
included do
|
|
before_action :sign_in_from_clerk_session, unless: :devise_controller?
|
|
end
|
|
|
|
private
|
|
|
|
def sign_in_from_clerk_session
|
|
return if user_signed_in?
|
|
|
|
clerk_user = safe_clerk_user
|
|
return unless clerk_user
|
|
|
|
return unless clerk.organization&.slug == STAFF_ORG_SLUG
|
|
|
|
email = primary_email(clerk_user)
|
|
return unless email
|
|
|
|
user = User.active.find_by(email: email) || provision_user_for_clerk(email, clerk_user)
|
|
return unless user
|
|
|
|
sign_in(user, store: true)
|
|
end
|
|
|
|
def safe_clerk_user
|
|
clerk.user
|
|
rescue StandardError => e
|
|
Rails.logger.warn("[clerk-bridge] reading clerk.user failed: #{e.class}: #{e.message}")
|
|
nil
|
|
end
|
|
|
|
def primary_email(clerk_user)
|
|
addresses = clerk_user.respond_to?(:email_addresses) ? clerk_user.email_addresses : nil
|
|
addresses&.first&.email_address&.to_s&.downcase.presence
|
|
end
|
|
|
|
def provision_user_for_clerk(email, clerk_user)
|
|
account = Account.first
|
|
return nil unless account
|
|
|
|
first_name = clerk_user.respond_to?(:first_name) ? clerk_user.first_name : nil
|
|
last_name = clerk_user.respond_to?(:last_name) ? clerk_user.last_name : nil
|
|
|
|
User.create!(
|
|
account: account,
|
|
email: email,
|
|
first_name: first_name.presence,
|
|
last_name: last_name.presence,
|
|
role: User::ADMIN_ROLE,
|
|
password: Devise.friendly_token(40)
|
|
)
|
|
rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique => e
|
|
Rails.logger.warn("[clerk-bridge] provision failed for #{email}: #{e.message}")
|
|
User.active.find_by(email: email)
|
|
end
|
|
end
|