-
Notifications
You must be signed in to change notification settings - Fork 73
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
Add the IDP sign-in status API to the spec #436
Changes from all commits
e2f48cc
8304968
465c717
896e95d
07eb407
8948f99
f19c445
663f421
090262d
d682586
9557220
0c154cb
d932e3f
f128898
71083c8
3fbe365
238fdf4
13ca4f7
4db1336
0c77ac9
afe7360
ddb3f24
2098134
5b091a0
6a38c4b
654908f
652b436
fb02431
d70fa1f
620848c
b6b9be3
436ee85
3c8eb4a
04e7156
99147b3
e7ab849
1fbab48
7f6eef5
0f0c4fe
e80e54a
bf30c3d
49fe2ad
2133a0b
d28201f
0d55b05
60cdb08
48e4d1a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -40,6 +40,9 @@ spec: webdriver; urlPrefix: https://w3c.github.io/webdriver/ | |||||
text: no such alert; url: dfn-no-such-alert | ||||||
text: error code; url: dfn-error-code | ||||||
text: validating capabilities; url: dfn-validate-capabilities | ||||||
spec: webappsec-fetch-metadata; urlPrefix: https://w3c.github.io/webappsec-fetch-metadata/ | ||||||
type: dfn | ||||||
text: Directly User-Initiated Requests; url: directly-user-initiated | ||||||
</pre> | ||||||
|
||||||
<pre class=link-defaults> | ||||||
|
@@ -49,6 +52,7 @@ spec:html; type:dfn; for:environment settings object; text:global object | |||||
spec:html; type:dfn; for:html-origin-def; text:origin | ||||||
spec:webidl; type:dfn; text:resolve | ||||||
spec:webdriver2; type:dfn; text:error | ||||||
spec:fetch; type:dfn; for:/; text:response | ||||||
</pre> | ||||||
|
||||||
<style> | ||||||
|
@@ -314,6 +318,130 @@ value (which is used when a resource loaded as a third-party, not first-party). | |||||
for an [=IDP=] to adopt the FedCM API. It doesn't introduce security issues on the API because the | ||||||
[=RP=] cannot inspect the results from the fetches in any way. | ||||||
|
||||||
<!-- ============================================================ --> | ||||||
## The Login Status API ## {#browser-api-login-status} | ||||||
<!-- ============================================================ --> | ||||||
|
||||||
### Login Status Map ### {#hdr-login-status-map} | ||||||
|
||||||
Each [=user agent=] keeps a global, persistent <dfn>Login Status | ||||||
cbiesinger marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
map</dfn>, an initially empty [=map=]. The [=map/keys=] in this map are | ||||||
[=/origin=] (of [=IDPs=]), and the [=map/values=] are enums that can be one of | ||||||
"<dfn><code>unknown</code></dfn>", "<dfn><code>logged-in</code></dfn>", | ||||||
and "<dfn><code>logged-out</code></dfn>". | ||||||
|
||||||
<div algorithm> | ||||||
To <dfn>get the login status</dfn> for an [=/origin=] |origin|: | ||||||
1. If [=Login Status map=][|origin|] exists, return it. | ||||||
1. Otherwise, return [=unknown=]. | ||||||
|
||||||
</div> | ||||||
|
||||||
<div algorithm> | ||||||
To <dfn>set the login status</dfn> for an [=/origin=] |origin| to | ||||||
value |value|: | ||||||
1. Assert that |value| is one of [=logged-in=] or [=logged-out=]. | ||||||
1. [=map/Set=] [=Login Status map=][|origin|] to |value|. | ||||||
|
||||||
</div> | ||||||
|
||||||
### HTTP header API ### {#login-status-http} | ||||||
|
||||||
[=IDPs=] can set the login status using an HTTP [=response=] [=header=] as follows. | ||||||
|
||||||
Issue: The HTTP header checking should move into the Fetch spec, since it | ||||||
affects all resource loads. | ||||||
|
||||||
For each [=http-redirect fetch=] and [=http fetch=]'s [=response=], let |value| | ||||||
be the result of [=get a structured field value=] from the response's header | ||||||
list with name "<dfn><code>Set-Login</code></dfn>" and type "`item`". If |value| is not null, | ||||||
process this header as follows: | ||||||
|
||||||
<div algorithm="process the login status header"> | ||||||
1. Let |origin| be the response's [=response/URL=]'s [=/origin=]. | ||||||
1. Let |client| be the [=/request=]'s [=request/client=]. | ||||||
1. If the request's [=request/destination=] is not `"document"`: | ||||||
1. If |client| is null, return. | ||||||
1. If |origin| is not [=same origin=] with the [=/request=]'s | ||||||
[=request/origin=], return. | ||||||
1. If |client| is not [=same-origin with its ancestors=], return. | ||||||
1. Assert that |value| is a tuple. | ||||||
1. Let |token| be the first entry of |value|. | ||||||
1. If |token| is `"logged-in"`, [=set the login status=] for |origin| | ||||||
to [=logged-in=]. | ||||||
1. If |token| is `"logged-out"`, [=set the login status=] for |origin| | ||||||
to [=logged-out=]. | ||||||
|
||||||
</div> | ||||||
|
||||||
### JavaScript API ### {#login-status-javascript} | ||||||
|
||||||
[=IDPs=] can also use a JavaScript API to update the stored login status: | ||||||
cbiesinger marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
|
||||||
<pre class="idl"> | ||||||
enum LoginStatus { | ||||||
"logged-in", | ||||||
"logged-out", | ||||||
}; | ||||||
|
||||||
[Exposed=Window, SecureContext] | ||||||
interface NavigatorLogin { | ||||||
Promise<undefined> setStatus(LoginStatus status); | ||||||
samuelgoto marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
}; | ||||||
|
||||||
partial interface Navigator { | ||||||
[SecureContext] readonly attribute NavigatorLogin login; | ||||||
}; | ||||||
</pre> | ||||||
|
||||||
<div algorithm="setStatus"> | ||||||
When {{NavigatorLogin/setStatus()}} is called with argument |status|: | ||||||
cbiesinger marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
1. If the [=current settings object=] is not [=same-origin with its ancestors=], | ||||||
throw a {{SecurityError}} {{DOMException}}. | ||||||
1. Let |origin| be the [=current settings object=]'s | ||||||
[=environment settings object/origin=]. | ||||||
1. Let |value| be [=logged-in=] if |status| is `"logged-in"` or [=logged-out=] | ||||||
if |status| is `"logged-out"`. | ||||||
1. [=Set the login status=] for |origin| to |value|. | ||||||
|
||||||
</div> | ||||||
|
||||||
### Clearing the Login Status Map data ### {#login-status-clear-data} | ||||||
|
||||||
User agents MUST also clear the [=Login Status map=] data when: | ||||||
: the user clears all cookies or site settings data | ||||||
:: The user agent MUST clear the entire map. | ||||||
: the user clears all cookies or all site data for a specific origin | ||||||
:: The user agent MUST remove all entries that would be affected | ||||||
by the deleted cookies, that is, any entry with an origin | ||||||
to which a deleted cookie could be sent to. | ||||||
|
||||||
Note: For example, domain cookies may affect subdomains of | ||||||
the deleted origin, e.g. clearing cookies for `google.com` | ||||||
should also reset the login status for `accounts.google.com`, | ||||||
since it may rely on a domain cookie for google.com. | ||||||
: the user deletes individual cookies (if allowed by the user agent) | ||||||
:: the behavior is user agent-defined. | ||||||
|
||||||
Note: The user agent MAY want to reset the state to [=unknown=], | ||||||
since is impossible to know whether this cookie affects | ||||||
authorization state. | ||||||
: the user agent receives a <a http-header>Clear-Site-Data</a> header with a | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if this is sent from a subresource or iframe that does not match the top-level? I was trying to find an answer in Clear-Site-Data and it seems the spec is not updated at all to account for any sort of partitioning, but maybe we can at least add an issue to make sure we handle that at some point... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm. I found w3c/webappsec-clear-site-data#72... updated this wording. |
||||||
value of `"cookies"` or `"*"`, and the [=/request=]'s [=request/client=] is | ||||||
not null, and the client's [=environment settings object/origin=] is [=same | ||||||
origin=] with the [=top-level origin=] | ||||||
:: while [$clear cookies for origin|clearing cookies for | ||||||
origin$] it MUST remove any entries in the [=Login Status Map=] where | ||||||
the [=map/key=] is the input origin. | ||||||
|
||||||
Issue: Once Clear-Site-Data [supports partitioned cookies](https://github.com/w3c/webappsec-clear-site-data/issues/72), | ||||||
this wording should be updated. | ||||||
|
||||||
Note: Other website-initiated cookie changes should not affect this map. When | ||||||
[=IDP=] login state changes, it should send an explicit [=Set-Login=] header. | ||||||
[=RP=] state should not affect this map since it only reflects [=IDP=] state. | ||||||
|
||||||
<!-- ============================================================ --> | ||||||
## The connected accounts set ## {#browser-connected-accounts-set} | ||||||
<!-- ============================================================ --> | ||||||
|
@@ -559,21 +687,82 @@ To <dfn>create an IdentityCredential</dfn> given an {{IdentityProviderConfig}} | |||||
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 |loginStatus| be the result of [=get the login status=] with | ||||||
the [=/origin=] of |provider|'s {{IdentityProviderConfig/configURL}}. | ||||||
1. If |loginStatus| is [=unknown=], a user agent MAY set it to [=logged-out=]. | ||||||
1. If |loginStatus| is [=logged-out=], the user agent MUST do one of the following: | ||||||
|
||||||
* Return (failure, false). | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this to allow UAs to reduce prompt spam? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes |
||||||
* Prompt the user whether to continue. If the user continues, the user | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this so that we support button flows? Or is this strictly necessarily for dealing with the timing attack? If this is only to support button flows, can't we handle this case in a separate PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added it so that the following flow works reasonably, which I think is what Firefox wants to do:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is inside the "create an IdentityCredential" algorithm: nothing happens before this, right? That is, "UA prompts user to select an IDP before it does anything" isn't captured before we get to this point, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean? The potential IDP selector is handled on (new) line 623, already existing in the spec. "create an IdentityCredential" is called by DiscoverFromExternalSource. |
||||||
agent SHOULD set |loginStatus| to [=unknown=]. This MAY include an | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Isn't this a MUST? Otherwise, how can we move forward with the algorithm if the loginStatus is 'logged-out'? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't we also have to "wait" somewhere here until the user becomes 'logged-in'? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That happens if the user triggers the affordance to "show an IDP login dialog" and is encapsulated in that algorithm. I don't think the SHOULD needs to be a MUST; the algorithm should work fine as-is, no? I left it that way because some user agents don't really want to use an unknown state. |
||||||
affordance to [=show an IDP login dialog=]. | ||||||
|
||||||
* If the user cancels this dialog, return (failure, true). | ||||||
* If the user triggers this affordance: | ||||||
1. Let |config| be the result of running [=fetch the config file=] | ||||||
with |provider| and |globalObject|. | ||||||
1. If |config| is failure, return (failure, true). | ||||||
1. [=Show an IDP login dialog=] with |config|. | ||||||
1. If that algorithm returns failure, return (failure, true). | ||||||
|
||||||
Issue: We should perhaps provide a way to let the [=RP=] request that | ||||||
the second option is provided, possibly gated on a user gesture. | ||||||
See [this issue](https://github.com/fedidcg/FedCM/issues/442) for discussion. | ||||||
1. Let |requiresUserMediation| be |provider|'s {{IdentityProviderConfig/configURL}}'s [=/origin=]'s | ||||||
[=requires user mediation=]. | ||||||
1. Let |mediation| be |options|'s {{CredentialRequestOptions/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|. | ||||||
"{{CredentialMediationRequirement/silent}}", return (failure, true). | ||||||
1. Let |config| be the result of running [=fetch the config file=] with | ||||||
|provider| and |globalObject|. | ||||||
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. <dfn>Fetch accounts list step</dfn>: Let |accountsList| be the result of | ||||||
[=fetch the accounts list=] with |config|, |provider|, and |globalObject|. | ||||||
1. If |accountsList| is failure, or the size of |accountsList| is 0: | ||||||
1. [=Set the login status=] for the [=/origin=] of the | ||||||
{{IdentityProviderConfig/configURL}} to [=logged-out=]. | ||||||
A user agent may decide to skip this step if no credentials were | ||||||
sent to server. | ||||||
|
||||||
Note: For example, if the fetch failed due to a DNS error, no | ||||||
credentials were sent and therefore the [=IDP=] did not learn | ||||||
the user's identity. In this situation, we do not know whether | ||||||
the user is signed in or not and so we may not want to reset | ||||||
cbiesinger marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
the status. | ||||||
1. <dfn>Mismatch dialog step</dfn>: If |loginStatus| is [=logged-in=], show a | ||||||
dialog to the user. The contents of this dialog are defined by the user | ||||||
agent. This dialog SHOULD provide an affordance for the user to trigger | ||||||
the [=show an IDP login dialog=] algorithm with |config|; this dialog | ||||||
is the <dfn>confirm IDP login dialog</dfn>. | ||||||
|
||||||
Note: This situation happens when the browser expects the user | ||||||
to be signed in, but the accounts fetch indicated that the user | ||||||
is signed out. | ||||||
|
||||||
Note: This dialog ensures that silent tracking of the user is | ||||||
impossible by always showing UI of some kind when credentials | ||||||
were sent to the server. | ||||||
|
||||||
1. Wait until one of the following occurs: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this need to be a substep of the mismatch dialog step? Or can it just be step 3 (the step after) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it needs to be a substep, because all of this only happens if loginStatus is logged-in. |
||||||
|
||||||
* If the user closes the dialog, return (failure, true). | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does this return failure immediately? This allows a user-visible read of the logged in bit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure I understand, since this requires the user to do something the timing is effectively random, indistinguishable from the delayed promise rejection? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rejecting in a user-specified time is different than rejecting after a fixed 120s. So by seeing a rejection before that point, the IDP can determine they were not "logged-in". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, as of c8609ec the 120s has been replaced with a random timer. |
||||||
|
||||||
* If the [=show an IDP login dialog=] algorithm was triggered: | ||||||
|
||||||
1. Let |result| be the result of that algorithm. | ||||||
1. If |result| is failure, return (failure, true). The user | ||||||
agent MAY show a dialog to the user before or after | ||||||
returning failure indicating this failure. | ||||||
1. Otherwise, go back to the [=fetch accounts list step=]. | ||||||
|
||||||
1. Assert: |accountsList| is not failure and the size of |accountsList| is not 0. | ||||||
1. [=Set the login status=] for the [=/origin=] of the | ||||||
{{IdentityProviderConfig/configURL}} to [=logged-in=]. | ||||||
1. If |provider|'s {{IdentityProviderConfig/loginHint}} is not empty: | ||||||
1. For every |account| in |accountList|, remove |account| from |accountList| if |account|'s | ||||||
cbiesinger marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
{{IdentityProviderAccount/login_hints}} does not [=list/contain=] |provider|'s | ||||||
{{IdentityProviderConfig/loginHint}}. | ||||||
1. If |accountsList| is failure, return (failure, false). | ||||||
1. If |accountList| is now empty, go to the [=mismatch dialog step=]. | ||||||
1. For each |acc| in |accountsList|: | ||||||
1. If |acc|["{{IdentityProviderAccount/picture}}"] is present, [=fetch the account picture=] | ||||||
with |acc| and |globalObject|. | ||||||
|
@@ -595,7 +784,7 @@ the exception thrown. | |||||
[=compute the connection status=] algorithm given |provider| and |account|. When doing this, | ||||||
the user agent MAY show some UI to the user indicating that they are being | ||||||
<dfn>auto-reauthenticated</dfn>. | ||||||
1. Otherwise, if |mediation| is "{{CredentialMediationRequirement/silent}}", return failure. | ||||||
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. Set |accountState| to the result of running the [=compute the connection status=] algorithm | ||||||
|
@@ -732,6 +921,9 @@ or failure. | |||||
1. [=converted to an IDL value|Convert=] |json| to an {{IdentityProviderAPIConfig}} stored | ||||||
in |config|. | ||||||
1. If one of the previous two steps threw an exception, set |config| to failure. | ||||||
1. Set |config|.{{IdentityProviderAPIConfig/login_url}} to the result of [=computing | ||||||
the manifest URL=] with |provider|, |config| and |globalObject|. | ||||||
1. If |config|.{{IdentityProviderAPIConfig/login_url}} is null, return failure. | ||||||
1. Wait for both |config| and |configInWellKnown| to be set. | ||||||
1. If |configInWellKnown| is true, return |config|. Otherwise, return failure. | ||||||
</div> | ||||||
|
@@ -765,6 +957,7 @@ dictionary IdentityProviderAPIConfig { | |||||
required USVString accounts_endpoint; | ||||||
required USVString client_metadata_endpoint; | ||||||
required USVString id_assertion_endpoint; | ||||||
required USVString login_url; | ||||||
IdentityProviderBranding branding; | ||||||
}; | ||||||
</xmp> | ||||||
|
@@ -1123,6 +1316,31 @@ and a |responseBody|, run the following steps. This returns an [=ordered map=]. | |||||
1. Return |json|. | ||||||
</div> | ||||||
|
||||||
<div algorithm> | ||||||
To <dfn>show an IDP login dialog</dfn> given an {{IdentityProviderAPIConfig}} |config|, run | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This algorithm doesn't work for redirect login flows, correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should work for same-origin redirects since all that is required is that the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I meant for instances where the login dialog is in the same navigatable, and then navigate the user back to this page. I think I remember that being out of scope here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not positive I understand you correctly but I think that's out of scope yeah There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess this refers to flow that require cross origin navigation, for technical reasons or cases with authentication intermediaries which are currently not properly covered by this |
||||||
the following steps. This returns success or failure. | ||||||
1. [=Create a fresh top-level traversable=] with URL | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if the URL is null? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a validation step to fetching the config file to ensure that signin_url is also valid here. I also think that this represents the desired semantics better (don't accept the config file if there is no login_url even if login_url is not triggered during this specific request) |
||||||
|config|.{{IdentityProviderAPIConfig/login_url}}. | ||||||
1. The user agent MAY [=set up browsing context features=] or otherwise | ||||||
affect the presentation of this traversable in an implementation-defined | ||||||
way. | ||||||
1. Wait for one of the following conditions: | ||||||
* The user closes the browsing context: return failure. | ||||||
* {{IdentityProvider}}.{{IdentityProvider/close}} is called in the | ||||||
context of this new traversable: | ||||||
1. Close the traversable. | ||||||
1. Let |loginStatus| be the result of [=get the login status=] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, this is a bit weird in the implementation. Because we do not know whether we process the header before the idp.close, we allow header processing to also work. But I guess the spec is sync enough that it's not possible... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the spec is conceptually better than the impl; maybe we can do things better in our impl... |
||||||
with the [=/origin=] of the {{IdentityProviderAPIConfig/login_url}}. | ||||||
|
||||||
Note: The IDP login flow may set this value to logged-in using | ||||||
either the [[#login-status-javascript|JavaScript]] or | ||||||
[[#login-status-http|HTTP header]] API during the login | ||||||
flow. It is also possible that this change happened in | ||||||
a different browsing context. | ||||||
1. If |loginStatus| is [=logged-in=], return success. | ||||||
1. Otherwise, return failure. | ||||||
samuelgoto marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
</div> | ||||||
|
||||||
<!-- ============================================================ --> | ||||||
## The IdentityProvider Interface ## {#browser-api-identity-provider-interface} | ||||||
<!-- ============================================================ --> | ||||||
|
@@ -1139,13 +1357,23 @@ This specification introduces the {{IdentityUserInfo}} dictionary as well as the | |||||
}; | ||||||
|
||||||
[Exposed=Window, SecureContext] interface IdentityProvider { | ||||||
static undefined close(); | ||||||
static Promise<sequence<IdentityUserInfo>> getUserInfo(IdentityProviderConfig config); | ||||||
}; | ||||||
</pre> | ||||||
|
||||||
Issue: [Decide](https://github.com/fedidcg/FedCM/issues/476) whether {{IdentityProvider}} is the | ||||||
correct location for the {{IdentityProvider/getUserInfo()}} method. | ||||||
|
||||||
A {{IdentityProvider/close}} function is provided to signal to the browser that | ||||||
the login flow is finished. The reason for this function in addition to the | ||||||
header is that even when the user is already logged in, the login flow may not | ||||||
be finished yet; for example, an [=IDP=] may want to prompt the user to verify | ||||||
their phone number. To allow for such flows, the [=IDP=] must call | ||||||
{{IdentityProvider/close}} when the flow is fully done. | ||||||
|
||||||
See the [=show an IDP login dialog=] algorithm for more details. | ||||||
|
||||||
An {{IdentityUserInfo}} represents user account information from a user. This information is exposed | ||||||
to the [=IDP=] once the user has already used the FedCM API to login in the [=RP=]. That is, it is | ||||||
exposed when there exists an account |account| such that the [=connected accounts set=] [=list/contains=] | ||||||
|
@@ -1754,6 +1982,36 @@ The [=remote end steps=] are: | |||||
|
||||||
1. Return [=success=] with data `null`. | ||||||
|
||||||
## Confirm IDP login ## {#webdriver-confirmidplogin} | ||||||
|
||||||
<figure id="table-webdriver-confirmidplogin" class="table"> | ||||||
<table class="data"> | ||||||
<thead> | ||||||
<tr> | ||||||
<th>HTTP Method</th> | ||||||
<th>URI Template</th> | ||||||
</tr> | ||||||
</thead> | ||||||
<tbody> | ||||||
<tr> | ||||||
<td>POST</td> | ||||||
<td>`/session/{session id}/fedcm/confirmidplogin`</td> | ||||||
</tr> | ||||||
</tbody> | ||||||
</table> | ||||||
</figure> | ||||||
|
||||||
The [=remote end steps=] are: | ||||||
|
||||||
1. If no FedCM dialog is currently open, or the dialog is not a [=confirm IDP | ||||||
login dialog=] return a [=error|WebDriver error=] with [=error code=] | ||||||
[=no such alert=]. | ||||||
|
||||||
1. Act as if the user had clicked the "continue" button in the dialog and | ||||||
initiate the login flow. | ||||||
|
||||||
1. Return [=success=] with data `null`. | ||||||
|
||||||
## Account list ## {#webdriver-accountlist} | ||||||
|
||||||
<figure id="table-webdriver-accountlist" class="table"> | ||||||
|
@@ -1865,7 +2123,8 @@ The [=remote end steps=] are: | |||||
[=error code=] [=no such alert=]. | ||||||
|
||||||
1. Let |type| be a string that is "`AutoReauthn`" if the user is being [=auto-reauthenticated=], | ||||||
or "`AccountChooser`" otherwise. | ||||||
or "`AccountChooser`" is the dialog is an account chooser, or "`ConfirmIdpLogin`" if the | ||||||
dialog is a [=confirm IDP login dialog=]. | ||||||
|
||||||
1. Return [=success=] with data |type|. | ||||||
|
||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be necessary... are you sure it's needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I got a warning from bikeshed without it (it was ambiguous. Bikeshed actually picked the right one, but it seemed better not to rely on that)