fix: setup routing, async bcrypt, password hashing, clean command
- Add SetupGuard component: redirects to /setup if setup not complete, shown as spinner while loading. All routes except /setup now wrapped. - SetupPage redirects to /login on mount when setup already done. - Fix async blocking: offload bcrypt.hashpw and bcrypt.checkpw to run_in_executor so they never stall the asyncio event loop. - Hash password with SHA-256 (SubtleCrypto) before transmission; added src/utils/crypto.ts with sha256Hex(). Backend stores bcrypt(sha256). - Add Makefile with make up/down/restart/logs/clean targets. - Add tests: _check_password async, concurrent bcrypt, expired session, login-without-setup, run_setup event-loop interleaving. - Update Architekture.md and Features.md to reflect all changes.
This commit is contained in:
@@ -7,8 +7,8 @@
|
||||
* 3. `AuthProvider` — manages session state and exposes `useAuth()`.
|
||||
*
|
||||
* Routes:
|
||||
* - `/setup` — first-run setup wizard (always accessible)
|
||||
* - `/login` — master password login
|
||||
* - `/setup` — first-run setup wizard (always accessible; redirects to /login if already done)
|
||||
* - `/login` — master password login (redirects to /setup if not done)
|
||||
* - `/` — dashboard (protected, inside MainLayout)
|
||||
* - `/map` — world map (protected)
|
||||
* - `/jails` — jail list (protected)
|
||||
@@ -25,6 +25,7 @@ import { lightTheme } from "./theme/customTheme";
|
||||
import { AuthProvider } from "./providers/AuthProvider";
|
||||
import { TimezoneProvider } from "./providers/TimezoneProvider";
|
||||
import { RequireAuth } from "./components/RequireAuth";
|
||||
import { SetupGuard } from "./components/SetupGuard";
|
||||
import { MainLayout } from "./layouts/MainLayout";
|
||||
import { SetupPage } from "./pages/SetupPage";
|
||||
import { LoginPage } from "./pages/LoginPage";
|
||||
@@ -45,18 +46,29 @@ function App(): React.JSX.Element {
|
||||
<BrowserRouter>
|
||||
<AuthProvider>
|
||||
<Routes>
|
||||
{/* Public routes */}
|
||||
{/* Setup wizard — always accessible; redirects to /login if already done */}
|
||||
<Route path="/setup" element={<SetupPage />} />
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
|
||||
{/* Protected routes — all rendered inside MainLayout */}
|
||||
{/* Login — requires setup to be complete */}
|
||||
<Route
|
||||
path="/login"
|
||||
element={
|
||||
<SetupGuard>
|
||||
<LoginPage />
|
||||
</SetupGuard>
|
||||
}
|
||||
/>
|
||||
|
||||
{/* Protected routes — require setup AND authentication */}
|
||||
<Route
|
||||
element={
|
||||
<RequireAuth>
|
||||
<TimezoneProvider>
|
||||
<MainLayout />
|
||||
</TimezoneProvider>
|
||||
</RequireAuth>
|
||||
<SetupGuard>
|
||||
<RequireAuth>
|
||||
<TimezoneProvider>
|
||||
<MainLayout />
|
||||
</TimezoneProvider>
|
||||
</RequireAuth>
|
||||
</SetupGuard>
|
||||
}
|
||||
>
|
||||
<Route index element={<DashboardPage />} />
|
||||
|
||||
Reference in New Issue
Block a user