Add sign in flow using magic links

This commit is contained in:
Stanko K.R.
2025-10-07 19:33:51 +02:00
parent d0215e9fd2
commit 5cef4ffeb0
51 changed files with 908 additions and 268 deletions
+43 -10
View File
@@ -38,13 +38,31 @@ module Authentication
def require_tenant
unless ApplicationRecord.current_tenant.present?
set_current_identity_token
render "sessions/login_menu"
resume_identity
redirect_to session_login_menu_url(script_name: nil)
end
end
def require_identity
resume_identity || request_authentication
end
def require_authentication
resume_session || request_authentication
if resume_identity
resume_session || request_session_for_identity
else
request_authentication
end
end
def request_session_for_identity
redirect_to session_login_menu_url(script_name: nil)
end
def resume_identity
if identity = find_identity_by_cookie
set_current_identity(identity)
end
end
def resume_session
@@ -53,11 +71,15 @@ module Authentication
end
end
def find_identity_by_cookie
Identity.find_signed(cookies.signed[:identity_token]&.dig("id"))
end
def find_session_by_cookie
Session.find_signed(cookies.signed[:session_token])
end
def request_authentication(untenanted: false)
def request_authentication
if ApplicationRecord.current_tenant.present?
session[:return_to_after_authenticating] = request.url
end
@@ -84,26 +106,37 @@ module Authentication
end
end
def link_identity(user)
def link_identity(user_or_membership)
token_value = cookies.signed[:identity_token]
identity = Identity.find_signed(token_value["id"]) if token_value.present?
identity = user.set_identity(identity)
cookies.signed.permanent[:identity_token] = { value: { "id" => identity.signed_id, "updated_at" => identity.updated_at }, httponly: true, same_site: :lax }
if user_or_membership.is_a?(User)
identity = user_or_membership.set_identity(identity)
elsif user_or_membership.is_a?(Membership) && identity
user_or_membership.update!(identity: identity)
end
set_current_identity(identity)
end
def set_current_identity_token
Current.identity_token = Identity::Mock.new(**cookies.signed[:identity_token])
def set_current_identity(identity)
Current.identity_token = if identity
cookies.signed.permanent[:identity_token] = { value: { "id" => identity.signed_id, "updated_at" => identity.updated_at }, httponly: true, same_site: :lax }
Identity::Mock.new(**cookies.signed[:identity_token])
else
nil
end
end
def set_current_session(session)
logger.struct " Authorized User##{session.user.id}", authentication: { user: { id: session.user.id } }
Current.session = session
set_current_identity_token
cookies.signed.permanent[:session_token] = { value: session.signed_id, httponly: true, same_site: :lax, path: Account.sole.slug }
end
def terminate_session
Current.session.destroy
cookies.delete(:session_token)
cookies.delete(:identity_token)
end
end