Remove inline scripts

Remove inline scripts present in `layout.phtml` and `logout.phtml` to prevent CSP violation.
This commit is contained in:
raviks789 2023-07-19 17:45:01 +02:00
parent 33a5f765b9
commit da1bf7048d
4 changed files with 70 additions and 65 deletions

View File

@ -24,7 +24,15 @@ $iframeClass = $isIframe ? ' iframe' : '';
$innerLayoutScript = $this->layout()->innerLayout . '.phtml'; $innerLayoutScript = $this->layout()->innerLayout . '.phtml';
?><!DOCTYPE html> ?><!DOCTYPE html>
<html class="no-js<?= $iframeClass ?>" lang="<?= $lang ?>"> <html
class="no-js<?= $iframeClass ?>" lang="<?= $lang ?>"
data-icinga-window-name="<?= $this->protectId('Icinga') ?>"
data-icinga-timezone="<?= $timezone ?>"
data-icinga-base-url="<?= $this->baseUrl(); ?>"
<?php if ($isIframe): ?>
data-icinga-is-iframe
<?php endif ?>
>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="google" value="notranslate"> <meta name="google" value="notranslate">
@ -39,12 +47,6 @@ $innerLayoutScript = $this->layout()->innerLayout . '.phtml';
<base target="_parent"> <base target="_parent">
<?php else: ?> <?php else: ?>
<base href="<?= $this->baseUrl(); ?>/"> <base href="<?= $this->baseUrl(); ?>/">
<script type="text/javascript">
(function() {
var html = document.getElementsByTagName('html')[0];
html.className = html.className.replace(/no-js/, 'js');
}());
</script>
<?php endif ?> <?php endif ?>
<link rel="stylesheet" href="<?= $this->href($cssfile) ?>" media="all" type="text/css" /> <link rel="stylesheet" href="<?= $this->href($cssfile) ?>" media="all" type="text/css" />
<link type="image/png" rel="shortcut icon" href="<?= $this->baseUrl('img/favicon.png') ?>" /> <link type="image/png" rel="shortcut icon" href="<?= $this->baseUrl('img/favicon.png') ?>" />
@ -55,25 +57,6 @@ $innerLayoutScript = $this->layout()->innerLayout . '.phtml';
<div id="layout" class="default-layout<?php if ($showFullscreen): ?> fullscreen-layout<?php endif ?>"> <div id="layout" class="default-layout<?php if ($showFullscreen): ?> fullscreen-layout<?php endif ?>">
<?= $this->render($innerLayoutScript); ?> <?= $this->render($innerLayoutScript); ?>
</div> </div>
<script type="text/javascript">
(function() {
if (document.defaultView && document.defaultView.getComputedStyle) {
var matched;
var html = document.getElementsByTagName('html')[0];
var element = document.getElementById('layout');
var name = document.defaultView
.getComputedStyle(html)['font-family']
.replace(/['",]/g, '');
if (null !== (matched = name.match(/^([a-z]+)-layout$/))) {
element.className = element.className.replace('default-layout', name);
if ('object' === typeof window.console) {
window.console.log('Icinga Web 2: setting initial layout to ' + name);
}
}
}
}());
</script>
<div id="collapsible-control-ghost" class="collapsible-control"> <div id="collapsible-control-ghost" class="collapsible-control">
<button type="button"> <button type="button">
<!-- TODO: Accessibility attributes are missing since usage of the Icon class --> <!-- TODO: Accessibility attributes are missing since usage of the Icon class -->
@ -95,13 +78,6 @@ $innerLayoutScript = $this->layout()->innerLayout . '.phtml';
</div> </div>
</div> </div>
<script type="text/javascript" src="<?= $this->href($jsfile) ?>"></script> <script type="text/javascript" src="<?= $this->href($jsfile) ?>"></script>
<script type="text/javascript"> <script type="text/javascript" src="<?= $this->href('js/bootstrap.js') ?>"></script>
window.name = '<?= $this->protectId('Icinga') ?>';
var icinga = new Icinga({
baseUrl: '<?= $this->baseUrl(); ?>',
locale: '<?= $lang; ?>',
timezone: '<?= $timezone ?>'
});
</script>
</body> </body>
</html> </html>

View File

@ -1,3 +1,8 @@
<?php
use Icinga\Util\Csp;
?>
<!-- <!--
This view provides a workaround to logout from an external authentication provider, in case external This view provides a workaround to logout from an external authentication provider, in case external
authentication was configured (the default is to handle authentications internally in Icingaweb2). authentication was configured (the default is to handle authentications internally in Icingaweb2).
@ -9,43 +14,23 @@
--> -->
<div class="content"> <div class="content">
<div id="icinga-logo" aria-hidden="true"></div> <div id="icinga-logo" aria-hidden="true"></div>
<div class="alert alert-warning" id="logout-status"> <div class="alert alert-warning" id="logout-in-progress">
<b><?= $this->translate('Logging out...'); ?></b> <b><?= $this->translate('Logging out...'); ?></b>
<br> <p>
<?= $this->translate( <?= $this->translate(
'If this message does not disappear, it might be necessary to quit the' 'If this message does not disappear, it might be necessary to quit the'
. ' current session manually by clearing the cache, or by closing the current' . ' current session manually by clearing the cache, or by closing the current'
. ' browser session.' . ' browser session.'
); ?> ); ?>
</p>
</div> </div>
<div id="logout-successful" class="alert alert-success" hidden><?= $this->translate('Logout successful'); ?></div>
<div class="container"> <div class="container">
<a href="<?= $this->href('dashboard'); ?>"><?= $this->translate('Login'); ?></a> <a href="<?= $this->href('dashboard'); ?>"><?= $this->translate('Login'); ?></a>
</div> </div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript" src="<?= $this->href('js/logout.js'); ?>"></script>
/*
* When JavaScript is available, trigger an XmlHTTPRequest with the non-existing user 'logout' and abort it
* before it is able to finish. This will cause the browser to show a new authentication prompt in the next
* request.
*/
document.addEventListener('DOMContentLoaded', function () {
var msg = document.getElementById('logout-status');
try {
if (navigator.userAgent.toLowerCase().indexOf('msie') !== -1) {
document.execCommand('ClearAuthenticationCache');
} else {
var xhttp = new XMLHttpRequest();
xhttp.open('GET', 'arbitrary url', true, 'logout', 'logout');
xhttp.send('');
xhttp.abort();
}
} catch (e) {
}
msg.innerHTML = '<?= $this->translate('Logout successful!'); ?>';
msg.className = 'alert alert-success';
});
</script>
<style type="text/css"> <style type="text/css">
body { body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
@ -66,7 +51,7 @@
width: 100%; width: 100%;
} }
#logout-status { #logout-in-progress {
margin: 2em 0 1em; margin: 2em 0 1em;
font-size: 2em; font-size: 2em;
font-weight: bold; font-weight: bold;

28
public/js/bootstrap.js vendored Normal file
View File

@ -0,0 +1,28 @@
;(function () {
let html = document.documentElement;
window.name = html.dataset.icingaWindowName;
window.icinga = new Icinga({
baseUrl: html.dataset.icingaBaseUrl,
locale: html.lang,
timezone: html.dataset.icingaTimezone
});
if (! ('icingaIsIframe' in document.documentElement.dataset)) {
html.classList.replace('no-js', 'js');
}
if (window.getComputedStyle) {
let matched;
let element = document.getElementById('layout');
let name = window
.getComputedStyle(html)['font-family']
.replace(/['",]/g, '');
if (null !== (matched = name.match(/^([a-z]+)-layout$/))) {
element.classList.replace('default-layout', name);
if ('object' === typeof window.console) {
window.console.log('Icinga Web 2: setting initial layout to ' + name);
}
}
}
})();

16
public/js/logout.js Normal file
View File

@ -0,0 +1,16 @@
;(function () {
/**
* When JavaScript is available, trigger an XmlHTTPRequest with the non-existing user 'logout' and abort it
* before it is able to finish. This will cause the browser to show a new authentication prompt in the next
* request.
*/
document.getElementById('logout-in-progress').hidden = true;
document.getElementById('logout-successful').hidden = false;
try {
var xhttp = new XMLHttpRequest();
xhttp.open('GET', 'arbitrary url', true, 'logout', 'logout');
xhttp.send('');
xhttp.abort();
} catch (e) {
}
})();