module Authentication extend ActiveSupport::Concern included do before_action :set_current_account before_action :require_authentication helper_method :authenticated? end class_methods do def require_unauthenticated_access(**options) allow_unauthenticated_access **options before_action :redirect_authenticated_user, **options end def allow_unauthenticated_access(**options) skip_before_action :require_authentication, **options before_action :resume_session, **options end def require_untenanted_access(**options) skip_before_action :set_current_account, **options skip_before_action :require_authentication, **options before_action :redirect_tenanted_request, **options end end private def authenticated? Current.session.present? end def require_authentication resume_session || request_authentication end def resume_session if session = find_session_by_cookie set_current_session session end end def find_session_by_cookie Session.find_signed(cookies.signed[:session_token]) end def request_authentication session[:return_to_after_authenticating] = request.url redirect_to Launchpad.login_url(account: Current.account), allow_other_host: true end def after_authentication_url session.delete(:return_to_after_authenticating) || root_url end def redirect_authenticated_user redirect_to root_url if authenticated? end def redirect_tenanted_request redirect_to root_url if ApplicationRecord.current_tenant end def start_new_session_for(user) user.sessions.create!(user_agent: request.user_agent, ip_address: request.remote_ip).tap do |session| set_current_session session end end def set_current_session(session) logger.struct " Authorized User##{session.user.id}", authentication: { user: { id: session.user.id } } Current.session = session cookies.signed.permanent[:session_token] = { value: session.signed_id, httponly: true, same_site: :lax } end def set_current_account Current.account = Account.first end def terminate_session Current.session.destroy cookies.delete(:session_token) end end