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

Add static files server #9294

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
4 changes: 0 additions & 4 deletions config/defaults.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -877,10 +877,6 @@
// </FilesMatch>
$config['assets_path'] = '';

// While assets_path is for the browser, assets_dir informs
// PHP code about the location of asset files in filesystem
$config['assets_dir'] = '';

// Options passed when creating Guzzle HTTP client, used to fetch remote content
// For example:
// [
Expand Down
12 changes: 6 additions & 6 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,13 @@
}

// check if installer is still active
if ($RCMAIL->config->get('enable_installer') && is_readable('./installer/index.php')) {
if ($RCMAIL->config->get('enable_installer') && is_readable(__DIR__ . '/public_html/installer.php')) {
$RCMAIL->output->add_footer(html::div(['id' => 'login-addon', 'style' => 'background:#ef9398; border:2px solid #dc5757; padding:0.5em; margin:2em auto; width:50em'],
html::tag('h2', ['style' => 'margin-top:0.2em'], 'Installer script is still accessible') .
html::p(null, 'The install script of your Roundcube installation is still stored in its default location!') .
html::p(null, 'Please <b>remove</b> the whole <tt>installer</tt> folder from the Roundcube directory because
these files may expose sensitive configuration data like server passwords and encryption keys
to the public. Make sure you cannot access the <a href="./installer/">installer script</a> from your browser.')
html::tag('h2', ['style' => 'margin-top:0.2em'], 'The Installer is still accessible') .
html::p(null, 'The install script of your Roundcube installation is still available to everyone!') .
html::p(null, 'Please <b>remove</b> the <tt>public_html/installer.php</tt> file from the Roundcube directory because
it may expose sensitive configuration data like server passwords and encryption keys
to the public. Make sure you cannot access <a href="installer.php">the script</a> from your browser.')
));
}

Expand Down
4 changes: 2 additions & 2 deletions installer/check.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

if (!class_exists('rcmail_install', false) || !isset($RCI)) {
exit('Not allowed! Please open installer/index.php instead.');
exit('Not allowed! Please use installer.php instead.');
}

$required_php_exts = [
Expand Down Expand Up @@ -99,7 +99,7 @@
];

?>
<form action="index.php" method="get">
<form action="?" method="get">

<?php
echo '<input type="hidden" name="_step" value="' . ($RCI->configured ? 3 : 2) . '" />';
Expand Down
10 changes: 5 additions & 5 deletions installer/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

if (!class_exists('rcmail_install', false) || !isset($RCI)) {
exit('Not allowed! Please open installer/index.php instead.');
exit('Not allowed! Please use installer.php instead.');
}

// allow the current user to get to the next step
Expand All @@ -38,7 +38,7 @@
$save_button = '';
if (($dir = sys_get_temp_dir()) && @is_writable($dir)) {
echo '<iframe name="getconfig" style="display:none"></iframe>';
echo '<form id="getconfig_form" action="index.php" method="get" target="getconfig" style="display:none">';
echo '<form id="getconfig_form" action="?" method="get" target="getconfig" style="display:none">';
echo '<input name="_getconfig" value="2" /></form>';

$button_txt = html::quote('Save in ' . $dir);
Expand All @@ -48,7 +48,7 @@
echo '<p class="notice">Copy or download the following configuration and save it';
echo ' as <tt><b>config.inc.php</b></tt> within the <tt>' . RCUBE_CONFIG_DIR . '</tt> directory of your Roundcube installation.<br/>';
echo ' Make sure that there are no characters before the <tt>&lt;?php</tt> bracket when saving the file.';
echo '&nbsp;<input type="button" onclick="location.href=\'index.php?_getconfig=1\'" value="Download" />';
echo '&nbsp;<input type="button" onclick="location.href=\'?_getconfig=1\'" value="Download" />';
echo $save_button;

if ($RCI->legacy_config) {
Expand All @@ -65,14 +65,14 @@
echo '<p class="hint">Of course there are more options to configure.
Have a look at the defaults.inc.php file or visit <a href="https://github.com/roundcube/roundcubemail/wiki/Configuration" target="_blank">Howto_Config</a> to find out.</p>';

echo '<p><input type="button" onclick="location.href=\'./index.php?_step=3\'" value="CONTINUE" /></p>';
echo '<p><input type="button" onclick="location.href=\'?_step=3\'" value="CONTINUE" /></p>';

// echo '<style type="text/css"> .configblock { display:none } </style>';
echo "\n<hr style='margin-bottom:1.6em' />\n";
}

?>
<form action="index.php" method="post">
<form action="?" method="post">
<input type="hidden" name="_step" value="2" />

<fieldset>
Expand Down
15 changes: 8 additions & 7 deletions installer/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,26 +86,27 @@

// go to 'check env' step if we have a local configuration
if ($RCI->configured && empty($_REQUEST['_step'])) {
header('Location: ./?_step=1');
header('Location: ?_step=1');
exit;
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!DOCTYPE html>
<html xml:lang="en" lang="en">
<head>
<title>Roundcube Webmail Installer</title>
<meta name="Robots" content="noindex,nofollow" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<script type="text/javascript" src="client.js"></script>
<link rel="stylesheet" type="text/css" href="static.php/installer/styles.css" />
<link rel="shortcut icon" href="static.php/skins/elastic/images/favicon.ico" />
<script type="text/javascript" src="static.php/installer/client.js"></script>
</head>

<body>

<div id="banner">
<div class="banner-bg"></div>
<div class="banner-logo"><a href="http://roundcube.net"><img src="images/roundcube_logo.png" width="210" height="55" border="0" alt="Roundcube - open source webmail software" /></a></div>
<div class="banner-logo"><a href="http://roundcube.net"><img src="static.php/installer/images/roundcube_logo.png" width="210" height="55" border="0" alt="Roundcube - open source webmail software" /></a></div>
</div>

<div id="topnav">
Expand Down Expand Up @@ -150,7 +151,7 @@

foreach (['Check environment', 'Create config', 'Test config'] as $i => $item) {
$j = $i + 1;
$link = ($RCI->step >= $j || $RCI->configured) ? '<a href="./index.php?_step=' . $j . '">' . rcube::Q($item) . '</a>' : rcube::Q($item);
$link = ($RCI->step >= $j || $RCI->configured) ? '<a href="?_step=' . $j . '">' . rcube::Q($item) . '</a>' : rcube::Q($item);
printf('<li class="step%d%s">%s</li>', $j + 1, $RCI->step > $j ? ' passed' : ($RCI->step == $j ? ' current' : ''), $link);
}
?>
Expand Down
18 changes: 9 additions & 9 deletions installer/test.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

if (!class_exists('rcmail_install', false) || !isset($RCI)) {
exit('Not allowed! Please open installer/index.php instead.');
exit('Not allowed! Please use installer.php instead.');
}

/** @var rcmail_install $RCI */
Expand Down Expand Up @@ -167,7 +167,7 @@
$db_read = $DB->query('SELECT count(*) FROM ' . $DB->quote_identifier($RCI->config['db_prefix'] . 'users'));
if ($DB->is_error()) {
$RCI->fail('DB Schema', 'Database not initialized');
echo '<form action="index.php?_step=3" method="post">'
echo '<form action="?_step=3" method="post">'
. '<p><input type="submit" name="initdb" value="Initialize database" /></p>'
. '</form>';

Expand All @@ -179,7 +179,7 @@
$select = $RCI->versions_select(['name' => 'version']);
$select->add('0.9 or newer', '');

echo '<form action="index.php?_step=3" method="post">'
echo '<form action="?_step=3" method="post">'
. '<p class="suggestion">You should run the update queries to get the schema fixed.'
. '<br/><br/>Version to update from: ' . $select->show('')
. '&nbsp;<input type="submit" name="updatedb" value="Update" /></p>'
Expand Down Expand Up @@ -273,7 +273,7 @@

?>

<form action="index.php?_step=3" method="post">
<form action="?_step=3" method="post">

<h3>Test SMTP config</h3>

Expand Down Expand Up @@ -372,7 +372,7 @@

</form>

<form action="index.php?_step=3" method="post">
<form action="?_step=3" method="post">

<h3>Test IMAP config</h3>

Expand Down Expand Up @@ -452,12 +452,12 @@

<p class="warning">

After completing the installation and the final tests please <b>remove</b> the whole
installer folder from the document root of the webserver or make sure that
After completing the installation and the final tests please <b>remove</b> the
installer.php file from the document root of the webserver or make sure that
<tt>enable_installer</tt> option in <tt>config.inc.php</tt> is disabled.<br />
<br />

These files may expose sensitive configuration data like server passwords and encryption keys
to the public. Make sure you cannot access this installer from your browser.
The installer may expose sensitive configuration data like server passwords and encryption keys
to the public. Make sure you cannot access it from your browser.

</p>
5 changes: 2 additions & 3 deletions program/include/rcmail.php
Original file line number Diff line number Diff line change
Expand Up @@ -1542,8 +1542,7 @@ public function find_asset($path, $minified = true)
return null;
}

$assets_dir = $this->config->get('assets_dir');
$root_path = unslashify($assets_dir ?: INSTALL_PATH) . '/';
$root_path = unslashify(INSTALL_PATH) . '/';
$full_path = $root_path . trim($path, '/');

if (file_exists($full_path)) {
Expand Down Expand Up @@ -1943,7 +1942,7 @@ public static function get_uids($uids = null, $mbox = null, &$is_multifolder = f
}

/**
* Get resource file content (with assets_dir support)
* Get resource file content
*
* @param string $name File name
*
Expand Down
18 changes: 3 additions & 15 deletions program/include/rcmail_action.php
Original file line number Diff line number Diff line change
Expand Up @@ -368,15 +368,14 @@ public static function html_editor($mode = '', $editorId = null)

$language = $_SESSION['language'] ?? 'en_US';
$lang_codes = [$language];
$assets_dir = $rcmail->config->get('assets_dir') ?: INSTALL_PATH;
$skin_path = $rcmail->output->get_skin_path();

if ($pos = strpos($language, '_')) {
$lang_codes[] = substr($language, 0, $pos);
}

foreach ($lang_codes as $code) {
if (file_exists("{$assets_dir}/program/js/tinymce/langs/{$code}.js")) {
if (file_exists(INSTALL_PATH . "/program/js/tinymce/langs/{$code}.js")) {
$lang = $code;
break;
}
Expand Down Expand Up @@ -831,7 +830,7 @@ public static function get_uids($uids = null, $mbox = null, &$is_multifolder = f
}

/**
* Get resource file content (with assets_dir support)
* Get resource file content
*
* @param string $name File name
*
Expand All @@ -843,18 +842,7 @@ public static function get_resource_content($name)
$name = "program/resources/{$name}";
}

$assets_dir = rcmail::get_instance()->config->get('assets_dir');

if ($assets_dir) {
$path = slashify($assets_dir) . $name;
if (@file_exists($path)) {
$name = $path;
}
} else {
$name = INSTALL_PATH . $name;
}

return file_get_contents($name, false);
return file_get_contents(INSTALL_PATH . $name, false);
}

/**
Expand Down
30 changes: 16 additions & 14 deletions program/include/rcmail_output_html.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ protected function init($framed = false)

// load and setup the skin
$this->set_skin($this->config->get('skin'));
$this->set_assets_path($this->config->get('assets_path'), $this->config->get('assets_dir'));
$this->set_assets_path($this->config->get('assets_path'));

if (!empty($_REQUEST['_extwin'])) {
$this->set_env('extwin', 1);
Expand Down Expand Up @@ -188,10 +188,9 @@ public function set_env($name, $value, $addtojs = true)
/**
* Parse and set assets path
*
* @param string $path Assets path URL (relative or absolute)
* @param string $fs_dir Assets path in filesystem
* @param string $path Assets path URL (relative or absolute)
*/
public function set_assets_path($path, $fs_dir = null)
public function set_assets_path($path)
{
// set absolute path for assets if /index.php/foo/bar url is used
if (empty($path) && !empty($_SERVER['PATH_INFO'])) {
Expand Down Expand Up @@ -227,15 +226,6 @@ public function set_assets_path($path, $fs_dir = null)
}
}

// set filesystem path for assets
if ($fs_dir) {
if ($fs_dir[0] != '/') {
$fs_dir = realpath(RCUBE_INSTALL_PATH . $fs_dir);
}
// ensure the path ends with a slash
$this->assets_dir = rtrim($fs_dir, '/') . '/';
}

$this->assets_path = $path;
$this->set_env('assets_path', $path);
}
Expand Down Expand Up @@ -968,6 +958,10 @@ public function asset_url($path, $abs_url = false)
}

if (!$this->assets_path || in_array($path[0], ['?', '/', '.']) || strpos($path, '://')) {
if (!str_starts_with($path, 'static.php/') && strpos($path, '://') === false) {
$path = 'static.php/' . ltrim($path, '/');
}

return $path;
}

Expand Down Expand Up @@ -1002,7 +996,7 @@ protected function globals_callback($matches)
*/
protected function fix_paths($output)
{
$regexp = '!(src|href|background|data-src-[a-z]+)=(["\']?)([a-z0-9/_.-]+)(["\'\s>])!i';
$regexp = '!(src|href|background|data-src-[a-z]+)=(["\']?)([a-z0-9/_.?=-]+)(["\'\s>])!i';

return preg_replace_callback($regexp, [$this, 'file_callback'], $output);
}
Expand All @@ -1028,6 +1022,10 @@ protected function file_callback($matches)
$file = $this->file_mod($file);
}

if (!str_starts_with($file, 'static.php/') && strpos($file, '://') === false) {
$file = 'static.php/' . $file;
}

return $matches[1] . '=' . $matches[2] . $file . $matches[4];
}

Expand All @@ -1050,6 +1048,10 @@ protected function assets_callback($matches)
{
$file = $this->asset_url($matches[3]);

if (!str_starts_with($file, 'static.php/') && strpos($file, '://') === false) {
$file = 'static.php/' . $file;
}

return $matches[1] . '=' . $matches[2] . $file . $matches[4];
}

Expand Down
4 changes: 4 additions & 0 deletions program/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -10590,6 +10590,10 @@ function rcube_webmail() {
path = this.env.assets_path + path;
}

if (!path.startsWith('static.php/') && path.indexOf('://') == -1) {
path = 'static.php/' + path;
}

return path;
};

Expand Down
6 changes: 6 additions & 0 deletions program/lib/Roundcube/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -436,3 +436,9 @@ function rcube_autoload(string $classname): bool

return false;
}

if (!function_exists('str_starts_with')) {
function str_starts_with(string $haystack, string $needle) {
return strlen($needle) === 0 || strpos($haystack, $needle) === 0;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/atk4/core/blob/5.2.0/composer.json#L35-L38 would be better solution as installed dependencies are required in all cases

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. Anyway, we should consider bumping PHP version requirement to 8.1 for the next Roundcube version, especially if it will be a bump to 2.0.

4 changes: 1 addition & 3 deletions program/lib/Roundcube/rcube_plugin_api.php
Original file line number Diff line number Diff line change
Expand Up @@ -671,9 +671,7 @@ public function include_stylesheet($fn)
if ($fn[0] != '/' && !preg_match('|^https?://|i', $fn)) {
$rcube = rcube::get_instance();
$devel_mode = $rcube->config->get('devel_mode');
$assets_dir = $rcube->config->get('assets_dir');
$path = unslashify($assets_dir ?: RCUBE_INSTALL_PATH);
$dir = $path . (strpos($fn, 'plugins/') === false ? '/plugins' : '');
$dir = unslashify(RCUBE_INSTALL_PATH) . (strpos($fn, 'plugins/') === false ? '/plugins' : '');

// Prefer .less files in devel_mode (assume less.js is loaded)
if ($devel_mode) {
Expand Down
1 change: 0 additions & 1 deletion public_html/plugins

This file was deleted.

1 change: 0 additions & 1 deletion public_html/skins

This file was deleted.

Loading
Loading