diff --git a/index.bs b/index.bs
index 5aa5fbf29..e99295823 100644
--- a/index.bs
+++ b/index.bs
@@ -165,6 +165,8 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
text: opaque origin; url: concept-origin-opaque
text: tuple origin; url: concept-origin-tuple
text: document.domain; url:dom-document-domain
+ urlPrefix: form-control-infrastructure.html
+ text: autofill detail token; url: autofill-detail-tokens
spec: url; urlPrefix: https://url.spec.whatwg.org
type: dfn
@@ -1153,8 +1155,8 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S
: otherUI
:: OPTIONAL other information used by the [=authenticator=] to inform its UI. For example, this might include the user's
- {{displayName}}. [=otherUI=] is a mutable item and SHOULD NOT be bound to the [=public key credential source=]
- in a way that prevents [=otherUI=] from being updated.
+ {{displayName}}. [=public key credential source/otherUI=] is a mutable item and SHOULD NOT be bound to the
+ [=public key credential source=] in a way that prevents [=public key credential source/otherUI=] from being updated.
The [=authenticatorMakeCredential=] operation creates a [=public key credential source=] [=bound credential|bound=] to a \[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) [=internal method=] inherits the default behavior of
{{Credential/[[CollectFromCredentialStore]]()|Credential.[[CollectFromCredentialStore]]()}}, of returning an empty set.
+In general, the user agent SHOULD show some UI to the user to guide them in selecting and authorizing an authenticator with which
+to complete the operation. By setting |options|.{{CredentialRequestOptions/mediation}}
to {{CredentialMediationRequirement/conditional}}, [=[RPS]=] can indicate that a prominent modal UI should not be shown unless credentials are discovered. [=[RP]=]
+script SHOULD first check that {{PublicKeyCredential/isConditionalMediationAvailable()}} returns [TRUE] in order to avoid
+the possibility of causing a user-visible error to be returned if the user agent does not support
+{{CredentialMediationRequirement/conditional}} [=user mediation=].
+
This
{{CredentialsContainer/get()|navigator.credentials.get()}} operation can be aborted by leveraging the {{AbortController}};
see [[dom#abortcontroller-api-integration]] for detailed instructions.
@@ -2099,24 +2120,37 @@ When this method is invoked, the user agent MUST execute the following algorithm
1. Let |options| be the value of |options|.{{CredentialRequestOptions/publicKey}}
.
-1. If the {{PublicKeyCredentialRequestOptions/timeout}} member of |options| is present, check if its value lies
- within a reasonable range as defined by the [=client=] and if not, correct it to the closest value lying within that range.
- Set a timer |lifetimeTimer| to this adjusted value. If the {{PublicKeyCredentialRequestOptions/timeout}} member of
- |options| is not present, then set |lifetimeTimer| to a [=client=]-specific default.
+1. If |options|.{{CredentialRequestOptions/mediation}}
is present with the value
+ {{CredentialMediationRequirement/conditional}}:
- Recommended ranges and defaults for the {{PublicKeyCredentialRequestOptions/timeout}} member of |options| are as follows.
- If |options|.{{PublicKeyCredentialRequestOptions/userVerification}}
-
|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
is not [=list/empty=],
+ return a {{DOMException}} whose name is "{{NotSupportedError}}", and terminate this algorithm.
- : is set to {{UserVerificationRequirement/required}} or {{UserVerificationRequirement/preferred}}
- :: Recommended range: 30000 milliseconds to 600000 milliseconds.
- :: Recommended default value: 300000 milliseconds (5 minutes).
- |options|.{{PublicKeyCredentialRequestOptions/userVerification}}
+ |options|.{{CredentialRequestOptions/signal}}
's [=AbortSignal/abort reason=].
- : If |issuedRequests| is empty, |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
is not empty, and no |authenticator| will become available for any [=public key credentials=] therein,
- :: Indicate to the user that no eligible credential could be found. When the user acknowledges the dialog, throw a "{{NotAllowedError}}" {{DOMException}}.
+
+ |options|.{{CredentialRequestOptions/mediation}}
is {{CredentialMediationRequirement/conditional}}
+ and the user interacts with an <{input}> or <{textarea}> form control with an <{input/autocomplete}> attribute whose value
+ contains a `"webauthn"` [=autofill detail token=],
+ {{transports}}
members of the present {{PublicKeyCredentialDescriptor}}
[=list/items=] of |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
, if any. For example, if all {{PublicKeyCredentialDescriptor}}
[=list/items=] list only {{AuthenticatorTransport/internal}}
, but all [=platform authenticator|platform=] |authenticator|s have been tried, then there is no possibility of satisfying the request. Alternatively, all {{PublicKeyCredentialDescriptor}}
[=list/items=] may list {{transports}}
that the [=client platform=] does not support.
+ :: 1. If |silentlyDiscoveredCredentials| is not [=list/empty=]:
- : If an |authenticator| becomes available on this [=client device=],
- :: Note: This includes the case where an |authenticator| was available upon |lifetimeTimer| initiation.
+ 1. Prompt the user to optionally select a [=DiscoverableCredentialMetadata=] (|credentialMetadata|) from |silentlyDiscoveredCredentials|.
- 1. If |options|.{{PublicKeyCredentialRequestOptions/userVerification}}
is set to
- {{UserVerificationRequirement/required}} and the |authenticator| is not capable of performing [=user verification=],
- [=iteration/continue=].
+ Note: The prompt shown SHOULD include values from |credentialMetadata|'s [=DiscoverableCredentialMetadata/otherUI=]
+ such as {{PublicKeyCredentialEntity/name}} and {{PublicKeyCredentialUserEntity/displayName}}.
- 1. Let |userVerification| be the effective user verification requirement for assertion, a Boolean value, as
- follows. If |options|.{{PublicKeyCredentialRequestOptions/userVerification}}
+ 1. If the user selects a |credentialMetadata|,
- |publicKeyOptions|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
to be a [=list=] containing a
+ single {{PublicKeyCredentialDescriptor}} [=list/item=] whose {{PublicKeyCredentialDescriptor/id}}'s value is set to
+ |credentialMetadata|'s [=DiscoverableCredentialMetadata/id=]'s value and whose{{PublicKeyCredentialDescriptor/id}}
+ value is set to |credentialMetadata|'s [=DiscoverableCredentialMetadata/type=].
- |options|.{{CredentialRequestOptions/mediation}}
is not {{CredentialMediationRequirement/conditional}},
+ |issuedRequests| is empty, |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
is not empty,
+ and no |authenticator| will become available for any [=public key credentials=] therein,
+ :: Indicate to the user that no eligible credential could be found. When the user acknowledges the dialog, throw a "{{NotAllowedError}}" {{DOMException}}.
- 1.
- If |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
- {{transports}}
members of the present {{PublicKeyCredentialDescriptor}}
[=list/items=] of |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
, if any. For example, if all {{PublicKeyCredentialDescriptor}}
[=list/items=] list only {{AuthenticatorTransport/internal}}
, but all [=platform authenticator|platform=] |authenticator|s have been tried, then there is no possibility of satisfying the request. Alternatively, all {{PublicKeyCredentialDescriptor}}
[=list/items=] may list {{transports}}
that the [=client platform=] does not support.
- 1. Execute a [=client platform=]-specific procedure to determine which, if any, [=public key credentials=] described by
- |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
are [=bound credential|bound=] to this
- |authenticator|, by matching with |rpId|,
- |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}.{{PublicKeyCredentialDescriptor/id}}
,
- and
- |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}.{{PublicKeyCredentialDescriptor/type}}
.
- Set |allowCredentialDescriptorList| to this filtered list.
+ : If an |authenticator| becomes available on this [=client device=],
+ :: Note: This includes the case where an |authenticator| was available upon |lifetimeTimer| initiation.
- 1. If |allowCredentialDescriptorList| [=list/is empty=], [=continue=].
+ 1. If |options|.{{CredentialRequestOptions/mediation}}
is {{CredentialMediationRequirement/conditional}}
+ and the |authenticator| supports the [=silentCredentialDiscovery=] operation:
- 1. Let |distinctTransports| be a new [=ordered set=].
+ 1. Let |collectedDiscoveredCredentialMetadata| be the result of invoking the [=silentCredentialDiscovery=] operation on |authenticator| with |rpId| as parameter.
- 1. If |allowCredentialDescriptorList| has exactly one value, set
- |savedCredentialIds|[|authenticator|]
to |allowCredentialDescriptorList|[0].id
's
- value (see [here](#authenticatorGetAssertion-return-values) in [[#sctn-op-get-assertion]] for more information).
+ 1. [=list/For each=] |credentialMetadata| of |collectedDiscoveredCredentialMetadata|:
- 1. [=list/For each=] credential descriptor |C| in |allowCredentialDescriptorList|,
- [=set/append=] each value, if any, of |C|.{{transports}}
to |distinctTransports|.
+ 1. [=map/Set=] |silentlyDiscoveredCredentials|[|credentialMetadata|] to |authenticator|.
- Note: This will aggregate only distinct values of {{transports}} (for this [=authenticator=]) in
- |distinctTransports| due to the properties of [=ordered sets=].
+ Note: A request will be issued to this authenticator upon user selection of a credential via
+ interaction with a particular UI context
+ (see [here](#GetAssn-ConditionalMediation-Interact-FormControl) for details).
- 1. If |distinctTransports|
- |options|.{{CredentialRequestOptions/mediation}}
is {{CredentialMediationRequirement/conditional}}
+ and the |authenticator| does not support the [=silentCredentialDiscovery=] operation to allow use of such authenticators during a
+ {{CredentialMediationRequirement/conditional}} [=user mediation=] request.
+
+ 1. [=set/Append=] |authenticator| to |issuedRequests|.
: If an |authenticator| ceases to be available on this [=client device=],
:: [=set/Remove=] |authenticator| from |issuedRequests|.
@@ -2400,10 +2410,129 @@ When this method is invoked, the user agent MUST execute the following algorithm
user without [=user consent|consent=], this step MUST NOT be executed before |lifetimeTimer| has expired. See
[[#sctn-assertion-privacy]] for details.
-During the above process, the user agent SHOULD show some UI to the user to guide them in the process of selecting and
-authorizing an authenticator with which to complete the operation.
+#### Issuing a Credential Request to an Authenticator #### {#sctn-issuing-cred-request-to-authenticator}
+
+This sub-algorithm of {{PublicKeyCredential/[[DiscoverFromExternalSource]]()}} encompasses the specific UI context-independent
+steps necessary for requesting a [=credential=] from a given [=authenticator=], using given {{PublicKeyCredentialRequestOptions}}.
+It is called by {{PublicKeyCredential/[[DiscoverFromExternalSource]]()}} from various points depending on which [=user mediation=]
+the present [=authentication ceremony=] is subject to (e.g.: {{CredentialMediationRequirement/conditional}} mediation).
+
+This algorithm accepts the following arguments:
+
+|options|.{{PublicKeyCredentialRequestOptions/userVerification}}
is set to
+ {{UserVerificationRequirement/required}} and the |authenticator| is not capable of performing [=user verification=],
+ return [FALSE].
+
+ 1. Let |userVerification| be the effective user verification requirement for assertion, a Boolean value, as
+ follows. If |options|.{{PublicKeyCredentialRequestOptions/userVerification}}
+
+ |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
+ |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}
are [=bound credential|bound=] to this
+ |authenticator|, by matching with |rpId|,
+ |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}.{{PublicKeyCredentialDescriptor/id}}
,
+ and |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}.{{PublicKeyCredentialDescriptor/type}}
.
+ Set |allowCredentialDescriptorList| to this filtered list.
+
+ 1. If |allowCredentialDescriptorList| [=list/is empty=], return [FALSE].
+
+ 1. Let |distinctTransports| be a new [=ordered set=].
+
+ 1. If |allowCredentialDescriptorList| has exactly one value, set
+ |savedCredentialIds|[|authenticator|]
to |allowCredentialDescriptorList|[0].id
's
+ value (see [here](#authenticatorGetAssertion-return-values) in [[#sctn-op-get-assertion]] for more information).
+
+ 1. [=list/For each=] credential descriptor |C| in |allowCredentialDescriptorList|,
+ [=set/append=] each value, if any, of |C|.{{transports}}
to |distinctTransports|.
+
+ Note: This will aggregate only distinct values of {{transports}} (for this [=authenticator=]) in
+ |distinctTransports| due to the properties of [=ordered sets=].
+
+ 1. If |distinctTransports|
+ |descriptor|.{{PublicKeyCredentialDescriptor/id}}
in this authenticator
- returns non-null, and the returned [=list/item=]'s [=RP ID=] and [=type=] match
+ returns non-null, and the returned [=list/item=]'s [=RP ID=] and [=public key credential source/type=] match
|rpEntity|.{{PublicKeyCredentialRpEntity/id}}
and
|excludeCredentialDescriptorList|.{{PublicKeyCredentialDescriptor/type}}
respectively,
then collect an [=authorization gesture=] confirming [=user
@@ -4407,6 +4536,54 @@ This operation is ignored if it is invoked in an [=authenticator session=] which
or [=authenticatorGetAssertion=] operation currently in progress.
+### The silentCredentialDiscovery operation ### {#sctn-op-silent-discovery}
+
+This is an OPTIONAL operation authenticators MAY support to enable {{CredentialMediationRequirement/conditional}}
+[=user mediation=].
+
+It takes the following input parameter:
+
+: |rpId|
+:: The caller's [=RP ID=], as determined by the [=client=].
+
+When this operation is invoked, the [=authenticator=] MUST perform the following procedure:
+
+1. Let |collectedDiscoverableCredentialMetadata| be a new [=list=] whose [=list/items=] are
+ DiscoverableCredentialMetadata [=structs=] with the following [=struct/items=]:
+
+