"use client"; import { useState, useEffect } from "react"; import { useTranslations } from "next-intl"; import Modal from "./Modal"; import Button from "./Button"; import Input from "./Input"; type KiroAuthModalProps = { isOpen: boolean; providerId?: string; providerLabel?: string; onMethodSelect: (method: string, config?: Record) => void; onClose: () => void; }; /** * Kiro Auth Method Selection Modal * Auto-detects token from AWS SSO cache or allows manual import */ export default function KiroAuthModal({ isOpen, providerId = "kiro", providerLabel = "Kiro", onMethodSelect, onClose, }: KiroAuthModalProps) { const t = useTranslations("kiroAuthModal"); const [selectedMethod, setSelectedMethod] = useState(null); const [idcStartUrl, setIdcStartUrl] = useState(""); const [idcRegion, setIdcRegion] = useState("us-east-1"); const [refreshToken, setRefreshToken] = useState(""); const [apiKey, setApiKey] = useState(""); const [apiKeyRegion, setApiKeyRegion] = useState("us-east-1"); const [error, setError] = useState(null); const [importing, setImporting] = useState(false); const [importingApiKey, setImportingApiKey] = useState(false); const [autoDetecting, setAutoDetecting] = useState(false); useEffect(() => { if (isOpen) return; setSelectedMethod(null); setIdcStartUrl(""); setIdcRegion("us-east-1"); setRefreshToken(""); setApiKey(""); setApiKeyRegion("us-east-1"); setError(null); }, [isOpen]); // Auto-detect token when import method is selected useEffect(() => { if (selectedMethod !== "import" || !isOpen) return; const autoDetect = async () => { setAutoDetecting(true); setError(null); try { const res = await fetch( `/api/oauth/kiro/auto-import?targetProvider=${encodeURIComponent(providerId)}` ); const data = await res.json(); if (data.found) { onMethodSelect("import"); onClose(); return; } else { setError(data.error || t("errorAutoDetect")); } } catch (err) { setError(t("errorAutoDetectFailed")); } finally { setAutoDetecting(false); } }; autoDetect(); }, [providerId, selectedMethod, isOpen, onMethodSelect, onClose, t]); const handleMethodSelect = (method) => { setSelectedMethod(method); setError(null); }; const handleBack = () => { setSelectedMethod(null); setError(null); }; const handleImportToken = async () => { if (!refreshToken.trim()) { setError(t("errorRefreshTokenRequired")); return; } setImporting(true); setError(null); try { const res = await fetch( `/api/oauth/kiro/import?targetProvider=${encodeURIComponent(providerId)}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ refreshToken: refreshToken.trim(), }), } ); const data = await res.json(); if (!res.ok) { throw new Error(data.error || t("errorImportFailed")); } // Success - close modal onMethodSelect("import"); onClose(); } catch (err) { setError(err instanceof Error ? err.message : t("errorImportFailed")); } finally { setImporting(false); } }; const handleImportApiKey = async () => { if (!apiKey.trim()) { setError(t("errorApiKeyRequired")); return; } setImportingApiKey(true); setError(null); try { const res = await fetch( `/api/oauth/kiro/api-key?targetProvider=${encodeURIComponent(providerId)}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ apiKey: apiKey.trim(), region: apiKeyRegion.trim() || "us-east-1", }), } ); const data = await res.json(); if (!res.ok) { throw new Error(data.error?.message || data.error || t("errorApiKeyImportFailed")); } onMethodSelect("api-key"); onClose(); } catch (err) { setError(err instanceof Error ? err.message : t("errorApiKeyImportFailed")); } finally { setImportingApiKey(false); } }; const handleIdcContinue = () => { if (!idcStartUrl.trim()) { setError(t("errorIdcStartUrlRequired")); return; } onMethodSelect("idc", { startUrl: idcStartUrl.trim(), region: idcRegion }); }; const handleSocialLogin = (provider) => { onMethodSelect("social", { provider }); }; return (
{/* Method Selection */} {!selectedMethod && (

{t("chooseMethod")}

{/* AWS Builder ID */} {/* AWS IAM Identity Center (IDC) */} {/* Google Social Login */} {/* GitHub Social Login */} {/* Import Token */} {/* API Key */}
)} {/* IDC Configuration */} {selectedMethod === "idc" && (
setIdcStartUrl(e.target.value)} placeholder={t("idcStartUrlPlaceholder")} className="font-mono text-sm" />

{t("idcStartUrlDescription")}

setIdcRegion(e.target.value)} placeholder={t("regionPlaceholder")} className="font-mono text-sm" />

{t("idcRegionDescription")}

{error &&

{error}

}
)} {/* Import Token */} {selectedMethod === "import" && (
{/* Auto-detecting state */} {autoDetecting && (
progress_activity

{t("autoDetecting")}

{t("readingCredentials", { providerLabel })}

)} {/* Form (shown after auto-detect completes) */} {!autoDetecting && ( <> {/* Info message if not auto-detected */} {!error && (
info

{t("tokenNotDetected", { providerLabel })}

)}
setRefreshToken(e.target.value)} placeholder={t("tokenPlaceholder")} className="font-mono text-sm" />
{error && (

{error}

)}
)}
)} {/* API Key Import */} {selectedMethod === "api-key" && (
setApiKey(e.target.value)} placeholder={t("apiKeyPlaceholder", { providerLabel })} className="font-mono text-sm" />

{t("apiKeyStoredDescription")}

setApiKeyRegion(e.target.value)} placeholder={t("regionPlaceholder")} className="font-mono text-sm" />

{t("apiKeyRegionDescription")}

{error && (

{error}

)}
)}
); }