[webauthn] Support NoCredentialsError and UserCancelledError codes (#2062)

AdamEisfeld has just created a new issue for https://github.com/w3c/webauthn:

== Support NoCredentialsError and UserCancelledError codes ==
## Related

An alternate solution to [](https://github.com/w3c/webauthn/issues/1568) / the issues described in [](https://github.com/w3c/webauthn/issues/1749).

## To Sum Up

The current paradigm creates a bad UX, because we have no way of knowing if a user has connected their current device to web auth, and so we either need to show them UI for both Create and Get paths, relying on their memory of what they have done, or we need to conditionally only show them the Get path if we "think" the user has connected their current device (based on some information passed to us from our backend), potentially causing the user to attempt web auth and fail if their connection has been destroyed for some reason.

Proposed Solution A is to implement a "Get OR Create" mechanism that handles the details under the hood. This would solve the primary issue but introduces other concerns around state / the desire for frontends to provide a bit of a custom Create path (eg; entering a custom "device name" to associate with the key).

Proposed Solution B is to implement a "does key exist" function that returns a simple boolean depending on whether or not the current device is indeed found in the list of allowed credentials. This would solve the primary issue but introduces possible anonymity / privacy concerns.

## Proposed Change

Currently, if a user attempts to Get credentials for a device that does not have any, they see some form of automatic "Passkey does not exist" UI, requiring the user to click a Cancel button to back out of the procedure. The error thrown from clicking this Cancel button is a DOMException, with a name of "**NotAllowedError**". This is the same error that is thrown if a user DOES have credentials for their device but still opts to manually cancel out of the procedure.

### Change 1 ###

Throw "NoCredentialsError" if the user cancels out of a credentials.get() flow AND the reason for the cancellation is due to the device not having any credentials.

### Change 2 ###

Throw "UserCancelledError" if the user cancels out of a credentials.get() flow AND the reason for the cancellation is NOT due to the device not having any credentials.

## Benefits

- We can detect NoCredentialsError and store a cookie on the device in order to avoid showing the Get flow and instead show the Create flow on next-launch, until the user goes through with the creation. Meaning if they close the website entirely and come back, they won't need to go through this unhappy path again.
- We can automatically push the user through to the Create flow as a result of this error, now that we know they don't have any credentials on this device.
- The Get / Create flows remain separate instead of a possibly over-controlling "Get OR Create" flow that would make it more difficult for custom state-based interactions to take place (eg; entering a custom device name in the case of Create to be passed up to your backend)
- Although this is similar to Solution B ("does key exist") in the sense it exposes some form of anonymous information, the information is obtained as a result of the user attempting to get them, instead of hidden from the user as a preliminary background step.
- I imagine the required code change would be minimal as these are just error codes, perhaps with a bit of state tracking to determine which to throw

## Risks

- This could affect backwards compatibility, assuming people are already looking for the NoCredentialsError explicitly.


Please view or discuss this issue at https://github.com/w3c/webauthn/issues/2062 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Wednesday, 24 April 2024 18:36:26 UTC