"use client"; import { useEffect, useState, useTransition } from "react"; import { useRouter } from "next/navigation"; import { startAuthentication } from "@simplewebauthn/browser"; import { loginWithPassword, beginAuthentication, finishAuthentication, } from "@/app/auth-actions"; type Props = { passkeysAvailable: boolean; next: string; }; export default function AuthForm({ passkeysAvailable, next }: Props) { const router = useRouter(); const [isPending, startTransition] = useTransition(); const [platformReady, setPlatformReady] = useState(false); const [pointerDevice, setPointerDevice] = useState(false); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [passkeyError, setPasskeyError] = useState(null); const [formError, setFormError] = useState(null); useEffect(() => { if (typeof window === "undefined") return; setPointerDevice( window.matchMedia("(hover: hover) and (pointer: fine)").matches, ); if ( !passkeysAvailable || typeof window.PublicKeyCredential === "undefined" || typeof window.PublicKeyCredential .isUserVerifyingPlatformAuthenticatorAvailable !== "function" ) { return; } let cancelled = false; window.PublicKeyCredential .isUserVerifyingPlatformAuthenticatorAvailable() .then((ok) => { if (!cancelled) setPlatformReady(Boolean(ok)); }) .catch(() => {}); return () => { cancelled = true; }; }, [passkeysAvailable]); const showPasskey = passkeysAvailable && platformReady; const destination = next && next.startsWith("/") ? next : "/"; function handlePasskey() { setPasskeyError(null); setFormError(null); startTransition(async () => { try { const options = await beginAuthentication(); const response = await startAuthentication({ optionsJSON: options }); const result = await finishAuthentication(response); if (result.ok) { router.push(destination); router.refresh(); } else { setPasskeyError(result.error); } } catch (err) { const message = err instanceof Error ? err.message : "Passkey sign-in failed"; if ( message.toLowerCase().includes("notallowed") || message.toLowerCase().includes("cancel") ) { setPasskeyError("Sign-in was cancelled"); } else { setPasskeyError(message); } } }); } function handleSubmit(e: React.FormEvent) { e.preventDefault(); setFormError(null); setPasskeyError(null); startTransition(async () => { const result = await loginWithPassword(username, password); if (result.ok) { router.push(destination); router.refresh(); } else { setFormError(result.error); } }); } return (
CM

Sign in

CM Bot V2 — operator console

{showPasskey && ( <>
{passkeyError && (

{passkeyError}

)}
or
)}
{formError && (

{formError}

)}

Forgot the password? Check the deployment’s{" "} .env {" "} for CM_AGENT_PASSWORD.

); }