Skip to content

Commit

Permalink
Clean up partitioned service worker/cookies interaction WPT
Browse files Browse the repository at this point in the history
Bug: None
Change-Id: I6ce33cd6685f00c150158e92a1fb2a231680adb5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4935871
Reviewed-by: Shuran Huang <shuuran@chromium.org>
Commit-Queue: Dylan Cutler <dylancutler@google.com>
Cr-Commit-Position: refs/heads/main@{#1210431}
  • Loading branch information
DCtheTall authored and Chromium LUCI CQ committed Oct 16, 2023
1 parent feaf2c2 commit 5efdbab
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/partitioned-cookies-test-helpers.js"></script>
</head>

<!--
This test exercises partitioned service workers' interaction with partitioned cookies.
Partitioned service workers should only be able to interact with partitioned cookies whose
partition key matches the worker's partition.
This test exercises partitioned service workers' interaction with partitioned
cookies. Partitioned service workers should only be able to interact with
partitioned cookies whose partition key matches the worker's partition.
-->

<body>
Expand All @@ -24,7 +25,8 @@
const absolute_scope = new URL(scope, window.location).href;

// Set a Partitioned cookie.
document.cookie = '__Host-partitioned=123; Secure; Path=/; SameSite=None; Partitioned;';
document.cookie =
'__Host-partitioned=123; Secure; Path=/; SameSite=None; Partitioned;';
assert_true(document.cookie.includes('__Host-partitioned=123'));

// Set an unpartitioned cookie.
Expand All @@ -35,12 +37,7 @@
await wait_for_state(t, reg.installing, 'activated');
t.add_cleanup(() => reg.unregister());

// on_message will be reassigned below based on the expected reply from the service worker.
let on_message;
self.addEventListener('message', ev => on_message(ev));
navigator.serviceWorker.addEventListener('message', evt => {
self.postMessage(evt.data, '*');
});
const next_message = worker_message_generator();

const retrieved_registrations =
await navigator.serviceWorker.getRegistrations();
Expand All @@ -49,62 +46,46 @@
const filtered_registrations =
retrieved_registrations.filter(reg => reg.scope == absolute_scope);

// First test that the worker script started correctly and message passing is enabed.
let resolve_wait_promise;
let wait_promise = new Promise(resolve => {
resolve_wait_promise = resolve;
});
let got;
on_message = ev => {
got = ev.data;
resolve_wait_promise();
};
// First test that the worker script started correctly and message passing
// is enabed.
filtered_registrations[0].active.postMessage({type: 'test_message'});
await wait_promise;
assert_true(got.ok, 'Message passing');
const msg1 = await next_message();
assert_true(msg1.ok, 'Message passing');

// Test that the partitioned cookie is available to this worker via HTTP.
wait_promise = new Promise(resolve => {
resolve_wait_promise = resolve;
});
on_message = ev => {
got = ev.data;
resolve_wait_promise();
};
filtered_registrations[0].active.postMessage({type: 'echo_cookies_http'});
await wait_promise;
assert_true(got.ok, 'Get cookies');
assert_true(got.cookies.includes('__Host-partitioned'), 'Can access partitioned cookie via HTTP');
assert_true(got.cookies.includes('unpartitioned'), 'Can access unpartitioned cookie via HTTP');
const msg2 = await next_message();
assert_true(msg2.ok, 'Get cookies');
assert_true(
msg2.cookies.includes('__Host-partitioned'),
'Can access partitioned cookie via HTTP');
assert_true(
msg2.cookies.includes('unpartitioned'),
'Can access unpartitioned cookie via HTTP');

// Test that the partitioned cookie is available to this worker via CookieStore API.
wait_promise = new Promise(resolve => {
resolve_wait_promise = resolve;
});
on_message = ev => {
got = ev.data;
resolve_wait_promise();
};
// Test that the partitioned cookie is available to this worker via
// CookieStore API.
filtered_registrations[0].active.postMessage({type: 'echo_cookies_js'});
await wait_promise;
assert_true(got.ok, 'Get cookies');
assert_true(got.cookies.includes('__Host-partitioned'), 'Can access partitioned cookie via JS');
assert_true(got.cookies.includes('unpartitioned'), 'Can access unpartitioned cookie via JS');
const msg3 = await next_message();
assert_true(msg3.ok, 'Get cookies');
assert_true(
msg3.cookies.includes('__Host-partitioned'),
'Can access partitioned cookie via JS');
assert_true(
msg3.cookies.includes('unpartitioned'),
'Can access unpartitioned cookie via JS');

// Test that the partitioned cookie is not available to this worker in HTTP
// requests from importScripts.
wait_promise = new Promise(resolve => {
resolve_wait_promise = resolve;
});
on_message = ev => {
got = ev.data;
resolve_wait_promise();
};
filtered_registrations[0].active.postMessage({type: 'echo_cookies_import'});
await wait_promise;
assert_true(got.ok, 'Get cookies');
assert_true(got.cookies.includes('__Host-partitioned'), 'Can access partitioned cookie via importScripts');
assert_true(got.cookies.includes('unpartitioned'), 'Can access unpartitioned cookie via importScripts');
const msg4 = await next_message();
assert_true(msg4.ok, 'Get cookies');
assert_true(
msg4.cookies.includes('__Host-partitioned'),
'Can access partitioned cookie via importScripts');
assert_true(
msg4.cookies.includes('unpartitioned'),
'Can access unpartitioned cookie via importScripts');

const popup = window.open(
new URL(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<meta charset="utf-8"/>
<meta name="timeout" content="long">
<title>Service Worker: Partitioned Cookies 3P Iframe</title>
<script src="partitioned-cookies-test-helpers.js"></script>
<script src="/resources/testharness.js"></script>
<script src="test-helpers.sub.js"></script>
</head>
Expand All @@ -15,7 +16,9 @@
const scope = './partitioned-cookies-3p-';
const absolute_scope = new URL(scope, window.location).href;

assert_false(document.cookie.includes('__Host-partitioned=123'), 'DOM cannot access partitioned cookie');
assert_false(
document.cookie.includes('__Host-partitioned=123'),
'DOM cannot access partitioned cookie');

const reg = await service_worker_unregister_and_register(t, script, scope);
await wait_for_state(t, reg.installing, 'activated');
Expand All @@ -25,80 +28,47 @@
let filtered_registrations =
retrieved_registrations.filter(reg => reg.scope == absolute_scope);

// on_message will be reassigned below based on the expected reply from the service worker.
let on_message;
self.addEventListener('message', ev => on_message(ev));
navigator.serviceWorker.addEventListener('message', evt => {
self.postMessage(evt.data, '*');
});
const next_message = worker_message_generator();

// First test that the worker script started correctly and message passing is enabled.
let resolve_wait_promise;
let wait_promise = new Promise(resolve => {
resolve_wait_promise = resolve;
});
let got;
on_message = ev => {
got = ev.data;
resolve_wait_promise();
};
// First test that the worker script started correctly and message passing
// is enabled.
filtered_registrations[0].active.postMessage({type: 'test_message'});
await wait_promise;
assert_true(got.ok, 'Message passing');
const msg1 = await next_message();
assert_true(msg1.ok, 'Message passing');

// Test that the partitioned cookie is not available to this worker via HTTP.
wait_promise = new Promise(resolve => {
resolve_wait_promise = resolve;
});
on_message = ev => {
got = ev.data;
resolve_wait_promise();
};
filtered_registrations[0].active.postMessage({type: 'echo_cookies_http'});
await wait_promise;
assert_true(got.ok, 'Get cookies');
const msg2 = await next_message();
assert_true(msg2.ok, 'Get cookies');
assert_false(
got.cookies.includes('__Host-partitioned'),
msg2.cookies.includes('__Host-partitioned'),
'Worker cannot access partitioned cookie via HTTP');
assert_true(
got.cookies.includes('unpartitioned'),
msg2.cookies.includes('unpartitioned'),
'Worker can access unpartitioned cookie via HTTP');

// Test that the partitioned cookie is not available to this worker via CookieStore API.
wait_promise = new Promise(resolve => {
resolve_wait_promise = resolve;
});
on_message = ev => {
got = ev.data;
resolve_wait_promise();
};
// Test that the partitioned cookie is not available to this worker via
// CookieStore API.
filtered_registrations[0].active.postMessage({type: 'echo_cookies_js'});
await wait_promise;
assert_true(got.ok, 'Get cookies');
const msg3 = await next_message();
assert_true(msg3.ok, 'Get cookies');
assert_false(
got.cookies.includes('__Host-partitioned'),
msg3.cookies.includes('__Host-partitioned'),
'Worker cannot access partitioned cookie via JS');
assert_true(
got.cookies.includes('unpartitioned'),
msg3.cookies.includes('unpartitioned'),
'Worker can access unpartitioned cookie via JS');

// Test that the partitioned cookie is not available to this worker in HTTP
// requests from importScripts.
wait_promise = new Promise(resolve => {
resolve_wait_promise = resolve;
});
on_message = ev => {
got = ev.data;
resolve_wait_promise();
};
filtered_registrations[0].active.postMessage({type: 'echo_cookies_import'});
await wait_promise;
assert_true(got.ok, 'Get cookies');
const msg4 = await next_message();
assert_true(msg4.ok, 'Get cookies');
assert_false(
got.cookies.includes('__Host-partitioned'),
msg4.cookies.includes('__Host-partitioned'),
'Worker cannot access partitioned cookie via importScripts');
assert_true(
got.cookies.includes('unpartitioned'),
msg4.cookies.includes('unpartitioned'),
'Worker can access unpartitioned cookie via importScripts');
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,53 +1,3 @@
self.addEventListener('message', ev => ev.waitUntil(onMessage(ev)));

async function onMessage(event) {
if (!event.data)
return;
switch (event.data.type) {
case 'test_message':
return onTestMessage(event);
case 'echo_cookies_http':
return onEchoCookiesHttp(event);
case 'echo_cookies_js':
return onEchoCookiesJs(event);
case 'echo_cookies_import':
return onEchoCookiesImport(event);
default:
return;
}
}

// test_message just verifies that the message passing is working.
async function onTestMessage(event) {
event.source.postMessage({ok: true});
}

async function onEchoCookiesHttp(event) {
try {
const resp = await fetch(
`${self.origin}/cookies/resources/list.py`, {credentials: 'include'});
const cookies = await resp.json();
event.source.postMessage({ok: true, cookies: Object.keys(cookies)});
} catch (err) {
event.source.postMessage({ok: false});
}
}

// echo_cookies returns the names of all of the cookies available to the worker.
async function onEchoCookiesJs(event) {
try {
const cookie_objects = await self.cookieStore.getAll();
const cookies = cookie_objects.map(c => c.name);
event.source.postMessage({ok: true, cookies});
} catch (err) {
event.source.postMessage({ok: false});
}
}

// Sets `self._cookies` variable, array of the names of cookies available to
// the request.
importScripts(`${self.origin}/cookies/resources/list-cookies-for-script.py`);

function onEchoCookiesImport(event) {
event.source.postMessage({ok: true, cookies: self._cookies});
}
// Import the code from the 1P partitioned worker.
// We use separate URLs for each worker script to keep their scopes unique.
importScripts('./partitioned-cookies-sw.js');
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Return a generator containing the worker's message.
//
// Usage:
// await navigator.serviceWorker.register(...)
// ...
// const nextMessage = worker_message_generator();
// const msg_1 = await nextMessage();
// const msg_2 = await nextMessage();
// const msg_3 = await nextMessage();
//
// Worker should have its own onmessage event listener that
// postMessages replies to the DOM.
function worker_message_generator() {
const buffer = [];
let resolve = null;

navigator.serviceWorker.addEventListener('message', message => {
buffer.push(message.data);
if (resolve) {
resolve();
}
});

return async function () {
if (buffer.length != 0) {
return buffer.shift();
}
await new Promise(r => resolve = r);
return buffer.shift();
}
}

0 comments on commit 5efdbab

Please sign in to comment.