diff options
Diffstat (limited to 'js/cookies.js')
-rw-r--r-- | js/cookies.js | 374 |
1 files changed, 187 insertions, 187 deletions
diff --git a/js/cookies.js b/js/cookies.js index 217468b..b176fbb 100644 --- a/js/cookies.js +++ b/js/cookies.js @@ -2,7 +2,7 @@ ηMatrix - a browser extension to black/white list requests. Copyright (C) 2013-2019 Raymond Hill - Copyright (C) 2019-2020 Alessio Vanni + Copyright (C) 2019-2022 Alessio Vanni This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see {http://www.gnu.org/licenses/}. - Home: https://libregit.spks.xyz/heckyel/ematrix + Home: https://gitlab.com/vannilla/ematrix uMatrix Home: https://github.com/gorhill/uMatrix */ @@ -50,205 +50,205 @@ // Look for cookies to record for a specific web page let recordPageCookiesAsync = function (pageStats) { - // Store the page stats objects so that it doesn't go away - // before we handle the job. - // rhill 2013-10-19: pageStats could be nil, for example, this can - // happens if a file:// ... makes an xmlHttpRequest - if (!pageStats) { + // Store the page stats objects so that it doesn't go away + // before we handle the job. + // rhill 2013-10-19: pageStats could be nil, for example, this can + // happens if a file:// ... makes an xmlHttpRequest + if (!pageStats) { return; - } - recordPageCookiesQueue.set(pageStats.pageUrl, pageStats); - if (processPageRecordQueueTimer === null) { + } + recordPageCookiesQueue.set(pageStats.pageUrl, pageStats); + if (processPageRecordQueueTimer === null) { processPageRecordQueueTimer = - vAPI.setTimeout(processPageRecordQueue, 1000); - } + vAPI.setTimeout(processPageRecordQueue, 1000); + } }; let cookieLogEntryBuilder = [ - '', - '{', - '', - '-cookie:', - '', - '}' + '', + '{', + '', + '-cookie:', + '', + '}' ]; let recordPageCookie = function (pageStore, key) { - if (vAPI.isBehindTheSceneTabId(pageStore.tabId)) { + if (vAPI.isBehindTheSceneTabId(pageStore.tabId)) { + return; + } + + let entry = CookieCache.get(key); + let pageHostname = pageStore.pageHostname; + let block = ηm.mustBlock(pageHostname, entry.hostname, 'cookie'); + + cookieLogEntryBuilder[0] = CookieUtils.urlFromEntry(entry); + cookieLogEntryBuilder[2] = entry.session ? 'session' : 'persistent'; + cookieLogEntryBuilder[4] = encodeURIComponent(entry.name); + + let cookieURL = cookieLogEntryBuilder.join(''); + + // rhill 2013-11-20: + // https://github.com/gorhill/httpswitchboard/issues/60 + // Need to URL-encode cookie name + pageStore.recordRequest('cookie', cookieURL, block); + ηm.logger.writeOne(pageStore.tabId, 'net', + pageHostname, cookieURL, 'cookie', block); + + entry.usedOn.add(pageHostname); + + // rhill 2013-11-21: + // https://github.com/gorhill/httpswitchboard/issues/65 + // Leave alone cookies from behind-the-scene requests if + // behind-the-scene processing is disabled. + if (!block) { return; - } - - let entry = CookieCache.get(key); - let pageHostname = pageStore.pageHostname; - let block = ηm.mustBlock(pageHostname, entry.hostname, 'cookie'); - - cookieLogEntryBuilder[0] = CookieUtils.urlFromEntry(entry); - cookieLogEntryBuilder[2] = entry.session ? 'session' : 'persistent'; - cookieLogEntryBuilder[4] = encodeURIComponent(entry.name); - - let cookieURL = cookieLogEntryBuilder.join(''); - - // rhill 2013-11-20: - // https://github.com/gorhill/httpswitchboard/issues/60 - // Need to URL-encode cookie name - pageStore.recordRequest('cookie', cookieURL, block); - ηm.logger.writeOne(pageStore.tabId, 'net', - pageHostname, cookieURL, 'cookie', block); - - entry.usedOn.add(pageHostname); - - // rhill 2013-11-21: - // https://github.com/gorhill/httpswitchboard/issues/65 - // Leave alone cookies from behind-the-scene requests if - // behind-the-scene processing is disabled. - if (!block) { - return; - } - if (!ηm.userSettings.deleteCookies) { + } + if (!ηm.userSettings.deleteCookies) { return; - } - removeCookieAsync(key); + } + removeCookieAsync(key); }; // Look for cookies to potentially remove for a specific web page let removePageCookiesAsync = function (pageStats) { - // Hold onto pageStats objects so that it doesn't go away - // before we handle the job. - // rhill 2013-10-19: pageStats could be nil, for example, this can - // happens if a file:// ... makes an xmlHttpRequest - if (!pageStats) { + // Hold onto pageStats objects so that it doesn't go away + // before we handle the job. + // rhill 2013-10-19: pageStats could be nil, for example, this can + // happens if a file:// ... makes an xmlHttpRequest + if (!pageStats) { return; - } - removePageCookiesQueue.set(pageStats.pageUrl, pageStats); - if (processPageRemoveQueueTimer === null) { + } + removePageCookiesQueue.set(pageStats.pageUrl, pageStats); + if (processPageRemoveQueueTimer === null) { processPageRemoveQueueTimer = - vAPI.setTimeout(processPageRemoveQueue, 15 * 1000); - } + vAPI.setTimeout(processPageRemoveQueue, 15 * 1000); + } }; // Candidate for removal let removeCookieAsync = function (key) { - removeCookieQueue.add(key); + removeCookieQueue.add(key); }; let chromeCookieRemove = function (entry, name) { - let url = CookieUtils.urlFromEntry(entry); - if (url === '') { + let url = CookieUtils.urlFromEntry(entry); + if (url === '') { return; - } - let sessionKey = CookieUtils.keyFromURL(UriTools.set(url), - 'session', name); - let persistKey = CookieUtils.keyFromURL(UriTools.set(url), - 'persistent', name); + } + let sessionKey = CookieUtils.keyFromURL(UriTools.set(url), + 'session', name); + let persistKey = CookieUtils.keyFromURL(UriTools.set(url), + 'persistent', name); - let callback = function(details) { + let callback = function(details) { let success = !!details; let template = success ? - i18nCookieDeleteSuccess : - i18nCookieDeleteFailure; + i18nCookieDeleteSuccess : + i18nCookieDeleteFailure; if (CookieCache.remove(sessionKey)) { - if (success) { + if (success) { ηm.cookieRemovedCounter += 1; - } - ηm.logger.writeOne('', 'info', 'cookie', - template.replace('{{value}}', - sessionKey)); + } + ηm.logger.writeOne('', 'info', 'cookie', + template.replace('{{value}}', + sessionKey)); } if (CookieCache.remove(persistKey)) { - if (success) { + if (success) { ηm.cookieRemovedCounter += 1; - } - ηm.logger.writeOne('', 'info', 'cookie', - template.replace('{{value}}', - persistKey)); + } + ηm.logger.writeOne('', 'info', 'cookie', + template.replace('{{value}}', + persistKey)); } - }; + }; - vAPI.cookies.remove({ - url: url, name: name - }, callback); + vAPI.cookies.remove({ + url: url, name: name + }, callback); }; let i18nCookieDeleteSuccess = vAPI.i18n('loggerEntryCookieDeleted'); let i18nCookieDeleteFailure = vAPI.i18n('loggerEntryDeleteCookieError'); let processPageRecordQueue = function () { - processPageRecordQueueTimer = null; + processPageRecordQueueTimer = null; - for (let pageStore of recordPageCookiesQueue.values()) { + for (let pageStore of recordPageCookiesQueue.values()) { findAndRecordPageCookies(pageStore); - } - recordPageCookiesQueue.clear(); + } + recordPageCookiesQueue.clear(); }; let processPageRemoveQueue = function () { - processPageRemoveQueueTimer = null; + processPageRemoveQueueTimer = null; - for (let pageStore of removePageCookiesQueue.values()) { + for (let pageStore of removePageCookiesQueue.values()) { findAndRemovePageCookies(pageStore); - } - removePageCookiesQueue.clear(); + } + removePageCookiesQueue.clear(); }; // Effectively remove cookies. let processRemoveQueue = function () { - let userSettings = ηm.userSettings; - let deleteCookies = userSettings.deleteCookies; - - // Session cookies which timestamp is *after* tstampObsolete will - // be left untouched - // https://github.com/gorhill/httpswitchboard/issues/257 - let dusc = userSettings.deleteUnusedSessionCookies; - let dusca = userSettings.deleteUnusedSessionCookiesAfter; - let tstampObsolete = dusc ? - Date.now() - dusca * 60 * 1000 : + let userSettings = ηm.userSettings; + let deleteCookies = userSettings.deleteCookies; + + // Session cookies which timestamp is *after* tstampObsolete will + // be left untouched + // https://github.com/gorhill/httpswitchboard/issues/257 + let dusc = userSettings.deleteUnusedSessionCookies; + let dusca = userSettings.deleteUnusedSessionCookiesAfter; + let tstampObsolete = dusc ? + Date.now() - dusca * 60 * 1000 : 0; - let srcHostnames; - let entry; + let srcHostnames; + let entry; - for (let key of removeCookieQueue) { + for (let key of removeCookieQueue) { // rhill 2014-05-12: Apparently this can happen. I have to // investigate how (A session cookie has same name as a // persistent cookie?) entry = CookieCache.get(key); if (entry === undefined) { - continue; - } + continue; + } // Delete obsolete session cookies: enabled. if (tstampObsolete !== 0 && entry.session) { - if (entry.tstamp < tstampObsolete) { + if (entry.tstamp < tstampObsolete) { chromeCookieRemove(entry, entry.name); continue; - } + } } // Delete all blocked cookies: disabled. if (deleteCookies === false) { - continue; + continue; } // Query scopes only if we are going to use them if (srcHostnames === undefined) { - srcHostnames = ηm.tMatrix.extractAllSourceHostnames(); + srcHostnames = ηm.tMatrix.extractAllSourceHostnames(); } // Ensure cookie is not allowed on ALL current web pages: It can // happen that a cookie is blacklisted on one web page while // being whitelisted on another (because of per-page permissions). if (canRemoveCookie(key, srcHostnames)) { - chromeCookieRemove(entry, entry.name); + chromeCookieRemove(entry, entry.name); } - } + } - removeCookieQueue.clear(); + removeCookieQueue.clear(); - vAPI.setTimeout(processRemoveQueue, processRemoveQueuePeriod); + vAPI.setTimeout(processRemoveQueue, processRemoveQueuePeriod); }; // Once in a while, we go ahead and clean everything that might have been @@ -258,145 +258,145 @@ // maybe a user has 1000s of cookies sitting in his browser... let processClean = function () { - let us = ηm.userSettings; + let us = ηm.userSettings; - if (us.deleteCookies || us.deleteUnusedSessionCookies) { + if (us.deleteCookies || us.deleteUnusedSessionCookies) { let keys = Array.from(CookieCache.keys()); - let len = keys.length; - let step, offset, n; + let len = keys.length; + let step, offset, n; if (len > 25) { - step = len / 25; - offset = Math.floor(Math.random() * len); - n = 25; + step = len / 25; + offset = Math.floor(Math.random() * len); + n = 25; } else { - step = 1; - offset = 0; - n = len; + step = 1; + offset = 0; + n = len; } let i = offset; while (n--) { - removeCookieAsync(keys[Math.floor(i % len)]); - i += step; + removeCookieAsync(keys[Math.floor(i % len)]); + i += step; } - } + } - vAPI.setTimeout(processClean, processCleanPeriod); + vAPI.setTimeout(processClean, processCleanPeriod); }; let findAndRecordPageCookies = function (pageStore) { - for (let key of CookieCache.keys()) { + for (let key of CookieCache.keys()) { if (CookieUtils.matchDomains(key, pageStore.allHostnamesString)) { - recordPageCookie(pageStore, key); + recordPageCookie(pageStore, key); } - } + } }; let findAndRemovePageCookies = function (pageStore) { - for (let key of CookieCache.keys()) { + for (let key of CookieCache.keys()) { if (CookieUtils.matchDomains(key, pageStore.allHostnamesString)) { - removeCookieAsync(key); + removeCookieAsync(key); } - } + } }; let canRemoveCookie = function (key, srcHostnames) { - let entry = CookieCache.get(key); - if (entry === undefined) { - return false; - } + let entry = CookieCache.get(key); + if (entry === undefined) { + return false; + } - let cookieHostname = entry.hostname; - let srcHostname; + let cookieHostname = entry.hostname; + let srcHostname; - for (srcHostname of entry.usedOn) { + for (srcHostname of entry.usedOn) { if (ηm.mustAllow(srcHostname, cookieHostname, 'cookie')) { - return false; + return false; } - } + } - // Maybe there is a scope in which the cookie is 1st-party-allowed. - // For example, if I am logged in into `github.com`, I do not want to be - // logged out just because I did not yet open a `github.com` page after - // re-starting the browser. - srcHostname = cookieHostname; + // Maybe there is a scope in which the cookie is 1st-party-allowed. + // For example, if I am logged in into `github.com`, I do not want to be + // logged out just because I did not yet open a `github.com` page after + // re-starting the browser. + srcHostname = cookieHostname; - let pos; + let pos; - for (;;) { + for (;;) { if (srcHostnames.has(srcHostname)) { - if (ηm.mustAllow(srcHostname, cookieHostname, 'cookie')) { + if (ηm.mustAllow(srcHostname, cookieHostname, 'cookie')) { return false; - } + } } if (srcHostname === entry.domain) { - break; + break; } pos = srcHostname.indexOf('.'); if (pos === -1) { - break; + break; } srcHostname = srcHostname.slice(pos + 1); - } - return true; + } + return true; }; // Listen to any change in cookieland, we will update page stats accordingly. vAPI.cookies.onChanged = function (cookie) { - // rhill 2013-12-11: If cookie value didn't change, no need to record. - // https://github.com/gorhill/httpswitchboard/issues/79 - let key = CookieUtils.keyFromCookie(cookie); - let entry = CookieCache.get(key); + // rhill 2013-12-11: If cookie value didn't change, no need to record. + // https://github.com/gorhill/httpswitchboard/issues/79 + let key = CookieUtils.keyFromCookie(cookie); + let entry = CookieCache.get(key); - if (entry === undefined) { + if (entry === undefined) { entry = CookieCache.add(cookie); - } else { + } else { entry.tstamp = Date.now(); if (cookie.value === entry.value) { - return; - } + return; + } entry.value = cookie.value; - } + } - // Go through all pages and update if needed, as one cookie can be used - // by many web pages, so they need to be recorded for all these pages. - let pageStores = ηm.pageStores; - let pageStore; - for (let tabId in pageStores) { + // Go through all pages and update if needed, as one cookie can be used + // by many web pages, so they need to be recorded for all these pages. + let pageStores = ηm.pageStores; + let pageStore; + for (let tabId in pageStores) { if (pageStores.hasOwnProperty(tabId) === false) { - continue; + continue; } pageStore = pageStores[tabId]; if (!CookieUtils.matchDomains(key, pageStore.allHostnamesString)) { - continue; + continue; } recordPageCookie(pageStore, key); - } + } }; // Listen to any change in cookieland, we will update page stats accordingly. vAPI.cookies.onRemoved = function (cookie) { - let key = CookieUtils.keyFromCookie(cookie); - if (CookieCache.remove(key)) { + let key = CookieUtils.keyFromCookie(cookie); + if (CookieCache.remove(key)) { ηm.logger.writeOne('', 'info', 'cookie', - i18nCookieDeleteSuccess.replace('{{value}}', - key)); - } + i18nCookieDeleteSuccess.replace('{{value}}', + key)); + } }; // Listen to any change in cookieland, we will update page stats accordingly. vAPI.cookies.onAllRemoved = function () { - for (let key of CookieCache.keys()) { + for (let key of CookieCache.keys()) { if (CookieCache.remove(key)) { - ηm.logger.writeOne('', 'info', 'cookie', - i18nCookieDeleteSuccess.replace('{{value}}', - key)); + ηm.logger.writeOne('', 'info', 'cookie', + i18nCookieDeleteSuccess.replace('{{value}}', + key)); } - } + } }; vAPI.cookies.getAll(CookieCache.addVector); @@ -408,7 +408,7 @@ // Expose only what is necessary return { - recordPageCookies: recordPageCookiesAsync, - removePageCookies: removePageCookiesAsync + recordPageCookies: recordPageCookiesAsync, + removePageCookies: removePageCookiesAsync }; })(); |