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:
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user