'use client' import { useState } from 'react' import { useRouter } from 'next/navigation' import { useTranslations } from 'next-intl' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { useToast } from '@/components/ui/use-toast' import { Loader2, KeyRound } from 'lucide-react' export default function ResetPasswordPage() { const t = useTranslations('reset_password') const [password, setPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('') const [isLoading, setIsLoading] = useState(false) const { toast } = useToast() const router = useRouter() const handleResetPassword = async (e: React.FormEvent) => { e.preventDefault() setIsLoading(true) const strong = password.length >= 8 && /[a-z]/.test(password) && /[A-Z]/.test(password) && /[0-9]/.test(password) && /[^a-zA-Z0-9]/.test(password) if (!strong) { toast({ title: t('weak_title'), description: t('weak_description'), variant: 'destructive', }) setIsLoading(false) return } if (password !== confirmPassword) { toast({ title: t('mismatch_title'), description: t('weak_description'), variant: 'destructive', }) setIsLoading(false) return } try { // Routed through the API so the has_password flag flips in lock-step // with the password update. This is the unlock path for BankID-only // users who enrolled MFA and got locked out — the recovery session // bypasses AAL2, the API flips has_password, and the lockout banner // disappears the next time they log in. const res = await fetch('/api/account/password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ password }), }) if (!res.ok) { const body = (await res.json().catch(() => ({}))) as { error?: string } toast({ title: t('save_failed_title'), description: body.error || t('save_failed_description'), variant: 'destructive', }) return } toast({ title: t('saved_title'), description: t('saved_description'), }) router.push('/') router.refresh() } catch { toast({ title: t('save_failed_title'), description: t('save_failed_description'), variant: 'destructive', }) } finally { setIsLoading(false) } } return (

{t('title')}

{t('subtitle')}

setPassword(e.target.value)} required minLength={8} disabled={isLoading} className="h-11" />
setConfirmPassword(e.target.value)} required minLength={8} disabled={isLoading} className="h-11" />
) }