"use client" import { useState } from "react" import { Button } from "./ui/button" import { Input } from "./ui/input" import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "./ui/dialog" import { AlertCircle, CheckCircle, Copy, Shield, Check } from "lucide-react" import { getApiUrl } from "../lib/api-config" import Image from "next/image" interface TwoFactorSetupProps { open: boolean onClose: () => void onSuccess: () => void } export function TwoFactorSetup({ open, onClose, onSuccess }: TwoFactorSetupProps) { const [step, setStep] = useState(1) const [qrCode, setQrCode] = useState("") const [secret, setSecret] = useState("") const [backupCodes, setBackupCodes] = useState([]) const [verificationCode, setVerificationCode] = useState("") const [error, setError] = useState("") const [loading, setLoading] = useState(false) const [copiedSecret, setCopiedSecret] = useState(false) const [copiedCodes, setCopiedCodes] = useState(false) const handleSetupStart = async () => { setError("") setLoading(true) try { const token = localStorage.getItem("proxmenux-auth-token") const response = await fetch(getApiUrl("/api/auth/totp/setup"), { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, }) const data = await response.json() if (!response.ok) { throw new Error(data.message || "Failed to setup 2FA") } setQrCode(data.qr_code) setSecret(data.secret) setBackupCodes(data.backup_codes) setStep(2) } catch (err) { setError(err instanceof Error ? err.message : "Failed to setup 2FA") } finally { setLoading(false) } } const handleVerify = async () => { if (!verificationCode || verificationCode.length !== 6) { setError("Please enter a 6-digit code") return } setError("") setLoading(true) try { const token = localStorage.getItem("proxmenux-auth-token") const response = await fetch(getApiUrl("/api/auth/totp/enable"), { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, body: JSON.stringify({ token: verificationCode }), }) const data = await response.json() if (!response.ok) { throw new Error(data.message || "Invalid verification code") } setStep(3) } catch (err) { setError(err instanceof Error ? err.message : "Verification failed") } finally { setLoading(false) } } const copyToClipboard = (text: string, type: "secret" | "codes") => { navigator.clipboard.writeText(text) if (type === "secret") { setCopiedSecret(true) setTimeout(() => setCopiedSecret(false), 2000) } else { setCopiedCodes(true) setTimeout(() => setCopiedCodes(false), 2000) } } const handleClose = () => { setStep(1) setQrCode("") setSecret("") setBackupCodes([]) setVerificationCode("") setError("") onClose() } const handleFinish = () => { handleClose() onSuccess() } return ( Configurar Autenticación de Dos Factores Añade una capa extra de seguridad a tu cuenta {error && (

{error}

)} {step === 1 && (

La autenticación de dos factores (2FA) añade una capa extra de seguridad requiriendo un código de tu aplicación de autenticación además de tu contraseña.

Necesitarás:

  • Una aplicación de autenticación (Google Authenticator, Authy, etc.)
  • Escanear un código QR o introducir una clave manualmente
  • Guardar códigos de respaldo de forma segura
)} {step === 2 && (

1. Escanea el código QR

Abre tu aplicación de autenticación y escanea este código QR

{qrCode && (
QR Code
)}

O introduce la clave manualmente:

2. Introduce el código de verificación

Introduce el código de 6 dígitos que aparece en tu aplicación

setVerificationCode(e.target.value.replace(/\D/g, "").slice(0, 6))} className="text-center text-lg tracking-widest font-mono" maxLength={6} disabled={loading} />
)} {step === 3 && (

2FA Activado Correctamente

Tu cuenta ahora está protegida con autenticación de dos factores

Importante: Guarda tus códigos de respaldo

Estos códigos te permitirán acceder a tu cuenta si pierdes acceso a tu aplicación de autenticación. Guárdalos en un lugar seguro.

Códigos de Respaldo
{backupCodes.map((code, index) => (
{code}
))}
)}
) }