Skip to content

No real WebOTP (navigator.credentials.get) wiring in AuthorizerVerifyOtp #66

Description

@lakhansamani

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions