feat(auth): add login/logout, user identity, and soft auth gate
- api/logout.php: destroys session + clears cookie, redirects to / - api/guest-session.php: sets guest flag, lets users explore without account - layout.php: removes hard PHP redirect; authenticated users see email + "Logg ut" in topbar; guests see guest banner (sticky, dismissible) and auth gate modal (dismissible via localStorage) instead of redirect - layout_footer.php: injects auth gate modal + JS for banner/modal dismiss - layout_dashboard.php: adds username + "Logg ut" to dash-topbar - index.php: adds "Utforsk uten konto" link under primary login CTA - tools.css: .guest-banner, .auth-gate-*, .topbar-user, .dash-topbar__user Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+36
-9
@@ -2,11 +2,8 @@
|
||||
declare(strict_types=1);
|
||||
// Required vars: $toolName (string), $toolTitle (string), $toolKind (string), $toolBadge (string)
|
||||
require_once __DIR__ . '/bootstrap.php';
|
||||
if (!dbnToolsIsAuthenticated()) {
|
||||
$return = urlencode($_SERVER['REQUEST_URI'] ?? '/');
|
||||
header('Location: /?return=' . $return);
|
||||
exit;
|
||||
}
|
||||
|
||||
$layoutIsGuest = !dbnToolsIsAuthenticated();
|
||||
|
||||
$uiLang = dbnToolsCurrentLanguage();
|
||||
$navItems = dbnToolsLaunchedTools($uiLang);
|
||||
@@ -17,12 +14,23 @@ $toolKind = $toolMeta['sub'] ?? ($toolKind ?? '');
|
||||
$toolBadge = $toolMeta['badge'] ?? ($toolBadge ?? '');
|
||||
$langPath = strtok((string)($_SERVER['REQUEST_URI'] ?? '/'), '?') ?: '/';
|
||||
|
||||
// Credit balance for free-tier users
|
||||
// Credit balance — only meaningful for authenticated free-tier users
|
||||
$layoutFreeTierBalance = -1;
|
||||
if (dbnToolsIsFreeTier()) {
|
||||
if (!$layoutIsGuest && dbnToolsIsFreeTier()) {
|
||||
require_once __DIR__ . '/FreeTier.php';
|
||||
$layoutFreeTierBalance = FreeTier::balance((int)$_SESSION['dbn_tools_sso_uid']);
|
||||
}
|
||||
|
||||
// User identity for topbar (null for guests)
|
||||
$layoutAuthUser = $layoutIsGuest ? null : dbnToolsAuthenticatedUser();
|
||||
$layoutUserDisplay = '';
|
||||
if ($layoutAuthUser !== null) {
|
||||
$email = (string)($layoutAuthUser['email'] ?? '');
|
||||
// Show only local part (before @) to keep topbar compact
|
||||
$layoutUserDisplay = strstr($email, '@', true) ?: $email;
|
||||
}
|
||||
|
||||
$layoutReturnUrl = urlencode($_SERVER['REQUEST_URI'] ?? '/');
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="<?= htmlspecialchars($uiLang) ?>">
|
||||
@@ -35,9 +43,9 @@ if (dbnToolsIsFreeTier()) {
|
||||
<?php endif; ?>
|
||||
<link rel="stylesheet" href="assets/css/tools.css">
|
||||
</head>
|
||||
<body data-authenticated="true" data-active-tool="<?= htmlspecialchars($toolName) ?>">
|
||||
<body data-authenticated="<?= $layoutIsGuest ? 'false' : 'true' ?>" data-active-tool="<?= htmlspecialchars($toolName) ?>">
|
||||
<script>
|
||||
window.DBN_TOOLS_AUTHENTICATED = true;
|
||||
window.DBN_TOOLS_AUTHENTICATED = <?= $layoutIsGuest ? 'false' : 'true' ?>;
|
||||
window.DBN_TOOLS_LANG = <?= json_encode($uiLang, JSON_UNESCAPED_UNICODE) ?>;
|
||||
<?php if ($layoutFreeTierBalance >= 0): ?>
|
||||
window.DBN_FREE_TIER_BALANCE = <?= $layoutFreeTierBalance ?>;
|
||||
@@ -49,6 +57,15 @@ window.DBN_FREE_TIER_BALANCE = <?= $layoutFreeTierBalance ?>;
|
||||
<button onclick="this.parentElement.remove()" aria-label="Dismiss" class="syttende-mai-close">✕</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($layoutIsGuest): ?>
|
||||
<div id="guestBanner" class="guest-banner" role="alert" aria-live="polite">
|
||||
<span>Du er ikke innlogget — verktøyene krever konto for å fungere.</span>
|
||||
<a href="/?return=<?= $layoutReturnUrl ?>" class="guest-banner__login">Logg inn</a>
|
||||
<button id="guestBannerClose" class="guest-banner__close" aria-label="Lukk">✕</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<main id="appShell" class="app-shell">
|
||||
<header class="topbar">
|
||||
<div>
|
||||
@@ -67,9 +84,19 @@ window.DBN_FREE_TIER_BALANCE = <?= $layoutFreeTierBalance ?>;
|
||||
<a href="<?= htmlspecialchars($langPath . '?lang=' . $langCode) ?>" class="<?= $langCode === $uiLang ? 'is-active' : '' ?>"><?= htmlspecialchars(dbnToolsLanguageLabel($langCode)) ?></a>
|
||||
<?php endforeach; ?>
|
||||
</nav>
|
||||
<?php if ($layoutIsGuest): ?>
|
||||
<a href="/?return=<?= $layoutReturnUrl ?>" class="secondary-button" style="text-decoration:none;">Logg inn</a>
|
||||
<?php else: ?>
|
||||
<a href="/dashboard/" class="secondary-button" style="text-decoration:none;">📚 Min korpus</a>
|
||||
<span id="healthPill" class="status-pill"><?= htmlspecialchars(dbnToolsT('session_active', $uiLang)) ?></span>
|
||||
<button id="healthButton" class="secondary-button" type="button"><?= htmlspecialchars(dbnToolsT('health', $uiLang)) ?></button>
|
||||
<span class="topbar-user">
|
||||
<?php if ($layoutUserDisplay !== ''): ?>
|
||||
<span class="topbar-user__name" title="<?= htmlspecialchars($layoutAuthUser['email'] ?? '') ?>"><?= htmlspecialchars($layoutUserDisplay) ?></span>
|
||||
<?php endif; ?>
|
||||
<a href="/api/logout.php" class="topbar-user__logout">Logg ut</a>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user