Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Base url config fix #2792

Merged
merged 4 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions app/Core/Bootstrap/LoadConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
}
Expand All @@ -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.
*
Expand Down
8 changes: 1 addition & 7 deletions app/Core/Configuration/laravelConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@
'channels' => [
'stack' => [
'driver' => 'stack',
// Add the Sentry log channel to the stack
'channels' => ['single', 'sentry'],
'channels' => ['single'],
],
'single' => [
'driver' => 'daily',
Expand All @@ -114,11 +113,6 @@
'level' => 'critical',
'replace_placeholders' => true,
],
'sentry' => [
'driver' => 'sentry',
'level' => 'error',
'bubble' => true,
],
],
'default' => 'stack',
],
Expand Down
35 changes: 1 addition & 34 deletions app/Core/Http/IncomingRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
*/
Expand Down
111 changes: 111 additions & 0 deletions tests/Unit/app/Core/ApplicationUrlTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php

namespace Tests\Unit\App\Core;

use Leantime\Core\Application;
use Leantime\Core\Bootstrap\LoadConfig;
use Leantime\Core\Bootstrap\SetRequestForConsole;
use Leantime\Core\Configuration\Environment;

class ApplicationUrlTest extends \Unit\TestCase
{
protected $app;

protected $config;

protected function setUp(): void
{

parent::setUp();

$this->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']);
}
}
Loading