fix(auth): resolve demo login redirect loop, fix backend API bugs, restore clean login UI, and add comprehensive API docs with headers

This commit is contained in:
2026-09-04 11:49:13 +05:30
parent b152f73c3d
commit 3ad281aae6
8 changed files with 1299 additions and 52 deletions

View File

@@ -20,7 +20,7 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
const [dropdownOpen, setDropdownOpen] = useState(false)
const dropdownRef = useRef<HTMLDivElement>(null)
const { userId, user, globalSettings, switchUser, hasAccessTo, loading } = useActiveUser();
const { userId, user, globalSettings, switchUser, logout, hasAccessTo, loading } = useActiveUser();
const [maintenance, setMaintenance] = useState(false);
const [checkingMaintenance, setCheckingMaintenance] = useState(true);
@@ -264,6 +264,13 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
>
Reset Demo
</button>
<div className="h-px bg-border my-1" />
<button
onClick={logout}
className="w-full text-left flex items-center gap-2 px-3 py-2 text-sm text-red-500 hover:bg-red-500/10 rounded-lg transition-colors font-semibold"
>
Sign Out
</button>
</div>
</div>
)}

View File

@@ -30,22 +30,32 @@ export default function LoginPage() {
if (data.success) {
if (typeof window !== "undefined") {
localStorage.setItem("activeUserId", data.token)
// Set auth_token cookie required by Next.js 16 proxy.ts middleware
const cookieVal = data.role === "admin" ? "admin" : (data.token || "authenticated");
document.cookie = `auth_token=${cookieVal}; path=/; max-age=2592000; SameSite=Lax`;
localStorage.setItem("activeUserId", data.token);
// Create new session token for single-device login
const sessionToken = crypto.randomUUID();
localStorage.setItem("active_session_token", sessionToken);
fetch(`/api/users/${data.token}/session`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ session_token: sessionToken })
}).finally(() => {
if (data.role === "admin") {
window.location.href = "/admin";
} else {
window.location.href = "/dashboard";
if (data.token && data.token !== "admin") {
try {
await fetch(`/api/users/${data.token}/session`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ session_token: sessionToken })
});
} catch (e) {
console.warn("Session update skipped", e);
}
});
}
if (data.role === "admin") {
window.location.href = "/admin";
} else {
window.location.href = "/dashboard";
}
}
} else {
setError(data.error || "Invalid email or password.")
@@ -54,6 +64,7 @@ export default function LoginPage() {
setError("An error occurred. Please try again.")
}
}
return (
<div className="min-h-screen bg-background flex flex-col items-center justify-center p-6 selection:bg-[#00F0FF]/20">
<Link href="/" className="absolute top-8 left-8 text-muted-foreground hover:text-foreground flex items-center gap-2 transition-colors font-medium">

View File

@@ -46,6 +46,7 @@ export default function SignupPage() {
const loginData = await loginRes.json();
if (loginData.success && typeof window !== "undefined") {
document.cookie = `auth_token=${loginData.token}; path=/; max-age=2592000; SameSite=Lax`;
localStorage.setItem("activeUserId", loginData.token);
const sessionToken = crypto.randomUUID();
localStorage.setItem("active_session_token", sessionToken);