# Cookie session (signed session id), resumed on every request. Everything # is usable without signing in; controllers call `require_authentication` # where an account is needed. module Authentication extend ActiveSupport::Concern included do before_action :resume_session helper_method :signed_in? end private def signed_in? = Current.user.present? def resume_session Current.session = Session.find_by(id: cookies.signed[:session_id]) if cookies.signed[:session_id] touch_session if Current.session end def touch_session s = Current.session return if s.last_active_at && s.last_active_at > 1.hour.ago s.update_columns(last_active_at: Time.current) s.user.update_columns(last_seen_at: Time.current) end def require_authentication render json: { error: "unauthenticated" }, status: :unauthorized unless signed_in? end def start_session_for(user) reset_session Current.session = user.sessions.create!(user_agent: request.user_agent, ip_address: request.remote_ip, last_active_at: Time.current) cookies.signed.permanent[:session_id] = { value: Current.session.id, httponly: true, same_site: :lax, secure: Rails.env.production? } end def terminate_session Current.session&.destroy Current.session = nil cookies.delete(:session_id) end end