#!/usr/bin/env ruby module LifePex end require "sinatra/base" # web require "sinatra/cookies" require "slim" require "sinatra/namespace" # api require "doc_my_routes" # api doc require "bcrypt" # security require "jwt" require "rack/csrf" require "securerandom" require "sequel" # db require "json" # helpers require "active_support" require "active_support/core_ext" require "pry" # debug # Load environment variables require_relative "./utils/env" module LifePex APP_ENV = load_dotenv end # Initialize framework require_relative "./utils/url.rb" require_relative "./utils/boot_framework" LifePex::BootFramework.boot_application do harshly_need_env "LIFEPEX_DB" kindly_ask_env "LIFEPEX_BASE_URL" kindly_ask_env "LIFEPEX_SECRET" do warning "\"LIFEPEX_SECRET\" will be randomly generated as a fallback" ENV["LIFEPEX_SECRET"] = SecureRandom.hex(64) end harshly_do env["LIFEPEX_SECRET"].size < 8 do error "Your secret is NOT very secret, fix this (at least 8 hexadigits entropy)" end end.finish! # Setup module variables module LifePex DB = Sequel.connect ENV["LIFEPEX_DB"] BASE_URL = ENV["LIFEPEX_BASE_URL"] || "http://localhost:4567" SECRET = ENV["LIFEPEX_SECRET"] CODE_VERSION = DB[:meta].first[:code_version] CODE_DATE = DB[:meta].first[:code_date] include LifePex::Utils::Url module Systems end end # Then we load all the systems Dir[File.join(__dir__, 'utils', '*.rb')].each { |file| require file } require_relative "./achievements/dsl.rb" require_relative "./achievements/achievement.rb" Dir[File.join(__dir__, 'models', '*.rb')].each { |file| require file } Dir[File.join(__dir__, 'systems', '*.rb')].each { |file| require file } # Static file serving in this file because it is overkill to create a file for this class LifePex::Systems::PublicSystem < Sinatra::Base set :public_folder, "public" end # Main app class LifePex::App < Sinatra::Base DocMyRoutes.configure do |config| config.title = "LifePex" config.description = "LifePex JSON REST API documentation" end set :session_secret, LifePex::SECRET enable :sessions # use Rack::Csrf, skip: ["POST:/api/*"], :raise => (LifePex::APP_ENV != "production") if LifePex::APP_ENV != "test" set :protection, :except => :json_csrf if LifePex::APP_ENV != "test" LifePex::Systems.constants .filter { |system| system.to_s =~ /System$/ } .each { |system| use LifePex::Systems.const_get(system) puts "Loaded #{system.to_s.green}" } # use LifePex::Systems::AuthSystem # use LifePex::Systems::PublicSystem # use LifePex::Systems::UserSystem # use LifePex::Systems::PexSystem # use LifePex::Systems::Pex2System # use LifePex::Systems::AchievementSystem # use LifePex::Systems::UserPexSystem include JSON::API not_found do if accept_json? { message: "No route or entity \"#{request.path}\" found" }.to_json else raise end end get "/api/meta/v1", provides: "json" do LifePex::Systems::ApiList.get_all_api_routes.to_json end set :bind, ENV["LIFEPEX_BIND"] || "127.0.0.1" set :environment, LifePex::APP_ENV ENV["RACK_ENV"] = LifePex::APP_ENV run! if app_file == $0 end