@@ -82,15 +82,25 @@ function debounce(func, delay) {
8282const debouncedLogBlockedContent = debounce ( logBlockedContent , 1000 ) ;
8383
8484async function isWhitelisted ( url ) {
85+ if ( ! url || typeof url !== 'string' ) {
86+ console . warn ( 'isWhitelisted: Invalid or empty URL provided.' ) ;
87+ return false ;
88+ }
8589 try {
86- const hostname = new URL ( url ) . hostname ;
90+ const urlObj = new URL ( url ) ;
91+ const hostname = urlObj . hostname . toLowerCase ( ) ;
92+
93+ if ( ! hostname ) {
94+ console . warn ( `isWhitelisted: Extracted empty hostname from URL: ${ url } ` ) ;
95+ return false ;
96+ }
97+
8798 const result = await chrome . storage . local . get ( 'whitelist' ) ;
8899 const whitelist = result . whitelist || [ ] ;
89- console . log ( 'Background checking whitelist for:' , hostname , 'Whitelist:' , whitelist ) ;
90- return whitelist . includes ( hostname ) ;
100+ return whitelist . map ( h => h . toLowerCase ( ) ) . includes ( hostname ) ;
91101 } catch ( error ) {
92- console . error ( ' Error checking whitelist:' , error ) ;
93- return false ;
102+ console . error ( ` Error checking whitelist for URL " ${ url } ":` , error ) ;
103+ return false ;
94104 }
95105}
96106
@@ -100,20 +110,39 @@ async function notifyWhitelistChange() {
100110 console . log ( `Notifying ${ tabs . length } tabs about whitelist changes` ) ;
101111
102112 for ( const tab of tabs ) {
113+ if ( ! tab . id || ! tab . url ) continue ; // Skip tabs without id or url
114+
103115 try {
104- if ( tab . url && tab . url . startsWith ( 'http' ) ) {
116+ let tabHostname ;
117+ try {
118+ const tabUrlObj = new URL ( tab . url ) ;
119+ tabHostname = tabUrlObj . hostname . toLowerCase ( ) ;
120+ } catch ( e ) {
121+ console . debug ( `Skipping tab with invalid URL for whitelist notification: ${ tab . url } ` , e ) ;
122+ continue ;
123+ }
124+
125+ if ( tab . url . startsWith ( 'http' ) ) {
105126 const isWhitelistedUrl = await isWhitelisted ( tab . url ) ;
127+
106128 await chrome . tabs . sendMessage ( tab . id , {
107129 action : "setWhitelisted" ,
108130 value : isWhitelistedUrl
109- } ) . catch ( error => console . debug ( `Tab not ready for message: ${ tab . id } ` , error ) ) ;
131+ } ) . catch ( error => console . debug ( `Tab not ready for "setWhitelisted" message: ${ tab . id } , URL: ${ tab . url } ` , error ) ) ;
110132
111133 if ( isWhitelistedUrl ) {
112- await chrome . tabs . reload ( tab . id ) ;
134+ const currentWhitelistResult = await chrome . storage . local . get ( 'whitelist' ) ;
135+ const currentWhitelist = ( currentWhitelistResult . whitelist || [ ] ) . map ( h => h . toLowerCase ( ) ) ;
136+
137+ if ( currentWhitelist . includes ( tabHostname ) ) {
138+ setTimeout ( ( ) => {
139+ chrome . tabs . reload ( tab . id ) . catch ( err => console . debug ( `Error reloading tab ${ tab . id } : ${ err . message } ` ) ) ;
140+ } , 250 ) ;
141+ }
113142 }
114143 }
115144 } catch ( error ) {
116- console . debug ( ' Error updating tab:' , error ) ;
145+ console . debug ( ` Error processing tab ${ tab . id } for whitelist notification:` , error ) ;
117146 }
118147 }
119148 } catch ( error ) {
@@ -122,26 +151,26 @@ async function notifyWhitelistChange() {
122151}
123152
124153chrome . webNavigation . onCommitted . addListener ( async ( details ) => {
125- if ( details . frameId === 0 ) { // Main frame only
126- const isWhitelistedUrl = await isWhitelisted ( details . url ) ;
127- console . log ( 'Navigation detected, sending whitelist status:' , details . url , isWhitelistedUrl ) ;
128- if ( isWhitelistedUrl ) {
154+ if ( details . frameId === 0 && details . url ) {
155+ const whitelisted = await isWhitelisted ( details . url ) ;
156+ console . log ( 'Navigation detected, sending whitelist status:' , details . url , whitelisted ) ;
157+ if ( whitelisted ) {
129158 chrome . tabs . sendMessage ( details . tabId , {
130159 action : "setWhitelisted" ,
131160 value : true
132- } ) . catch ( error => console . debug ( ' Tab not ready yet:' , error ) ) ;
161+ } ) . catch ( error => console . debug ( ` Tab not ready for "setWhitelisted" (onCommitted): ${ details . tabId } , URL: ${ details . url } ` , error ) ) ;
133162 }
134163 }
135164} ) ;
136165
137166chrome . webNavigation . onCompleted . addListener ( async ( details ) => {
138- if ( details . frameId === 0 ) { // Main frame only
139- const isWhitelistedUrl = await isWhitelisted ( details . url ) ;
140- console . log ( 'Navigation completed, confirming whitelist status:' , details . url , isWhitelistedUrl ) ;
167+ if ( details . frameId === 0 && details . url ) {
168+ const whitelisted = await isWhitelisted ( details . url ) ;
169+ console . log ( 'Navigation completed, confirming whitelist status:' , details . url , whitelisted ) ;
141170 chrome . tabs . sendMessage ( details . tabId , {
142171 action : "setWhitelisted" ,
143- value : isWhitelistedUrl
144- } ) . catch ( error => console . debug ( ' Tab not ready yet on completed:' , error ) ) ;
172+ value : whitelisted
173+ } ) . catch ( error => console . debug ( ` Tab not ready for "setWhitelisted" (onCompleted): ${ details . tabId } , URL: ${ details . url } ` , error ) ) ;
145174 }
146175} ) ;
147176
@@ -152,10 +181,18 @@ chrome.webRequest.onBeforeRequest.addListener(
152181 return { cancel : false } ;
153182 }
154183
155- const isSuspiciousUrl = checkSuspiciousURL ( details . url ) ;
184+ let isSuspiciousUrl = false ;
185+ if ( details . url && typeof details . url === 'string' ) {
186+ try {
187+ isSuspiciousUrl = checkSuspiciousURL ( details . url ) ;
188+ } catch ( e ) {
189+ console . warn ( `Error parsing URL in onBeforeRequest for checkSuspiciousURL: ${ details . url } ` , e ) ;
190+ isSuspiciousUrl = false ;
191+ }
192+ }
156193
157194 if ( isSuspiciousUrl ) {
158- console . log ( 'Suspicious URL detected:' , details . url ) ;
195+ console . log ( 'Suspicious URL detected, blocking request :' , details . url ) ;
159196 return { cancel : true } ;
160197 }
161198
@@ -173,8 +210,12 @@ chrome.webRequest.onHeadersReceived.addListener(
173210
174211 const hasSuspiciousHeaders = checkSuspiciousHeaders ( details . responseHeaders ) ;
175212 if ( hasSuspiciousHeaders ) {
176- chrome . tabs . sendMessage ( details . tabId , { action : "suspiciousHeadersDetected" } )
177- . catch ( error => console . error ( 'Error sending message:' , error ) ) ;
213+ if ( details . tabId && details . tabId >= 0 ) {
214+ chrome . tabs . sendMessage ( details . tabId , { action : "suspiciousHeadersDetected" } )
215+ . catch ( error => console . debug ( `Error sending "suspiciousHeadersDetected" message to tab ${ details . tabId } :` , error ) ) ;
216+ } else {
217+ console . warn ( "Cannot send suspiciousHeadersDetected message: Invalid tabId." , details ) ;
218+ }
178219 }
179220 return { responseHeaders : details . responseHeaders } ;
180221 } ,
@@ -186,48 +227,83 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
186227 console . log ( 'Received message:' , request ) ;
187228 switch ( request . action ) {
188229 case "logWarning" :
189- debouncedLogBlockedContent ( sender . tab . url , request . patterns , Date . now ( ) ) ;
230+ let logUrl = "Unknown URL" ;
231+ if ( sender && sender . tab && sender . tab . url ) {
232+ try {
233+ logUrl = sender . tab . url ;
234+ } catch ( e ) {
235+ console . warn ( "Error parsing sender.tab.url for logging:" , e ) ;
236+ }
237+ }
238+ debouncedLogBlockedContent ( logUrl , request . patterns , Date . now ( ) ) ;
190239 console . warn ( request . message ) ;
191240 break ;
192241 case "analyzeURL" :
193242 isWhitelisted ( request . url ) . then ( whitelisted => {
194243 if ( whitelisted ) {
195244 sendResponse ( { isSuspicious : false , whitelisted : true } ) ;
196245 } else {
197- const result = memoizedAnalyzeURL ( request . url ) ;
198- if ( Date . now ( ) - result . timestamp < config . cacheDurationMs ) {
199- sendResponse ( { isSuspicious : result . isSuspicious , whitelisted : false } ) ;
200- } else {
201- const newResult = memoizedAnalyzeURL ( request . url ) ;
202- sendResponse ( { isSuspicious : newResult . isSuspicious , whitelisted : false } ) ;
246+ let analysisResult ;
247+ try {
248+ const result = memoizedAnalyzeURL ( request . url ) ;
249+ if ( Date . now ( ) - result . timestamp < config . cacheDurationMs ) {
250+ analysisResult = { isSuspicious : result . isSuspicious , whitelisted : false } ;
251+ } else {
252+ const newResult = memoizedAnalyzeURL ( request . url ) ;
253+ analysisResult = { isSuspicious : newResult . isSuspicious , whitelisted : false } ;
254+ }
255+ } catch ( e ) {
256+ console . warn ( `Error analyzing URL "${ request . url } ":` , e ) ;
257+ analysisResult = { isSuspicious : false , whitelisted : false , error : "URL analysis failed" } ;
203258 }
259+ sendResponse ( analysisResult ) ;
204260 }
261+ } ) . catch ( error => {
262+ console . error ( `Error in analyzeURL handler for URL "${ request . url } ":` , error ) ;
263+ sendResponse ( { isSuspicious : false , whitelisted : false , error : "Whitelist check failed" } ) ;
205264 } ) ;
206- return true ;
265+ return true ;
207266 case "exportLogs" :
208- chrome . storage . local . get ( [ 'blockedLogs' ] , result => {
267+ chrome . storage . local . get ( [ 'blockedLogs' ] , ( result ) => {
268+ if ( chrome . runtime . lastError ) {
269+ console . error ( "Error retrieving logs for export:" , chrome . runtime . lastError ) ;
270+ sendResponse ( { logs : [ ] , error : "Failed to retrieve logs" } ) ;
271+ return ;
272+ }
209273 sendResponse ( { logs : result . blockedLogs || [ ] } ) ;
210274 } ) ;
211- return true ;
275+ return true ;
212276 case "updateConfig" :
213- updateConfig ( request . newConfig ) ;
214- sendResponse ( { success : true } ) ;
277+ if ( request . newConfig && typeof request . newConfig === 'object' ) {
278+ updateConfig ( request . newConfig ) ;
279+ sendResponse ( { success : true } ) ;
280+ } else {
281+ console . warn ( "Invalid newConfig received:" , request . newConfig ) ;
282+ sendResponse ( { success : false , error : "Invalid configuration data" } ) ;
283+ }
215284 return true ;
216285 case "whitelistUpdated" :
217286 console . log ( 'Whitelist updated message received, notifying tabs' ) ;
218- notifyWhitelistChange ( ) ;
219- chrome . storage . local . get ( 'whitelist' ) . then ( result => {
220- const whitelist = result . whitelist || [ ] ;
221- console . log ( 'Whitelist updated (via merged listener):' , whitelist ) ;
222- } ) ;
287+ notifyWhitelistChange ( ) ;
288+ sendResponse ( { success : true } ) ;
223289 return true ;
224290 }
291+ return false ;
225292} ) ;
226293
227294function logBlockedContent ( url , patterns , timestamp ) {
295+
296+ const validatedUrl = ( typeof url === 'string' && url . length > 0 ) ? url : "Invalid or Unspecified URL" ;
297+ const validatedPatterns = Array . isArray ( patterns ) ? patterns : [ "Unknown Pattern" ] ;
298+
228299 chrome . storage . local . get ( [ 'blockedLogs' ] , function ( result ) {
300+ if ( chrome . runtime . lastError ) {
301+ console . error ( "Error retrieving logs for logging blocked content:" , chrome . runtime . lastError ) ;
302+ return ;
303+ }
229304 let logs = result . blockedLogs || [ ] ;
230- logs . push ( { url, patterns, timestamp } ) ;
305+ logs . push ( { url : validatedUrl , patterns : validatedPatterns , timestamp } ) ;
306+
231307 const retentionDate = Date . now ( ) - ( config . logRetentionDays * 24 * 60 * 60 * 1000 ) ;
232308 logs = logs . filter ( log => log . timestamp > retentionDate ) ;
233309
0 commit comments