diff --git a/config.inc.php b/config.inc.php index b9ab8159..08c8daee 100644 --- a/config.inc.php +++ b/config.inc.php @@ -712,6 +712,10 @@ $CONF['xmlrpc_enabled'] = false; //More details in Password_Expiration.md $CONF['password_expiration'] = 'YES'; +// If defined, use this rather than trying to construct it from $_SERVER parameters. +// used in (at least) password-recover.php. +$CONF['site_url'] = null; + $CONF['version'] = '3.3.5'; // If you want to keep most settings at default values and/or want to ensure diff --git a/functions.inc.php b/functions.inc.php index 65ed7d23..02b7ba54 100644 --- a/functions.inc.php +++ b/functions.inc.php @@ -2317,4 +2317,46 @@ function getRemoteAddr() { return $REMOTE_ADDR; } + +/** + * @param array $server + * @return string URL to Postfixadmin - will always end in a '/' + */ +function getSiteUrl(array $server = []): string { + if (Config::has('site_url')) { + $url = Config::read_string('site_url'); + if (!empty($url)) { + return $url; + } + } + + if (empty($server)) { + $server = $_SERVER; + } + + // ideally need to support installation unnder a random prefix + // - https://example.com/my-postfixadmin-3.1.2/index.php + // - https://example.com/my-postfixadmin-3.1.2/users/password-recover.php + // in either case, we want https://example.com/my-postfixadmin-3.1.2/ + + $uri = dirname($server['REQUEST_URI']); + if (preg_match('!/users/.*.php!', $uri)) { + $uri = dirname($uri); + } + + // ensure it ends with a / + if (substr($uri, -1, 1) !== '/') { + $uri = $uri . '/'; + } + + + $https = isset($server['HTTPS']) && $server['HTTPS'] == 'on' ? 'https' : 'http'; + + if (isset($server['REQUEST_SCHEME'])) { + $https = $server['REQUEST_SCHEME']; + } + + return $https . '://' . $server['HTTP_HOST'] . $uri; +} + /* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */ diff --git a/public/setup.php b/public/setup.php index fad981a2..df2864b2 100644 --- a/public/setup.php +++ b/public/setup.php @@ -600,6 +600,8 @@ function do_software_environment_check() { } + $info[] = "Postfixadmin public url detected as " . getSiteUrl($_SERVER) . " use \$CONF['site_url'] to override"; + $info[] = "Postfixadmin installed at - " . realpath(__DIR__); $error_log_file = ini_get('error_log'); diff --git a/public/users/password-recover.php b/public/users/password-recover.php index 8ad4822f..68cb7a7d 100644 --- a/public/users/password-recover.php +++ b/public/users/password-recover.php @@ -45,13 +45,13 @@ if ($context === 'admin' && !Config::read('forgotten_admin_password_reset') || } function sendCodebyEmail($to, $username, $code) { - $https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http'; + $url = getSiteUrl($_SERVER) . 'password-change.php?username=' . urlencode($username) . '&code=' . $code; - $_SERVER['REQUEST_SCHEME'] = isset($_SERVER['REQUEST_SCHEME']) ? $_SERVER['REQUEST_SCHEME'] : $https; - - $url = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['REQUEST_URI']) . '/password-change.php?username=' . urlencode($username) . '&code=' . $code; - - return smtp_mail($to, Config::read('admin_email'), Config::Lang('pPassword_welcome'), Config::read('admin_smtp_password'), Config::lang_f('pPassword_recovery_email_body', $url)); + return smtp_mail($to, + Config::read('admin_email'), + Config::Lang('pPassword_welcome'), + Config::read('admin_smtp_password'), + Config::lang_f('pPassword_recovery_email_body', $url)); } function sendCodebySMS($to, $username, $code) { diff --git a/tests/GetSiteUrlTest.php b/tests/GetSiteUrlTest.php new file mode 100644 index 00000000..c195efa5 --- /dev/null +++ b/tests/GetSiteUrlTest.php @@ -0,0 +1,54 @@ +getAll(); + $orig['site_url'] = 'https://example.com/postfixadmin-1.2.3.4/'; + Config::getInstance()->setAll($orig); + + $this->assertEquals('https://example.com/postfixadmin-1.2.3.4/', getSiteUrl($server)); + } + + public function testViaDiscovery() { + $server = [ + 'HTTP_HOST' => 'example.org', + 'REQUEST_SCHEME' => 'https', + 'REQUEST_URI' => '/postfixadmin-1.2.3.4/setup.php', + ]; + + $orig = Config::getInstance()->getAll(); + unset($orig['site_url']); + Config::getInstance()->setAll($orig); + + $this->assertEquals('https://example.org/postfixadmin-1.2.3.4/', getSiteUrl($server)); + } + + public function testViaDiscoveryNoPrefix() { + $server = [ + 'HTTP_HOST' => 'example.org', + 'REQUEST_SCHEME' => 'https', + 'REQUEST_URI' => '/setup.php', + ]; + + $orig = Config::getInstance()->getAll(); + unset($orig['site_url']); + Config::getInstance()->setAll($orig); + + $this->assertEquals('https://example.org/', getSiteUrl($server)); + } + + public function testViaDiscoveryhttp() { + $server = [ + 'HTTP_HOST' => 'example.org', + 'REQUEST_SCHEME' => 'http', + 'REQUEST_URI' => '/setup.php', + ]; + + $orig = Config::getInstance()->getAll(); + unset($orig['site_url']); + Config::getInstance()->setAll($orig); + + $this->assertEquals('http://example.org/', getSiteUrl($server)); + } +}