Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
QuiteAFancyEmerald
GitHub Repository: QuiteAFancyEmerald/Holy-Unblocker
Path: blob/master/views/scram/scramjet.sw-blacklist.js
5227 views
1
importScripts('{{route}}{{/scram/scramjet.all.js}}');
2
const { ScramjetServiceWorker } = $scramjetLoadWorker();
3
const scramjet = new ScramjetServiceWorker();
4
5
// Get list of blacklisted domains.
6
const blacklist = {},
7
nativeFunction = Function;
8
fetch('{{route}}{{/assets/json/blacklist.json}}').then((request) => {
9
request.json().then((jsonData) => {
10
// Organize each domain by their tld (top level domain) ending.
11
jsonData.forEach((domain) => {
12
const domainTld = domain.replace(/.+(?=\.\w)/, '');
13
if (!blacklist.hasOwnProperty(domainTld)) blacklist[domainTld] = [];
14
15
// Store each entry in an array. Each tld has its own array, which will
16
// later be concatenated into a regular expression.
17
blacklist[domainTld].push(
18
encodeURIComponent(domain.slice(0, -domainTld.length))
19
.replace(/([()])/g, '\\$1')
20
.replace(/(\*\.)|\./g, (match, firstExpression) =>
21
firstExpression ? '(?:.+\\.)?' : '\\' + match
22
)
23
);
24
});
25
26
// Turn each domain list into a regular expression and prevent this
27
// from being accidentally modified afterward.
28
for (let [domainTld, domainList] of Object.entries(blacklist))
29
blacklist[domainTld] = new RegExp(`^(?:${domainList.join('|')})$`);
30
Object.freeze(blacklist);
31
});
32
});
33
34
async function handleRequest(event) {
35
await scramjet.loadConfig();
36
if (scramjet.route(event)) {
37
// The one and only ghetto domain blacklist.
38
try {
39
const domain = new URL(
40
nativeFunction(`return ${scramjet.config.codec.decode}`)()(
41
new URL(event.request.url).pathname.replace(
42
scramjet.config.prefix,
43
''
44
)
45
)
46
).hostname,
47
domainTld = domain.replace(/.+(?=\.\w)/, '');
48
49
// If the domain is in the blacklist, return a 406 response code.
50
if (
51
blacklist.hasOwnProperty(domainTld) &&
52
blacklist[domainTld].test(domain.slice(0, -domainTld.length))
53
)
54
return new Response(new Blob(), { status: 406 });
55
} catch (e) {
56
// This is the case where it is an invalid fetch request, or the WASM file.
57
}
58
59
return scramjet.fetch(event);
60
}
61
return fetch(event.request);
62
}
63
64
self.addEventListener('fetch', (event) => {
65
event.respondWith(handleRequest(event));
66
});
67
68
let playgroundData;
69
self.addEventListener('message', (event) => {
70
if (event.data.type === 'playgroundData') {
71
playgroundData = event.data;
72
} else if (event.data.type === 'requestAC') {
73
// Set up a message channel from common.js to process autocomplete search results.
74
const requestPort = event.ports[0];
75
requestPort.addEventListener('message', async (event) => {
76
const response = await scramjet.fetch(event.data);
77
78
// This contains some duplicate code from common.js, since Response objects
79
// cannot be passed through service workers and must be preprocessed.
80
const responseType = response.headers.get('content-type');
81
let responseJSON = {};
82
if (responseType && responseType.indexOf('application/json') !== -1)
83
responseJSON = await response.json();
84
else
85
try {
86
responseJSON = await response.text();
87
try {
88
responseJSON = JSON.parse(responseJSON);
89
} catch (e) {
90
responseJSON = JSON.parse(
91
responseJSON.replace(/^[^[{]*|[^\]}]*$/g, '')
92
);
93
}
94
} catch (e) {
95
// responseJSON will be an empty object if everything was invalid.
96
}
97
98
// Return the processed data.
99
requestPort.postMessage({
100
responseJSON: responseJSON,
101
searchType: event.data.type,
102
time: event.data.request.headers.get('Date'),
103
});
104
});
105
requestPort.start();
106
}
107
});
108
109