Debuggler LogoDebuggler
All challenges

The Code That Expired

Authentication

You requested a fresh code with Resend and entered the new one from the simulator, but Verify keeps rejecting it. First code worked — the resend path is broken.

After you fix it

  • After Resend, Verify should accept the newly issued code shown in the simulator.
  • The first code should still work if you never pressed Resend.
  • Wrong codes should still show an error.
import { useState, useEffect, useRef } from "react";

const GATEWAY = { first: "482910", resend: "719304" };

export default function App() {
  const [phone, setPhone] = useState("");
  const [step, setStep] = useState("phone");
  const [activeCode, setActiveCode] = useState("");
  const [entry, setEntry] = useState("");
  const [error, setError] = useState("");
  const verifyAgainst = useRef(null);

  useEffect(() => {
    const b = document.body;
    const pb = b.style.background;
    const pm = b.style.margin;
    b.style.background = "#fafafa";
    b.style.margin = "0";
    return () => {
      b.style.background = pb;
      b.style.margin = pm;
    };
  }, []);

  const sendCode = (kind) => {
    const code = kind === "resend" ? GATEWAY.resend : GATEWAY.first;
    setActiveCode(code);
    setEntry("");
    setError("");
    if (kind !== "resend") verifyAgainst.current = code;
    setStep("otp");
  };

  const verify = () => {
    if (entry.trim() === verifyAgainst.current) {
      setStep("done");
      setError("");
    } else {
      setError("That code did not match.");
    }
  };

  return (
    <div style={styles.page}>
      <div style={styles.card}>
        <h1 style={styles.h1}>Verify your phone</h1>
        {step === "phone" && (
          <>
            <p style={styles.sub}>We will text a one-time code to finish sign-in.</p>
            <input data-testid="phone-input" value={phone} onChange={(e) => setPhone(e.target.value)} placeholder="+1 mobile" style={styles.input} />
            <button type="button" data-testid="send-code-btn" disabled={!phone.trim()} onClick={() => sendCode("first")} style={styles.btn}>Send code</button>
          </>
        )}
        {step === "otp" && (
          <>
            <p style={styles.sub}>Enter the code we sent to {phone || "your number"}.</p>
            <p data-testid="issued-code" style={styles.sim}>Simulator delivery: {activeCode}</p>
            <input data-testid="otp-input" value={entry} onChange={(e) => setEntry(e.target.value)} placeholder="6-digit code" style={styles.input} />
            {error && <p data-testid="otp-error" style={styles.err}>{error}</p>}
            <div style={styles.row}>
              <button type="button" data-testid="verify-btn" onClick={verify} style={styles.btn}>Verify</button>
              <button type="button" data-testid="resend-btn" onClick={() => sendCode("resend")} style={styles.btnGhost}>Resend</button>
            </div>
          </>
        )}
        {step === "done" && <p data-testid="otp-success" style={styles.ok}>Phone verified — redirecting…</p>}
      </div>
    </div>
  );
}

const styles = {
  page: { display: "flex", justifyContent: "center", padding: "48px 20px", fontFamily: "'Segoe UI', system-ui, sans-serif" },
  card: { background: "#fff", borderRadius: 14, padding: "28px 30px", width: "100%", maxWidth: 380, boxShadow: "0 1px 3px rgba(0,0,0,0.08)" },
  h1: { margin: "0 0 8px", fontSize: 20, fontWeight: 700 },
  sub: { margin: "0 0 14px", fontSize: 14, color: "#666" },
  sim: { margin: "0 0 12px", fontSize: 12, color: "#555", background: "#f4f4f5", padding: "8px 10px", borderRadius: 8 },
  input: { width: "100%", boxSizing: "border-box", padding: "10px 12px", fontSize: 15, borderRadius: 8, border: "1px solid #ddd", marginBottom: 12 },
  err: { margin: "0 0 10px", fontSize: 13, color: "#b45309" },
  ok: { margin: 0, fontSize: 14, color: "#047857", fontWeight: 600 },
  row: { display: "flex", gap: 10 },
  btn: { flex: 1, padding: "10px 12px", fontSize: 14, fontWeight: 600, background: "#4f46e5", color: "#fff", border: "none", borderRadius: 8, cursor: "pointer" },
  btnGhost: { flex: 1, padding: "10px 12px", fontSize: 14, fontWeight: 600, background: "#fff", color: "#444", border: "1px solid #ddd", borderRadius: 8, cursor: "pointer" },
};