diff --git a/app/layout.tsx b/app/layout.tsx index 95b76d5..4fdc56c 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -37,7 +37,7 @@ export default function RootLayout({ suppressHydrationWarning > - + {children} diff --git a/components/PasswordGate.tsx b/components/PasswordGate.tsx index 4a9bf4b..bbb2efe 100644 --- a/components/PasswordGate.tsx +++ b/components/PasswordGate.tsx @@ -6,19 +6,29 @@ import { Lock } from 'lucide-react'; const SESSION_UNLOCKED_KEY = 'kvideo-unlocked'; -export function PasswordGate({ children }: { children: React.ReactNode }) { +export function PasswordGate({ children, hasEnvPassword: initialHasEnvPassword }: { children: React.ReactNode, hasEnvPassword: boolean }) { const [isLocked, setIsLocked] = useState(true); const [password, setPassword] = useState(''); const [error, setError] = useState(false); const [isClient, setIsClient] = useState(false); - const [hasEnvPassword, setHasEnvPassword] = useState(false); + const [hasEnvPassword, setHasEnvPassword] = useState(initialHasEnvPassword); const [isValidating, setIsValidating] = useState(false); useEffect(() => { + const settings = settingsStore.getSettings(); + const isUnlocked = sessionStorage.getItem(SESSION_UNLOCKED_KEY) === 'true'; + + // Determine initial lock state immediately + // Lock if (local password enabled OR env password exists) AND not already unlocked in session + const shouldBeLocked = (settings.passwordAccess || initialHasEnvPassword) && !isUnlocked; + + setIsLocked(shouldBeLocked); setIsClient(true); + + // Still run background checks to keep everything in sync checkEnvPasswordStatus(); checkLockStatus(); - }, []); + }, [initialHasEnvPassword]); const checkEnvPasswordStatus = async () => { try { @@ -31,40 +41,30 @@ export function PasswordGate({ children }: { children: React.ReactNode }) { settingsStore.syncEnvSubscriptions(data.subscriptionSources); } } catch { - // Silently fail - env password not available + // Silently fail } }; const checkLockStatus = async () => { const settings = settingsStore.getSettings(); + const isUnlocked = sessionStorage.getItem(SESSION_UNLOCKED_KEY) === 'true'; - // Check if env password is set try { const res = await fetch('/api/config'); const data = await res.json(); const envPasswordSet = data.hasEnvPassword; - // Lock if either local or env password is enabled - if (!settings.passwordAccess && !envPasswordSet) { - setIsLocked(false); - return; - } + // Updated lock state check + const currentlyLocked = (settings.passwordAccess || envPasswordSet) && !isUnlocked; + setIsLocked(currentlyLocked); } catch { - // If API fails, just check local settings - if (!settings.passwordAccess) { - setIsLocked(false); - return; - } - } - - const isUnlocked = sessionStorage.getItem(SESSION_UNLOCKED_KEY) === 'true'; - if (isUnlocked) { - setIsLocked(false); - } else { - setIsLocked(true); + // Handle error by checking local settings + const currentlyLocked = settings.passwordAccess && !isUnlocked; + setIsLocked(currentlyLocked); } }; + const handleUnlock = async (e: React.FormEvent) => { e.preventDefault(); setIsValidating(true); diff --git a/package-lock.json b/package-lock.json index 4b4c6c6..d7e9764 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "kvideo", - "version": "3.1.0", + "version": "3.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "kvideo", - "version": "3.1.0", + "version": "3.3.0", "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", diff --git a/package.json b/package.json index b66fccc..5ac30e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kvideo", - "version": "3.1.0", + "version": "3.3.0", "private": true, "scripts": { "dev": "next dev",