diff options
Diffstat (limited to 'testing/web-platform/tests/credential-management/fedcm-network-requests.https.html')
-rw-r--r-- | testing/web-platform/tests/credential-management/fedcm-network-requests.https.html | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/testing/web-platform/tests/credential-management/fedcm-network-requests.https.html b/testing/web-platform/tests/credential-management/fedcm-network-requests.https.html new file mode 100644 index 0000000000..ebcf61ba18 --- /dev/null +++ b/testing/web-platform/tests/credential-management/fedcm-network-requests.https.html @@ -0,0 +1,192 @@ +<!DOCTYPE html> +<title>Federated Credential Management API network request tests.</title> +<link rel="help" href="https://fedidcg.github.io/FedCM"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> + +<body> + +<script type="module"> +import {default_request_options, + default_alt_request_options, + fedcm_test, + select_manifest, + set_fedcm_cookie} from './support/fedcm-helper.sub.js'; + +function loadUrlInIframe(url) { + let iframe = document.createElement("iframe"); + return new Promise(resolve => { + iframe.src = url; + iframe.onload = function() { resolve(iframe); }; + document.body.appendChild(iframe); + }); +} + +fedcm_test(async t => { + const cred = await navigator.credentials.get(default_request_options()); + assert_equals(cred.token, "token"); +}, "Successfully obtaining token should resolve the promise."); + +fedcm_test(async t => { + const first = navigator.credentials.get(default_request_options()); + const second = navigator.credentials.get(default_alt_request_options()); + + // We have to call promise_rejects_dom here, because if we call it after + // the promise gets rejected, the unhandled rejection event handler is called + // and fails the test even if we handle the rejection later. + const rej = promise_rejects_dom(t, 'AbortError', second); + + const first_cred = await first; + assert_equals(first_cred.token, "token"); + + return rej; +}, +"When there's a pending request, a second `get` call should be rejected. "); + +fedcm_test(async t => { + let test_options = default_request_options(); + test_options.identity.providers = []; + const cred = navigator.credentials.get(test_options); + return promise_rejects_js(t, TypeError, cred); +}, "Reject when provider list is empty"); + +fedcm_test(async t => { + let test_options = default_request_options(); + delete test_options.identity.providers[0].configURL; + const cred = navigator.credentials.get(test_options); + return promise_rejects_js(t, TypeError, cred); +}, "Reject when configURL is missing" ); + +fedcm_test(async t => { + let test_options = default_request_options(); + test_options.identity.providers[0].configURL = 'test'; + const cred = navigator.credentials.get(test_options); + return promise_rejects_dom(t, "InvalidStateError", cred); +}, "Reject when configURL is invalid"); + +fedcm_test(async t => { + let test_options = default_request_options(); + test_options.identity.providers[0].clientId = ''; + const cred = navigator.credentials.get(test_options); + return promise_rejects_dom(t, "InvalidStateError", cred); +}, "Reject when clientId is empty"); + +fedcm_test(async t => { + let test_options = default_request_options(); + assert_true("nonce" in test_options.identity.providers[0]); + delete test_options.identity.providers[0].nonce; + const cred = await navigator.credentials.get(test_options); + assert_equals(cred.token, "token"); +}, "nonce is not required in FederatedIdentityProvider."); + +fedcm_test(async t => { + let test_options = default_request_options(); + delete test_options.identity.providers[0].clientId; + const cred = navigator.credentials.get(test_options); + return promise_rejects_js(t, TypeError, cred); +}, "Reject when clientId is missing" ); + +fedcm_test(async t => { + let controller = new AbortController(); + let test_options = default_request_options(); + test_options.signal = controller.signal; + const cred = navigator.credentials.get(test_options); + controller.abort(); + return promise_rejects_dom(t, 'AbortError', cred); +}, "Test the abort signal"); + +fedcm_test(async t => { + let controller = new AbortController(); + let test_options = default_request_options(); + test_options.signal = controller.signal; + const first_cred = navigator.credentials.get(test_options); + controller.abort(); + await promise_rejects_dom(t, 'AbortError', first_cred); + + const second_cred = await navigator.credentials.get(default_request_options()); + assert_equals(second_cred.token, "token"); +}, "Get after abort should work"); + +fedcm_test(async t => { + let test_options = default_request_options('manifest-not-in-list.json'); + const cred = navigator.credentials.get(test_options); + return promise_rejects_dom(t, 'NetworkError', cred); +}, 'Test that the promise is rejected if the manifest is not in the manifest list'); + +fedcm_test(async t => { + let test_options = default_request_options("manifest_redirect_accounts.json"); + await select_manifest(t, test_options); + + const cred = navigator.credentials.get(test_options); + return promise_rejects_dom(t, 'NetworkError', cred); +}, 'Test that promise is rejected if accounts endpoint redirects'); +// A malicious site might impersonate an IDP, redirecting the accounts endpoint to a +// legitimate IDP in order to get the list of user accounts. + +fedcm_test(async t => { + let test_options = default_request_options("manifest_redirect_token.json"); + await select_manifest(t, test_options); + + const cred = navigator.credentials.get(test_options); + return promise_rejects_dom(t, 'NetworkError', cred); +}, 'Test that token endpoint does not follow redirects'); +// The token endpoint should not follow redirects because the user has not consented +// to share their identity with the redirect destination. + +fedcm_test(async t => { + // Reset the client_metadata fetch count. + const clear_metadata_count_path = `support/fedcm/client_metadata_clear_count.py`; + await fetch(clear_metadata_count_path); + + const cred = await navigator.credentials.get(default_request_options()); + assert_equals(cred.token, "token"); + + await new Promise(resolve => { + let popup_window = window.open('support/fedcm/client_metadata.py?skip_checks=1'); + const popup_window_load_handler = (event) => { + popup_window.removeEventListener('load', popup_window_load_handler); + popup_window.close(); + resolve(); + }; + popup_window.addEventListener('load', popup_window_load_handler); + }); + + const client_metadata_counter = await fetch(clear_metadata_count_path); + const client_metadata_counter_text = await client_metadata_counter.text() + assert_equals(client_metadata_counter_text, "2"); +}, 'Test client_metadata request'); +// Test: +// - Headers sent to client metadata endpoint. (Counter is not incremented if the headers are +// wrong.) +// - That the client metadata response is not cached. If the client metadata response were +// cached, when the user visits the IDP as a first party, the IDP would be able to determine the +// last RP the user visited regardless of whether the user granted consent via the FedCM prompt. + +fedcm_test(async t => { + const service_worker_url = 'support/fedcm/intercept_service_worker.js'; + const sw_scope_url = '/credential-management/support/fedcm/'; + // URL for querying number of page loads observed by service worker. + const query_sw_intercepts_url = 'support/fedcm/query_service_worker_intercepts.html'; + const page_in_sw_scope_url = 'support/fedcm/simple.html'; + + const sw_registration = await service_worker_unregister_and_register( + t, service_worker_url, sw_scope_url); + t.add_cleanup(() => service_worker_unregister(t, sw_scope_url)); + await wait_for_state(t, sw_registration.installing, 'activated'); + + // Verify that service worker works. + await loadUrlInIframe(page_in_sw_scope_url); + let query_sw_iframe = await loadUrlInIframe(query_sw_intercepts_url); + assert_equals(query_sw_iframe.contentDocument.body.textContent, "1"); + + await set_fedcm_cookie(); + const cred = await navigator.credentials.get(default_request_options()); + assert_equals(cred.token, "token"); + + // Use cache buster query parameter to avoid cached response. + let query_sw_iframe2 = await loadUrlInIframe(query_sw_intercepts_url + "?2"); + assert_equals(query_sw_iframe2.contentDocument.body.textContent, "1"); +}, 'Test that service worker cannot observe fetches performed by FedCM API'); + +</script> |