summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/cross-origin-embedder-policy/credentialless/service-worker-coep-credentialless-proxy.https.window.js
blob: 8ffea043259b3b97ba12394f0257bd907aed4a65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// META: script=/common/get-host-info.sub.js
// META: script=/common/utils.js
// META: script=/common/dispatcher/dispatcher.js
// META: script=./resources/common.js
// META: script=/service-workers/service-worker/resources/test-helpers.sub.js

const same_origin = get_host_info().HTTPS_ORIGIN;
const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;

promise_test(async test => {
  const this_token_1 = token();
  const this_token_2 = token();

  // Register a COEP:credentialless ServiceWorker.
  const sw_token = token();
  const sw_url =
    executor_service_worker_path + coep_credentialless + `&uuid=${sw_token}`;
  // Executors should be controlled by the service worker.
  const scope = executor_path;
  const sw_registration =
    await service_worker_unregister_and_register(test, sw_url, scope);
  test.add_cleanup(() => sw_registration.unregister());
  await wait_for_state(test, sw_registration.installing, 'activated');

  // Configure the ServiceWorker to proxy the fetch requests. Wait for the
  // worker to be installed and activated.
  send(sw_token, `
    fetchHandler = event => {
      if (!event.request.url.includes("/proxied"))
        return;

      send("${this_token_1}", "ServiceWorker: Proxying");

      // Response with a cross-origin no-cors resource.
      const url = "${cross_origin}" + "/common/blank.html";

      event.respondWith(new Promise(async resolve => {
        try {
          let response = await fetch(url, {
            mode: "no-cors",
            credentials: "include"
          });
          send("${this_token_1}", "ServiceWorker: Fetch success");
          resolve(response);
        } catch (error) {
          send("${this_token_1}", "ServiceWorker: Fetch failure");
          resolve(new Response("", {status: 400}));
        }
      }));
    }

    await clients.claim();

    send("${this_token_1}", serviceWorker.state);
  `)
  assert_equals(await receive(this_token_1), "activated");

  // Create a COEP:credentialless document.
  const document_token = environments["document"](coep_credentialless)[0];

  // The document fetches a same-origin no-cors resource. The requests needs to
  // be same-origin to be handled by the ServiceWorker.
  send(document_token, `
    try {
      const response = await fetch("/proxied", { mode: "no-cors", });

      send("${this_token_2}", "Document: Fetch success");
    } catch (error) {
      send("${this_token_2}", "Document: Fetch error");
    }
  `);

  // The COEP:credentialless ServiceWorker is able to handle the cross-origin
  // no-cors request, requested with credentials.
  assert_equals(await receive(this_token_1), "ServiceWorker: Proxying");
  assert_equals(await receive(this_token_1), "ServiceWorker: Fetch success");

  // The COEP:credentialless Document is allowed by CORP to get it.
  assert_equals(await receive(this_token_2), "Document: Fetch success");

  // test.add_cleanup doesn't allow waiting for a promise. Unregistering a
  // ServiceWorker is an asynchronous operation. It might not be completed on
  // time for the next test. Do it here for extra flakiness safety.
  await sw_registration.unregister()
}, "COEP:credentialless ServiceWorker");