summaryrefslogtreecommitdiffstats
path: root/toolkit/components/antitracking/test/browser/storageAccessAPIHelpers.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /toolkit/components/antitracking/test/browser/storageAccessAPIHelpers.js
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/antitracking/test/browser/storageAccessAPIHelpers.js')
-rw-r--r--toolkit/components/antitracking/test/browser/storageAccessAPIHelpers.js197
1 files changed, 197 insertions, 0 deletions
diff --git a/toolkit/components/antitracking/test/browser/storageAccessAPIHelpers.js b/toolkit/components/antitracking/test/browser/storageAccessAPIHelpers.js
new file mode 100644
index 0000000000..2837cf68a2
--- /dev/null
+++ b/toolkit/components/antitracking/test/browser/storageAccessAPIHelpers.js
@@ -0,0 +1,197 @@
+/* global allowListed */
+
+async function hasStorageAccessInitially() {
+ let hasAccess = await document.hasStorageAccess();
+ ok(hasAccess, "Has storage access");
+}
+
+async function noStorageAccessInitially() {
+ let hasAccess = await document.hasStorageAccess();
+ ok(!hasAccess, "Doesn't yet have storage access");
+}
+
+async function callRequestStorageAccess(callback, expectFail) {
+ let dwu = SpecialPowers.getDOMWindowUtils(window);
+ let helper = dwu.setHandlingUserInput(true);
+
+ let origin = new URL(location.href).origin;
+
+ let success = true;
+ // We only grant storage exceptions when the reject tracker behavior is enabled.
+ let rejectTrackers =
+ [
+ SpecialPowers.Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER,
+ SpecialPowers.Ci.nsICookieService
+ .BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
+ ].includes(
+ SpecialPowers.Services.prefs.getIntPref("network.cookie.cookieBehavior")
+ ) && !isOnContentBlockingAllowList();
+ const TEST_ANOTHER_3RD_PARTY_ORIGIN = SpecialPowers.useRemoteSubframes
+ ? "http://another-tracking.example.net"
+ : "https://another-tracking.example.net";
+ // With another-tracking.example.net, we're same-eTLD+1, so the first try succeeds.
+ if (origin != TEST_ANOTHER_3RD_PARTY_ORIGIN) {
+ if (rejectTrackers) {
+ let p;
+ let threw = false;
+ try {
+ p = document.requestStorageAccess();
+ } catch (e) {
+ threw = true;
+ } finally {
+ helper.destruct();
+ }
+ ok(!threw, "requestStorageAccess should not throw");
+ try {
+ if (callback) {
+ if (expectFail) {
+ await p.catch(_ => callback(dwu));
+ success = false;
+ } else {
+ await p.then(_ => callback(dwu));
+ }
+ } else {
+ await p;
+ }
+ } catch (e) {
+ success = false;
+ }
+ ok(!success, "Should not have worked without user interaction");
+
+ await noStorageAccessInitially();
+
+ await interactWithTracker();
+
+ helper = dwu.setHandlingUserInput(true);
+ }
+ if (
+ SpecialPowers.Services.prefs.getIntPref(
+ "network.cookie.cookieBehavior"
+ ) == SpecialPowers.Ci.nsICookieService.BEHAVIOR_ACCEPT &&
+ !isOnContentBlockingAllowList()
+ ) {
+ try {
+ if (callback) {
+ if (expectFail) {
+ await document.requestStorageAccess().catch(_ => callback(dwu));
+ success = false;
+ } else {
+ await document.requestStorageAccess().then(_ => callback(dwu));
+ }
+ } else {
+ await document.requestStorageAccess();
+ }
+ } catch (e) {
+ success = false;
+ } finally {
+ helper.destruct();
+ }
+ ok(success, "Should not have thrown");
+
+ await hasStorageAccessInitially();
+
+ await interactWithTracker();
+
+ helper = dwu.setHandlingUserInput(true);
+ }
+ }
+
+ let p;
+ let threw = false;
+ try {
+ p = document.requestStorageAccess();
+ } catch (e) {
+ threw = true;
+ } finally {
+ helper.destruct();
+ }
+ let rejected = false;
+ try {
+ if (callback) {
+ if (expectFail) {
+ await p.catch(_ => callback(dwu));
+ rejected = true;
+ } else {
+ await p.then(_ => callback(dwu));
+ }
+ } else {
+ await p;
+ }
+ } catch (e) {
+ rejected = true;
+ }
+
+ success = !threw && !rejected;
+ let hasAccess = await document.hasStorageAccess();
+ is(
+ hasAccess,
+ success,
+ "Should " + (success ? "" : "not ") + "have storage access now"
+ );
+ if (
+ success &&
+ rejectTrackers &&
+ window.location.search != "?disableWaitUntilPermission" &&
+ origin != TEST_ANOTHER_3RD_PARTY_ORIGIN
+ ) {
+ // Wait until the permission is visible in parent process to avoid race
+ // conditions. We don't need to wait the permission to be visible in content
+ // processes since the content process doesn't rely on the permission to
+ // know the storage access is updated.
+ await waitUntilPermission(
+ "http://example.net/browser/toolkit/components/antitracking/test/browser/page.html",
+ "3rdPartyStorage^" + window.origin
+ );
+ }
+
+ return [threw, rejected];
+}
+
+async function waitUntilPermission(url, name) {
+ let originAttributes = SpecialPowers.isContentWindowPrivate(window)
+ ? { privateBrowsingId: 1 }
+ : {};
+ await new Promise(resolve => {
+ let id = setInterval(async _ => {
+ if (
+ await SpecialPowers.testPermission(
+ name,
+ SpecialPowers.Services.perms.ALLOW_ACTION,
+ {
+ url,
+ originAttributes,
+ }
+ )
+ ) {
+ clearInterval(id);
+ resolve();
+ }
+ }, 0);
+ });
+}
+
+async function interactWithTracker() {
+ await new Promise(resolve => {
+ let orionmessage = onmessage;
+ onmessage = _ => {
+ onmessage = orionmessage;
+ resolve();
+ };
+
+ info("Let's interact with the tracker");
+ window.open(
+ "/browser/toolkit/components/antitracking/test/browser/3rdPartyOpenUI.html?messageme"
+ );
+ });
+
+ // Wait until the user interaction permission becomes visible in our process
+ await waitUntilPermission(window.origin, "storageAccessAPI");
+}
+
+function isOnContentBlockingAllowList() {
+ // We directly check the window.allowListed here instead of checking the
+ // permission. The allow list permission might not be available since it is
+ // not in the preload list.
+
+ return window.allowListed;
+}