Summary
AuthorizerVerifyOtp.tsx's OTP input has autoComplete="one-time-code" — the standard declarative HTML attribute browsers use as a hint for native WebOTP auto-fill — but nothing in this component, or anywhere else in this package or @authorizerdev/authorizer-js, actually calls the WebOTP JS API (navigator.credentials.get({ otp: { transport: ['sms'] } })).
Confirmed via a full source-tree search (both packages, case-insensitive) for credentials.get, OTPCredential, WebOTP, webotp: zero real matches anywhere.
Impact
The autocomplete="one-time-code" attribute alone does relatively little on its own in most browsers/platforms without the page also calling the Credential Management API — on the platforms where it does trigger something automatically (e.g. some mobile browser + OS combinations), it's inconsistent and not the documented/recommended pattern. The WebOTP API spec and browser vendor guidance both expect the page to explicitly call navigator.credentials.get() with an otp option, typically racing it against the form's normal submit flow. Without that call, users on browsers/platforms that don't auto-honor the bare attribute get no auto-fill benefit at all — they always have to copy/paste or manually type the SMS code, even on Android Chrome where WebOTP is best supported.
Suggested fix
In AuthorizerVerifyOtp.tsx, when an SMS-OTP verification is in progress (not TOTP/email-OTP), call navigator.credentials.get({ otp: { transport: ['sms'] }, signal }) (feature-detected via window.OTPCredential, same pattern the existing autoComplete="one-time-code" attribute already implies), and populate the OTP field when it resolves — cancelling via AbortController on unmount/submit. This is a well-documented ~15-20 line addition; happy to point to a reference implementation if useful.
Context
Found while building live e2e test coverage for Authorizer's MFA methods (a real browser driving SMS-OTP enrollment and login-challenge verification against a real backend). The e2e task set out to test WebOTP auto-fill specifically, but after confirming there's no real JS hook to exercise, shipped a test.skip() documenting the gap rather than fabricating a test around a mock that wouldn't prove anything about actual product behavior — this issue is that documentation's cross-repo counterpart, matching how the missing Discord login button gap was handled (#64).
Summary
AuthorizerVerifyOtp.tsx's OTP input hasautoComplete="one-time-code"— the standard declarative HTML attribute browsers use as a hint for native WebOTP auto-fill — but nothing in this component, or anywhere else in this package or@authorizerdev/authorizer-js, actually calls the WebOTP JS API (navigator.credentials.get({ otp: { transport: ['sms'] } })).Confirmed via a full source-tree search (both packages, case-insensitive) for
credentials.get,OTPCredential,WebOTP,webotp: zero real matches anywhere.Impact
The
autocomplete="one-time-code"attribute alone does relatively little on its own in most browsers/platforms without the page also calling the Credential Management API — on the platforms where it does trigger something automatically (e.g. some mobile browser + OS combinations), it's inconsistent and not the documented/recommended pattern. The WebOTP API spec and browser vendor guidance both expect the page to explicitly callnavigator.credentials.get()with anotpoption, typically racing it against the form's normal submit flow. Without that call, users on browsers/platforms that don't auto-honor the bare attribute get no auto-fill benefit at all — they always have to copy/paste or manually type the SMS code, even on Android Chrome where WebOTP is best supported.Suggested fix
In
AuthorizerVerifyOtp.tsx, when an SMS-OTP verification is in progress (not TOTP/email-OTP), callnavigator.credentials.get({ otp: { transport: ['sms'] }, signal })(feature-detected viawindow.OTPCredential, same pattern the existingautoComplete="one-time-code"attribute already implies), and populate the OTP field when it resolves — cancelling viaAbortControlleron unmount/submit. This is a well-documented ~15-20 line addition; happy to point to a reference implementation if useful.Context
Found while building live e2e test coverage for Authorizer's MFA methods (a real browser driving SMS-OTP enrollment and login-challenge verification against a real backend). The e2e task set out to test WebOTP auto-fill specifically, but after confirming there's no real JS hook to exercise, shipped a
test.skip()documenting the gap rather than fabricating a test around a mock that wouldn't prove anything about actual product behavior — this issue is that documentation's cross-repo counterpart, matching how the missing Discord login button gap was handled (#64).