Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace the 60 second timeout with a random delay #453

Merged
merged 6 commits into from
May 9, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 25 additions & 17 deletions spec/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -482,20 +482,26 @@ algorithm is invoked, the user agent MUST execute the following steps. This retu


Issue: Support choosing accounts from multiple [=IDP=]s, as described [here](https://github.com/fedidcg/FedCM/issues/319).
1. Run {{WindowOrWorkerGlobalScope/setTimeout()}} passing a [=task=] which throws a
{{NetworkError}}, after a timeout of 60 seconds.

Issue: Do not use {{WindowOrWorkerGlobalScope/setTimeout()}} directly, as that is not correct. See the relevant
[issue](https://github.com/fedidcg/FedCM/issues/389).

Note: the purpose of having a timer here is to avoid leaking the reason causing this
method to throw an error. If there was no such timer, the developer could easily infer
whether the user has an account with the [=IDP=] or not, or whether the user closed the UI without granting permission to share the [=IDP=] account information with the [=RP=].
1. Let |provider| be |options|["{{CredentialRequestOptions/identity}}"]["{{IdentityCredentialRequestOptions/providers}}"][0].
1. Let |credential| be the result of running [=create an IdentityCredential=] with |provider|,
|options|["{{CredentialRequestOptions/mediation}}"], and |globalObject|.
1. If |credential| is failure, throw a new "{{NetworkError}}" {{DOMException}}.
1. Return |credential|.
1. If |credential| is a pair:
1. Let |throwImmediately| be the value of the second element of the pair.
1. If |throwImmediately| is false, the user agent SHOULD wait a random
amount of time before the next step, unless it has implemented
another way to prevent exposing to the RP whether the user has
an account logged in to the RP.

Note: The intention here is as follows. If we resolved the promise immediately,
then an RP could infer that no dialog was shown because the promise was
resolved quickly, after just the network delay. A shown dialog implies
that the user is logged in to one or more accounts of the IDP. To prevent
this information leakage, especially without user confirmation, we specify
this delay. However, UAs may have different UI approaches here and prevent
it in a different way.
1. [=Queue a global task=] on the [=DOM manipulation task source=]
to throw a new "{{NetworkError}}" {{DOMException}}.
1. Otherwise, return |credential|.
</div>

<!-- ============================================================ -->
Expand All @@ -507,19 +513,21 @@ agent UI, and creates the {{IdentityCredential}} that is then returned to the [=

<div algorithm>
To <dfn>create an IdentityCredential</dfn> given an {{IdentityProviderConfig}}
|provider|, a {{CredentialRequestOptions/mediation}} |mediation|, and a |globalObject|, run the
following steps. This returns an {{IdentityCredential}} or failure.
|provider|, a {{CredentialRequestOptions/mediation}} |mediation|, and a
|globalObject|, run the following steps. This returns an {{IdentityCredential}}
or a pair (failure, bool), where the bool indicates whether to skip delaying
the exception thrown.
1. Assert: These steps are running [=in parallel=].
1. Let |requiresUserMediation| be |provider|'s {{IdentityProviderConfig/configURL}}'s [=/origin=]'s
[=requires user mediation=].
1. If |requiresUserMediation| is true and |mediation| is
"{{CredentialMediationRequirement/silent}}", return failure.
1. Let |config| be the result of running [=fetch the config file=] with |provider| and
|globalObject|.
1. If |config| is failure, return failure.
1. If |config| is failure, return (failure, false).
1. Let |accountsList| be the result of [=fetch the accounts list=] with |config|, |provider|,
and |globalObject|.
1. If |accountsList| is failure, return failure.
1. If |accountsList| is failure, return (failure, false).
1. For each |acc| in |accountsList|:
1. If |acc|["{{IdentityProviderAccount/picture}}"] is present, [=fetch the account picture=]
with |acc| and |globalObject|.
Expand Down Expand Up @@ -554,7 +562,7 @@ following steps. This returns an {{IdentityCredential}} or failure.
1. Otherwise:
1. Set |account| to the result of running the [=select an account=] from the
|accountsList|.
1. If |account| is failure, return failure.
1. If |account| is failure, return (failure, true).
1. Set |accountState| to the result of running the [=compute the connection status=] algorithm
given |provider| and |account|.
1. If |accountState| is [=compute the connection status/disconnected=]:
Expand All @@ -564,7 +572,7 @@ following steps. This returns an {{IdentityCredential}} or failure.
1. Wait until the [=user agent=]'s dialogs requesting for user choice or permission to be
closed, if any are created in the previous steps.
1. Assert: |account| is not null.
1. If |permission| is false, then return failure.
1. If |permission| is false, then return (failure, true).
1. Let |credential| be the result of running the [=fetch an identity assertion=] algorithm with
|account|'s {{IdentityProviderAccount/id}}, |provider|, |config|, and
|globalObject|.
Expand Down