class ApplicationController < ActionController::Base include BotBlocker # Changes to the importmap will invalidate the etag for HTML responses stale_when_importmap_changes SESSION_TIMEOUT = 3.days before_action :check_session_timeout helper_method :supported_languages, :current_user, :logged_in?, :admin?, :reviewer_or_admin?, :contributor_or_above?, :setup_completed? private def supported_languages @supported_languages ||= SupportedLanguage.where(active: true).order(:sort_order, :name) end def current_user return @current_user if defined?(@current_user) # First check session if session[:user_id] @current_user = User.find_by(id: session[:user_id]) # Then check remember me cookie elsif cookies.signed[:remember_token] user = User.find_by_valid_remember_token(cookies.signed[:remember_token]) if user session[:user_id] = user.id @current_user = user else # Invalid or expired remember token, clear it cookies.delete(:remember_token) end end @current_user end def check_session_timeout return unless logged_in? return if cookies.signed[:remember_token].present? if session[:last_activity_at].present? last_activity = Time.parse(session[:last_activity_at]) if last_activity < SESSION_TIMEOUT.ago reset_session redirect_to login_path, alert: "Your session has expired. Please sign in again." return end end session[:last_activity_at] = Time.current.to_s end def logged_in? current_user.present? end def admin? logged_in? && current_user.admin? end def reviewer_or_admin? logged_in? && (current_user.reviewer? || current_user.admin?) end def contributor_or_above? logged_in? end def require_login unless logged_in? redirect_to login_path, alert: "You must be logged in to access this page." end end def require_admin unless logged_in? redirect_to login_path, alert: "You must be logged in to access this page." return end unless current_user.admin? redirect_to root_path, alert: "You must be an administrator to access this page." end end def require_reviewer unless reviewer_or_admin? redirect_to root_path, alert: "You must be a reviewer or administrator to access this page." end end def require_contributor unless contributor_or_above? redirect_to root_path, alert: "You must be a contributor to access this page." end end def setup_completed? SetupState.installed? end end