From 846ebc942c579db2ebacdc0de6c76980ede8c799 Mon Sep 17 00:00:00 2001 From: Martin Kellner Date: Tue, 23 Sep 2025 11:22:45 +0200 Subject: [PATCH 1/7] Add first version of conditional create --- packages/web-core/src/services/WebAuthnService.ts | 15 ++++++++++++--- .../app/(no-auth)/login/PasswordForm.tsx | 3 ++- playground/connect-next/app/(no-auth)/page.tsx | 12 ++++++++---- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/web-core/src/services/WebAuthnService.ts b/packages/web-core/src/services/WebAuthnService.ts index ea4bb441..350c7f8d 100644 --- a/packages/web-core/src/services/WebAuthnService.ts +++ b/packages/web-core/src/services/WebAuthnService.ts @@ -2,7 +2,7 @@ /// <- add this line import type { ClientCapabilities } from '@corbado/types'; import type { CredentialRequestOptionsJSON } from '@corbado/webauthn-json'; -import { create, get } from '@corbado/webauthn-json'; +import { get } from '@corbado/webauthn-json'; import type { CredentialCreationOptionsJSON } from '@corbado/webauthn-json/src/webauthn-json/basic/json'; import FingerprintJS from '@fingerprintjs/fingerprintjs'; import { detectIncognito } from 'detectincognitojs'; @@ -39,10 +39,19 @@ export class WebAuthnService { async createPasskeyRaw(serializedChallenge: string): Promise { const abortController = this.abortOngoingOperation(); const challenge = JSON.parse(serializedChallenge); - challenge.signal = abortController.signal; this.#abortController = abortController; - const signedChallenge = await create(challenge); + console.log('createPasskeyRaw challenge', challenge); + + const publicKey = PublicKeyCredential.parseCreationOptionsFromJSON(challenge.publicKey); + console.log('createPasskeyRaw publicKey', publicKey); + const credential = (await navigator.credentials.create({ + publicKey, + signal: abortController.signal, + mediation: challenge.mediation, + } as any)) as PublicKeyCredential; + const signedChallenge = credential.toJSON(); + return JSON.stringify(signedChallenge); } diff --git a/playground/connect-next/app/(no-auth)/login/PasswordForm.tsx b/playground/connect-next/app/(no-auth)/login/PasswordForm.tsx index 85458313..d10edea5 100644 --- a/playground/connect-next/app/(no-auth)/login/PasswordForm.tsx +++ b/playground/connect-next/app/(no-auth)/login/PasswordForm.tsx @@ -35,7 +35,7 @@ export const PasswordForm = ({ onClick, initialUserProvidedIdentifier, initialEr name='email' type='email' placeholder='user@acme.com' - autoComplete='email' + autoComplete='username' required className='mt-1 block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-black focus:outline-none focus:ring-black sm:text-sm' value={username} @@ -53,6 +53,7 @@ export const PasswordForm = ({ onClick, initialUserProvidedIdentifier, initialEr id='password' name='password' type='password' + autoComplete='current-password' required className='mt-1 block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-black focus:outline-none focus:ring-black sm:text-sm' value={password} diff --git a/playground/connect-next/app/(no-auth)/page.tsx b/playground/connect-next/app/(no-auth)/page.tsx index 99005811..14deca36 100644 --- a/playground/connect-next/app/(no-auth)/page.tsx +++ b/playground/connect-next/app/(no-auth)/page.tsx @@ -14,7 +14,7 @@ export default function SignupPage() { const [password, setPassword] = useState(''); const [message, setMessage] = useState(''); - const handleSignup = async (e: FormEvent) => { + const handleSignup = async (e: FormEvent) => { e.preventDefault(); const username = generateRandomString(10); @@ -58,7 +58,10 @@ export default function SignupPage() {

Sign Up

Create an account with your email, phone and password

-
+