fix(ui+auth): origin-forwarding for sign-in + disable dark mode + center dialog
Three related cleanups while QA-testing on iPad:
1. Origin-forwarding bug on /api/auth/sign-in-by-identifier
- The custom identifier-sign-in route forwarded to better-auth's
/sign-in/email handler but did NOT preserve the inbound Origin +
Referer headers. Better-auth's CSRF check then 403'd every login
with MISSING_OR_NULL_ORIGIN — and the UI showed a generic
"Invalid credentials" toast even when the password was right.
- Fix: pass through req.headers.get('origin') and
req.headers.get('referer') when constructing forwardReq.
- Affects: every login attempt from any device (this isn't dev-
only); discovered testing from 192.168.1.17 → app on the same
LAN IP. Production users hit the same path.
2. Dark mode disabled
- Drop the Sun/Moon toggle from user-menu, the documentElement
class flip, darkMode from ui-store, darkMode from the user-
preferences validator. Hardcode sonner theme="light" (was
reading next-themes which isn't actually wired anywhere else).
- The 10 stray `dark:` Tailwind utilities are left alone — they're
inactive without the `dark` class on <html> so they don't ship
anything that renders, just dead CSS.
3. Center dialog animation
- Dialog content was sliding in from the top-right corner (slide-
in-from-left-1/2 + slide-in-from-top-[48%]) which felt jarring.
Drop the slide directions, keep just zoom-in-95 + the base
fade-in/out so dialogs appear in place with a subtle scale-up.
4. Login placeholder
- Removed the "you@example.com or yourname" placeholder so the
field reads as a clean empty input below the "Email or username"
label.
No tests added (the 1340 vitest suite passes); changes are surface-
level UI tweaks + the origin-header fix where a unit-test of the
custom route would mostly be testing better-auth's behaviour.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { Moon, Sun, LogOut, User, Settings, Bell, Check, Building2 } from 'lucide-react';
|
||||
import { LogOut, User, Settings, Bell, Check, Building2 } from 'lucide-react';
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
import { useUIStore } from '@/stores/ui-store';
|
||||
@@ -51,17 +51,10 @@ export function UserMenu({ trigger, align = 'end', user, ports }: UserMenuProps)
|
||||
const currentPortId = useUIStore((s) => s.currentPortId);
|
||||
const currentPortSlug = useUIStore((s) => s.currentPortSlug);
|
||||
const setPort = useUIStore((s) => s.setPort);
|
||||
const darkMode = useUIStore((s) => s.darkMode);
|
||||
const toggleDarkMode = useUIStore((s) => s.toggleDarkMode);
|
||||
|
||||
const base = currentPortSlug ? `/${currentPortSlug}` : '';
|
||||
const showPortSwitcher = ports && ports.length > 1;
|
||||
|
||||
function handleToggleDarkMode() {
|
||||
toggleDarkMode();
|
||||
document.documentElement.classList.toggle('dark');
|
||||
}
|
||||
|
||||
function handlePortChange(port: Port) {
|
||||
if (port.id === currentPortId) return;
|
||||
setPort(port.id, port.slug);
|
||||
@@ -132,20 +125,6 @@ export function UserMenu({ trigger, align = 'end', user, ports }: UserMenuProps)
|
||||
Notification preferences
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem onClick={handleToggleDarkMode}>
|
||||
{darkMode ? (
|
||||
<>
|
||||
<Sun className="w-4 h-4 mr-2" aria-hidden />
|
||||
Light Mode
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Moon className="w-4 h-4 mr-2" aria-hidden />
|
||||
Dark Mode
|
||||
</>
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
className="text-destructive focus:text-destructive"
|
||||
onClick={() => router.push('/api/auth/sign-out')}
|
||||
|
||||
Reference in New Issue
Block a user