Skip to content
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
2 changes: 1 addition & 1 deletion Jobs/.htaccess
Original file line number Diff line number Diff line change
@@ -1 +1 @@
deny from all
Require all denied
4 changes: 3 additions & 1 deletion Pages/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ protected function __construct($titleKey = '', $pageDepth = 0)
$this->smarty->assign('Version', Configuration::VERSION);
$this->smarty->assign('DisplayVersion', $this->GetDisplayVersion());
$this->smarty->assign('Path', $this->path);
$this->smarty->assign('ScriptUrl', Configuration::Instance()->GetScriptUrl());
$scriptUrl = Configuration::Instance()->GetScriptUrl();
$this->smarty->assign('ScriptUrl', $scriptUrl);
$this->smarty->assign('ScriptUrlMissingWebSuffix', $scriptUrl !== '' && !str_ends_with(rtrim($scriptUrl, '/'), '/Web'));
$this->smarty->assign('UserName', !is_null($userSession) ? $userSession->FirstName : '');
$this->smarty->assign('DisplayWelcome', $this->DisplayWelcome());
$this->smarty->assign('UserId', $userSession->UserId);
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ To run LibreBooking from a prebuilt release, your server needs:

- PHP >= 8.2 with the extensions: ctype, curl, fileinfo, intl, json, mbstring, mysqli, openssl, pdo, pdo_mysql, tokenizer, xml
- Optional PHP extensions: bcmath (needed for Active Directory authentication), gd (image processing), ldap (LDAP authentication)
- A web server like Apache or Nginx
- Apache >= 2.4. Other web servers, including Nginx, may work when configured
with equivalent routing and access-control rules, but are not currently
supported or tested by the LibreBooking project.
- MySQL >= 8.0 (2018) or MariaDB >= 10.6 (2021)
- Composer (for managing PHP dependencies)
- Git (optional, useful for cloning the repository or managing updates)
Expand Down
4 changes: 2 additions & 2 deletions Web/Services/.htaccess
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Limit GET POST PUT DELETE OPTIONS>
Allow from all
Require all granted
</Limit>


Expand All @@ -14,4 +14,4 @@ RewriteRule ^(.*)$ blank.html [QSA,L]

Header Set Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type, x-booked-sessiontoken, x-booked-userid"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
2 changes: 1 addition & 1 deletion config/.htaccess
Original file line number Diff line number Diff line change
@@ -1 +1 @@
deny from all
Require all denied
7 changes: 7 additions & 0 deletions docs/source/BASIC-CONFIGURATION.rst
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,13 @@ Frontend Settings
because application links and other features may not work correctly. Set
``script.url`` (or ``LB_SCRIPT_URL``) to dismiss the warning.

``script.url`` must always end with ``/Web``. The webserver document root
must not be set directly to the ``Web`` directory with ``/Web`` omitted
from the URL — that configuration is not supported and breaks navigation
links and login/SSO redirects. LibreBooking can still be installed in a
subdirectory/subsite under the document root, as long as ``/Web`` remains
the final path segment (e.g. ``https://example.com/librebooking/Web``).

**css.theme**
Theme to use for the application. Options: default, dimgray, dark_red,
dark_green, french_blue, cake_blue, orange.
Expand Down
22 changes: 22 additions & 0 deletions docs/source/FAQ.rst
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,25 @@ Related threads:

- `<https://github.com/LibreBooking/librebooking/discussions/752>`__
- `<https://github.com/LibreBooking/librebooking/issues/13>`__

Can I set the document root directly to the ``Web`` directory and drop ``/Web`` from the URL?
------------------------------------------------------------------------------------------------

No. LibreBooking can be installed at the document root or in a
subdirectory/subsite underneath it, but the public URL must always include
``/Web/`` (e.g. ``https://example.com/Web/`` or
``https://example.com/librebooking/Web/``), and ``script.url`` must be set
accordingly.

Pointing the document root directly at the ``Web`` directory so that URLs
omit ``/Web`` (e.g. ``https://example.com/schedule.php``) is not supported.
Several parts of the application assume ``/Web`` is present in the request
path, including navigation-link validation and login/SSO redirect
construction, so omitting it breaks Schedule/Calendar navigation and can
break external authentication redirects.

See :doc:`INSTALLATION` and :doc:`BASIC-CONFIGURATION`.

Related threads:

- `<https://github.com/LibreBooking/librebooking/issues/1590>`__
10 changes: 10 additions & 0 deletions docs/source/INSTALLATION.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ Alternatively, you can clone the application directly from the official GitHub r

git clone https://github.com/LibreBooking/librebooking.git

.. important::
The document root (or subsite) must point at the LibreBooking project
directory itself, **not** at its ``Web`` subdirectory. LibreBooking can be
installed directly at the document root or in a subdirectory/subsite
underneath it (e.g. ``https://example.com/librebooking/``), but the public
URL must always include ``/Web/`` (e.g. ``https://example.com/Web/`` or
``https://example.com/librebooking/Web/``). Pointing the document root
directly at ``Web`` and omitting ``/Web/`` from the URL is not supported —
it breaks navigation links and login/SSO redirects.

After copying or cloning the application to your web server:

Install PHP dependencies using Composer:
Expand Down
1 change: 1 addition & 0 deletions lang/en_us.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ protected function _LoadStrings()
$strings['SignOut'] = 'Sign Out';
$strings['JavascriptRequired'] = 'This application requires JavaScript to function properly. Please enable JavaScript in your browser settings.';
$strings['ScriptUrlNotConfigured'] = 'LibreBooking is not configured correctly. The <code>script.url</code> setting is empty, so some application features will not work. Please contact the administrator.';
$strings['ScriptUrlMissingWebSuffix'] = 'LibreBooking is not configured correctly. The <code>script.url</code> setting must end with <code>/Web</code>, or navigation links and login redirects will not work correctly. Please contact the administrator.';
$strings['LayoutDescription'] = 'Starts on %s, showing %s days at a time';
$strings['AllResources'] = 'All Resources';
$strings['TakeOffline'] = 'Take Offline';
Expand Down
27 changes: 27 additions & 0 deletions tests/Infrastructure/Common/SmartyPageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,38 @@ public function testGlobalHeaderDoesNotDisplayWarningWhenScriptUrlIsConfigured()
{
$page = new SmartyPage();
$page->assign('ScriptUrl', 'https://librebooking.example/Web');
$page->assign('ScriptUrlMissingWebSuffix', false);

$output = $page->fetch('globalheader.tpl');

$this->assertStringNotContainsString('id="script-url-warning"', $output);
$this->assertStringNotContainsString('ScriptUrlNotConfigured', $output);
$this->assertStringNotContainsString('id="script-url-web-suffix-warning"', $output);
$this->assertStringNotContainsString('ScriptUrlMissingWebSuffix', $output);
}

public function testGlobalHeaderDisplaysWarningWhenScriptUrlIsMissingWebSuffix(): void
{
$page = new SmartyPage();
$page->assign('ScriptUrl', 'https://librebooking.example');
$page->assign('ScriptUrlMissingWebSuffix', true);

$output = $page->fetch('globalheader.tpl');

$this->assertStringContainsString('id="script-url-web-suffix-warning"', $output);
$this->assertStringContainsString('ScriptUrlMissingWebSuffix', $output);
}

public function testGlobalHeaderPrefersEmptyWarningOverWebSuffixWarning(): void
{
$page = new SmartyPage();
$page->assign('ScriptUrl', '');
$page->assign('ScriptUrlMissingWebSuffix', true);

$output = $page->fetch('globalheader.tpl');

$this->assertStringContainsString('id="script-url-warning"', $output);
$this->assertStringNotContainsString('id="script-url-web-suffix-warning"', $output);
}

public function testCreateUrlLinkifiesHttpAndHttpsUrls(): void
Expand Down
6 changes: 5 additions & 1 deletion tpl/globalheader.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,15 @@
</div>
</noscript>

{* Alert everyone if `script.url` is unset as it will cause issues. *}
{* Alert everyone if `script.url` is unset or missing the required `/Web` suffix, as either will cause issues. *}
{if !isset($ScriptUrl) || $ScriptUrl eq ''}
<div id="script-url-warning" class="alert alert-danger text-center m-2" role="alert">
{translate key="ScriptUrlNotConfigured"}
</div>
{elseif !empty($ScriptUrlMissingWebSuffix)}
<div id="script-url-web-suffix-warning" class="alert alert-danger text-center m-2" role="alert">
{translate key="ScriptUrlMissingWebSuffix"}
</div>
{/if}

{if !isset($HideNavBar) || $HideNavBar == false}
Expand Down
6 changes: 1 addition & 5 deletions uploads/.htaccess
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
deny from all

<Files ~ "^.*">
Deny from all
</Files>
Require all denied