ChromeUtils.defineESModuleGetters(this, { Downloads: "resource://gre/modules/Downloads.sys.mjs", FormHistory: "resource://gre/modules/FormHistory.sys.mjs", PermissionTestUtils: "resource://testing-common/PermissionTestUtils.sys.mjs", PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs", Sanitizer: "resource:///modules/Sanitizer.sys.mjs", SiteDataTestUtils: "resource://testing-common/SiteDataTestUtils.sys.mjs", }); function createIndexedDB(host, originAttributes) { let uri = Services.io.newURI("https://" + host); let principal = Services.scriptSecurityManager.createContentPrincipal( uri, originAttributes ); return SiteDataTestUtils.addToIndexedDB(principal.origin); } function checkIndexedDB(host, originAttributes) { return new Promise(resolve => { let data = true; let uri = Services.io.newURI("https://" + host); let principal = Services.scriptSecurityManager.createContentPrincipal( uri, originAttributes ); let request = indexedDB.openForPrincipal(principal, "TestDatabase", 1); request.onupgradeneeded = function (e) { data = false; }; request.onsuccess = function (e) { resolve(data); }; }); } function createHostCookie(host, originAttributes) { Services.cookies.add( host, "/test", "foo", "bar", false, false, false, Date.now() + 24000 * 60 * 60, originAttributes, Ci.nsICookie.SAMESITE_NONE, Ci.nsICookie.SCHEME_HTTPS ); } function createDomainCookie(host, originAttributes) { Services.cookies.add( "." + host, "/test", "foo", "bar", false, false, false, Date.now() + 24000 * 60 * 60, originAttributes, Ci.nsICookie.SAMESITE_NONE, Ci.nsICookie.SCHEME_HTTPS ); } function checkCookie(host, originAttributes) { for (let cookie of Services.cookies.cookies) { if ( ChromeUtils.isOriginAttributesEqual( originAttributes, cookie.originAttributes ) && cookie.host.includes(host) ) { return true; } } return false; } async function deleteOnShutdown(opt) { // Let's clean up all the data. await new Promise(resolve => { Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, resolve); }); await SpecialPowers.pushPrefEnv({ set: [ ["privacy.sanitize.sanitizeOnShutdown", opt.sanitize], ["privacy.clearOnShutdown.cookies", opt.sanitize], ["privacy.clearOnShutdown.offlineApps", opt.sanitize], ["browser.sanitizer.loglevel", "All"], ], }); // Custom permission without considering OriginAttributes if (opt.cookiePermission !== undefined) { let uri = Services.io.newURI("https://www.example.com"); PermissionTestUtils.add(uri, "cookie", opt.cookiePermission); } // Let's create a tab with some data. await opt.createData( (opt.fullHost ? "www." : "") + "example.org", opt.originAttributes ); ok( await opt.checkData( (opt.fullHost ? "www." : "") + "example.org", opt.originAttributes ), "We have data for www.example.org" ); await opt.createData( (opt.fullHost ? "www." : "") + "example.com", opt.originAttributes ); ok( await opt.checkData( (opt.fullHost ? "www." : "") + "example.com", opt.originAttributes ), "We have data for www.example.com" ); // Cleaning up. await Sanitizer.runSanitizeOnShutdown(); // All gone! is( !!(await opt.checkData( (opt.fullHost ? "www." : "") + "example.org", opt.originAttributes )), opt.expectedForOrg, "Do we have data for www.example.org?" ); is( !!(await opt.checkData( (opt.fullHost ? "www." : "") + "example.com", opt.originAttributes )), opt.expectedForCom, "Do we have data for www.example.com?" ); // Clean up. await Sanitizer.sanitize(["cookies", "offlineApps"]); if (opt.cookiePermission !== undefined) { let uri = Services.io.newURI("https://www.example.com"); PermissionTestUtils.remove(uri, "cookie"); } } function runAllCookiePermissionTests(originAttributes) { let tests = [ { name: "IDB", createData: createIndexedDB, checkData: checkIndexedDB }, { name: "Host Cookie", createData: createHostCookie, checkData: checkCookie, }, { name: "Domain Cookie", createData: createDomainCookie, checkData: checkCookie, }, ]; // Delete all, no custom permission, data in example.com, cookie permission set // for www.example.com tests.forEach(methods => { add_task(async function deleteStorageOnShutdown() { info( methods.name + ": Delete all, no custom permission, data in example.com, cookie permission set for www.example.com - OA: " + originAttributes.name ); await deleteOnShutdown({ sanitize: true, createData: methods.createData, checkData: methods.checkData, originAttributes: originAttributes.oa, cookiePermission: undefined, expectedForOrg: false, expectedForCom: false, fullHost: false, }); }); }); // Delete all, no custom permission, data in www.example.com, cookie permission // set for www.example.com tests.forEach(methods => { add_task(async function deleteStorageOnShutdown() { info( methods.name + ": Delete all, no custom permission, data in www.example.com, cookie permission set for www.example.com - OA: " + originAttributes.name ); await deleteOnShutdown({ sanitize: true, createData: methods.createData, checkData: methods.checkData, originAttributes: originAttributes.oa, cookiePermission: undefined, expectedForOrg: false, expectedForCom: false, fullHost: true, }); }); }); // All is session, but with ALLOW custom permission, data in example.com, // cookie permission set for www.example.com tests.forEach(methods => { add_task(async function deleteStorageWithCustomPermission() { info( methods.name + ": All is session, but with ALLOW custom permission, data in example.com, cookie permission set for www.example.com - OA: " + originAttributes.name ); await deleteOnShutdown({ sanitize: true, createData: methods.createData, checkData: methods.checkData, originAttributes: originAttributes.oa, cookiePermission: Ci.nsICookiePermission.ACCESS_ALLOW, expectedForOrg: false, expectedForCom: true, fullHost: false, }); }); }); // All is session, but with ALLOW custom permission, data in www.example.com, // cookie permission set for www.example.com tests.forEach(methods => { add_task(async function deleteStorageWithCustomPermission() { info( methods.name + ": All is session, but with ALLOW custom permission, data in www.example.com, cookie permission set for www.example.com - OA: " + originAttributes.name ); await deleteOnShutdown({ sanitize: true, createData: methods.createData, checkData: methods.checkData, originAttributes: originAttributes.oa, cookiePermission: Ci.nsICookiePermission.ACCESS_ALLOW, expectedForOrg: false, expectedForCom: true, fullHost: true, }); }); }); // All is default, but with SESSION custom permission, data in example.com, // cookie permission set for www.example.com tests.forEach(methods => { add_task(async function deleteStorageOnlyCustomPermission() { info( methods.name + ": All is default, but with SESSION custom permission, data in example.com, cookie permission set for www.example.com - OA: " + originAttributes.name ); await deleteOnShutdown({ sanitize: false, createData: methods.createData, checkData: methods.checkData, originAttributes: originAttributes.oa, cookiePermission: Ci.nsICookiePermission.ACCESS_SESSION, expectedForOrg: true, // expected data just for example.com when using indexedDB because // QuotaManager deletes for principal. expectedForCom: false, fullHost: false, }); }); }); // All is default, but with SESSION custom permission, data in www.example.com, // cookie permission set for www.example.com tests.forEach(methods => { add_task(async function deleteStorageOnlyCustomPermission() { info( methods.name + ": All is default, but with SESSION custom permission, data in www.example.com, cookie permission set for www.example.com - OA: " + originAttributes.name ); await deleteOnShutdown({ sanitize: false, createData: methods.createData, checkData: methods.checkData, originAttributes: originAttributes.oa, cookiePermission: Ci.nsICookiePermission.ACCESS_SESSION, expectedForOrg: true, expectedForCom: false, fullHost: true, }); }); }); // Session mode, but with unsupported custom permission, data in // www.example.com, cookie permission set for www.example.com tests.forEach(methods => { add_task(async function deleteStorageOnlyCustomPermission() { info( methods.name + ": All is session only, but with unsupported custom custom permission, data in www.example.com, cookie permission set for www.example.com - OA: " + originAttributes.name ); await deleteOnShutdown({ sanitize: true, createData: methods.createData, checkData: methods.checkData, originAttributes: originAttributes.oa, cookiePermission: 123, // invalid cookie permission expectedForOrg: false, expectedForCom: false, fullHost: true, }); }); }); }