From c205e6ad73f14db1f7efdf1e4e4b594eb73a1f34 Mon Sep 17 00:00:00 2001
From: yyamashita <yyamashita@hetzner.yyamashita.com>
Date: Sat, 20 Jun 2026 00:29:50 +0900
Subject: Add step-by-step debug display to passkey registration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---
 app/routes/auth.register.tsx | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

(limited to 'app/routes/auth.register.tsx')

diff --git a/app/routes/auth.register.tsx b/app/routes/auth.register.tsx
index 75a7d7c..28d5b03 100644
--- a/app/routes/auth.register.tsx
+++ b/app/routes/auth.register.tsx
@@ -117,11 +117,14 @@ export default function Register() {
   const [token, setToken] = useState("");
   const [status, setStatus] = useState<"idle" | "loading" | "error">("idle");
   const [errorMsg, setErrorMsg] = useState("");
+  const [step, setStep] = useState("");
 
   async function handleRegister() {
     setStatus("loading");
     setErrorMsg("");
+    setStep("");
     try {
+      setStep("1. options 取得中…");
       const optRes = await fetch("/auth/register?intent=options", {
         method: "POST",
         headers: { "Content-Type": "application/json" },
@@ -132,17 +135,20 @@ export default function Register() {
         throw new Error(err.error ?? "オプション取得に失敗しました");
       }
       const optJSON = await optRes.json();
+      setStep("2. options 受信 OK → credentials.create() 呼び出し中…");
+
+      const userId = b64urlToBuffer(optJSON.user.id);
+      const challenge = b64urlToBuffer(optJSON.challenge);
 
-      // @simplewebauthn/browser を使わず WebAuthn API を直接呼ぶ
       const credential = await navigator.credentials.create({
         publicKey: {
           rp: optJSON.rp,
           user: {
-            id: b64urlToBuffer(optJSON.user.id),
+            id: userId,
             name: optJSON.user.name,
             displayName: optJSON.user.displayName ?? optJSON.user.name,
           },
-          challenge: b64urlToBuffer(optJSON.challenge),
+          challenge,
           pubKeyCredParams: optJSON.pubKeyCredParams,
           timeout: 60000,
           attestation: "none",
@@ -154,6 +160,7 @@ export default function Register() {
       }) as PublicKeyCredential | null;
 
       if (!credential) throw new Error("クレデンシャルの作成に失敗しました");
+      setStep("3. credential 取得 OK → サーバー送信中…");
 
       const attestation = credential.response as AuthenticatorAttestationResponse;
       const regResponse: RegistrationResponseJSON = {
@@ -194,7 +201,7 @@ export default function Register() {
         <h1>log</h1>
       </header>
       <div className="auth-box">
-        <h2>パスキーを登録</h2>
+        <h2>パスキーを登録 [debug]</h2>
         <p>登録トークンを入力してパスキーを作成します。</p>
         <input
           type="password"
@@ -215,8 +222,11 @@ export default function Register() {
         <button className="btn" onClick={handleRegister} disabled={status === "loading" || !token}>
           {status === "loading" ? "登録中…" : "パスキーを登録"}
         </button>
+        {step && (
+          <p style={{ marginTop: ".75rem", fontSize: ".8rem", color: "#6b7280" }}>{step}</p>
+        )}
         {status === "error" && (
-          <p className="error-msg" style={{ marginTop: ".75rem" }}>{errorMsg}</p>
+          <p className="error-msg" style={{ marginTop: ".5rem" }}>{errorMsg}</p>
         )}
       </div>
     </div>
-- 
cgit v1.2.3

