Phase 7: Auth & Security upgrade (JWT, 2FA, Login UI)
This commit is contained in:
@@ -5,31 +5,85 @@
|
||||
import Gitea from "./routes/Gitea.svelte";
|
||||
import Files from "./routes/Files.svelte";
|
||||
import Terminal from "./routes/Terminal.svelte";
|
||||
import Login from "./routes/Login.svelte";
|
||||
import { onMount } from "svelte";
|
||||
import { getToken, checkAuth, setToken } from "./lib/api.js";
|
||||
|
||||
let page = $state("dashboard");
|
||||
let dark = $state(false);
|
||||
let authorized = $state(false);
|
||||
let loading = $state(true);
|
||||
|
||||
onMount(async () => {
|
||||
// Theme init
|
||||
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||
dark = true;
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
dark = false;
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
|
||||
// Auth check
|
||||
const token = getToken();
|
||||
if (!token) {
|
||||
loading = false;
|
||||
authorized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await checkAuth();
|
||||
authorized = true;
|
||||
} catch (e) {
|
||||
console.error("Auth check failed:", e);
|
||||
setToken("");
|
||||
authorized = false;
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
});
|
||||
|
||||
function toggleTheme() {
|
||||
dark = !dark;
|
||||
document.documentElement.classList.toggle("dark", dark);
|
||||
if (dark) {
|
||||
document.documentElement.classList.add("dark");
|
||||
localStorage.theme = 'dark';
|
||||
} else {
|
||||
document.documentElement.classList.remove("dark");
|
||||
localStorage.theme = 'light';
|
||||
}
|
||||
}
|
||||
|
||||
function logout() {
|
||||
setToken("");
|
||||
window.location.reload();
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex h-screen overflow-hidden bg-surface-50 {dark ? 'dark bg-surface-900' : ''}">
|
||||
<Sidebar bind:page {dark} {toggleTheme} />
|
||||
<main class="flex-1 overflow-auto">
|
||||
<div class="max-w-[1400px] mx-auto p-6 lg:p-8">
|
||||
{#if page === "dashboard"}
|
||||
<Dashboard />
|
||||
{:else if page === "docker"}
|
||||
<Docker />
|
||||
{:else if page === "gitea"}
|
||||
<Gitea />
|
||||
{:else if page === "files"}
|
||||
<Files />
|
||||
{:else if page === "terminal"}
|
||||
<Terminal />
|
||||
{/if}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
{#if loading}
|
||||
<div class="flex h-screen items-center justify-center bg-surface-50 dark:bg-surface-950">
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600"></div>
|
||||
</div>
|
||||
{:else if !authorized}
|
||||
<Login />
|
||||
{:else}
|
||||
<div class="flex h-screen overflow-hidden bg-surface-50 {dark ? 'dark bg-surface-900' : ''}">
|
||||
<Sidebar bind:page {dark} {toggleTheme} {logout} />
|
||||
<main class="flex-1 overflow-auto">
|
||||
<div class="max-w-[1400px] mx-auto p-6 lg:p-8">
|
||||
{#if page === "dashboard"}
|
||||
<Dashboard />
|
||||
{:else if page === "docker"}
|
||||
<Docker />
|
||||
{:else if page === "gitea"}
|
||||
<Gitea />
|
||||
{:else if page === "files"}
|
||||
<Files />
|
||||
{:else if page === "terminal"}
|
||||
<Terminal />
|
||||
{/if}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user