"""Runs real passkey ceremonies against a locally running Website, in headless Chrome with a virtual authenticator. swift run Website & # serves http://localhost:8080 over the in-memory database "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --headless=new --remote-debugging-port=9333 \\ --user-data-dir="$(mktemp -d)" about:blank & python3 Tests/Browser/passkeys.py Needs a fresh server: it joins accounts that must not exist yet. Stdlib only. """ import os, sys, time sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from cdp import connect BASE = "http://localhost:8080" chrome = connect(9333) chrome.send("Page.enable") chrome.send("Runtime.enable") chrome.send("WebAuthn.enable") authenticator = chrome.send("WebAuthn.addVirtualAuthenticator", options={ "protocol": "ctap2", "transport": "internal", "hasResidentKey": True, "hasUserVerification": True, "isUserVerified": True, "automaticPresenceSimulation": True, })["authenticatorId"] def open_sign_in(return_path): chrome.send("Page.navigate", url=f"{BASE}/sign-in?return={return_path}") assert chrome.wait_for("document.querySelector('[data-passkey]') && !document.querySelector('[data-passkey]').hidden"), \ "the passkey button never appeared" def press(email): chrome.evaluate(f"document.querySelector('#email').value = {email!r}; document.querySelector('[data-passkey]').click(); true") def status(): return chrome.evaluate("document.querySelector('[data-passkey-status]')?.textContent ?? ''") def credentials(): return chrome.send("WebAuthn.getCredentials", authenticatorId=authenticator)["credentials"] results = [] def check(name, ok, detail=""): results.append(ok) print(f"{'PASS' if ok else 'FAIL'} {name}{' ยท ' + str(detail) if detail else ''}") # 1. An unknown email registers a passkey and creates the account, then returns to the intent. open_sign_in("/search") press("sam.okafor@example.com") landed = chrome.wait_for("location.pathname === '/search'") check("join: registers a passkey and lands on the intent", landed, status() if not landed else chrome.evaluate("location.pathname")) check("join: the page is rendered for the new account", "Account of sam.okafor" in chrome.evaluate("document.documentElement.outerHTML")) held = credentials() check("join: the authenticator holds one discoverable credential", len(held) == 1 and held[0]["isResidentCredential"], f"{len(held)} held") # 2. Signed out, the same passkey signs in with no email at all. chrome.evaluate("fetch('/sign-out', {method: 'POST'}).then(() => true)") open_sign_in("/grading-guide") press("") landed = chrome.wait_for("location.pathname === '/grading-guide'") check("sign-in: a discoverable passkey signs in without an email", landed, status() if not landed else "") check("sign-in: as the same account", "Account of sam.okafor" in chrome.evaluate("document.documentElement.outerHTML")) check("sign-in: the signature counter moved on", credentials()[0]["signCount"] >= 2, credentials()[0]["signCount"]) # 3. By email, the ceremony names the account's credential. chrome.evaluate("fetch('/sign-out', {method: 'POST'}).then(() => true)") open_sign_in("/") press("Sam.Okafor@Example.com") check("sign-in: by email, normalized", chrome.wait_for("location.pathname === '/'"), status()) # 4. A demo account has no passkey, and none can be added to it. chrome.evaluate("fetch('/sign-out', {method: 'POST'}).then(() => true)") open_sign_in("/") press("mara.v@example.com") refused = chrome.wait_for("(document.querySelector('[data-passkey-status]')?.textContent ?? '').includes('no passkey')") check("refusal: an existing account is never handed a new passkey", refused and len(credentials()) == 1, status()) check("refusal: nobody was signed in", chrome.evaluate("location.pathname") == "/sign-in") sys.exit(0 if all(results) else 1)