Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
DazaSeal
GitHub Repository: DazaSeal/Lunanom
Path: blob/master/public/uv/uv.handler.js
334 views
1
if (!self.__uv) {
2
__uvHook(self, self.__uv$config, self.__uv$config.bare);
3
};
4
5
async function __uvHook(window, config = {}, bare = '/bare/') {
6
if ('__uv' in window && window.__uv instanceof Ultraviolet) return false;
7
8
if (window.document && !!window.window) {
9
window.document.querySelectorAll("script[__uv-script]").forEach(node => node.remove())
10
};
11
12
const worker = !window.window;
13
const master = '__uv';
14
const methodPrefix = '__uv$';
15
const __uv = new Ultraviolet({
16
...config,
17
window,
18
});
19
20
if (typeof config.construct === 'function') {
21
config.construct(__uv, worker ? 'worker' : 'window');
22
};
23
24
const { client } = __uv;
25
const {
26
HTMLMediaElement,
27
HTMLScriptElement,
28
HTMLAudioElement,
29
HTMLVideoElement,
30
HTMLInputElement,
31
HTMLEmbedElement,
32
HTMLTrackElement,
33
HTMLAnchorElement,
34
HTMLIFrameElement,
35
HTMLAreaElement,
36
HTMLLinkElement,
37
HTMLBaseElement,
38
HTMLFormElement,
39
HTMLImageElement,
40
HTMLSourceElement,
41
} = window;
42
43
client.nativeMethods.defineProperty(window, '__uv', {
44
value: __uv,
45
enumerable: false,
46
});
47
48
49
__uv.meta.origin = location.origin;
50
__uv.location = client.location.emulate(
51
(href) => {
52
if (href === 'about:srcdoc') return new URL(href);
53
if (href.startsWith('blob:')) href = href.slice('blob:'.length);
54
return new URL(__uv.sourceUrl(href));
55
},
56
(href) => {
57
return __uv.rewriteUrl(href);
58
},
59
);
60
61
__uv.cookieStr = window.__uv$cookies || '';
62
__uv.meta.url = __uv.location;
63
__uv.domain = __uv.meta.url.host;
64
__uv.blobUrls = new window.Map();
65
__uv.referrer = '';
66
__uv.cookies = [];
67
__uv.localStorageObj = {};
68
__uv.sessionStorageObj = {};
69
70
try {
71
__uv.bare = new URL(bare, window.location.href);
72
} catch(e) {
73
__uv.bare = window.parent.__uv.bare;
74
};
75
76
if (__uv.location.href === 'about:srcdoc') {
77
__uv.meta = window.parent.__uv.meta;
78
};
79
80
// Storage wrappers
81
client.nativeMethods.defineProperty(client.storage.storeProto, '__uv$storageObj', {
82
get() {
83
if (this === client.storage.sessionStorage) return __uv.sessionStorageObj;
84
if (this === client.storage.localStorage) return __uv.localStorageObj;
85
},
86
enumerable: false,
87
});
88
89
if (window.localStorage) {
90
for (const key in window.localStorage) {
91
if (key.startsWith(methodPrefix + __uv.location.origin + '@')) {
92
__uv.localStorageObj[key.slice((methodPrefix + __uv.location.origin + '@').length)] = window.localStorage.getItem(key);
93
};
94
};
95
96
__uv.lsWrap = client.storage.emulate(client.storage.localStorage, __uv.localStorageObj);
97
};
98
99
if (window.sessionStorage) {
100
for (const key in window.sessionStorage) {
101
if (key.startsWith(methodPrefix + __uv.location.origin + '@')) {
102
__uv.sessionStorageObj[key.slice((methodPrefix + __uv.location.origin + '@').length)] = window.sessionStorage.getItem(key);
103
};
104
};
105
106
__uv.ssWrap = client.storage.emulate(client.storage.sessionStorage, __uv.sessionStorageObj);
107
};
108
109
110
111
let rawBase = window.document ? client.node.baseURI.get.call(window.document) : window.location.href;
112
let base = __uv.sourceUrl(rawBase);
113
114
client.nativeMethods.defineProperty(__uv.meta, 'base', {
115
get() {
116
if (!window.document) return __uv.meta.url.href;
117
118
if (client.node.baseURI.get.call(window.document) !== rawBase) {
119
rawBase = client.node.baseURI.get.call(window.document);
120
base = __uv.sourceUrl(rawBase);
121
};
122
123
return base;
124
},
125
});
126
127
128
__uv.methods = {
129
setSource: methodPrefix + 'setSource',
130
source: methodPrefix + 'source',
131
location: methodPrefix + 'location',
132
function: methodPrefix + 'function',
133
string: methodPrefix + 'string',
134
eval: methodPrefix + 'eval',
135
parent: methodPrefix + 'parent',
136
top: methodPrefix + 'top',
137
};
138
139
__uv.filterKeys = [
140
master,
141
__uv.methods.setSource,
142
__uv.methods.source,
143
__uv.methods.location,
144
__uv.methods.function,
145
__uv.methods.string,
146
__uv.methods.eval,
147
__uv.methods.parent,
148
__uv.methods.top,
149
methodPrefix + 'protocol',
150
methodPrefix + 'storageObj',
151
methodPrefix + 'url',
152
methodPrefix + 'modifiedStyle',
153
methodPrefix + 'config',
154
'Ultraviolet',
155
'__uvHook',
156
];
157
158
159
client.on('wrap', (target, wrapped) => {
160
client.nativeMethods.defineProperty(wrapped, 'name', client.nativeMethods.getOwnPropertyDescriptor(target, 'name'));
161
client.nativeMethods.defineProperty(wrapped, 'length', client.nativeMethods.getOwnPropertyDescriptor(target, 'length'));
162
163
client.nativeMethods.defineProperty(wrapped, __uv.methods.string, {
164
enumerable: false,
165
value: client.nativeMethods.fnToString.call(target),
166
});
167
168
client.nativeMethods.defineProperty(wrapped, __uv.methods.function, {
169
enumerable: false,
170
value: target,
171
});
172
});
173
174
client.fetch.on('request', event => {
175
event.data.input = __uv.rewriteUrl(event.data.input);
176
});
177
178
client.fetch.on('requestUrl', event => {
179
event.data.value = __uv.sourceUrl(event.data.value);
180
});
181
182
client.fetch.on('responseUrl', event => {
183
event.data.value = __uv.sourceUrl(event.data.value);
184
});
185
186
// XMLHttpRequest
187
client.xhr.on('open', event => {
188
event.data.input = __uv.rewriteUrl(event.data.input);
189
});
190
191
client.xhr.on('responseUrl', event => {
192
event.data.value = __uv.sourceUrl(event.data.value);
193
});
194
195
196
// Workers
197
client.workers.on('worker', event => {
198
event.data.url = __uv.rewriteUrl(event.data.url);
199
});
200
201
client.workers.on('addModule', event => {
202
event.data.url = __uv.rewriteUrl(event.data.url);
203
});
204
205
client.workers.on('importScripts', event => {
206
for (const i in event.data.scripts) {
207
event.data.scripts[i] = __uv.rewriteUrl(event.data.scripts[i]);
208
};
209
});
210
211
client.workers.on('postMessage', event => {
212
let to = event.data.origin;
213
214
event.data.origin = '*';
215
event.data.message = {
216
__data: event.data.message,
217
__origin: __uv.meta.url.origin,
218
__to: to,
219
};
220
});
221
222
// Navigator
223
client.navigator.on('sendBeacon', event => {
224
event.data.url = __uv.rewriteUrl(event.data.url);
225
});
226
227
// Cookies
228
client.document.on('getCookie', event => {
229
event.data.value = __uv.cookieStr;
230
});
231
232
client.document.on('setCookie', event => {
233
Promise.resolve(__uv.cookie.setCookies(event.data.value, __uv.db, __uv.meta)).then(() => {
234
__uv.cookie.db().then(db => {
235
__uv.cookie.getCookies(db).then(cookies => {
236
__uv.cookieStr = __uv.cookie.serialize(cookies, __uv.meta, true);
237
});
238
});
239
});
240
const cookie = __uv.cookie.setCookie(event.data.value)[0];
241
242
if (!cookie.path) cookie.path = '/';
243
if (!cookie.domain) cookie.domain = __uv.meta.url.hostname;
244
245
if (__uv.cookie.validateCookie(cookie, __uv.meta, true)) {
246
if (__uv.cookieStr.length) __uv.cookieStr += '; ';
247
__uv.cookieStr += `${cookie.name}=${cookie.value}`;
248
};
249
250
event.respondWith(event.data.value);
251
});
252
253
// HTML
254
client.element.on('setInnerHTML', event => {
255
switch (event.that.tagName) {
256
case 'SCRIPT':
257
event.data.value = __uv.js.rewrite(event.data.value);
258
break;
259
case 'STYLE':
260
event.data.value = __uv.rewriteCSS(event.data.value);
261
break;
262
default:
263
event.data.value = __uv.rewriteHtml(event.data.value);
264
};
265
});
266
267
client.element.on('getInnerHTML', event => {
268
switch (event.that.tagName) {
269
case 'SCRIPT':
270
event.data.value = __uv.js.source(event.data.value);
271
break;
272
default:
273
event.data.value = __uv.sourceHtml(event.data.value);
274
};
275
});
276
277
client.element.on('setOuterHTML', event => {
278
event.data.value = __uv.rewriteHtml(event.data.value, { document: event.that.tagName === 'HTML' });
279
});
280
281
client.element.on('getOuterHTML', event => {
282
switch (event.that.tagName) {
283
case 'HEAD':
284
event.data.value = __uv.sourceHtml(
285
event.data.value.replace(/<head(.*)>(.*)<\/head>/s, '<op-head$1>$2</op-head>')
286
).replace(/<op-head(.*)>(.*)<\/op-head>/s, '<head$1>$2</head>');
287
break;
288
case 'BODY':
289
event.data.value = __uv.sourceHtml(
290
event.data.value.replace(/<body(.*)>(.*)<\/body>/s, '<op-body$1>$2</op-body>')
291
).replace(/<op-body(.*)>(.*)<\/op-body>/s, '<body$1>$2</body>');
292
break;
293
default:
294
event.data.value = __uv.sourceHtml(event.data.value, { document: event.that.tagName === 'HTML' });
295
break;
296
};
297
298
//event.data.value = __uv.sourceHtml(event.data.value, { document: event.that.tagName === 'HTML' });
299
});
300
301
client.document.on('write', event => {
302
if (!event.data.html.length) return false;
303
event.data.html = [__uv.rewriteHtml(event.data.html.join(''))];
304
});
305
306
client.document.on('writeln', event => {
307
if (!event.data.html.length) return false;
308
event.data.html = [__uv.rewriteHtml(event.data.html.join(''))];
309
});
310
311
client.element.on('insertAdjacentHTML', event => {
312
event.data.html = __uv.rewriteHtml(event.data.html);
313
});
314
315
// EventSource
316
317
client.eventSource.on('construct', event => {
318
event.data.url = __uv.rewriteUrl(event.data.url);
319
});
320
321
322
client.eventSource.on('url', event => {
323
event.data.url = __uv.rewriteUrl(event.data.url);
324
});
325
326
// History
327
client.history.on('replaceState', event => {
328
if (event.data.url) event.data.url = __uv.rewriteUrl(event.data.url, '__uv' in event.that ? event.that.__uv.meta : __uv.meta);
329
});
330
client.history.on('pushState', event => {
331
if (event.data.url) event.data.url = __uv.rewriteUrl(event.data.url, '__uv' in event.that ? event.that.__uv.meta : __uv.meta);
332
});
333
334
// Element get set attribute methods
335
client.element.on('getAttribute', event => {
336
if (client.element.hasAttribute.call(event.that, __uv.attributePrefix + '-attr-' + event.data.name)) {
337
event.respondWith(
338
event.target.call(event.that, __uv.attributePrefix + '-attr-' + event.data.name)
339
);
340
};
341
});
342
343
// Message
344
client.message.on('postMessage', event => {
345
let to = event.data.origin;
346
let call = __uv.call;
347
348
349
if (event.that) {
350
call = event.that.__uv$source.call;
351
};
352
353
event.data.origin = '*';
354
event.data.message = {
355
__data: event.data.message,
356
__origin: (event.that || event.target).__uv$source.location.origin,
357
__to: to,
358
};
359
360
event.respondWith(
361
worker ?
362
call(event.target, [event.data.message, event.data.transfer], event.that) :
363
call(event.target, [event.data.message, event.data.origin, event.data.transfer], event.that)
364
);
365
366
});
367
368
client.message.on('data', event => {
369
const { value: data } = event.data;
370
if (typeof data === 'object' && '__data' in data && '__origin' in data) {
371
event.respondWith(data.__data);
372
};
373
});
374
375
client.message.on('origin', event => {
376
const data = client.message.messageData.get.call(event.that);
377
if (typeof data === 'object' && data.__data && data.__origin) {
378
event.respondWith(data.__origin);
379
};
380
});
381
382
client.overrideDescriptor(window, 'origin', {
383
get: (target, that) => {
384
return __uv.location.origin;
385
},
386
});
387
388
client.node.on('baseURI', event => {
389
if (event.data.value.startsWith(window.location.origin)) event.data.value = __uv.sourceUrl(event.data.value);
390
});
391
392
client.element.on('setAttribute', event => {
393
if (event.that instanceof HTMLMediaElement && event.data.name === 'src' && event.data.value.startsWith('blob:')) {
394
event.target.call(event.that, __uv.attributePrefix + '-attr-' + event.data.name, event.data.value);
395
event.data.value = __uv.blobUrls.get(event.data.value);
396
return;
397
};
398
399
if (__uv.attrs.isUrl(event.data.name)) {
400
event.target.call(event.that, __uv.attributePrefix + '-attr-' + event.data.name, event.data.value);
401
event.data.value = __uv.rewriteUrl(event.data.value);
402
};
403
404
if (__uv.attrs.isStyle(event.data.name)) {
405
event.target.call(event.that, __uv.attributePrefix + '-attr-' + event.data.name, event.data.value);
406
event.data.value = __uv.rewriteCSS(event.data.value, { context: 'declarationList' });
407
};
408
409
if (__uv.attrs.isHtml(event.data.name)) {
410
event.target.call(event.that, __uv.attributePrefix + '-attr-' + event.data.name, event.data.value);
411
event.data.value = __uv.rewriteHtml(event.data.value, {...__uv.meta, document: true, injectHead:__uv.createHtmlInject(__uv.handlerScript, __uv.bundleScript, __uv.configScript, __uv.cookieStr, window.location.href) });
412
};
413
414
if (__uv.attrs.isSrcset(event.data.name)) {
415
event.target.call(event.that, __uv.attributePrefix + '-attr-' + event.data.name, event.data.value);
416
event.data.value = __uv.html.wrapSrcset(event.data.value);
417
};
418
419
if (__uv.attrs.isForbidden(event.data.name)) {
420
event.data.name = __uv.attributePrefix + '-attr-' + event.data.name;
421
};
422
});
423
424
client.element.on('audio', event => {
425
event.data.url = __uv.rewriteUrl(event.data.url);
426
});
427
428
// Element Property Attributes
429
client.element.hookProperty([HTMLAnchorElement, HTMLAreaElement, HTMLLinkElement, HTMLBaseElement], 'href', {
430
get: (target, that) => {
431
return __uv.sourceUrl(
432
target.call(that)
433
);
434
},
435
set: (target, that, [val]) => {
436
client.element.setAttribute.call(that, __uv.attributePrefix + '-attr-href', val)
437
target.call(that, __uv.rewriteUrl(val));
438
},
439
});
440
441
client.element.hookProperty([HTMLScriptElement, HTMLAudioElement, HTMLVideoElement, HTMLMediaElement, HTMLImageElement, HTMLInputElement, HTMLEmbedElement, HTMLIFrameElement, HTMLTrackElement, HTMLSourceElement], 'src', {
442
get: (target, that) => {
443
return __uv.sourceUrl(
444
target.call(that)
445
);
446
},
447
set: (target, that, [val]) => {
448
if (new String(val).toString().trim().startsWith('blob:') && that instanceof HTMLMediaElement) {
449
client.element.setAttribute.call(that, __uv.attributePrefix + '-attr-src', val)
450
return target.call(that, __uv.blobUrls.get(val) || val);
451
};
452
453
client.element.setAttribute.call(that, __uv.attributePrefix + '-attr-src', val)
454
target.call(that, __uv.rewriteUrl(val));
455
},
456
});
457
458
client.element.hookProperty([HTMLFormElement], 'action', {
459
get: (target, that) => {
460
return __uv.sourceUrl(
461
target.call(that)
462
);
463
},
464
set: (target, that, [val]) => {
465
client.element.setAttribute.call(that, __uv.attributePrefix + '-attr-action', val)
466
target.call(that, __uv.rewriteUrl(val));
467
},
468
});
469
470
client.element.hookProperty([HTMLImageElement], 'srcset', {
471
get: (target, that) => {
472
return client.element.getAttribute.call(that, __uv.attributePrefix + '-attr-srcset') || target.call(that);
473
},
474
set: (target, that, [val]) => {
475
client.element.setAttribute.call(that, __uv.attributePrefix + '-attr-srcset', val)
476
target.call(that, __uv.html.wrapSrcset(val));
477
},
478
});
479
480
client.element.hookProperty(HTMLScriptElement, 'integrity', {
481
get: (target, that) => {
482
return client.element.getAttribute.call(that, __uv.attributePrefix + '-attr-integrity');
483
},
484
set: (target, that, [val]) => {
485
client.element.setAttribute.call(that, __uv.attributePrefix + '-attr-integrity', val);
486
},
487
});
488
489
client.element.hookProperty(HTMLIFrameElement, 'sandbox', {
490
get: (target, that) => {
491
return client.element.getAttribute.call(that, __uv.attributePrefix + '-attr-sandbox') || target.call(that);
492
},
493
set: (target, that, [val]) => {
494
client.element.setAttribute.call(that, __uv.attributePrefix + '-attr-sandbox', val);
495
},
496
});
497
498
client.element.hookProperty(HTMLIFrameElement, 'contentWindow', {
499
get: (target, that) => {
500
const win = target.call(that);
501
try {
502
if (!win.__uv) __uvHook(win, config, bare);
503
return win;
504
} catch (e) {
505
return win;
506
};
507
},
508
});
509
510
client.element.hookProperty(HTMLIFrameElement, 'contentDocument', {
511
get: (target, that) => {
512
const doc = target.call(that);
513
try {
514
const win = doc.defaultView
515
if (!win.__uv) __uvHook(win, config, bare);
516
return doc;
517
} catch (e) {
518
return win;
519
};
520
},
521
});
522
523
client.element.hookProperty(HTMLIFrameElement, 'srcdoc', {
524
get: (target, that) => {
525
return client.element.getAttribute.call(that, __uv.attributePrefix + '-attr-srcdoc') || target.call(that);
526
},
527
set: (target, that, [val]) => {
528
target.call(that, __uv.rewriteHtml(val, {
529
document: true,
530
injectHead: __uv.createHtmlInject(__uv.handlerScript, __uv.bundleScript, __uv.configScript, __uv.cookieStr, window.location.href)
531
}))
532
},
533
});
534
535
client.node.on('getTextContent', event => {
536
if (event.that.tagName === 'SCRIPT') {
537
event.data.value = __uv.js.source(event.data.value);
538
};
539
});
540
541
client.node.on('setTextContent', event => {
542
if (event.that.tagName === 'SCRIPT') {
543
event.data.value = __uv.js.rewrite(event.data.value);
544
};
545
});
546
547
// Until proper rewriting is implemented for service workers.
548
// Not sure atm how to implement it with the already built in service worker
549
if ('serviceWorker' in window.navigator) {
550
delete window.Navigator.prototype.serviceWorker;
551
};
552
553
// Document
554
client.document.on('getDomain', event => {
555
event.data.value = __uv.domain;
556
});
557
client.document.on('setDomain', event => {
558
if (!event.data.value.toString().endsWith(__uv.meta.url.hostname.split('.').slice(-2).join('.'))) return event.respondWith('');
559
event.respondWith(__uv.domain = event.data.value);
560
})
561
562
client.document.on('url', event => {
563
event.data.value = __uv.location.href;
564
});
565
566
client.document.on('documentURI', event => {
567
event.data.value = __uv.location.href;
568
});
569
570
client.document.on('referrer', event => {
571
event.data.value = __uv.referrer || __uv.sourceUrl(event.data.value);
572
});
573
574
client.document.on('parseFromString', event => {
575
if (event.data.type !== 'text/html') return false;
576
event.data.string = __uv.rewriteHtml(event.data.string, {...__uv.meta, document: true, });
577
});
578
579
// Attribute (node.attributes)
580
client.attribute.on('getValue', event => {
581
if (client.element.hasAttribute.call(event.that.ownerElement, __uv.attributePrefix + '-attr-' + event.data.name)) {
582
event.data.value = client.element.getAttribute.call(event.that.ownerElement, __uv.attributePrefix + '-attr-' + event.data.name);
583
};
584
});
585
586
client.attribute.on('setValue', event => {
587
if (__uv.attrs.isUrl(event.data.name)) {
588
client.element.setAttribute.call(event.that.ownerElement, __uv.attributePrefix + '-attr-' + event.data.name, event.data.value);
589
event.data.value = __uv.rewriteUrl(event.data.value);
590
};
591
592
if (__uv.attrs.isStyle(event.data.name)) {
593
client.element.setAttribute.call(event.that.ownerElement, __uv.attributePrefix + '-attr-' + event.data.name, event.data.value);
594
event.data.value = __uv.rewriteCSS(event.data.value, { context: 'declarationList' });
595
};
596
597
if (__uv.attrs.isHtml(event.data.name)) {
598
client.element.setAttribute.call(event.that.ownerElement, __uv.attributePrefix + '-attr-' + event.data.name, event.data.value);
599
event.data.value = __uv.rewriteHtml(event.data.value, {...__uv.meta, document: true, injectHead:__uv.createHtmlInject(__uv.handlerScript, __uv.bundleScript, __uv.configScript, __uv.cookieStr, window.location.href) });
600
};
601
602
if (__uv.attrs.isSrcset(event.data.name)) {
603
client.element.setAttribute.call(event.that.ownerElement, __uv.attributePrefix + '-attr-' + event.data.name, event.data.value);
604
event.data.value = __uv.html.wrapSrcset(event.data.value);
605
};
606
607
});
608
609
// URL
610
client.url.on('createObjectURL', event => {
611
let url = event.target.call(event.that, event.data.object);
612
if (url.startsWith('blob:' + location.origin)) {
613
let newUrl = 'blob:' + (__uv.meta.url.href !== 'about:blank' ? __uv.meta.url.origin : window.parent.__uv.meta.url.origin) + url.slice('blob:'.length + location.origin.length);
614
__uv.blobUrls.set(newUrl, url);
615
event.respondWith(newUrl);
616
} else {
617
event.respondWith(url);
618
};
619
});
620
621
client.url.on('revokeObjectURL', event => {
622
if (__uv.blobUrls.has(event.data.url)) {
623
const old = event.data.url;
624
event.data.url = __uv.blobUrls.get(event.data.url);
625
__uv.blobUrls.delete(old);
626
};
627
});
628
629
client.storage.on('get', event => {
630
event.data.name = methodPrefix + __uv.meta.url.origin + '@' + event.data.name;
631
});
632
633
client.storage.on('set', event => {
634
if (event.that.__uv$storageObj) {
635
event.that.__uv$storageObj[event.data.name] = event.data.value;
636
};
637
event.data.name = methodPrefix + __uv.meta.url.origin + '@' + event.data.name;
638
});
639
640
client.storage.on('delete', event => {
641
if (event.that.__uv$storageObj) {
642
delete event.that.__uv$storageObj[event.data.name];
643
};
644
event.data.name = methodPrefix + __uv.meta.url.origin + '@' + event.data.name;
645
});
646
647
client.storage.on('getItem', event => {
648
event.data.name = methodPrefix + __uv.meta.url.origin + '@' + event.data.name;
649
});
650
651
client.storage.on('setItem', event => {
652
if (event.that.__uv$storageObj) {
653
event.that.__uv$storageObj[event.data.name] = event.data.value;
654
};
655
event.data.name = methodPrefix + __uv.meta.url.origin + '@' + event.data.name;
656
});
657
658
client.storage.on('removeItem', event => {
659
if (event.that.__uv$storageObj) {
660
delete event.that.__uv$storageObj[event.data.name];
661
};
662
event.data.name = methodPrefix + __uv.meta.url.origin + '@' + event.data.name;
663
});
664
665
client.storage.on('clear', event => {
666
if (event.that.__uv$storageObj) {
667
for (const key of client.nativeMethods.keys.call(null, event.that.__uv$storageObj)) {
668
delete event.that.__uv$storageObj[key];
669
client.storage.removeItem.call(event.that, methodPrefix + __uv.meta.url.origin + '@' + key);
670
event.respondWith();
671
};
672
};
673
});
674
675
client.storage.on('length', event => {
676
if (event.that.__uv$storageObj) {
677
event.respondWith(client.nativeMethods.keys.call(null, event.that.__uv$storageObj).length);
678
};
679
});
680
681
client.storage.on('key', event => {
682
if (event.that.__uv$storageObj) {
683
event.respondWith(
684
(client.nativeMethods.keys.call(null, event.that.__uv$storageObj)[event.data.index] || null)
685
);
686
};
687
});
688
689
client.websocket.on('websocket', async event => {
690
let url;
691
try {
692
url = new URL(event.data.url);
693
} catch(e) {
694
return;
695
};
696
697
const headers = {
698
Host: url.host,
699
Origin: __uv.meta.url.origin,
700
Pragma: 'no-cache',
701
'Cache-Control': 'no-cache',
702
Upgrade: 'websocket',
703
'User-Agent': window.navigator.userAgent,
704
'Connection': 'Upgrade',
705
};
706
707
const cookies = __uv.cookie.serialize(__uv.cookies, { url }, false);
708
709
if (cookies) headers.Cookie = cookies;
710
const protocols = [...event.data.protocols];
711
712
const remote = {
713
protocol: url.protocol,
714
host: url.hostname,
715
port: url.port || (url.protocol === 'wss:' ? '443' : '80'),
716
path: url.pathname + url.search,
717
};
718
719
if (protocols.length) headers['Sec-WebSocket-Protocol'] = protocols.join(', ');
720
721
event.data.url = (__uv.bare.protocol === 'https:' ? 'wss://' : 'ws://') + __uv.bare.host + __uv.bare.pathname + 'v1/';
722
event.data.protocols = [
723
'bare',
724
__uv.encodeProtocol(JSON.stringify({
725
remote,
726
headers,
727
forward_headers: [
728
'accept',
729
'accept-encoding',
730
'accept-language',
731
'sec-websocket-extensions',
732
'sec-websocket-key',
733
'sec-websocket-version',
734
],
735
})),
736
];
737
738
const ws = new event.target(event.data.url, event.data.protocols);
739
740
client.nativeMethods.defineProperty(ws, methodPrefix + 'url', {
741
enumerable: false,
742
value: url.href,
743
});
744
745
event.respondWith(
746
ws
747
);
748
});
749
750
client.websocket.on('url', event => {
751
if ('__uv$url' in event.that) {
752
event.data.value = event.that.__uv$url;
753
};
754
});
755
756
client.websocket.on('protocol', event => {
757
if ('__uv$protocol' in event.that) {
758
event.data.value = event.that.__uv$protocol;
759
};
760
});
761
762
client.function.on('function', event => {
763
event.data.script = __uv.rewriteJS(event.data.script);
764
});
765
766
client.function.on('toString', event => {
767
if (__uv.methods.string in event.that) event.respondWith(event.that[__uv.methods.string]);
768
});
769
770
client.object.on('getOwnPropertyNames', event => {
771
event.data.names = event.data.names.filter(element => !(__uv.filterKeys.includes(element)));
772
});
773
774
client.object.on('getOwnPropertyDescriptors', event => {
775
for (const forbidden of __uv.filterKeys) {
776
delete event.data.descriptors[forbidden];
777
};
778
779
});
780
781
client.style.on('setProperty', event => {
782
if (client.style.dashedUrlProps.includes(event.data.property)) {
783
event.data.value = __uv.rewriteCSS(event.data.value, {
784
context: 'value',
785
...__uv.meta
786
})
787
};
788
});
789
790
client.style.on('getPropertyValue', event => {
791
if (client.style.dashedUrlProps.includes(event.data.property)) {
792
event.respondWith(
793
__uv.sourceCSS(
794
event.target.call(event.that, event.data.property),
795
{
796
context: 'value',
797
...__uv.meta
798
}
799
)
800
);
801
};
802
});
803
804
if ('CSS2Properties' in window) {
805
for (const key of client.style.urlProps) {
806
client.overrideDescriptor(window.CSS2Properties.prototype, key, {
807
get: (target, that) => {
808
return __uv.sourceCSS(
809
target.call(that),
810
{
811
context: 'value',
812
...__uv.meta
813
}
814
)
815
},
816
set: (target, that, val) => {
817
target.call(
818
that,
819
__uv.rewriteCSS(val, {
820
context: 'value',
821
...__uv.meta
822
})
823
);
824
}
825
});
826
};
827
} else if ('HTMLElement' in window) {
828
829
client.overrideDescriptor(
830
window.HTMLElement.prototype,
831
'style',
832
{
833
get: (target, that) => {
834
const value = target.call(that);
835
if (!value[methodPrefix + 'modifiedStyle']) {
836
837
for (const key of client.style.urlProps) {
838
client.nativeMethods.defineProperty(value, key, {
839
enumerable: true,
840
configurable: true,
841
get() {
842
const value = client.style.getPropertyValue.call(this, key) || '';
843
return __uv.sourceCSS(
844
value,
845
{
846
context: 'value',
847
...__uv.meta
848
}
849
)
850
},
851
set(val) {
852
client.style.setProperty.call(this,
853
(client.style.propToDashed[key] || key),
854
__uv.rewriteCSS(val, {
855
context: 'value',
856
...__uv.meta
857
})
858
)
859
}
860
});
861
client.nativeMethods.defineProperty(value, methodPrefix + 'modifiedStyle', {
862
enumerable: false,
863
value: true
864
});
865
};
866
};
867
return value;
868
}
869
}
870
);
871
};
872
873
client.style.on('setCssText', event => {
874
event.data.value = __uv.rewriteCSS(event.data.value, {
875
context: 'declarationList',
876
...__uv.meta
877
});
878
});
879
880
client.style.on('getCssText', event => {
881
event.data.value = __uv.sourceCSS(event.data.value, {
882
context: 'declarationList',
883
...__uv.meta
884
});
885
});
886
887
// Hooking functions & descriptors
888
client.fetch.overrideRequest();
889
client.fetch.overrideUrl();
890
client.xhr.overrideOpen();
891
client.xhr.overrideResponseUrl();
892
client.element.overrideHtml();
893
client.element.overrideAttribute();
894
client.element.overrideInsertAdjacentHTML();
895
client.element.overrideAudio();
896
// client.element.overrideQuerySelector();
897
client.node.overrideBaseURI();
898
client.node.overrideTextContent();
899
client.attribute.override();
900
client.document.overrideDomain();
901
client.document.overrideURL();
902
client.document.overrideDocumentURI();
903
client.document.overrideWrite();
904
client.document.overrideReferrer();
905
client.document.overrideParseFromString();
906
client.storage.overrideMethods();
907
client.storage.overrideLength();
908
//client.document.overrideQuerySelector();
909
client.object.overrideGetPropertyNames();
910
client.object.overrideGetOwnPropertyDescriptors();
911
client.history.overridePushState();
912
client.history.overrideReplaceState();
913
client.eventSource.overrideConstruct();
914
client.eventSource.overrideUrl();
915
client.websocket.overrideWebSocket();
916
client.websocket.overrideProtocol();
917
client.websocket.overrideUrl();
918
client.url.overrideObjectURL();
919
client.document.overrideCookie();
920
client.message.overridePostMessage();
921
client.message.overrideMessageOrigin();
922
client.message.overrideMessageData();
923
client.workers.overrideWorker();
924
client.workers.overrideAddModule();
925
client.workers.overrideImportScripts();
926
client.workers.overridePostMessage();
927
client.style.overrideSetGetProperty();
928
client.style.overrideCssText();
929
client.navigator.overrideSendBeacon();
930
client.function.overrideFunction();
931
client.function.overrideToString();
932
client.location.overrideWorkerLocation(
933
(href) => {
934
return new URL(__uv.sourceUrl(href));
935
}
936
);
937
938
client.overrideDescriptor(window, 'localStorage', {
939
get: (target, that) => {
940
return (that || window).__uv.lsWrap;
941
},
942
});
943
client.overrideDescriptor(window, 'sessionStorage', {
944
get: (target, that) => {
945
return (that || window).__uv.ssWrap;
946
},
947
});
948
949
950
client.override(window, 'open', (target, that, args) => {
951
if (!args.length) return target.apply(that, args);
952
let [url] = args;
953
954
url = __uv.rewriteUrl(url);
955
956
return target.call(that, url);
957
});
958
959
__uv.$wrap = function(name) {
960
if (name === 'location') return __uv.methods.location;
961
if (name === 'eval') return __uv.methods.eval;
962
return name;
963
};
964
965
966
__uv.$get = function(that) {
967
if (that === window.location) return __uv.location;
968
if (that === window.eval) return __uv.eval;
969
if (that === window.parent) {
970
return window.__uv$parent;
971
};
972
if (that === window.top) {
973
return window.__uv$top;
974
};
975
return that;
976
};
977
978
__uv.eval = client.wrap(window, 'eval', (target, that, args) => {
979
if (!args.length || typeof args[0] !== 'string') return target.apply(that, args);
980
let [script] = args;
981
982
script = __uv.rewriteJS(script);
983
return target.call(that, script);
984
});
985
986
__uv.call = function(target, args, that) {
987
return that ? target.apply(that, args) : target(...args);
988
};
989
990
__uv.call$ = function(obj, prop, args = []) {
991
return obj[prop].apply(obj, args);
992
};
993
994
client.nativeMethods.defineProperty(window.Object.prototype, master, {
995
get: () => {
996
return __uv;
997
},
998
enumerable: false
999
});
1000
1001
client.nativeMethods.defineProperty(window.Object.prototype, __uv.methods.setSource, {
1002
value: function(source) {
1003
if (!client.nativeMethods.isExtensible(this)) return this;
1004
1005
client.nativeMethods.defineProperty(this, __uv.methods.source, {
1006
value: source,
1007
writable: true,
1008
enumerable: false
1009
});
1010
1011
return this;
1012
},
1013
enumerable: false,
1014
});
1015
1016
client.nativeMethods.defineProperty(window.Object.prototype, __uv.methods.source, {
1017
value: __uv,
1018
writable: true,
1019
enumerable: false
1020
});
1021
1022
client.nativeMethods.defineProperty(window.Object.prototype, __uv.methods.location, {
1023
configurable: true,
1024
get() {
1025
return (this === window.document || this === window) ? __uv.location : this.location;
1026
},
1027
set(val) {
1028
if (this === window.document || this === window) {
1029
__uv.location.href = val;
1030
} else {
1031
this.location = val;
1032
};
1033
},
1034
});
1035
1036
client.nativeMethods.defineProperty(window.Object.prototype, __uv.methods.parent, {
1037
configurable: true,
1038
get() {
1039
const val = this.parent;
1040
1041
if (this === window) {
1042
try {
1043
return '__uv' in val ? val : this;
1044
} catch (e) {
1045
return this;
1046
};
1047
};
1048
return val;
1049
},
1050
set(val) {
1051
this.parent = val;
1052
},
1053
});
1054
1055
client.nativeMethods.defineProperty(window.Object.prototype, __uv.methods.top, {
1056
configurable: true,
1057
get() {
1058
const val = this.top;
1059
1060
if (this === window) {
1061
if (val === this.parent) return this[__uv.methods.parent];
1062
try {
1063
if (!('__uv' in val)) {
1064
let current = this;
1065
1066
while (current.parent !== val) {
1067
current = current.parent
1068
};
1069
1070
return '__uv' in current ? current : this;
1071
1072
} else {
1073
return val;
1074
};
1075
} catch (e) {
1076
return this;
1077
};
1078
};
1079
return val;
1080
},
1081
set(val) {
1082
this.top = val;
1083
},
1084
});
1085
1086
1087
client.nativeMethods.defineProperty(window.Object.prototype, __uv.methods.eval, {
1088
configurable: true,
1089
get() {
1090
return this === window ? __uv.eval : this.eval;
1091
},
1092
set(val) {
1093
this.eval = val;
1094
},
1095
});
1096
};
1097