mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-04-08 17:15:08 +02:00
Compare commits
No commits in common. "main" and "v2.12.2" have entirely different histories.
4
.github/workflows/php.yml
vendored
4
.github/workflows/php.yml
vendored
@ -100,9 +100,7 @@ jobs:
|
||||
|
||||
- name: Setup dependencies
|
||||
run: |
|
||||
composer init -n --require mockery/mockery:* --require ipl/i18n:@dev --require ipl/web:@dev
|
||||
composer config platform.php 7.2.9
|
||||
composer install -n --no-progress
|
||||
composer require -n --no-progress mockery/mockery ipl/i18n:@dev ipl/web:@dev
|
||||
git clone --depth 1 --branch snapshot/nightly https://github.com/Icinga/icinga-php-thirdparty.git vendor/icinga-php-thirdparty
|
||||
|
||||
- name: PHPUnit
|
||||
|
41
CHANGELOG.md
41
CHANGELOG.md
@ -4,47 +4,6 @@ Please make sure to always read our [Upgrading](doc/80-Upgrading.md) documentati
|
||||
|
||||
## What's New
|
||||
|
||||
### What's New in Version 2.12.4
|
||||
|
||||
This is a hotfix release which fixes the following issue:
|
||||
|
||||
Database login broken after upgrade [#5343](https://github.com/Icinga/icingaweb2/issues/5343)
|
||||
|
||||
### What's New in Version 2.12.3
|
||||
|
||||
**Notice:** This is a security release. It is recommended to upgrade _immediately_.
|
||||
|
||||
You can find all issues related to this release on our Roadmap.
|
||||
|
||||
#### Vulnerabilities, Closed
|
||||
|
||||
Cross site scripting is one of the worst attacks on web based platforms. Especially, if carrying it out is as easy as
|
||||
the first two mentioned here. You might recognize the open redirect on the login. You are correct, we attempted to fix
|
||||
it already with v2.11.3 but underestimated PHP's quirks. The last is difficult to exploit, hence the lowest severity
|
||||
of all, but don't be fooled by that!
|
||||
|
||||
All four of them are backported to v2.11.5.
|
||||
|
||||
* XSS in embedded content [CVE-2025-27405](https://github.com/Icinga/icingaweb2/security/advisories/GHSA-3x37-fjc3-ch8w)
|
||||
* DOM-based XSS [CVE-2025-27404](https://github.com/Icinga/icingaweb2/security/advisories/GHSA-c6pg-h955-wf66)
|
||||
* Open redirect on login page [CVE-2025-30164](https://github.com/Icinga/icingaweb2/security/advisories/GHSA-8r73-6686-wv8q)
|
||||
* Reflected XSS [CVE-2025-27609](https://github.com/Icinga/icingaweb2/security/advisories/GHSA-5cjw-fwjc-8j38)
|
||||
|
||||
Big thanks to all finders / reporters! :+1:
|
||||
|
||||
#### Bugs, Exterminated
|
||||
|
||||
Did you know, that we started [Icinga Notifications](https://icinga.com/docs/icinga-notifications/latest/) with support
|
||||
for PostgreSQL first? Reason for that is, we wanted to make sure we are fully compatible with it right away. To ensure
|
||||
things like logging in with a PostgreSQL authentication/group backend is case-insensitive, like it was always the case
|
||||
for MySQL. Now it **really** is case-insensitive! There are also two issues fixed, which many of you will probably have
|
||||
noticed since v2.12.2, sorry that it took so long :)
|
||||
|
||||
* Login against Postgres DB is case-sensitive [#5223](https://github.com/Icinga/icingaweb2/issues/5223)
|
||||
* Role list has no functioning quick search [#5300](https://github.com/Icinga/icingaweb2/issues/5300)
|
||||
* After clicking on Check now, the page does not refresh itself [#5293](https://github.com/Icinga/icingaweb2/issues/5293)
|
||||
* Service States display wrong since update to 2.12.2 [#5290](https://github.com/Icinga/icingaweb2/issues/5290)
|
||||
|
||||
### What's New in Version 2.12.2
|
||||
|
||||
You can find all issues related to this release on our Roadmap.
|
||||
|
@ -3,108 +3,18 @@
|
||||
|
||||
namespace Icinga\Controllers;
|
||||
|
||||
use Icinga\Web\Session;
|
||||
use ipl\Html\BaseHtmlElement;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Html\HtmlString;
|
||||
use ipl\Html\Text;
|
||||
use ipl\Web\Compat\CompatController;
|
||||
use ipl\Web\Url;
|
||||
use ipl\Web\Widget\Icon;
|
||||
use ipl\Web\Widget\Tabs;
|
||||
use Icinga\Web\Controller;
|
||||
|
||||
/**
|
||||
* Display external or internal links within an iframe
|
||||
*/
|
||||
class IframeController extends CompatController
|
||||
class IframeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display iframe w/ the given URL
|
||||
*/
|
||||
public function indexAction(): void
|
||||
public function indexAction()
|
||||
{
|
||||
$url = Url::fromPath($this->params->getRequired('url'));
|
||||
$urlHash = $this->getRequest()->getHeader('X-Icinga-URLHash');
|
||||
$expectedHash = hash('sha256', $url->getAbsoluteUrl() . Session::getSession()->getId());
|
||||
$iframeUrl = Url::fromPath('iframe', ['url' => $url->getAbsoluteUrl()]);
|
||||
|
||||
if (! in_array($url->getScheme(), ['http', 'https'], true)) {
|
||||
$this->httpBadRequest('Invalid URL scheme');
|
||||
}
|
||||
|
||||
$this->injectTabs();
|
||||
|
||||
$this->getTabs()->setRefreshUrl($iframeUrl);
|
||||
|
||||
if ($urlHash) {
|
||||
if ($urlHash !== $expectedHash) {
|
||||
$this->httpBadRequest('Invalid URL hash');
|
||||
}
|
||||
} else {
|
||||
$this->addContent(Html::tag('div', ['class' => 'iframe-warning'], [
|
||||
Html::tag('h2', $this->translate('Attention!')),
|
||||
Html::tag('p', ['class' => 'note'], $this->translate(
|
||||
'You are about to open untrusted content embedded in Icinga Web! Only proceed,'
|
||||
.' by clicking the link below, if you recognize and trust the source!'
|
||||
)),
|
||||
Html::tag('a', ['data-url-hash' => $expectedHash, 'href' => Html::escape($iframeUrl)], $url),
|
||||
Html::tag('p', ['class' => 'reason'], [
|
||||
new Icon('circle-info'),
|
||||
Text::create($this->translate(
|
||||
'You see this warning because you do not seem to have followed a link in Icinga Web.'
|
||||
. ' You can bypass this in the future by configuring a navigation item instead.'
|
||||
))
|
||||
])
|
||||
]));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->getTabs()->setHash($expectedHash);
|
||||
|
||||
$this->addContent(Html::tag(
|
||||
'div',
|
||||
['class' => 'iframe-container'],
|
||||
Html::tag('iframe', [
|
||||
'src' => $url,
|
||||
'sandbox' => 'allow-same-origin allow-scripts allow-popups allow-forms',
|
||||
])
|
||||
));
|
||||
}
|
||||
|
||||
private function injectTabs(): void
|
||||
{
|
||||
$this->tabs = new class extends Tabs {
|
||||
private $hash;
|
||||
|
||||
public function setHash($hash)
|
||||
{
|
||||
$this->hash = $hash;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function assemble()
|
||||
{
|
||||
$tabHtml = substr($this->tabs->render(), 34, -5);
|
||||
if ($this->refreshUrl !== null) {
|
||||
$tabHtml = preg_replace(
|
||||
[
|
||||
'/(?<=class="refresh-container-control spinner" href=")([^"]*)/',
|
||||
'/(\s)(?=href)/'
|
||||
],
|
||||
[
|
||||
$this->refreshUrl->getAbsoluteUrl(),
|
||||
' data-url-hash="' . $this->hash . '" '
|
||||
],
|
||||
$tabHtml
|
||||
);
|
||||
}
|
||||
|
||||
BaseHtmlElement::add(HtmlString::create($tabHtml));
|
||||
}
|
||||
};
|
||||
|
||||
$this->controls->setTabs($this->tabs);
|
||||
$this->view->url = $this->params->getRequired('url');
|
||||
}
|
||||
}
|
||||
|
@ -184,6 +184,15 @@ use ipl\Web\Widget\StateBadge;
|
||||
</div>
|
||||
<div class="about-social">
|
||||
<?= $this->qlink(
|
||||
null,
|
||||
'https://www.twitter.com/icinga',
|
||||
null,
|
||||
array(
|
||||
'target' => '_blank',
|
||||
'icon' => 'twitter',
|
||||
'title' => $this->translate('Icinga on Twitter')
|
||||
)
|
||||
) ?> <?= $this->qlink(
|
||||
null,
|
||||
'https://www.facebook.com/icinga',
|
||||
null,
|
||||
|
@ -28,6 +28,18 @@
|
||||
</div>
|
||||
</div>
|
||||
<ul id="social">
|
||||
<li>
|
||||
<?= $this->qlink(
|
||||
null,
|
||||
'https://twitter.com/icinga',
|
||||
null,
|
||||
array(
|
||||
'target' => '_blank',
|
||||
'icon' => 'twitter',
|
||||
'title' => $this->translate('Icinga on Twitter')
|
||||
)
|
||||
) ?>
|
||||
</li>
|
||||
<li>
|
||||
<?= $this->qlink(
|
||||
null,
|
||||
|
@ -6,7 +6,7 @@
|
||||
<?= $this->tabs->render($this); ?>
|
||||
<br/>
|
||||
<div>
|
||||
<h1>Could not <?= $action; ?> module "<?= $this->escape($moduleName); ?>"</h1>
|
||||
<h1>Could not <?= $action; ?> module "<?= $moduleName; ?>"</h1>
|
||||
<p>
|
||||
While operation the following error occurred:
|
||||
<br />
|
||||
|
@ -23,7 +23,7 @@ $modReason = [];
|
||||
|
||||
if (isset($requiredVendor, $requiredProject) && $requiredVendor && $requiredProject) {
|
||||
// TODO: I don't like this, can we define requirements somewhere else?
|
||||
$coreDeps = ['icinga-php-library' => '>= 0.14.2', 'icinga-php-thirdparty' => '>= 0.12'];
|
||||
$coreDeps = ['icinga-php-library' => '>= 0.13.2', 'icinga-php-thirdparty' => '>= 0.12'];
|
||||
|
||||
foreach ($coreDeps as $libraryName => $requiredVersion) {
|
||||
if (! $libraries->has($libraryName)) {
|
||||
|
8
application/views/scripts/iframe/index.phtml
Normal file
8
application/views/scripts/iframe/index.phtml
Normal file
@ -0,0 +1,8 @@
|
||||
<?php if (! $compact): ?>
|
||||
<div class="controls">
|
||||
<?= $tabs ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<div class="iframe-container">
|
||||
<iframe src="<?= $this->escape($url) ?>" frameborder="no"></iframe>
|
||||
</div>
|
@ -399,7 +399,7 @@ You will need to install certain dependencies depending on your setup:
|
||||
monitor your infrastructure
|
||||
* A web server, e.g. Apache or Nginx
|
||||
* PHP version ≥ 7.2
|
||||
* [Icinga PHP Library (ipl)](https://github.com/Icinga/icinga-php-library) (≥ 0.14.2)
|
||||
* [Icinga PHP Library (ipl)](https://github.com/Icinga/icinga-php-library) (≥ 0.13.2)
|
||||
* [Icinga PHP Thirdparty](https://github.com/Icinga/icinga-php-thirdparty) (≥ 0.12)
|
||||
* The following PHP modules must be installed: cURL, json, gettext, fileinfo, intl, dom, OpenSSL and xml
|
||||
* The [pdfexport](https://github.com/Icinga/icingaweb2-module-pdfexport) module (≥0.10) is required for the
|
||||
|
@ -58,8 +58,8 @@ Disabled by default.
|
||||
If you experience any problems while running SELinux in enforcing mode try to reproduce it in permissive mode. If the
|
||||
problem persists, it is not related to SELinux because in permissive mode SELinux will not deny anything.
|
||||
|
||||
When filing a bug report please add the following information additionally to the common ones:
|
||||
|
||||
When filing a bug report please add the following information additionally to the
|
||||
[common ones](https://icinga.com/icinga/faq/):
|
||||
* Output of `semodule -l | grep -e icinga2 -e icingaweb2 -e nagios -e apache`
|
||||
* Output of `semanage boolean -l | grep icinga`
|
||||
* Output of `ps -eZ | grep httpd`
|
||||
|
@ -8,7 +8,7 @@ namespace Icinga\Application;
|
||||
*/
|
||||
class Version
|
||||
{
|
||||
const VERSION = '2.12.4';
|
||||
const VERSION = '2.12.2';
|
||||
|
||||
/**
|
||||
* Get the version of this instance of Icinga Web 2
|
||||
|
@ -42,9 +42,4 @@ class RolesConfig extends IniRepository
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
protected function initializeSearchColumns(): array
|
||||
{
|
||||
return ['name'];
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ use Icinga\Exception\AuthenticationException;
|
||||
use Icinga\Repository\DbRepository;
|
||||
use Icinga\User;
|
||||
use PDO;
|
||||
use Zend_Db_Expr;
|
||||
|
||||
class DbUserBackend extends DbRepository implements UserBackendInterface, Inspectable
|
||||
{
|
||||
@ -180,28 +179,23 @@ class DbUserBackend extends DbRepository implements UserBackendInterface, Inspec
|
||||
{
|
||||
if ($this->ds->getDbType() === 'pgsql') {
|
||||
// Since PostgreSQL version 9.0 the default value for bytea_output is 'hex' instead of 'escape'
|
||||
$columns = ['password_hash' => new Zend_Db_Expr('ENCODE(password_hash, \'escape\')')];
|
||||
$columns = array('password_hash' => 'ENCODE(password_hash, \'escape\')');
|
||||
} else {
|
||||
// password_hash is intentionally not a valid query column,
|
||||
// by wrapping it in an expression it is not validated
|
||||
$columns = ['password_hash' => new Zend_Db_Expr('password_hash')];
|
||||
$columns = array('password_hash');
|
||||
}
|
||||
|
||||
$query = $this
|
||||
->select()
|
||||
->from('user', $columns)
|
||||
->where('active', true);
|
||||
|
||||
$nameColumn = 'name';
|
||||
if ($this->ds->getDbType() === 'mysql') {
|
||||
$username = strtolower($username);
|
||||
$nameColumn = new Zend_Db_Expr('BINARY LOWER(name)');
|
||||
|
||||
$query->getQuery()->where($nameColumn, $username);
|
||||
} else { // pgsql
|
||||
$query->where('user', $username);
|
||||
$nameColumn = 'BINARY LOWER(name)';
|
||||
}
|
||||
|
||||
$statement = $this->ds->getDbAdapter()->prepare($query->getQuery()->getSelectQuery());
|
||||
$query = $this->ds->select()
|
||||
->from($this->prependTablePrefix('user'), $columns)
|
||||
->where($nameColumn, $username)
|
||||
->where('active', true);
|
||||
|
||||
$statement = $this->ds->getDbAdapter()->prepare($query->getSelectQuery());
|
||||
$statement->execute();
|
||||
$statement->bindColumn(1, $lob, PDO::PARAM_LOB);
|
||||
$statement->fetch(PDO::FETCH_BOUND);
|
||||
|
@ -204,7 +204,7 @@ class DbUserGroupBackend extends DbRepository implements Inspectable, UserGroupB
|
||||
$membershipQuery = $this
|
||||
->select()
|
||||
->from('group_membership', array('group_name'))
|
||||
->where('user', $user->getUsername());
|
||||
->where('user_name', $user->getUsername());
|
||||
|
||||
$memberships = array();
|
||||
foreach ($membershipQuery as $membership) {
|
||||
|
@ -37,7 +37,7 @@ class Csv
|
||||
}
|
||||
$out = array();
|
||||
foreach ($row as & $val) {
|
||||
$out[] = '"' . ($val == '0' ? '0' : ($val ? str_replace('"', '""', $val) : '')) . '"';
|
||||
$out[] = '"' . ($val ? str_replace('"', '""', $val) : '') . '"';
|
||||
}
|
||||
$csv .= implode(',', $out) . "\r\n";
|
||||
}
|
||||
|
@ -5,11 +5,9 @@ namespace Icinga\File;
|
||||
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Options;
|
||||
use Exception;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Util\Environment;
|
||||
use Icinga\Web\FileCache;
|
||||
use Icinga\Web\Hook;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
@ -66,17 +64,8 @@ class Pdf
|
||||
return;
|
||||
}
|
||||
|
||||
$tmpDir = FileCache::instance()->directory('legacy_pdf');
|
||||
if ($tmpDir === false) {
|
||||
throw new Exception('Could not create temporary directory for PDF rendering');
|
||||
}
|
||||
|
||||
$options = new Options();
|
||||
$options->set('defaultPaperSize', 'A4');
|
||||
$options->set('fontDir', $tmpDir);
|
||||
$options->set('fontCache', $tmpDir);
|
||||
$options->set('tempDir', $tmpDir);
|
||||
$options->set('chroot', $tmpDir);
|
||||
$dompdf = new Dompdf($options);
|
||||
$dompdf->loadHtml($html);
|
||||
$dompdf->render();
|
||||
|
@ -7,7 +7,6 @@ use Icinga\Application\Icinga;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Util\StringHelper;
|
||||
use Icinga\Web\Navigation\NavigationItem;
|
||||
use Icinga\Web\Session;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Web\View;
|
||||
|
||||
@ -191,10 +190,6 @@ class NavigationItemRenderer
|
||||
|
||||
$target = $item->getTarget();
|
||||
if ($url->isExternal() && (!$target || in_array($target, $this->internalLinkTargets, true))) {
|
||||
$item->setAttribute('data-url-hash', hash(
|
||||
'sha256',
|
||||
$url->getAbsoluteUrl() . Session::getSession()->getId()
|
||||
));
|
||||
$url = Url::fromPath('iframe', array('url' => $url));
|
||||
}
|
||||
|
||||
|
@ -179,9 +179,10 @@ class Url
|
||||
}
|
||||
|
||||
$urlParts = parse_url($url);
|
||||
if ((isset($urlParts['scheme']) && $urlParts['scheme'] !== $request->getScheme())
|
||||
if (isset($urlParts['scheme']) && (
|
||||
$urlParts['scheme'] !== $request->getScheme()
|
||||
|| (isset($urlParts['host']) && $urlParts['host'] !== $request->getServer('SERVER_NAME'))
|
||||
|| (isset($urlParts['port']) && $urlParts['port'] != $request->getServer('SERVER_PORT'))
|
||||
|| (isset($urlParts['port']) && $urlParts['port'] != $request->getServer('SERVER_PORT')))
|
||||
) {
|
||||
$urlObject->setIsExternal();
|
||||
}
|
||||
|
@ -205,8 +205,7 @@ class View extends Zend_View_Abstract
|
||||
'th-thumb-empty' => true,
|
||||
'github-circled' => true,
|
||||
'history' => true,
|
||||
'binoculars' => true,
|
||||
'letter' => true
|
||||
'binoculars' => true
|
||||
//</editor-fold>
|
||||
];
|
||||
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
namespace Icinga\Web\Widget\Dashboard;
|
||||
|
||||
use Icinga\Web\Session;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
/**
|
||||
* A dashboard pane dashlet
|
||||
@ -57,15 +57,18 @@ class Dashlet extends UserWidget
|
||||
*/
|
||||
private $template =<<<'EOD'
|
||||
|
||||
<div class="container" data-icinga-url="{URL}" data-url-hash="{URL_HASH}">
|
||||
<h1><a
|
||||
href="{FULL_URL}"
|
||||
aria-label="{TOOLTIP}"
|
||||
title="{TOOLTIP}"
|
||||
data-url-hash="{FULL_URL_HASH}"
|
||||
data-base-target="col1"
|
||||
>{TITLE}</a></h1>
|
||||
<div class="container" data-icinga-url="{URL}">
|
||||
<h1><a href="{FULL_URL}" aria-label="{TOOLTIP}" title="{TOOLTIP}" data-base-target="col1">{TITLE}</a></h1>
|
||||
<p class="progress-label">{PROGRESS_LABEL}<span>.</span><span>.</span><span>.</span></p>
|
||||
<noscript>
|
||||
<div class="iframe-container">
|
||||
<iframe
|
||||
src="{IFRAME_URL}"
|
||||
frameborder="no"
|
||||
title="{TITLE_PREFIX}{TITLE}">
|
||||
</iframe>
|
||||
</div>
|
||||
</noscript>
|
||||
</div>
|
||||
EOD;
|
||||
|
||||
@ -247,22 +250,13 @@ EOD;
|
||||
|
||||
$url = $this->getUrl();
|
||||
$url->setParam('showCompact', true);
|
||||
$fullUrl = $url->getUrlWithout(['showCompact', 'limit', 'view']);
|
||||
|
||||
$urlHash = '';
|
||||
$fullUrlHash = '';
|
||||
if ($url->getPath() === 'iframe') {
|
||||
$urlHash = hash('sha256', Url::fromPath($url->getParam('url'))->getAbsoluteUrl()
|
||||
. Session::getSession()->getId());
|
||||
$fullUrlHash = hash('sha256', Url::fromPath($fullUrl->getParam('url'))->getAbsoluteUrl()
|
||||
. Session::getSession()->getId());
|
||||
}
|
||||
$iframeUrl = clone $url;
|
||||
$iframeUrl->setParam('isIframe');
|
||||
|
||||
$searchTokens = array(
|
||||
'{URL}',
|
||||
'{URL_HASH}',
|
||||
'{IFRAME_URL}',
|
||||
'{FULL_URL}',
|
||||
'{FULL_URL_HASH}',
|
||||
'{TOOLTIP}',
|
||||
'{TITLE}',
|
||||
'{TITLE_PREFIX}',
|
||||
@ -271,9 +265,8 @@ EOD;
|
||||
|
||||
$replaceTokens = array(
|
||||
$url,
|
||||
$urlHash,
|
||||
$fullUrl,
|
||||
$fullUrlHash,
|
||||
$iframeUrl,
|
||||
$url->getUrlWithout(['showCompact', 'limit', 'view']),
|
||||
sprintf($view->translate('Show %s', 'dashboard.dashlet.tooltip'), $view->escape($this->getTitle())),
|
||||
$view->escape($this->getTitle()),
|
||||
$view->translate('Dashlet') . ': ',
|
||||
|
@ -112,7 +112,7 @@ class Window
|
||||
{
|
||||
if (! isset(static::$window)) {
|
||||
$id = Icinga::app()->getRequest()->getHeader('X-Icinga-WindowId');
|
||||
if (empty($id) || $id === static::UNDEFINED || ! preg_match('/^\w+$/', $id)) {
|
||||
if (empty($id) || $id === static::UNDEFINED) {
|
||||
Icinga::app()->getResponse()->setOverrideWindowId();
|
||||
$id = static::generateId();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
Module: doc
|
||||
Version: 2.12.4
|
||||
Version: 2.12.2
|
||||
Description: Documentation module
|
||||
Extracts, shows and exports documentation for Icinga Web 2 and its modules.
|
||||
|
@ -1,5 +1,17 @@
|
||||
/*! Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */
|
||||
|
||||
// Mixins
|
||||
|
||||
.gradient(@a: @gray-lighter; @b: @gray-lightest) {
|
||||
background: @a;
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(@a), to(@b));
|
||||
background: -webkit-linear-gradient(top, @a, @b);
|
||||
background: -moz-linear-gradient(top, @a, @b);
|
||||
background: -ms-linear-gradient(top, @a, @b);
|
||||
background: -o-linear-gradient(top, @a, @b);
|
||||
background: linear-gradient(to bottom, @a, @b);
|
||||
}
|
||||
|
||||
// General styles
|
||||
|
||||
code {
|
||||
@ -72,7 +84,7 @@ table {
|
||||
}
|
||||
|
||||
tbody > tr:nth-child(odd) {
|
||||
background: @gray-light;
|
||||
.gradient()
|
||||
}
|
||||
|
||||
tbody > tr:nth-child(even) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
Module: migrate
|
||||
Version: 2.12.4
|
||||
Version: 2.12.2
|
||||
Description: Migrate module
|
||||
This module was introduced with the domain-aware authentication feature in version 2.5.0.
|
||||
It helps you migrating users and user configurations according to a given domain.
|
||||
|
@ -227,7 +227,7 @@ class BackendConfigForm extends ConfigForm
|
||||
'autosubmit' => true
|
||||
)
|
||||
);
|
||||
$resourceName = $this->getView()->escape($formData['resource'] ?? $this->getValue('resource'));
|
||||
$resourceName = isset($formData['resource']) ? $formData['resource'] : $this->getValue('resource');
|
||||
$this->addElement(
|
||||
'note',
|
||||
'resource_note',
|
||||
|
@ -284,10 +284,10 @@ $section->add(N_('Timeline'), array(
|
||||
/*
|
||||
* Reporting Section
|
||||
*/
|
||||
$section = $this->menuSection(N_('Reporting'), [
|
||||
'icon' => 'fa-chart-simple',
|
||||
$section = $this->menuSection(N_('Reporting'), array(
|
||||
'icon' => 'barchart',
|
||||
'priority' => 100
|
||||
]);
|
||||
));
|
||||
|
||||
/*
|
||||
* Current Incidents
|
||||
|
@ -1,5 +1,5 @@
|
||||
Module: monitoring
|
||||
Version: 2.12.4
|
||||
Version: 2.12.2
|
||||
Description: Icinga monitoring module
|
||||
IDO accessor and UI for your monitoring. This is the initial instalment for a
|
||||
graphical presentation of Icinga environments. The predecessor of Icinga DB.
|
||||
|
@ -602,7 +602,7 @@ class WebWizard extends Wizard implements SetupWizard
|
||||
)));
|
||||
|
||||
$set->add(new WebLibraryRequirement(array(
|
||||
'condition' => ['icinga-php-library', '>=', '0.14.2'],
|
||||
'condition' => ['icinga-php-library', '>=', '0.13.2'],
|
||||
'alias' => 'Icinga PHP library',
|
||||
'description' => mt(
|
||||
'setup',
|
||||
|
@ -1,5 +1,5 @@
|
||||
Module: setup
|
||||
Version: 2.12.4
|
||||
Version: 2.12.2
|
||||
Description: Setup module
|
||||
Web based wizard for setting up Icinga Web 2 and its modules.
|
||||
This includes the data backends (e.g. relational database, LDAP),
|
||||
|
@ -1,5 +1,5 @@
|
||||
Module: test
|
||||
Version: 2.12.4
|
||||
Version: 2.12.2
|
||||
Description: Translation module
|
||||
This module allows developers to run (unit) tests against Icinga Web 2 and
|
||||
any of its modules. Usually you do not need to enable this.
|
||||
|
@ -130,7 +130,7 @@ below.
|
||||

|
||||
|
||||
And when you want to test your changes, please read more about under the chapter
|
||||
[Testing Translations](03-Translation.md#module-translation-tests).
|
||||
[Testing Translations](Testing Translations).
|
||||
|
||||
## Testing Translations <a id="module-translation-tests"></a>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
Module: translation
|
||||
Version: 2.12.4
|
||||
Version: 2.12.2
|
||||
Description: Translation module
|
||||
This module allows developers and translators to translate modules for multiple
|
||||
languages. You do not need this module to run an internationalized web frontend.
|
||||
|
@ -282,39 +282,6 @@ a:hover > .icon-cancel {
|
||||
|
||||
// Responsive iFrames
|
||||
|
||||
.iframe-warning {
|
||||
h2, p, a {
|
||||
display: block;
|
||||
width: fit-content;
|
||||
font-size: 200%;
|
||||
margin: 0 auto;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1000%;
|
||||
color: @state-warning;
|
||||
}
|
||||
|
||||
.note {
|
||||
background: @gray-lighter;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.reason {
|
||||
.icon {
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
font-size: 100%;
|
||||
background: @gray-lightest;
|
||||
color: @text-color-light;
|
||||
}
|
||||
}
|
||||
|
||||
.iframe-container {
|
||||
position: relative;
|
||||
height: 0;
|
||||
@ -328,7 +295,6 @@ a:hover > .icon-cancel {
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@
|
||||
border-top: none;
|
||||
margin-left: -1px;
|
||||
min-width: 14em;
|
||||
z-index: 1001;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.tabs > .dropdown-nav-item > ul > li:hover > a {
|
||||
|
@ -83,9 +83,7 @@
|
||||
if ($container[0].contains(origFocus)
|
||||
&& origFocus.form
|
||||
&& ! origFocus.matches(
|
||||
'input[type=submit], input[type=reset], input[type=button]'
|
||||
+ ', button[type=submit], button[type=reset], button[type=button]'
|
||||
+ ', .autofocus, .autosubmit:not(:hover)'
|
||||
'input[type=submit], input[type=reset], input[type=button], .autofocus, .autosubmit:not(:hover)'
|
||||
)
|
||||
) {
|
||||
this.icinga.logger.debug('Not changing content for ' + containerId + ' form has focus');
|
||||
|
@ -170,21 +170,7 @@
|
||||
var $dashlet = $(this);
|
||||
var url = $dashlet.data('icingaUrl');
|
||||
if (typeof url !== 'undefined') {
|
||||
const urlHash = this.dataset.urlHash;
|
||||
if (urlHash) {
|
||||
_this.icinga.loader.loadUrl(
|
||||
url,
|
||||
$dashlet,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
true,
|
||||
undefined,
|
||||
{ "X-Icinga-URLHash": urlHash }
|
||||
);
|
||||
} else {
|
||||
_this.icinga.loader.loadUrl(url, $dashlet).autorefresh = true;
|
||||
}
|
||||
_this.icinga.loader.loadUrl(url, $dashlet).autorefresh = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -295,7 +281,6 @@
|
||||
var $eventTarget = $(event.target);
|
||||
var href = $a.attr('href');
|
||||
var linkTarget = $a.attr('target');
|
||||
const urlHash = this.dataset.urlHash;
|
||||
var $target;
|
||||
var formerUrl;
|
||||
|
||||
@ -406,20 +391,7 @@
|
||||
}
|
||||
|
||||
// Load link URL
|
||||
if (urlHash) {
|
||||
icinga.loader.loadUrl(
|
||||
href,
|
||||
$target,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
{ "X-Icinga-URLHash": urlHash }
|
||||
);
|
||||
} else {
|
||||
icinga.loader.loadUrl(href, $target);
|
||||
}
|
||||
icinga.loader.loadUrl(href, $target);
|
||||
|
||||
if ($a.closest('#menu').length > 0) {
|
||||
// Menu links should remove all but the first layout column
|
||||
|
@ -242,10 +242,6 @@
|
||||
loadUrl: function (url, $target, data, method, action, autorefresh, progressTimer, extraHeaders) {
|
||||
var id = null;
|
||||
|
||||
if (url.startsWith('//') || ! url.startsWith(this.baseUrl + '/')) {
|
||||
throw new Error('URL ' + url + ' is not relative to ' + this.baseUrl);
|
||||
}
|
||||
|
||||
// Default method is GET
|
||||
if ('undefined' === typeof method) {
|
||||
method = 'GET';
|
||||
|
@ -71,11 +71,6 @@ class UrlTest extends BaseTestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testWhetherProtocolRelativeUrlsAreDetectedAsBeingExternal()
|
||||
{
|
||||
$this->assertTrue(Url::fromPath('//testhost/path/to/my/url.html')->isExternal());
|
||||
}
|
||||
|
||||
public function testWhetherGetAbsoluteUrlReturnsTheGivenUsernameAndPassword()
|
||||
{
|
||||
$url = Url::fromPath('http://testusername:testpassword@testsite.com/path/to/my/url.html');
|
||||
|
Loading…
x
Reference in New Issue
Block a user