diff --git a/app/Core/Bootstrap/LoadConfig.php b/app/Core/Bootstrap/LoadConfig.php index d7783642e..3013251fb 100644 --- a/app/Core/Bootstrap/LoadConfig.php +++ b/app/Core/Bootstrap/LoadConfig.php @@ -69,11 +69,20 @@ public function bootstrap(Application $app) //Additional adjustments $finalConfig->set('APP_DEBUG', $finalConfig->get('debug') ? true : false); + if (preg_match('/.+\/$/', $finalConfig->get('appUrl'))) { + $url = rtrim($finalConfig->get('appUrl'), '/'); + $finalConfig->set('appUrl', $url); + $finalConfig->set('app.url', $url); + } + + $this->setBaseConstants($finalConfig->get('appUrl'), $app); + if ($finalConfig->get('app.url') == '') { $url = defined('BASE_URL') ? BASE_URL : 'http://localhost'; $finalConfig->set('app.url', $url); } + //Handle trailing slashes return $finalConfig; }); } @@ -93,6 +102,39 @@ public function bootstrap(Application $app) } + /** + * Sets the URL constants for the application. + * + * If the BASE_URL constant is not defined, it will be set based on the value of $appUrl parameter. + * If $appUrl is empty or not provided, it will be set using the getSchemeAndHttpHost method of the class. + * + * The APP_URL environment variable will be set to the value of $appUrl. + * + * If the CURRENT_URL constant is not defined, it will be set by appending the getRequestUri method result to the BASE_URL. + * + * @param string $appUrl The URL to be used as BASE_URL and APP_URL. Defaults to an empty string. + * @return void + */ + public function setBaseConstants($appUrl, $app) + { + + if (! defined('BASE_URL')) { + if (isset($appUrl) && ! empty($appUrl)) { + define('BASE_URL', $appUrl); + + } else { + define('BASE_URL', ! empty($app['request']) ? $app['request']->getSchemeAndHttpHost() : 'http://localhost'); + } + } + + putenv('APP_URL='.$appUrl); + + if (! defined('CURRENT_URL')) { + define('CURRENT_URL', ! empty($app['request']) ? BASE_URL.$app['request']->getRequestUri() : 'http://localhost'); + } + + } + /** * Load the configuration files. * diff --git a/app/Core/Configuration/laravelConfig.php b/app/Core/Configuration/laravelConfig.php index 73348271d..0e8a6cd78 100644 --- a/app/Core/Configuration/laravelConfig.php +++ b/app/Core/Configuration/laravelConfig.php @@ -93,8 +93,7 @@ 'channels' => [ 'stack' => [ 'driver' => 'stack', - // Add the Sentry log channel to the stack - 'channels' => ['single', 'sentry'], + 'channels' => ['single'], ], 'single' => [ 'driver' => 'daily', @@ -114,11 +113,6 @@ 'level' => 'critical', 'replace_placeholders' => true, ], - 'sentry' => [ - 'driver' => 'sentry', - 'level' => 'error', - 'bubble' => true, - ], ], 'default' => 'stack', ], diff --git a/app/Core/Http/IncomingRequest.php b/app/Core/Http/IncomingRequest.php index 84b2cfb73..3d014c06a 100644 --- a/app/Core/Http/IncomingRequest.php +++ b/app/Core/Http/IncomingRequest.php @@ -3,7 +3,6 @@ namespace Leantime\Core\Http; use Illuminate\Contracts\Container\BindingResolutionException; -use Leantime\Core\Configuration\Environment; use Leantime\Core\Console\CliRequest; use Symfony\Component\HttpFoundation\Request; @@ -74,44 +73,12 @@ public static function capture() default => parent::createFromGlobals(), }; - $request->setUrlConstants(); + //$request->setUrlConstants(); return $request; } - /** - * Sets the URL constants for the application. - * - * If the BASE_URL constant is not defined, it will be set based on the value of $appUrl parameter. - * If $appUrl is empty or not provided, it will be set using the getSchemeAndHttpHost method of the class. - * - * The APP_URL environment variable will be set to the value of $appUrl. - * - * If the CURRENT_URL constant is not defined, it will be set by appending the getRequestUri method result to the BASE_URL. - * - * @param string $appUrl The URL to be used as BASE_URL and APP_URL. Defaults to an empty string. - * @return void - */ - public function setUrlConstants($appUrl = '') - { - - if (! defined('BASE_URL')) { - if (isset($appUrl) && ! empty($appUrl)) { - define('BASE_URL', $appUrl); - - } else { - define('BASE_URL', parent::getSchemeAndHttpHost()); - } - } - - putenv('APP_URL='.$appUrl); - - if (! defined('CURRENT_URL')) { - define('CURRENT_URL', BASE_URL.$this->getRequestUri()); - } - } - /** * Gets the full URL including request uri and protocol */ diff --git a/tests/Unit/app/Core/ApplicationUrlTest.php b/tests/Unit/app/Core/ApplicationUrlTest.php new file mode 100644 index 000000000..7b46da66c --- /dev/null +++ b/tests/Unit/app/Core/ApplicationUrlTest.php @@ -0,0 +1,111 @@ +bootstrapApplication(); + + } + + protected function bootstrapApplication() + { + + $this->app = new Application(APP_ROOT); + $this->app->boot(); + + $this->app->bootstrapWith([LoadConfig::class, SetRequestForConsole::class]); + + $this->config = $this->app['config']; + } + + public function testBaseUrlIsSetCorrectlyFromConfig(): void + { + // Test default behavior (no LEAN_APP_URL set) + $this->assertEquals('http://localhost', BASE_URL); + $this->assertEquals('http://localhost', $this->config->get('app.url')); + + // Test with LEAN_APP_URL set + //putenv('LEAN_APP_URL=https://example.com'); + $_ENV['LEAN_APP_URL'] = 'https://example.com'; + + // Reinitialize application to test new environment + $this->bootstrapApplication(); + + //dd($this->config); + + $this->assertEquals('https://example.com', $this->config->get('app.url')); + $this->assertEquals('https://example.com', $this->config->get('appUrl')); + } + + public function testBaseUrlHandlesTrailingSlash(): void + { + + $_ENV['LEAN_APP_URL'] = 'https://example.com/'; + + $this->bootstrapApplication(); + + $this->assertEquals('https://example.com', $this->config->get('app.url')); + $this->assertEquals('https://example.com', $this->config->get('appUrl')); + } + + public function testBaseUrlHandlesSubdirectory(): void + { + + $_ENV['LEAN_APP_URL'] = 'https://example.com/leantime'; + + $this->bootstrapApplication(); + + $this->assertEquals('https://example.com/leantime', $this->config->get('app.url')); + $this->assertEquals('https://example.com/leantime', $this->config->get('appUrl')); + } + + public function testBaseUrlHandlesPort(): void + { + + $_ENV['LEAN_APP_URL'] = 'https://example.com:8443'; + + $this->bootstrapApplication(); + + $this->assertEquals('https://example.com:8443', $this->config->get('app.url')); + $this->assertEquals('https://example.com:8443', $this->config->get('appUrl')); + } + + public function testBaseUrlHandlesReverseProxy(): void + { + // Simulate reverse proxy headers + $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https'; + $_SERVER['HTTP_X_FORWARDED_HOST'] = 'example.com'; + + $_ENV['LEAN_APP_URL'] = 'https://example.com'; + + $this->bootstrapApplication(); + + $this->assertEquals('https://example.com', $this->config->get('app.url')); + $this->assertEquals('https://example.com', $this->config->get('appUrl')); + } + + protected function tearDown(): void + { + parent::tearDown(); + + // Clean up environment + putenv('LEAN_APP_URL'); + unset($_SERVER['HTTP_X_FORWARDED_PROTO']); + unset($_SERVER['HTTP_X_FORWARDED_HOST']); + } +}