mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 19:19:19 +02:00
Requirements: - parametres.php toggle: 'restricted_files_enabled' enables/disables the feature - Public TFE page: when enabled + access_type=Interne, hides files, shows French restriction message + access request form (metadata/synopsis still visible) - ERG emails (@erg.school / @erg.be): auto-approve, send 24h access link immediately - External emails: show justification textarea, create pending request, notify admin - Admin panel /admin/file-access.php: approve/reject requests with optional notes, sends access email on approval (linked from admin nav with pending count badge) Security: - One-time 24h email tokens (used_at + is_valid=0 on first click) - Token redeemed via POST /validate-access (GET shows confirmation page only) - Long-lived 30-day browser session in file_access_sessions table - Cookie: HttpOnly + Secure + SameSite=Strict - CSRF on all mutations, rate limiting on request submission - Audit trail: IP, UA, event, timestamp in file_access_audit Bug fixes: - admin/file-access.php: $vars never extract()ed → page was blank - Template had self-contained head/footer includes (double-include) - Admin approval URL used $requestId instead of $request['thesis_id'] - App::boot() now starts session so CSRF token works on public pages - Dispatcher routes /validate-access and /request-access through front controller
93 lines
4.4 KiB
PHP
93 lines
4.4 KiB
PHP
<?php
|
|
// header.php — unified site header for public and admin sections.
|
|
// Reads: $isAdmin (bool), $currentNav (string, public only)
|
|
$_isAdmin = !empty($isAdmin);
|
|
$_navCurrent = $currentNav ?? '';
|
|
$_currentPage = basename($_SERVER['PHP_SELF']);
|
|
$_thesisId = $_GET['id'] ?? null;
|
|
?>
|
|
<header>
|
|
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
|
|
|
|
<?php if ($_isAdmin): ?>
|
|
|
|
<nav aria-label="Navigation admin">
|
|
<a href="/" target="_blank" rel="noopener noreferrer">
|
|
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256"><path d="M208,72H128V32a8,8,0,0,0-13.66-5.66l-96,96a8,8,0,0,0,0,11.32l96,96A8,8,0,0,0,128,224V184h80a16,16,0,0,0,16-16V88A16,16,0,0,0,208,72Zm0,96H120a8,8,0,0,0-8,8v28.69L35.31,128,112,51.31V80a8,8,0,0,0,8,8h88Z"></path></svg>XAMXAM<span class="sr-only"> (site public, nouvel onglet)</span>
|
|
</a>
|
|
<ul>
|
|
<li><a href="/admin/" <?= $_currentPage === 'index.php' ? 'aria-current="page"' : '' ?>>Liste des TFE</a></li>
|
|
<li><a href="/admin/contenus.php" <?= in_array($_currentPage, ['contenus.php', 'contenus-edit.php']) ? 'aria-current="page"' : '' ?>>Contenus</a></li>
|
|
<li><a href="/admin/tags.php" <?= $_currentPage === 'tags.php' ? 'aria-current="page"' : '' ?>>Mots-clés</a></li>
|
|
<li><a href="/admin/file-access.php" <?= $_currentPage === 'file-access.php' ? 'aria-current="page"' : '' ?>>
|
|
Demandes d'accès
|
|
<?php if (isset($pendingCount) && $pendingCount > 0): ?>
|
|
<span class="admin-nav-badge"><?= $pendingCount ?></span>
|
|
<?php endif; ?>
|
|
</a></li>
|
|
<li><a href="/admin/system.php" <?= in_array($_currentPage, ['system.php', 'status.php', 'logs.php']) ? 'aria-current="page"' : '' ?>>Système</a></li>
|
|
<li><a href="/admin/acces-etudiante.php" <?= $_currentPage === 'acces-etudiante.php' ? 'aria-current="page"' : '' ?>>Accès étudiant·e</a></li>
|
|
<li><a href="/admin/parametres.php" <?= $_currentPage === 'parametres.php' ? 'aria-current="page"' : '' ?>>Paramètres</a></li>
|
|
<?php if ($_thesisId && in_array($_currentPage, ['edit.php', 'thanks.php'])): ?>
|
|
<li><a href="/admin/edit.php?id=<?= intval($_thesisId) ?>" <?= $_currentPage === 'edit.php' ? 'aria-current="page"' : '' ?>>Modifier</a></li>
|
|
<?php endif; ?>
|
|
<?php if ($_isAdmin && AdminAuth::hasPassword()): ?>
|
|
<li data-nav-logout><a href="/admin/logout.php">Déconnexion</a></li>
|
|
<?php endif; ?>
|
|
</ul>
|
|
</nav>
|
|
|
|
<?php else: ?>
|
|
|
|
<nav aria-label="Navigation principale">
|
|
<div class="nav-left">
|
|
<a href="/" class="nav-logo">Xamxam</a>
|
|
<ul class="nav-left-links">
|
|
<li>
|
|
<a href="/repertoire"
|
|
<?= ($_navCurrent === 'repertoire') ? 'aria-current="page"' : '' ?>>Répertoire</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<ul class="nav-right-links">
|
|
<li>
|
|
<a href="/licence"
|
|
<?= ($_navCurrent === 'licence') ? 'aria-current="page"' : '' ?>>Licences</a>
|
|
</li>
|
|
<li>
|
|
<a href="/apropos"
|
|
<?= ($_navCurrent === 'apropos') ? 'aria-current="page"' : '' ?>>À Propos</a>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<?php endif; ?>
|
|
|
|
</header>
|
|
|
|
<?php if (!$_isAdmin): ?>
|
|
<?php
|
|
// Search bar — public section only (rendered below header for equal height)
|
|
$searchBarValue = $searchBarValue ?? $_GET['query'] ?? '';
|
|
?>
|
|
<div class="header-search-wrap">
|
|
<form method="GET" action="/search"
|
|
role="search" aria-label="Recherche">
|
|
<label for="site-search-input" class="sr-only">Recherche</label>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
|
|
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
|
aria-hidden="true" focusable="false">
|
|
<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
|
|
</svg>
|
|
<input
|
|
id="site-search-input"
|
|
type="text"
|
|
name="query"
|
|
placeholder="Recherche..."
|
|
value="<?= htmlspecialchars($searchBarValue) ?>"
|
|
autocomplete="off"
|
|
>
|
|
</form>
|
|
</div>
|
|
<?php endif; ?>
|