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 the fields API #668

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
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
101 changes: 78 additions & 23 deletions spec/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ dictionary IdentityProviderRequestOptions : IdentityProviderConfig {
USVString nonce;
DOMString loginHint;
DOMString domainHint;
sequence<USVString> fields;
any params;
};
</xmp>
Expand Down Expand Up @@ -888,7 +889,7 @@ the exception thrown.
1. For each |acc| in |accountsList|:
1. If |acc| is [=eligible for auto reauthentication=] given |provider|, and |globalObject|,
set |registeredAccount| to |acc| and increase |numRegisteredAccounts| by 1.
1. Let |permission|, |disclosureTextShown|, and |isAutoSelected| be set to false.
1. Let |permission|, |permissionRequested|, and |isAutoSelected| be set to false.
npm1 marked this conversation as resolved.
Show resolved Hide resolved
1. If |mediation| is not "{{CredentialMediationRequirement/required}}", |requiresUserMediation|
is false, and |numRegisteredAccounts| is equal to 1:
1. Set |account| to |registeredAccount| and |permission| to true. When doing this, the user
Expand All @@ -898,30 +899,36 @@ 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=], 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.
1. Otherwise, let |permission| be the result of running [=request permission to sign-up=]
algorithm with |account|, |config|, |provider|, and |globalObject|. Also set
|disclosureTextShown| to true.
|permissionRequested| to true if the user agent [=supports showing a permission prompt=].
1. Otherwise:
1. Set |account| to the result of running the [=select an account=] from the
|accountsList|.
1. If |account| is failure, return (failure, true).
1. If [=compute the connection status=] of |account|, |provider| and |globalObject| is
cbiesinger marked this conversation as resolved.
Show resolved Hide resolved
[=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|, |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.
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}}, |disclosureTextShown|, |isAutoSelected|,
|account|'s {{IdentityProviderAccount/id}}, |permissionRequested|, |isAutoSelected|,
|provider|, |config|, and |globalObject|.
1. Return |credential|.
</div>
Expand Down Expand Up @@ -1229,18 +1236,37 @@ the token that will be provided to the [=RP=].

<div algorithm>
To <dfn>fetch an identity assertion</dfn> given a {{USVString}}
|accountId|, a boolean |disclosureTextShown|, a boolean |isAutoSelected|, an
|accountId|, a boolean |permissionRequested|, a boolean |isAutoSelected|, an
{{IdentityProviderRequestOptions}} |provider|, an {{IdentityProviderAPIConfig}} |config|,
and |globalObject|, run the following steps. This returns an {{IdentityCredential}} or failure.
1. Let |tokenUrl| be the result of [=computing the manifest URL=] given |provider|,
|config|["{{IdentityProviderAPIConfig/id_assertion_endpoint}}"], and |globalObject|.
1. If |tokenUrl| is failure, return failure.
1. Let |disclosureShownFor| and |fields| be the empty list.
1. If |permissionRequested| is true:
1. Set |fields| to |provider|.{{IdentityProviderRequestOptions/fields}}.
1. Set |disclosureShownFor| to the subset of strings in |fields| that are
in the [=list of recognized fields=].
1. Let |list| be a list with the following entries:
1. ("client_id", |provider|'s {{IdentityProviderConfig/clientId}})
1. ("nonce", |provider|'s {{IdentityProviderRequestOptions/nonce}})
1. ("account_id", |accountId|)
1. ("disclosure_text_shown", |disclosureTextShown|)
1. ("is_auto_selected", |isAutoSelected|)
1. If |fields| is not empty:
1. Let |fieldsString| be the entries of |fields| concatenated with a comma ("`,`")
between elements.
1. Append ("fields", |fieldsString|) to |list|.
1. If |disclosureShownFor| is not empty:
1. Let |disclosureString| be the entries of |disclosureShownFor| concatenated
with a comma ("`,`") between elements.
1. Append ("disclosure_shown_for", |disclosureString|) to |list|.
1. If |disclosureShownFor| contains all of "name", "email", and "picture", append
npm1 marked this conversation as resolved.
Show resolved Hide resolved
("disclosure_text_shown", true) to |list|.

Note: This parameter exists for backwards compatibility with older identity providers
that do not yet support `disclosure_shown_for`. At the time, the disclosure text,
if shown, always included name, email, and picture. Newer identity providers should
instead check `disclosure_shown_for`.
1. If |provider|'s {{IdentityProviderRequestOptions/params}} is not empty:
1. Let |json| be the result of [=serializing a JavaScript value to a JSON string=]
with |provider|'s {{IdentityProviderRequestOptions/params}}.
Expand Down Expand Up @@ -1338,26 +1364,49 @@ 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>
<div algorithm="request permission to sign-up">
To <dfn>request permission to sign-up</dfn> the user with a given an {{IdentityProviderAccount}} |account|,
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=].
1. Let |metadata| be the result of running [=fetch the client metadata=] with |config|,
|provider|, and |globalObject|.
1. Let |fields| be |provider|.{{IdentityProviderRequestOptions/fields}} or, if not present,
`["name", "email", "picture"]`.

Note: Omitted is different from an explicitly present empty list.
1. Let |metadata| be null.
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.
{{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 support user agents that
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: support galore, use synonym sometimes?

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
does not contain the fields required by the IDP. This is to support user agents that
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}}"]
cbiesinger marked this conversation as resolved.
Show resolved Hide resolved
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 |options|'s
{{IdentityCredentialRequestOptions/mode}} to customize the dialog shown.
1. If the user does not grant permission, return false.
1. Return true.
</div>
Expand Down Expand Up @@ -2024,6 +2073,12 @@ It will also contain the following parameters in the request body `application/x
with rp.example"), used by the [=request permission to sign-up=] algorithm for new users. It
is used as an assurance by the user agent to the [=IDP=] that it has indeed shown the terms
of service and privacy policy to the user in the cases where it is required to do so.
: <dfn>fields</dfn>
:: The list of fields that the [=RP=] has requested in {{IdentityProviderRequestOptions/fields}}.
: <dfn>disclosure_shown_for</dfn>
:: The list of fields that the user was prompted for. This can be a subset of
{{IdentityProviderRequestOptions/fields}} if a field is requested that is not in the [=list
of recognized fields=].
</dl>

For example:
Expand All @@ -2036,7 +2091,7 @@ Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
account_id=123&client_id=client1234&nonce=Ct60bD&disclosure_text_shown=true
account_id=123&client_id=client1234&nonce=Ct60bD&disclosure_text_shown=true&fields=name,email,picture&disclosure_shown_for=name,email,picture
```
</div>

Expand Down
Loading