<?php
namespace SHServ;
use \Fury\Modules\Router\Router;
use \Fury\Modules\ThinBuilder\ThinBuilder;
use \Fury\Modules\ErrorHandler\ErrorHandler;
use \SHServ\Factory\Factory;
use \SHServ\DevTools;
class App extends \Fury\Kernel\BaseApp{
public $routes;
public $router;
public $events_handlers;
public $error_handlers;
public $thin_builder;
public $console_flag;
// CUSTOM
public $utils;
public $sessions;
public $factory;
public $devtools;
public $control_scripts_instances = [];
protected $required_control_scripts_instance;
public function __construct() {
parent::__construct();
global $argv;
$this -> console_flag = isset($argv) ? true : false;
$this -> app_init();
$scripts = new \SHServ\Models\Scripts();
$scripts -> set_script_state("action", "spotlights_off", true);
}
public function app_init(): void {
if(!$this -> console_flag) {
$this -> error_handlers = new ErrorHandler();
}
\Fury\Modules\Template\Template::set_driver(new \Fury\Drivers\TemplateDriver());
$this -> router_json_to_post_emulate();
$this -> devtools = new DevTools();
$this -> router = new Router();
$this -> routes = new Routes($this -> router);
$this -> thin_builder = new ThinBuilder(FCONF['db'], new \Fury\Drivers\ThinBuilderDriver(bootstrap()));
$this -> control_scripts_init();
$this -> events_handlers = new EventsHandlers();
$this -> events_handlers -> handlers();
// CUSTOM
$this -> utils = new Utils();
$this -> sessions = new Sessions();
$this -> factory = new Factory();
}
public function api_auth_guard(): void {
$uri = $_SERVER['REQUEST_URI'] ?? '';
if (strpos($uri, '/api/v1/') !== 0) {
return;
}
// Rate limiting: 60 req/min per IP
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
$rate_limiter = new \SHServ\Tools\RateLimiter(60, 60);
if (!$rate_limiter -> check($ip)) {
header('Content-Type: application/json');
http_response_code(429);
echo json_encode([
'status' => false,
'error_alias' => 'rate_limit_exceeded',
'msg' => 'Too many requests'
]);
exit;
}
$token = null;
$auth_header = $_SERVER['HTTP_AUTHORIZATION'] ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ?? '';
if (strpos($auth_header, 'Bearer ') === 0) {
$token = substr($auth_header, 7);
}
if (!$token && isset($_COOKIE['auth_token'])) {
$token = $_COOKIE['auth_token'];
}
if (!$token || !app() -> sessions -> get_session_by_token($token)) {
header('Content-Type: application/json');
http_response_code(401);
echo json_encode([
'status' => false,
'error_alias' => 'unauthorized',
'msg' => 'Authentication required'
]);
exit;
}
}
public function root_folder(): String {
list($root) = explode('SHServ', __DIR__);
return $root;
}
protected function router_json_to_post_emulate(): void {
$content_type = $_SERVER['CONTENT_TYPE'] ?? '';
if (stripos($content_type, 'application/json') === false) {
return;
}
$raw_body = file_get_contents('php://input');
$json_data = json_decode($raw_body, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return;
}
foreach($json_data as $param_name => $param_val) {
$_POST[$param_name] = $param_val;
}
}
public function control_scripts_init(): void {
$this -> required_control_scripts_instance = new \SHServ\RequiredControlScriptsScope();
$scripts_dir = scandir(__DIR__ . "/../ControlScripts/Scopes/");
$scripts = array_filter($scripts_dir, function($item) {
return !is_dir($item) and (pathinfo($item))["extension"] == "php";
});
foreach($scripts as $script_name) {
$script_name = basename($script_name, ".php");
$full_script_name = "\\ControlScripts\\Scopes\\{$script_name}";
$script = new $full_script_name();
$this -> control_scripts_instances[$script_name] = $script;
}
}
}
new App();