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

Conversation

cbiesinger
Copy link
Collaborator

@cbiesinger cbiesinger commented Apr 12, 2023

This is a better user experience and also gives user agents mores
flexibility for their UI. It also makes the spec match Chrome's current
implementation.

This change does not add a delay when the user closes the dialog
explicitly. This is not necessary because the timing is effectively
random and therefore indistinguishable from other failures that do
have this delay, and it allows RPs to fall back to different types
of authentication immediately in this case.

Closes #389


Preview | Diff

@cbiesinger
Copy link
Collaborator Author

@RByers @samuelgoto @yi-gu

@cbiesinger
Copy link
Collaborator Author

also cc @martinthomson, @bvandersloot-mozilla and @cboozar

spec/index.bs Outdated Show resolved Hide resolved
@RByers
Copy link

RByers commented Apr 12, 2023

FWIW Christian and I chatted about this and I think the principle here should be that zero-account failures should be indistinguishable from a user not interacting with the UI.

spec/index.bs Outdated
@@ -484,6 +475,11 @@ failure.
1. If |config| is failure, return failure.
1. Let |accountsList| be the result of [=fetch the accounts list=] with |config|, |provider|,
and |globalObject|.
1. If |accountsList|'s size is 0 or if the fetch threw an exception:
1. Stop processing the algorithm and wait indefinitely.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One issue I see with this is that we do not allow new FedCM calls when there is a pending call. So this effectively means that the FedCM API cannot be invoked again in this page load. Other than that, this might be ok though it seems to require an implementation change on the Chromium side, right? Also, would we need to note somewhere that this would also be the behavior when the user closes/dismisses the user agent UI?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, and IMHO one that gets at the heart of why I think it's good to move the spec in this direction. Imagine an implementation which chooses to suppress or show very quiet UI when FedCM is invoked without a user gesture, but will show noisier UI when invoked in response to eg. a "login with X" button click. Such an implementation needs a way to cancel the first request and show the second (possibly with <60 seconds between them), right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, of course. So is it OK to leave aborting current requests up to the page, or should we auto-abort when a new request comes in? In particular, thinking about multi-IDP scenarios with two un-cooperating SDKs on the same page. Presumably the one with a user gesture should take priority over one without (regardless of whether it's before or after), right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good question, hmm

Currently the spec requires us to fail with NotAllowedErr (step 5 in https://w3c.github.io/webappsec-credential-management/#algorithm-store) and payments also fails a second request if the first one is not done yet

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So for the hypothetical scenario where the page uses a FedCM call during the page load and then there is a click which triggers another FedCM call, we would have two options:

  1. Remove the UI from the first FedCM call (possibly reject the promise, or just leave it unresolved) and initiate the second call. This has the advantage that there is no need to manually abort the first FedCM call.
  2. Force the developer to abort the first FedCM call manually, otherwise reject the second call (this is the current behavior). This has the advantage that we don't have to guess which FedCM calls should take priority, but does seem to require a bit more work from the RP. It also assumes the IDP does provide an abort method to cancel the call.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated the PR to not have the indefinite timeout. Please take another look. Also interested in thoughts from others (@martinthomson / @cboozar ?)

spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated
@@ -484,6 +475,11 @@ failure.
1. If |config| is failure, return failure.
1. Let |accountsList| be the result of [=fetch the accounts list=] with |config|, |provider|,
and |globalObject|.
1. If |accountsList|'s size is 0 or if the fetch threw an exception:
1. Stop processing the algorithm and wait indefinitely.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So for the hypothetical scenario where the page uses a FedCM call during the page load and then there is a click which triggers another FedCM call, we would have two options:

  1. Remove the UI from the first FedCM call (possibly reject the promise, or just leave it unresolved) and initiate the second call. This has the advantage that there is no need to manually abort the first FedCM call.
  2. Force the developer to abort the first FedCM call manually, otherwise reject the second call (this is the current behavior). This has the advantage that we don't have to guess which FedCM calls should take priority, but does seem to require a bit more work from the RP. It also assumes the IDP does provide an abort method to cancel the call.

spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
cbiesinger added a commit to cbiesinger/WebID that referenced this pull request Apr 19, 2023
As-is, the spec does not correctly handle fetch errors; this change
ensures that we correctly turn them into exceptions.

I am keeping the name of the processResponseConsumeBody parameter even
though it is no longer directly passed to the fetch algorithm because
conceptually this is a wrapper around fetch and the parameter does
have the same meaning as in the fetch algorithm.

This was split out of PR w3c-fedid#453
Copy link
Collaborator Author

@cbiesinger cbiesinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am splitting the relatively uncontroversial change to the fetch error handling into PR #455 so that this PR can focus on the timeout handling.

I will also update this PR to what Chrome currently implements which should be less controversial than this PR's current proposal.

spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
cbiesinger added a commit to cbiesinger/WebID that referenced this pull request Apr 19, 2023
The extract and convert steps can throw exceptions, but fetch's
processResponseConsumeBody does not really handle that. Instead,
set the respective return objects to failure and update the call
site where necessary.

This was split out of PR w3c-fedid#453 with major modifications.
cbiesinger added a commit to cbiesinger/WebID that referenced this pull request Apr 19, 2023
The extract and convert steps can throw exceptions, but fetch's
processResponseConsumeBody does not really handle that. Instead,
set the respective return objects to failure and update the call
site where necessary.

This was split out of PR w3c-fedid#453 with major modifications.
npm1 pushed a commit that referenced this pull request Apr 19, 2023
* Correctly handle fetch errors

The extract and convert steps can throw exceptions, but fetch's
processResponseConsumeBody does not really handle that. Instead,
set the respective return objects to failure and update the call
site where necessary.

This was split out of PR #453 with major modifications.

* review comments
This is a better user experience and also gives user agents mores
flexibility for their UI. It also makes the spec match Chrome's current
implementation.

This change does not add a delay when the user closes the dialog
explicitly. This is not necessary because the timing is effectively
random and therefore indistinguishable from other failures that do
have this delay, and it allows RPs to fall back to different types
of authentication immediately in this case.

Closes w3c-fedid#389
@cbiesinger cbiesinger changed the title Replace the 60 second timeout with an unresolved promise Replace the 60 second timeout with a random delay Apr 19, 2023
spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
@cbiesinger
Copy link
Collaborator Author

Please take another look!

spec/index.bs Outdated
1. Let |throwImmediately| be the value of the second element of the pair.
1. [=Queue a global task=] on the [=DOM manipulation task source=]
to throw a new "{{NetworkError}}" {{DOMException}}. If |throwImmediately| is true, this
MUST happen after a random delay between 0 and 60 seconds.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of comments:

  • I think it is a bit clearer to add the wait before the queue a global task step, otherwise. this sounds like this delay could happen in main thread! Something like 1. If |throwImmediately| is true, wait ... 1. Queue a global task
  • Do we need to hardcode the 60 seconds here? In fact, does the delay here need to be mandatory? I can imagine user agent UI such that it only attempts fetching once the user has interacted enough with the dialog, and may thus not need this delay. Perhaps making this wait optional and explaining the purpose is a better approach?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, but let me know if you want this less prescriptive

spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
Copy link
Collaborator

@npm1 npm1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! We should get someone from Mozilla to take a look before merging though...

spec/index.bs Outdated Show resolved Hide resolved
@cbiesinger
Copy link
Collaborator Author

@martinthomson, @bvandersloot-mozilla and @cboozar -- I'd love to hear your thoughts on this PR

spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
@npm1 npm1 added the agenda+ Regular CG meeting agenda items label Apr 21, 2023
@cbiesinger cbiesinger mentioned this pull request May 8, 2023
@cboozar
Copy link

cboozar commented May 9, 2023

Sorry for the late reply, these changes look good to me 👍

@npm1
Copy link
Collaborator

npm1 commented May 9, 2023

Thanks for the review! Merging.

@npm1 npm1 merged commit c8609ec into w3c-fedid:main May 9, 2023
@cbiesinger cbiesinger deleted the timeout branch May 9, 2023 17:27
github-actions bot added a commit that referenced this pull request May 9, 2023
SHA: c8609ec
Reason: push, by npm1

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@cbiesinger cbiesinger removed the agenda+ Regular CG meeting agenda items label May 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Do not use setTimeout directly
5 participants