add auth system: users, login, JWT, protected routes

Domain: User entity, AuthPort/PasswordHashPort/SecretStore ports.
Adapters: auth (argon2 hashing, JWT tokens), secret-store (env-based),
config-sqlite user repository, http-api auth routes + extractors.
Application: auth_service. SPA: login page, auth client, protected router.
This commit is contained in:
2026-06-19 01:39:42 +02:00
parent 4139330234
commit adda731dc6
41 changed files with 1331 additions and 153 deletions

View File

@@ -1,8 +1,9 @@
import { Link, useRouterState } from "@tanstack/react-router"
import { Link, useNavigate, useRouterState } from "@tanstack/react-router"
import {
SidebarProvider,
Sidebar,
SidebarContent,
SidebarFooter,
SidebarHeader,
SidebarMenu,
SidebarMenuItem,
@@ -12,6 +13,8 @@ import {
} from "@/components/ui/sidebar"
import { Separator } from "@/components/ui/separator"
import { Toaster } from "@/components/ui/sonner"
import { Button } from "@/components/ui/button"
import { clearToken } from "@/api/auth"
import {
LayoutDashboard,
Database,
@@ -19,6 +22,7 @@ import {
Layers,
Save,
BookOpen,
LogOut,
} from "lucide-react"
const NAV = [
@@ -32,6 +36,12 @@ const NAV = [
export function AppShell({ children }: { children: React.ReactNode }) {
const { location } = useRouterState()
const navigate = useNavigate()
function logout() {
clearToken()
navigate({ to: "/login" })
}
return (
<SidebarProvider>
@@ -59,6 +69,12 @@ export function AppShell({ children }: { children: React.ReactNode }) {
})}
</SidebarMenu>
</SidebarContent>
<SidebarFooter className="p-2">
<Button variant="ghost" size="sm" className="w-full justify-start" onClick={logout}>
<LogOut className="mr-2 h-4 w-4" />
Sign Out
</Button>
</SidebarFooter>
</Sidebar>
<SidebarInset>
<header className="flex h-12 items-center gap-2 border-b px-4">