forked from fa/breadcrumb-the-shire
Eliminate all inline scripts to enable script-src 'self' without 'unsafe-inline', providing strong XSS mitigation via CSP. Inline script removal: - login.phtml: replace inline APP_ASSET_BASE with data-asset-base attribute + app-boot.js (matching default.phtml pattern) - api-docs: extract SwaggerUI init to js/pages/admin-api-docs-index.js - docs: extract checkbox enablement to js/pages/admin-docs-index.js - language-switcher: replace onchange handler with data-auto-submit attribute + js/components/app-auto-submit.js event listener CSP policy (dev + prod nginx): default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; form-action 'self'; base-uri 'self'; frame-ancestors 'none'; manifest-src 'self' Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
69 lines
2.8 KiB
PHTML
69 lines
2.8 KiB
PHTML
<?php
|
|
use MintyPHP\I18n;
|
|
use MintyPHP\Http\Request;
|
|
|
|
$locales = defined('APP_LOCALES') ? APP_LOCALES : [I18n::$defaultLocale];
|
|
$returnTarget = Request::pathWithQuery();
|
|
$variant = $variant ?? 'select';
|
|
$baseUrl = lurl('lang');
|
|
$isLoggedIn = !empty($_SESSION['user']['id']);
|
|
$publicTarget = Request::stripLocale($returnTarget);
|
|
$publicTarget = ltrim($publicTarget, '/');
|
|
$base = \MintyPHP\Router::getBaseUrl();
|
|
$base = rtrim($base, '/');
|
|
$publicTarget = ltrim($publicTarget, '/');
|
|
?>
|
|
|
|
<?php if ($variant === 'menu-items'): ?>
|
|
<?php foreach ($locales as $locale): ?>
|
|
<?php
|
|
$isActive = $locale === I18n::$locale;
|
|
$normalizedLocale = strtolower(trim((string) $locale));
|
|
if (strpos($normalizedLocale, '-') !== false) {
|
|
$normalizedLocale = explode('-', $normalizedLocale, 2)[0];
|
|
}
|
|
$languageLabels = [
|
|
'de' => t('German'),
|
|
'en' => t('English'),
|
|
];
|
|
$label = $languageLabels[$normalizedLocale] ?? strtoupper((string) $locale);
|
|
$publicUrl = $base . '/' . $locale . ($publicTarget !== '' ? '/' . $publicTarget : '');
|
|
$switchUrl = $isLoggedIn
|
|
? ($baseUrl . '?locale=' . $locale . '&return=' . urlencode($returnTarget))
|
|
: $publicUrl;
|
|
?>
|
|
<li>
|
|
<a href="<?php e($switchUrl); ?>"
|
|
class="<?php e($isActive ? 'active' : ''); ?>"
|
|
<?php if ($isActive) { ?>aria-current="true"<?php } ?>>
|
|
<?php e($label); ?>
|
|
</a>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<?php if ($isLoggedIn): ?>
|
|
<form class="nav nav--lang" method="get" action="<?php e($baseUrl); ?>" aria-label="<?php e(t('Language switcher')); ?>">
|
|
<input type="hidden" name="return" value="<?php e($returnTarget); ?>">
|
|
<select class="lang-select" name="locale" data-auto-submit>
|
|
<?php foreach ($locales as $locale): ?>
|
|
<option value="<?php e($locale); ?>" <?php if ($locale === I18n::$locale) { ?>selected<?php } ?>>
|
|
<?php e(strtoupper((string) $locale)); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</form>
|
|
<?php else: ?>
|
|
<div class="nav nav--lang" role="listbox" aria-label="<?php e(t('Language switcher')); ?>">
|
|
<?php foreach ($locales as $locale): ?>
|
|
<?php
|
|
$publicUrl = $base . '/' . $locale . ($publicTarget !== '' ? '/' . $publicTarget : '');
|
|
?>
|
|
<a href="<?php e($publicUrl); ?>" class="lang-link"
|
|
<?php if ($locale === I18n::$locale) { ?>aria-current="true"<?php } ?>>
|
|
<?php e(strtoupper((string) $locale)); ?>
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|