summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/storage-access-api/resources
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/storage-access-api/resources
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/storage-access-api/resources')
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/echo-cookie-header.py12
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/embedded_responder.js97
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/embedded_worker.js17
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-ABA-iframe.https.html9
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-ABA-iframe.sub.https.window.js11
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.html8
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.https.html10
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/permissions-iframe.https.html10
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-ABA-iframe.https.html7
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-ABA-iframe.sub.https.window.js12
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.html10
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.https.html11
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/script-with-cookie-header.py19
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/set-cookie-header.py12
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html259
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe.sub.html131
16 files changed, 635 insertions, 0 deletions
diff --git a/testing/web-platform/tests/storage-access-api/resources/echo-cookie-header.py b/testing/web-platform/tests/storage-access-api/resources/echo-cookie-header.py
new file mode 100644
index 0000000000..f1599e3a89
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/echo-cookie-header.py
@@ -0,0 +1,12 @@
+def main(request, response):
+ # Set the cors enabled headers.
+ origin = request.headers.get(b"Origin")
+ headers = []
+ if origin is not None and origin != b"null":
+ headers.append((b"Content-Type", b"text/plain"))
+ headers.append((b"Access-Control-Allow-Origin", origin))
+ headers.append((b"Access-Control-Allow-Credentials", 'true'))
+
+ cookie_header = request.headers.get(b"Cookie", b"")
+
+ return (200, headers, cookie_header)
diff --git a/testing/web-platform/tests/storage-access-api/resources/embedded_responder.js b/testing/web-platform/tests/storage-access-api/resources/embedded_responder.js
new file mode 100644
index 0000000000..bc13c7e7e8
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/embedded_responder.js
@@ -0,0 +1,97 @@
+"use strict";
+
+test_driver.set_test_context(window.top);
+
+let worker;
+
+function waitForWorkerMessage(worker) {
+ return new Promise(resolve => {
+ const listener = (event) => {
+ worker.removeEventListener("message", listener);
+ resolve(event.data);
+ };
+ worker.addEventListener("message", listener);
+ });
+}
+
+function connectAndGetRequestCookiesFrom(origin) {
+ return new Promise((resolve, reject) => {
+ const ws = new WebSocket(origin +'/echo-cookie');
+ ws.onmessage = event => {
+ const cookies = event.data;
+ resolve(cookies);
+ ws.onerror = undefined;
+ ws.onclose = undefined;
+ };
+ ws.onerror = () => reject(new Error('Unexpected error event'));
+ ws.onclose = evt => reject('Unexpected close event: ' + JSON.stringify(evt));
+ });
+}
+
+window.addEventListener("message", async (event) => {
+ function reply(data) {
+ event.source.postMessage(
+ {timestamp: event.data.timestamp, data}, event.origin);
+ }
+
+ switch (event.data["command"]) {
+ case "hasStorageAccess":
+ reply(await document.hasStorageAccess());
+ break;
+ case "requestStorageAccess": {
+ const obtainedAccess = await document.requestStorageAccess()
+ .then(() => true, () => false);
+ reply(obtainedAccess);
+ }
+ break;
+ case "write document.cookie":
+ document.cookie = event.data.cookie;
+ reply(undefined);
+ break;
+ case "document.cookie":
+ reply(document.cookie);
+ break;
+ case "set_permission":
+ await test_driver.set_permission(...event.data.args);
+ reply(undefined);
+ break;
+ case "observe_permission_change":
+ const status = await navigator.permissions.query({name: "storage-access"});
+ status.addEventListener("change", (event) => {
+ reply(event.target.state)
+ }, { once: true });
+ break;
+ case "reload":
+ window.location.reload();
+ break;
+ case "navigate":
+ window.location.href = event.data.url;
+ break;
+ case "httpCookies":
+ // The `httpCookies` variable is defined/set by
+ // script-with-cookie-header.py.
+ reply(httpCookies);
+ break;
+ case "cors fetch":
+ reply(await fetch(event.data.url, {mode: 'cors', credentials: 'include'}).then((resp) => resp.text()));
+ break;
+ case "no-cors fetch":
+ reply(await fetch(event.data.url, {mode: 'no-cors', credentials: 'include'}).then((resp) => resp.text()));
+ break;
+ case "start_dedicated_worker":
+ worker = new Worker("embedded_worker.js");
+ reply(undefined);
+ break;
+ case "message_worker": {
+ const p = waitForWorkerMessage(worker);
+ worker.postMessage(event.data.message);
+ reply(await p.then(resp => resp.data))
+ break;
+ }
+ case "get_cookie_via_websocket":{
+ reply(await connectAndGetRequestCookiesFrom(event.data.origin));
+ break;
+ }
+ default:
+ }
+});
diff --git a/testing/web-platform/tests/storage-access-api/resources/embedded_worker.js b/testing/web-platform/tests/storage-access-api/resources/embedded_worker.js
new file mode 100644
index 0000000000..f3a0fb257a
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/embedded_worker.js
@@ -0,0 +1,17 @@
+"use strict";
+
+self.onmessage = async (message) => {
+ function reply(data) {
+ self.postMessage({data});
+ }
+
+ switch (message.data.command) {
+ case "fetch": {
+ const response = await fetch(message.data.url, {mode: 'cors', credentials: 'include'})
+ .then((resp) => resp.text());
+ reply(response);
+ break;
+ }
+ default:
+ }
+};
diff --git a/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-ABA-iframe.https.html b/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-ABA-iframe.https.html
new file mode 100644
index 0000000000..fdceefc0ab
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-ABA-iframe.https.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<meta charset=utf-8>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/storage-access-api/helpers.js"></script>
+<body>
+<script src="/storage-access-api/resources/hasStorageAccess-ABA-iframe.sub.https.window.js"></script> \ No newline at end of file
diff --git a/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-ABA-iframe.sub.https.window.js b/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-ABA-iframe.sub.https.window.js
new file mode 100644
index 0000000000..d6227ee47e
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-ABA-iframe.sub.https.window.js
@@ -0,0 +1,11 @@
+// META: script=../helpers.js
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+'use strict';
+
+// This expects to be run in an iframe that is cross-site to the top-level frame.
+(async function() {
+ // Create a test with a single-child iframe that is same-site to the top-level frame but cross-site to the iframe
+ // that is being created here, for the purpose of testing hasStorageAccess in an A(B(A)) frame tree setting.
+ RunTestsInIFrame("https://{{host}}:{{ports[https][0]}}/storage-access-api/resources/hasStorageAccess-iframe.https.html?testCase=ABA");
+})();
diff --git a/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.html b/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.html
new file mode 100644
index 0000000000..d57c3961e5
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<meta charset=utf-8>
+
+<script src="/resources/testharness.js"></script>
+<!-- no testharnessreport.js -->
+<script src="../helpers.js"></script>
+<div id=log></div>
+<script src="/storage-access-api/hasStorageAccess-insecure.sub.window.js"></script>
diff --git a/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.https.html b/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.https.html
new file mode 100644
index 0000000000..46194adcf8
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.https.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<meta charset=utf-8>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<!-- no testharnessreport.js -->
+<script src="../helpers.js"></script>
+<div id=log></div>
+<script src="/storage-access-api/hasStorageAccess.sub.https.window.js"></script>
diff --git a/testing/web-platform/tests/storage-access-api/resources/permissions-iframe.https.html b/testing/web-platform/tests/storage-access-api/resources/permissions-iframe.https.html
new file mode 100644
index 0000000000..b83a05c3f1
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/permissions-iframe.https.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<meta charset=utf-8>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<!-- no testharnessreport.js -->
+<script src="../helpers.js"></script>
+<div id=log></div>
+<script src="/storage-access-api/storage-access-permission.sub.https.window.js"></script>
diff --git a/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-ABA-iframe.https.html b/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-ABA-iframe.https.html
new file mode 100644
index 0000000000..7452ff89a0
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-ABA-iframe.https.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+
+<script src="/resources/testharness.js"></script>
+<script src="/storage-access-api/helpers.js"></script>
+<body>
+<script src="/storage-access-api/resources/requestStorageAccess-ABA-iframe.sub.https.window.js"></script> \ No newline at end of file
diff --git a/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-ABA-iframe.sub.https.window.js b/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-ABA-iframe.sub.https.window.js
new file mode 100644
index 0000000000..8bfef8022a
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-ABA-iframe.sub.https.window.js
@@ -0,0 +1,12 @@
+// META: script=../helpers.js
+'use strict';
+
+// This expects to be run in an iframe that is cross-site to the top-level
+// frame.
+(async function() {
+ // Create a test with a single-child iframe that is same-site to the top-level
+ // frame but cross-site to the iframe that is being created here, for the
+ // purpose of testing requestStorageAccess in an A(B(A)) frame tree setting.
+ RunTestsInIFrame(
+ 'https://{{domains[www]}}:{{ports[https][0]}}/storage-access-api/resources/requestStorageAccess-iframe.https.html?testCase=ABA');
+})();
diff --git a/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.html b/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.html
new file mode 100644
index 0000000000..8b47786e17
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<meta charset=utf-8>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<!-- no testharnessreport.js -->
+<script src="../helpers.js"></script>
+<div id=log></div>
+<script src="/storage-access-api/requestStorageAccess-insecure.sub.window.js"></script>
diff --git a/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.https.html b/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.https.html
new file mode 100644
index 0000000000..828af799e6
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.https.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<meta charset=utf-8>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<!-- no testharnessreport.js -->
+<script src="../helpers.js"></script>
+<script src="/cookies/resources/cookie-helper.sub.js"></script>
+<div id=log></div>
+<script src="/storage-access-api/requestStorageAccess.sub.https.window.js"></script>
diff --git a/testing/web-platform/tests/storage-access-api/resources/script-with-cookie-header.py b/testing/web-platform/tests/storage-access-api/resources/script-with-cookie-header.py
new file mode 100644
index 0000000000..83129a5559
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/script-with-cookie-header.py
@@ -0,0 +1,19 @@
+def main(request, response):
+ script = request.GET.first(b"script")
+ cookie_header = request.headers.get(b"Cookie", b"")
+
+ body = b"""
+ <!DOCTYPE html>
+ <meta charset="utf-8">
+ <title>Subframe with HTTP Cookies</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script>
+ var httpCookies = "%s";
+ </script>
+
+ <script src="%s"></script>
+ """ % (cookie_header, script)
+
+ return (200, [], body)
diff --git a/testing/web-platform/tests/storage-access-api/resources/set-cookie-header.py b/testing/web-platform/tests/storage-access-api/resources/set-cookie-header.py
new file mode 100644
index 0000000000..e937ba2ca4
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/set-cookie-header.py
@@ -0,0 +1,12 @@
+from urllib.parse import unquote
+from wptserve.utils import isomorphic_encode
+
+def main(request, response):
+ # Cookies may require whitespace (e.g. in the `Expires` attribute), so the
+ # query string should be decoded.
+ cookie = unquote(request.url_parts.query)
+ headers = []
+ headers.append((b"Set-Cookie", isomorphic_encode(cookie)))
+
+ return (200, headers, "")
+
diff --git a/testing/web-platform/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html b/testing/web-platform/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html
new file mode 100644
index 0000000000..ffb419f799
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html
@@ -0,0 +1,259 @@
+<!doctype html>
+<meta charset="utf-8">
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/storage-access-api/helpers.js"></script>
+<script>
+(async function() {
+ test_driver.set_test_context(window.top);
+ const type = (new URLSearchParams(window.location.search)).get("type");
+ const id = (new URLSearchParams(window.location.search)).get("id");
+ let message = "HasAccess for " + type;
+ // Step 6 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
+ try {
+ await MaybeSetStorageAccess("*", "*", "blocked");
+ await test_driver.set_permission({ name: 'storage-access' }, 'granted');
+ switch (type) {
+ case "none": {
+ let couldRequestStorageAccessForNone = true;
+ try {
+ await document.requestStorageAccess({});
+ } catch (_) {
+ couldRequestStorageAccessForNone = false;
+ }
+ if (couldRequestStorageAccessForNone) {
+ message = "Requesting access for {} should fail."
+ }
+ let couldRequestStorageAccessForAllFalse = true;
+ try {
+ await document.requestStorageAccess({all:false});
+ } catch (_) {
+ couldRequestStorageAccessForAllFalse = false;
+ }
+ if (couldRequestStorageAccessForAllFalse) {
+ message = "Requesting access for {all:false} should fail."
+ }
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should not be readable if not requested.";
+ }
+ break;
+ }
+ case "cookies": {
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess || document.cookie.includes("test="+id)) {
+ message = "First-party cookies should not be readable before handle is loaded.";
+ }
+ await document.requestStorageAccess({cookies: true});
+ hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (!hasUnpartitionedCookieAccess || !document.cookie.includes("test="+id)) {
+ message = "First-party cookies should be readable if cookies were requested.";
+ }
+ break;
+ }
+ case "sessionStorage": {
+ const handle = await document.requestStorageAccess({sessionStorage: true});
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should not be readable if not requested.";
+ }
+ if (id != handle.sessionStorage.getItem("test")) {
+ message = "No first-party Session Storage access";
+ }
+ if (!!window.sessionStorage.getItem("test")) {
+ message = "Handle should not override window Session Storage";
+ }
+ window.onstorage = (e) => {
+ if (e.key == "window_event") {
+ if (e.newValue != id) {
+ handle.sessionStorage.setItem("handle_event", "wrong data " + e.newValue);
+ } else if (e.storageArea != handle.sessionStorage) {
+ handle.sessionStorage.setItem("handle_event", "storage area mismatch");
+ } else {
+ handle.sessionStorage.setItem("handle_event", id);
+ }
+ }
+ };
+ break;
+ }
+ case "localStorage": {
+ const handle = await document.requestStorageAccess({localStorage: true});
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should not be readable if not requested.";
+ }
+ if (id != handle.localStorage.getItem("test")) {
+ message = "No first-party Local Storage access";
+ }
+ if (!!window.localStorage.getItem("test")) {
+ message = "Handle should not override window Local Storage";
+ }
+ window.onstorage = (e) => {
+ if (e.key == "window_event") {
+ if (e.newValue != id) {
+ handle.localStorage.setItem("handle_event", "wrong data " + e.newValue);
+ } else if (e.storageArea != handle.localStorage) {
+ handle.localStorage.setItem("handle_event", "storage area mismatch");
+ } else {
+ handle.localStorage.setItem("handle_event", id);
+ }
+ }
+ };
+ break;
+ }
+ case "indexedDB": {
+ const handle = await document.requestStorageAccess({indexedDB: true});
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should not be readable if not requested.";
+ }
+ const handle_dbs = await handle.indexedDB.databases();
+ if (handle_dbs.length != 1 || handle_dbs[0].name != id) {
+ message = "No first-party IndexedDB access";
+ }
+ const local_dbs = await window.indexedDB.databases();
+ if (local_dbs.length != 0) {
+ message = "Handle should not override window IndexedDB";
+ }
+ await handle.indexedDB.deleteDatabase(id);
+ break;
+ }
+ case "locks": {
+ const handle = await document.requestStorageAccess({locks: true});
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should not be readable if not requested.";
+ }
+ const handle_state = await handle.locks.query();
+ if (handle_state.held.length != 1 || handle_state.held[0].name != id) {
+ message = "No first-party Web Lock access";
+ }
+ const local_state = await window.navigator.locks.query();
+ if (local_state.held.length != 0) {
+ message = "Handle should not override window Web Locks";
+ }
+ await handle.locks.request(id, {steal: true}, async () => {});
+ break;
+ }
+ case "caches": {
+ const handle = await document.requestStorageAccess({caches: true});
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should not be readable if not requested.";
+ }
+ const handle_has = await handle.caches.has(id);
+ if (!handle_has) {
+ message = "No first-party Cache Storage access";
+ }
+ const local_has = await window.caches.has(id);
+ if (local_has) {
+ message = "Handle should not override window Cache Storage";
+ }
+ await handle.caches.delete(id);
+ break;
+ }
+ case "getDirectory": {
+ const handle = await document.requestStorageAccess({getDirectory: true});
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should not be readable if not requested.";
+ }
+ const handle_root = await handle.getDirectory();
+ let handle_has = await handle_root.getFileHandle(id).then(() => true, () => false);
+ if (!handle_has) {
+ message = "No first-party Origin Private File System access";
+ }
+ const local_root = await window.navigator.storage.getDirectory();
+ let local_has = await local_root.getFileHandle(id).then(() => true, () => false);
+ if (local_has) {
+ message = "Handle should not override window Origin Private File System";
+ }
+ await handle_root.removeEntry(id);
+ break;
+ }
+ case "estimate": {
+ const handle = await document.requestStorageAccess({estimate: true});
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should not be readable if not requested.";
+ }
+ const handle_estimate = await handle.estimate();
+ if (handle_estimate.usage <= 0) {
+ message = "No first-party quota access";
+ }
+ const local_estimate = await window.navigator.storage.estimate();
+ if (local_estimate > 0) {
+ message = "Handle should not override window quota";
+ }
+ break;
+ }
+ case "blobStorage": {
+ const handle = await document.requestStorageAccess({createObjectURL: true, revokeObjectURL: true});
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should not be readable if not requested.";
+ }
+ let blob = await fetch(atob(id)).then(
+ (response) => response.text(),
+ () => "");
+ if (blob != "TEST") {
+ message = "Blob storage should be readable in this context";
+ }
+ URL.revokeObjectURL(atob(id));
+ blob = await fetch(atob(id)).then(
+ (response) => response.text(),
+ () => "");
+ if (blob != "TEST") {
+ message = "Handle should not override window blob storage";
+ }
+ handle.revokeObjectURL(atob(id));
+ blob = await fetch(atob(id)).then(
+ (response) => response.text(),
+ () => "");
+ if (blob != "") {
+ message = "No first-party blob access";
+ }
+ const url = handle.createObjectURL(new Blob(["TEST2"]));
+ blob = await fetch(url).then(
+ (response) => response.text(),
+ () => "");
+ if (blob != "TEST2") {
+ message = "A blob url created via the handle should be readable";
+ }
+ handle.revokeObjectURL(url);
+ blob = await fetch(url).then(
+ (response) => response.text(),
+ () => "");
+ if (blob != "") {
+ message = "A blob url removed via the handle should be cleared";
+ }
+ break;
+ }
+ case "BroadcastChannel": {
+ const handle = await document.requestStorageAccess({BroadcastChannel: true});
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should not be readable if not requested.";
+ }
+ const handle_channel = handle.BroadcastChannel(id);
+ handle_channel.postMessage("Same-origin handle access");
+ handle_channel.close();
+ const local_channel = new BroadcastChannel(id);
+ local_channel.postMessage("Same-origin local access");
+ local_channel.close();
+ break;
+ }
+ default: {
+ message = "Unexpected type " + type;
+ break;
+ }
+ }
+ } catch (_) {
+ message = "Unable to load handle in same-origin context for " + type;
+ }
+ // Step 7 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
+ await MaybeSetStorageAccess("*", "*", "allowed");
+ await test_driver.set_permission({ name: 'storage-access' }, 'prompt');
+ window.top.postMessage(message, "*");
+})();
+</script>
diff --git a/testing/web-platform/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe.sub.html b/testing/web-platform/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe.sub.html
new file mode 100644
index 0000000000..8c30973416
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe.sub.html
@@ -0,0 +1,131 @@
+<!doctype html>
+<meta charset="utf-8">
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/storage-access-api/helpers.js"></script>
+<body>
+<script>
+(async function() {
+ test_driver.set_test_context(window.top);
+ const type = (new URLSearchParams(window.location.search)).get("type");
+ const id = (new URLSearchParams(window.location.search)).get("id");
+ let message = "";
+ // Step 4 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
+ try {
+ await MaybeSetStorageAccess("*", "*", "blocked");
+ await test_driver.set_permission({ name: 'storage-access' }, 'granted');
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should not be readable before handle is loaded.";
+ }
+ const handle = await document.requestStorageAccess({all: true});
+ hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (!hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should be readable after handle is loaded.";
+ }
+ switch (type) {
+ case "none": {
+ break;
+ }
+ case "cookies": {
+ if (document.cookie.includes("test="+id)) {
+ message = "Cross-site first-party cookies should be empty";
+ }
+ break;
+ }
+ case "sessionStorage": {
+ if (!!handle.sessionStorage.getItem("test")) {
+ message = "Cross-site first-party Session Storage should be empty";
+ }
+ handle.sessionStorage.setItem("test2", id);
+ if (window.sessionStorage.getItem("test2") == id) {
+ message = "Handle bound partitioned instead of unpartitioned Session Storage";
+ }
+ handle.sessionStorage.clear();
+ window.sessionStorage.clear();
+ break;
+ }
+ case "localStorage": {
+ if (!!handle.localStorage.getItem("test")) {
+ message = "Cross-site first-party Local Storage should be empty";
+ }
+ handle.localStorage.setItem("test2", id);
+ if (window.localStorage.getItem("test2") == id) {
+ message = "Handle bound partitioned instead of unpartitioned Local Storage";
+ }
+ handle.localStorage.clear();
+ window.localStorage.clear();
+ break;
+ }
+ case "indexedDB": {
+ const dbs = await handle.indexedDB.databases();
+ if (dbs.length != 0) {
+ message = "Cross-site first-party IndexedDB should be empty";
+ }
+ break;
+ }
+ case "locks": {
+ const state = await handle.locks.query();
+ if (state.held.length != 0) {
+ message = "Cross-site first-party Web Locks should be empty";
+ }
+ break;
+ }
+ case "caches": {
+ const has = await handle.caches.has(id);
+ if (has) {
+ message = "Cross-site first-party Cache Storage should be empty";
+ }
+ break;
+ }
+ case "getDirectory": {
+ const root = await handle.getDirectory();
+ let has = await root.getFileHandle(id).then(() => true, () => false);;
+ if (has) {
+ message = "Cross-site first-party Origin Private File System should be empty";
+ }
+ break;
+ }
+ case "estimate": {
+ const estimate = await handle.estimate();
+ if (estimate.usage > 0) {
+ message = "Cross-site first-party estimate should be empty";
+ }
+ break;
+ }
+ case "blobStorage": {
+ const blob = await fetch(atob(id)).then(
+ (response) => response.text(),
+ () => "");
+ if (blob != "") {
+ message = "Cross-site first-party blob storage should be empty";
+ }
+ break;
+ }
+ case "BroadcastChannel": {
+ const channel = handle.BroadcastChannel(id);
+ channel.postMessage("Cross-origin handle access");
+ channel.close();
+ break;
+ }
+ default: {
+ message = "Unexpected type " + type;
+ break;
+ }
+ }
+ } catch (_) {
+ message = "Unable to load handle in cross-site context for all";
+ }
+ await MaybeSetStorageAccess("*", "*", "allowed");
+ await test_driver.set_permission({ name: 'storage-access' }, 'prompt');
+ if (message) {
+ window.top.postMessage(message, "*");
+ return;
+ }
+ // Step 5 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
+ let iframe = document.createElement("iframe");
+ iframe.src = "https://{{hosts[][]}}:{{ports[https][0]}}/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html?type=" + type + "&id=" + id;
+ document.body.appendChild(iframe);
+})();
+</script>
+</body>