-
Notifications
You must be signed in to change notification settings - Fork 2
/
background.js
221 lines (204 loc) · 6.57 KB
/
background.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
let browserAPI = undefined;
/**
* excludedWebsites is a list of famous websites that people usually visit
* and we don't want to run our extension on.
* this is to save unnecessary code run and db queries
*/
const excludedWebsites = [
"google.com",
"youtube.com",
"facebook.com",
"baidu.com",
"wikipedia.org",
"reddit.com",
"yahoo.com",
"twitter.com",
"x.com",
"instagram.com",
"linkedin.com",
"microsoft.com",
"pinterest.com",
"apple.com",
// Add more websites as needed
];
const ecommerceTargets = [
"jumia", "amazon", "ebay", "walmart", "argos", "tesco", "aliexpress", "noon", "bestbuy", "target", "sainsburys"
]
const socialTargets = [
"twitter",
"linkedin"
]
function shouldByPassPage(domainName, path) {
if (['twitter.com', 'x.com'].includes(domainName) && path.length > 1 && path.split("/").length == 2) {
return false
}
if (['linkedin.com'].includes(domainName) && path.length > 1 && path.split("/").length == 4) {
return false
}
return excludedWebsites.indexOf(domainName) >= 0
}
export async function handleTabVisit(actions, tabId, tabUrl) {
browserAPI = actions;
const urlObject = new URL(tabUrl);
// ignore urls for local files, firefox about:config and so on..
if (!urlObject.hostname || urlObject.hostname === 'newtab') {
return showOk(tabId);
}
const domainName = urlObject.hostname.startsWith("www.")
? urlObject.hostname.slice(4)
: urlObject.hostname;
if (shouldByPassPage(domainName, urlObject.pathname)) {
return showOk(tabId);
}
const targetObj = getTarget(domainName)
// const eCommerce = getEcommerceTarget(domainName);
if (targetObj.type === 'ecommerce') {
const script = `${targetObj.target}-blocker`;
await injectScript(script, tabId);
const res = await browserAPI.sendMessageToTab(tabId, {});
if (res && res.brandName) {
const json = await getBoycottItem("brand", res.brandName);
if (json) {
await showBoycottWarning(tabId, json);
return;
}
}
}
else if (targetObj.type === 'social') {
const script = `${targetObj.target}-blocker`;
await injectScript(script, tabId);
const res = await browserAPI.sendMessageToTab(tabId, {});
if (res && res.figureName) {
const json = await getBoycottItem("figure", res.figureName);
if (json) {
await showBoycottWarning(tabId, json);
return;
}
}
// if (res && res.brandName) {
// const json = await getBoycottItem("brand", res.brandName);
// if (json) {
// await showBoycottWarning(tabId, "brand", json);
// return;
// }
// }
} else {
const json = await getBoycottItem("website", domainName);
if (json) {
await showBoycottWarning(tabId, json);
return
}
}
return showOk(tabId);
}
async function showOk(tabId) {
await browserAPI.cacheSet({ boycottZItem: null })
browserAPI.setIcon({
tabId,
path: {
128: `/icons/green-triangle-128.png`,
},
});
}
async function showBoycottWarning(tabId, boycottObject) {
await browserAPI.cacheSet({ boycottZItem: boycottObject })
var notification = {
title: "Boycott Warning",
};
if (boycottObject.type === "brand") {
notification.message = `You visited a product from a boycotted brand: ${boycottObject.label}. Click on the boycott-Z extension to learn more.`;
} else if (boycottObject.type === "website") {
notification.message = `You visited a boycott brand's website: ${boycottObject.name}. Click on the boycott-Z extension to learn more.`;
} else if (boycottObject.type === "figure") {
notification.message = `You visited an anti-palestinian profile: ${boycottObject.name}. Click on the boycott-Z extension to learn more.`;
}
browserAPI.notify(notification);
await flash(6, 300, tabId);
}
async function flash(nTimes, period, tabId) {
return await new Promise((resolve) => {
let isEven = true;
const interval = setInterval(async () => {
if (nTimes == 0) {
await browserAPI.setIcon({
tabId,
path: {
128: `/icons/red-triangle-128.png`,
},
});
clearInterval(interval);
resolve();
} else {
await browserAPI.setIcon({
tabId,
path: {
128: `/icons/${isEven ? "red" : "green"}-triangle-128.png`,
},
});
isEven = !isEven;
}
nTimes--;
}, period);
});
}
async function injectScript(scriptName, tabId) {
await browserAPI.executeScript({
target: { tabId },
files: [`/content-scripts/${scriptName}.js`],
});
return;
}
async function getBoycottItem(itemType, key) {
let matcher = ""
if (itemType === 'website') {
matcher = `name=like.*${key}` // to include subdomains
} else if (itemType === 'brand') {
matcher = `name=like.*${key
.trim()
.replaceAll(" ", "%20")}*`
} else if (itemType === 'figure') {
key = key.trim()
let nameParts = key.split(" ").filter(x => !!x)
let keyX = key
.replaceAll(" ", "%20")
matcher = `name=like.*${keyX}*`
if (nameParts.length >= 3) {
matcher = `name.like.*${keyX}*`
let matcher2 = `name.like.*${nameParts.slice(0, 2).join(" ").replaceAll(" ", "%20")}*`
let matcher3 = `name.like.*${nameParts.slice(1, 3).join(" ").replaceAll(" ", "%20")}*`
matcher = `or=(${matcher},${matcher2},${matcher3})`
}
}
const url = `https://lwnimzaynwyplgjazboz.supabase.co/rest/v1/blacklist?limit=5&type=eq.${itemType}&${matcher}`;
const response = await fetch(url, {
headers: {
apiKey:
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imx3bmltemF5bnd5cGxnamF6Ym96Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTk3MDE0ODQsImV4cCI6MjAxNTI3NzQ4NH0.Cgv3FHAXjMU5aon3dgREuAdkVQ0l9LKRdtR6zrqaIFg",
},
});
if (!response.ok) {
let b = await response.json()
console.log(b)
throw new Error("Network response was not ok");
}
const jsonData = await response.json();
if (Array.isArray(jsonData) && jsonData.length > 0) {
return jsonData[0];
}
return null;
}
function getEcommerceTarget(url) {
const matchingSite = ecommerceTargets.find((site) => url.includes(site));
if (matchingSite) {
return { isEcommerce: true, target: matchingSite };
} else {
return { isEcommerce: false, target: null };
}
}
function getTarget(url) {
let matchingSite = ecommerceTargets.find((site) => url.includes(site));
if (matchingSite) return { type: "ecommerce", target: matchingSite }
matchingSite = socialTargets.find((site) => url.includes(site));
if (matchingSite) return { type: "social", target: matchingSite }
return { type: null, target: null }
}