1818 * this program. If not, see <https://www.gnu.org/licenses/>.
1919 */
2020
21+ // depends on /nscl/common/SessionCache.js
22+ // depends on /nscl/service/TabCache.js
23+ // depends on /nscl/service/TabTies.js
2124
2225var TabGuard = ( ( ) => {
23- ( async ( ) => { await include ( [ "/nscl/service/TabCache.js" , "/nscl/service/TabTies.js" ] ) ; } ) ( ) ;
2426
25- const anonymizedTabs = new Map ( ) ;
26- browser . tabs . onRemoved . addListener ( tab => {
27- anonymizedTabs . delete ( tab . id ) ;
27+ let anonymizedTabs = new Map ( ) ;
28+ browser . tabs . onRemoved . addListener ( ( { id} ) => {
29+ if ( anonymizedTabs . has ( id ) ) {
30+ anonymizedTabs . delete ( id ) ;
31+ session . save ( ) ;
32+ }
2833 } ) ;
2934
30- const anonymizedRequests = new Set ( ) ;
35+ const anonymizedRequests = new Set ( ) ; // ephemeral, lifespan is webRequest
36+
37+ // Domain groups:
38+ // property keys are domains, property values are domain Sets
39+ // (session-persisted)
40+
41+ let Groups = {
42+ allowed : { } ,
43+ filtered : { } ,
44+ } ;
45+ const forget = ( ) => {
46+ Groups . allowed = { } ;
47+ Groups . filtered = { } ;
48+ } ;
3149
32- let allowedGroups , filteredGroups ;
33- let forget = ( ) => {
34- allowedGroups = { } ;
35- filteredGroups = { } ;
50+ const groupsSerDe = ( source , callback ) => {
51+ const target = { } ;
52+ for ( const [ which , group ] of Object . entries ( source ) ) {
53+ const targetGroup = { } ;
54+ for ( const [ domain , otherDomains ] of Object . entries ( group ) ) {
55+ targetGroup [ domain ] = callback ( otherDomains ) ;
56+ }
57+ target [ which ] = targetGroup ;
58+ }
59+ return target ;
3660 } ;
37- forget ( ) ;
61+ const session = new SessionCache (
62+ "TabGuard" , // storageKey
63+ {
64+ afterLoad ( data ) { // afterLoad
65+ if ( ! data ) return ;
66+ anonymizedTabs = new Map ( data . anonymizedTabs ) ;
67+ Groups = groupsSerDe ( data . Groups , domainsArray => new Set ( domainsArray ) ) ;
68+ } ,
69+ beforeSave ( ) {
70+ return {
71+ anonymizedTabs : [ ...anonymizedTabs ] ,
72+ Groups : groupsSerDe ( Groups , domainsSet => [ ...domainsSet ] ) ,
73+ }
74+ } ,
75+ }
76+ ) ;
3877
3978 function mergeGroups ( groups ,
4079 { tabDomain, otherDomains} , /* anonymizedTabInfo */
@@ -48,6 +87,7 @@ var TabGuard = (() => {
4887 ( groups [ d ] || ( groups [ d ] = new Set ( ) ) ) . add ( tabDomain ) ;
4988 }
5089 }
90+ session . save ( ) ;
5191 }
5292
5393 const AUTH_HEADERS_RX = / ^ (?: a u t h o r i z a t i o n | c o o k i e ) / i;
@@ -65,9 +105,10 @@ var TabGuard = (() => {
65105 return flat ;
66106 }
67107
68- let scheduledCuts = new Set ( ) ;
108+ const scheduledCuts = new Set ( ) ;
69109
70110 return {
111+ wakening : Promise . all ( [ TabCache . wakening , TabTies . wakening , session . load ( ) ] ) ,
71112 forget,
72113 // must be called from a webRequest.onBeforeSendHeaders blocking listener
73114 onSend ( request ) {
@@ -199,7 +240,7 @@ var TabGuard = (() => {
199240 suspiciousDomains . push ( getDomain ( tab . url ) ) ;
200241 } ) ) ;
201242
202- const legitDomains = allowedGroups [ tabDomain ] || new Set ( ) ;
243+ const legitDomains = Groups . allowed [ tabDomain ] || new Set ( ) ;
203244 legitDomains . add ( tabDomain ) ;
204245
205246 let otherDomains = new Set ( suspiciousDomains . filter ( d => d && ! legitDomains . has ( d ) ) ) ;
@@ -213,11 +254,13 @@ var TabGuard = (() => {
213254 requestHeaders = requestHeaders . filter ( h => ! AUTH_HEADERS_RX . test ( h . name ) ) ;
214255 debug ( "[TabGuard] Removing auth headers from %o (%o)" , request , requestHeaders ) ;
215256 anonymizedTabs . set ( tabId , { tabDomain, otherDomains : [ ...otherDomains ] } ) ;
257+ session . save ( ) ;
258+
216259 anonymizedRequests . add ( request . id ) ;
217260 return { requestHeaders} ;
218261 } ;
219262
220- let quietDomains = filteredGroups [ tabDomain ] ;
263+ let quietDomains = Groups . filtered [ tabDomain ] ;
221264 if ( mainFrame ) {
222265 const promptOption = ns . sync . TabGuardPrompt ;
223266
@@ -238,9 +281,9 @@ var TabGuard = (() => {
238281 if ( ret . button !== 0 ) {
239282 return { cancel : true } ;
240283 }
241- const groups = ret . option === 0 ? filteredGroups : allowedGroups ;
284+ const groups = ret . option === 0 ? Groups . filtered : Groups . allowed ;
242285 mergeGroups ( groups , { tabDomain, otherDomains} ) ;
243- return groups === filteredGroups ? filterAuth ( ) : null ;
286+ return groups === Groups . filtered ? filterAuth ( ) : null ;
244287 } ) ( ) ;
245288 }
246289 }
@@ -288,7 +331,7 @@ var TabGuard = (() => {
288331 allow ( tabId ) {
289332 if ( ! TabGuard . isAnonymizedTab ( tabId ) ) return ;
290333 const info = this . getAnonymizedTabInfo ( tabId ) ;
291- mergeGroups ( allowedGroups , info ) ;
334+ mergeGroups ( Groups . allowed , info ) ;
292335 }
293336 }
294337} ) ( ) ;
0 commit comments