summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/credential-management/fedcm-network-requests.https.html
diff options
context:
space:
mode:
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.html192
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>