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

Specify "Use another account". #678

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Prev Previous commit
Next Next commit
Merge remote-tracking branch 'origin/main' into otheraccount
cbiesinger committed Mar 13, 2025
commit ccf4850b343310fa7a9041bd0881e402bae646d5
86 changes: 57 additions & 29 deletions spec/index.bs
Original file line number Diff line number Diff line change
@@ -918,30 +918,38 @@ the exception thrown.
1. Otherwise, if |mediation| is "{{CredentialMediationRequirement/silent}}", return (failure, true).
1. Otherwise, if |accountsList|'s size is 1:
1. Set |account| to |accountsList|[0].
1. If [=compute the connection status=] of |account|, |provider| and |globalObject| returns
1. If [=compute the connection status=] of |account|, |provider|, and |globalObject| returns
[=compute the connection status/connected=]:
1. Show a dialog to request user permission to sign in via |account|, and set the result
in |permission|. The user agent MAY use |options|'s
{{IdentityCredentialRequestOptions/context}} and |options|'s
{{IdentityCredentialRequestOptions/mode}} to customize the dialog.
{{IdentityCredentialRequestOptions/mode}} to customize the
dialog.
1. If |modeSettings|.{{IdentityProviderModeSettings/supports_use_other_account}} is true,
that dialog MUST provide an affordance to use another account. If that
affordance is triggered:
1. [=Show an IDP login dialog=] with |config|, |provider|, and |globalObject|.
1. If that returned success, go back to the [=fetch accounts step=].
1. Otherwise, let |permission| be the result of running [=request permission to sign-up=]
algorithm with |account|, |modeSettings|, |config|, |provider|, and
|globalObject|. Also set |disclosureTextShown| to true.
|globalObject|. Also set |permissionRequested| to true if the user
agent [=supports showing a permission prompt=].
1. Otherwise:
1. Set |account| to the result of running [=select an account=] with
|accountsList|, |modeSettings|, |config|, |provider|, and |globalObject|.
1. If |account| is failure, return (failure, true).
1. If [=compute the connection status=] of |account|, |provider|, and |globalObject|
is [=compute the connection status/connected=], set |permission| to true.
1. If [=compute the connection status=] of |account|, |provider|, and |globalObject| is
[=compute the connection status/connected=], set |permission| to true.
1. Otherwise, if |provider|.{{IdentityProviderRequestOptions/fields}} is [=list/empty=],
[=create a connection between the RP and the IdP account=] with |provider|, |account|,
and |globalObject|, and set |permission| to true.

Note: The connection would normally be created in the [=request permission to sign-up=]
algorithm, but we do not want to show an extra dialog in this case.
1. Otherwise:
1. Let |permission| be the result of running the [=request permission to sign-up=]
algorithm with |account|, |modeSettings|, |config|, |provider|, and |globalObject|.
1. Set |disclosureTextShown| to true.
1. Set |permissionRequested| to true.
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.
@@ -1132,6 +1140,7 @@ dictionary IdentityProviderAPIConfig {
USVString disconnect_endpoint;
IdentityProviderBranding branding;
IdentityProviderModes modes;
USVString account_label;
};
</xmp>

@@ -1404,11 +1413,12 @@ The <a>request permission to sign-up</a> algorithm fetches the [=client metadata
waits for the user to grant permission to use the given account, and returns whether the user
granted permission or not.

<div algorithm>
To <dfn>request permission to sign-up</dfn> the user with a given an {{IdentityProviderAccount}}
|account|, some {{IdentityProviderModeSettings}} |modeSettings|, an {{IdentityProviderAPIConfig}}
|config|, an {{IdentityProviderRequestOptions}} |provider|, and a |globalObject|, run the following
steps. This returns a boolean.
<div algorithm="request permission to sign-up">
To <dfn>request permission to sign-up</dfn> the user with a given an {{IdentityProviderAccount}} |account|,
some {{IdentityProviderModeSettings}} |modeSettings|, an
{{IdentityProviderAPIConfig}} |config|, an {{IdentityProviderRequestOptions}}
|provider|, and a |globalObject|, run the following steps. This returns a
boolean.
1. Assert: These steps are running [=in parallel=].
Copy link
Contributor

Choose a reason for hiding this comment

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

The parallel steps would be better presented as bullets (which might bullets within a numbered step), rather than as numbered steps. As this stands, I am unsure exactly which steps are running in parallel.

Copy link

Choose a reason for hiding this comment

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

This would not be correct. Please check the definition of "in parallel": https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel

Copy link
Contributor

Choose a reason for hiding this comment

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

The definition of "in parallel" is not sufficient for me (and I have some familiarity with the subject) to know whether the numbered steps (1)-(20) of which this Assert is (1) are to run in parallel with each other (which appears possible, and indeed, the most likely meaning) or that this sequence of 20 steps is to occur in parallel with other operations (sequences, single steps, etc.) in the spec.

Presuming that one goal of writing this specification is to have it be comprehensible by readers who are new to the subject, I suggest that some rewording would be helpful.

Copy link

Choose a reason for hiding this comment

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

A PR to the HTML spec is welcome, but I think it's pretty clear personally:

means those steps are to be run, one after another

Copy link
Contributor

Choose a reason for hiding this comment

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

"In parallel" does not mean "in sequence", no matter what spec is written as if it does.

Also, I highly doubt that most readers of this spec will go to the HTML spec, so while I may well submit a PR there (if I can find where to do so; it wasn't obvious when I looked for it yesterday), I think it better to provide more clarity in the FedCM spec.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For better or worse, "in parallel" is an existing term in specland. Ted, do you have a specific suggestion for how to improve this?

In general we should assume that readers either know what these terms mean or click through to their definition, IMO.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

(https://github.com/whatwg/html/blob/main/source is where you would send PRs for the HTML spec)

Copy link
Contributor

@TallTed TallTed Nov 25, 2024

Choose a reason for hiding this comment

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

Unfortunately, GitHub's web interface (my primary tool) can't handle docs the size of that WHATWG source. But, I was able to view it, and noted the "parallel queue".

<p>A <dfn export>parallel queue</dfn> represents a queue of algorithm steps that must be run in 
series.</p>

I think that's a more apt description of this 20-step sequence. Something like

Suggested change
1. Assert: These steps are running [=in parallel=].
1. Assert: These steps comprise a [=parallel queue=] that should run [=in parallel=] with any other active algorithms and/or [=parallel queues=].

(That does presume that plurals of defined terms are properly handled; the last might need change from [=parallel queues=] to [=parallel queue=].)

I've added a note to whatwg/html#10049, but noting that they have 1923 open issues and 169 pending pull requests, I don't have high hopes of it being addressed in a timely fashion.

Copy link
Contributor

Choose a reason for hiding this comment

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

@domenic — Your thumb-down emoji doesn't communicate even as well as the "in parallel" that is meant to be understood as some language other than English. If you have an argument against my points, please do me the courtesy of writing it out.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am at a loss. @domenic, you are not participating usefully. Please refrain from emoting unexplained "thumb down". If you have an argument against what I've said, please put into words, so I and others can consider your point(s) against my own.

1. Let |fields| be |provider|.{{IdentityProviderRequestOptions/fields}} or, if not present,
`["name", "email", "picture"]`.
@@ -1418,24 +1428,42 @@ steps. This returns a boolean.
1. If |fields| is not [=list/empty=], set |metadata| to the result of running [=fetch the client
metadata=] with |config|, |provider|, and |globalObject|.
1. Prompt the user to gather explicit intent to create an account. The user agent MAY use the
{{IdentityProviderBranding}} to inform the style choices of its UI. Additionally:
1. If |metadata| is not failure, |metadata|["{{IdentityProviderClientMetadata/privacy_policy_url}}"]
is defined and the |provider|'s {{IdentityProviderConfig/clientId}} is not in the list of
|account|["{{IdentityProviderAccount/approved_clients}}"], then the user agent MUST display
the |metadata|["{{IdentityProviderClientMetadata/privacy_policy_url}}"] link.
1. If |metadata| is not failure, |metadata|["{{IdentityProviderClientMetadata/terms_of_service_url}}"]
is defined, and the |provider|'s {{IdentityProviderConfig/clientId}} is not in the list of
|account|["{{IdentityProviderAccount/approved_clients}}"], then the user agent MUST display
the |metadata|["{{IdentityProviderClientMetadata/terms_of_service_url}}"] link.
1. The user agent MAY use the
{{IdentityCredentialRequestOptions/context}} and |options|'s
{{IdentityCredentialRequestOptions/mode}} to customize the dialog shown.
1. If |modeSettings|.{{IdentityProviderModeSettings/supports_use_other_account}} is true,
the account chooser MUST provide an affordance to use another account unless such an
affordance was provided in a previous step (e.g., if [=select an account=] was
invoked). If that affordance is triggered:
1. [=Show an IDP login dialog=] with |config|, |provider|, and |globalObject|.
1. If that returned success, go back to the [=fetch accounts step=].
{{IdentityProviderBranding}} to inform the style choices of its UI. Additionally, if the user agent
<dfn>supports showing a permission prompt</dfn>:

Note: Identity providers should support showing their own permission prompt using
{{IdentityAssertionResponse/continue_on}} when the `disclosure_shown_for` parameter
does not contain the fields required by the IDP. This is to enable user agents that
do not support showing a permission prompt.

1. If |fields| is not [=list/empty=]:
1. If |metadata| is not failure, |metadata|["{{IdentityProviderClientMetadata/privacy_policy_url}}"]
is defined, and the |provider|'s {{IdentityProviderConfig/clientId}} is not in the list of
|account|["{{IdentityProviderAccount/approved_clients}}"], then the user agent MUST display
the |metadata|["{{IdentityProviderClientMetadata/privacy_policy_url}}"] link.
1. If |metadata| is not failure, |metadata|["{{IdentityProviderClientMetadata/terms_of_service_url}}"]
is defined, and the |provider|'s {{IdentityProviderConfig/clientId}} is not in the list of
|account|["{{IdentityProviderAccount/approved_clients}}"], then the user agent MUST display
the |metadata|["{{IdentityProviderClientMetadata/terms_of_service_url}}"] link.
1. The user agent MUST prompt the user for permission to share the data in |fields|,
interpreting the strings in the <dfn>list of recognized fields</dfn> as follows:
: `"name"`
:: The user's name as given in {{IdentityProviderAccount}}.{{IdentityProviderAccount/name}}.
: `"email"`
:: The user's email address as given in {{IdentityProviderAccount}}.{{IdentityProviderAccount/email}}.
: `"picture"`
:: The user's profile picture as given in {{IdentityProviderAccount}}.{{IdentityProviderAccount/picture}}.

Any other string is ignored for forwards compatibility.
1. The user agent MAY use the
{{IdentityCredentialRequestOptions/context}} and |provider|'s
{{IdentityCredentialRequestOptions/mode}} to customize the dialog shown.
1. If |modeSettings|.{{IdentityProviderModeSettings/supports_use_other_account}} is true,
the account chooser MUST provide an affordance to use another account unless such an
affordance was provided in a previous step (e.g., if [=select an account=] was
invoked). If that affordance is triggered:
1. [=Show an IDP login dialog=] with |config|, |provider|, and |globalObject|.
1. If that returned success, go back to the [=fetch accounts step=].
1. If the user does not grant permission, return false.
1. Return true.
</div>
You are viewing a condensed version of this merge commit. You can view the full changes here.