18
18
* limitations under the License.
19
19
*/
20
20
import 'emoji-log' ;
21
- import Browser , { Runtime } from 'webextension-polyfill' ;
21
+ import Browser , { Cookies , Runtime } from 'webextension-polyfill' ;
22
22
import { ReportedStorage } from '../types/ReportedModel' ;
23
23
import { ZestScript , ZestScriptMessage } from '../types/zestScript/ZestScript' ;
24
24
@@ -39,6 +39,105 @@ function zapApiUrl(zapurl: string, action: string): string {
39
39
return `${ zapurl } JSON/client/action/${ action } /` ;
40
40
}
41
41
42
+ function getUrlFromCookieDomain ( domain : string ) : string {
43
+ return domain . startsWith ( '.' )
44
+ ? `http://${ domain . substring ( 1 ) } `
45
+ : `http://${ domain } ` ;
46
+ }
47
+
48
+ function getCookieTabUrl ( cookie : Cookies . Cookie ) : Promise < string > {
49
+ const getAllTabs = Browser . tabs . query ( {
50
+ currentWindow : true ,
51
+ } ) ;
52
+ return new Promise ( ( resolve , reject ) => {
53
+ getAllTabs
54
+ . then ( ( allTabs ) => {
55
+ for ( const tab of allTabs ) {
56
+ if ( tab . url ) {
57
+ const getAllCookiesForTab = Browser . cookies . getAll ( { url : tab . url } ) ;
58
+ getAllCookiesForTab . then ( ( cookies ) => {
59
+ for ( const c of cookies ) {
60
+ if (
61
+ c . name === cookie . name &&
62
+ c . value === cookie . value &&
63
+ c . domain === cookie . domain &&
64
+ c . storeId === cookie . storeId
65
+ ) {
66
+ resolve (
67
+ tab . url ? tab . url : getUrlFromCookieDomain ( cookie . domain )
68
+ ) ;
69
+ }
70
+ }
71
+ } ) ;
72
+ }
73
+ }
74
+ } )
75
+ . catch ( ( error ) => {
76
+ console . error ( `Could not fetch tabs: ${ error . message } ` ) ;
77
+ reject ( getUrlFromCookieDomain ( cookie . domain ) ) ;
78
+ } ) ;
79
+ } ) ;
80
+ }
81
+
82
+ function reportCookies (
83
+ cookie : Cookies . Cookie ,
84
+ zapurl : string ,
85
+ zapkey : string
86
+ ) : boolean {
87
+ let cookieString = `${ cookie . name } =${ cookie . value } ; path=${ cookie . path } ; domain=${ cookie . domain } ` ;
88
+ if ( cookie . expirationDate ) {
89
+ cookieString = cookieString . concat (
90
+ `; expires=${ new Date ( cookie . expirationDate * 1000 ) . toUTCString ( ) } `
91
+ ) ;
92
+ }
93
+ if ( cookie . secure ) {
94
+ cookieString = cookieString . concat ( `; secure` ) ;
95
+ }
96
+ if ( cookie . sameSite === 'lax' || cookie . sameSite === 'strict' ) {
97
+ cookieString = cookieString . concat ( `; SameSite=${ cookie . sameSite } ` ) ;
98
+ }
99
+ if ( cookie . httpOnly ) {
100
+ cookieString = cookieString . concat ( `; HttpOnly` ) ;
101
+ }
102
+
103
+ getCookieTabUrl ( cookie )
104
+ . then ( ( cookieUrl ) => {
105
+ const repStorage = new ReportedStorage (
106
+ 'Cookies' ,
107
+ '' ,
108
+ cookie . name ,
109
+ '' ,
110
+ cookieString ,
111
+ cookieUrl
112
+ ) ;
113
+ const repStorStr : string = repStorage . toShortString ( ) ;
114
+ if (
115
+ ! reportedStorage . has ( repStorStr ) &&
116
+ repStorage . url . startsWith ( 'http' )
117
+ ) {
118
+ const body = `objectJson=${ encodeURIComponent (
119
+ repStorage . toString ( )
120
+ ) } &apikey=${ encodeURIComponent ( zapkey ) } `;
121
+
122
+ fetch ( zapApiUrl ( zapurl , 'reportObject' ) , {
123
+ method : 'POST' ,
124
+ body,
125
+ headers : {
126
+ 'Content-Type' : 'application/x-www-form-urlencoded' ,
127
+ } ,
128
+ } ) ;
129
+
130
+ reportedStorage . add ( repStorStr ) ;
131
+ }
132
+ } )
133
+ . catch ( ( error ) => {
134
+ console . log ( error ) ;
135
+ return false ;
136
+ } ) ;
137
+
138
+ return true ;
139
+ }
140
+
42
141
function handleMessage (
43
142
request : MessageEvent ,
44
143
zapurl : string ,
@@ -134,10 +233,24 @@ async function onMessageHandler(
134
233
return Promise . resolve ( val ) ;
135
234
}
136
235
236
+ function cookieChangeHandler (
237
+ changeInfo : Cookies . OnChangedChangeInfoType
238
+ ) : void {
239
+ Browser . storage . sync
240
+ . get ( {
241
+ zapurl : 'http://localhost:8080/' ,
242
+ zapkey : 'not set' ,
243
+ } )
244
+ . then ( ( items ) => {
245
+ reportCookies ( changeInfo . cookie , items . zapurl , items . zapkey ) ;
246
+ } ) ;
247
+ }
248
+
137
249
Browser . action . onClicked . addListener ( ( _tab : Browser . Tabs . Tab ) => {
138
250
Browser . runtime . openOptionsPage ( ) ;
139
251
} ) ;
140
252
253
+ Browser . cookies . onChanged . addListener ( cookieChangeHandler ) ;
141
254
Browser . runtime . onMessage . addListener ( onMessageHandler ) ;
142
255
143
256
Browser . runtime . onInstalled . addListener ( ( ) : void => {
@@ -147,3 +260,5 @@ Browser.runtime.onInstalled.addListener((): void => {
147
260
zapkey : 'not set' ,
148
261
} ) ;
149
262
} ) ;
263
+
264
+ export { reportCookies } ;
0 commit comments