'use client' import { Suspense, useEffect, useState } from 'react' import { useRouter, useSearchParams } from 'next/navigation' import BrandingLogo from '../ui/BrandingLogo' import { getApiBase } from '../lib/auth' type ResetVerification = { status: string recipient_hint?: string auth_provider?: string expires_at?: string } function ResetPasswordPageContent() { const router = useRouter() const searchParams = useSearchParams() const token = searchParams.get('token') ?? '' const [verification, setVerification] = useState(null) const [loading, setLoading] = useState(false) const [verifying, setVerifying] = useState(true) const [password, setPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('') const [error, setError] = useState(null) const [status, setStatus] = useState(null) useEffect(() => { const verifyToken = async () => { if (!token) { setError('Password reset link is invalid or missing.') setVerifying(false) return } setVerifying(true) setError(null) setStatus(null) try { const baseUrl = getApiBase() const response = await fetch( `${baseUrl}/auth/password/reset/verify?token=${encodeURIComponent(token)}`, ) const data = await response.json().catch(() => null) if (!response.ok) { throw new Error(typeof data?.detail === 'string' ? data.detail : 'Password reset link is invalid.') } setVerification(data) } catch (err) { console.error(err) setVerification(null) setError(err instanceof Error ? err.message : 'Password reset link is invalid.') } finally { setVerifying(false) } } void verifyToken() }, [token]) const submit = async (event: React.FormEvent) => { event.preventDefault() if (!token) { setError('Password reset link is invalid or missing.') return } if (password.trim().length < 8) { setError('Password must be at least 8 characters.') return } if (password !== confirmPassword) { setError('Passwords do not match.') return } setLoading(true) setError(null) setStatus(null) try { const baseUrl = getApiBase() const response = await fetch(`${baseUrl}/auth/password/reset`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token, new_password: password }), }) const data = await response.json().catch(() => null) if (!response.ok) { throw new Error(typeof data?.detail === 'string' ? data.detail : 'Unable to reset password.') } setStatus('Password updated. You can now sign in with the new password.') setPassword('') setConfirmPassword('') window.setTimeout(() => router.push('/login'), 1200) } catch (err) { console.error(err) setError(err instanceof Error ? err.message : 'Unable to reset password.') } finally { setLoading(false) } } const providerLabel = verification?.auth_provider === 'jellyfin' ? 'Jellyfin, Seerr, and Magent' : 'Magent' return (

Reset password

Choose a new password for your account.

{verifying &&
Checking password reset link…
} {!verifying && verification && (
This reset link was sent to {verification.recipient_hint || 'your email'} and will update the password used for {providerLabel}.
)} {error &&
{error}
} {status &&
{status}
}
) } export default function ResetPasswordPage() { return ( Loading password reset…}> ) }