@freedomofpress/webcat 0.0.0-stage → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +45 -0
- package/data/block.json +101 -0
- package/data/list.json +80 -0
- package/dist/hooks/content.js +1 -0
- package/dist/lib/browser/chrome.d.ts +86 -0
- package/dist/lib/browser/chrome.js +138 -0
- package/dist/lib/browser/kvstore.d.ts +70 -0
- package/dist/lib/browser/kvstore.js +241 -0
- package/dist/lib/browser/permissions.d.ts +113 -0
- package/dist/lib/browser/permissions.js +182 -0
- package/dist/lib/browser/requests.d.ts +145 -0
- package/dist/lib/browser/requests.js +292 -0
- package/dist/lib/browser/scripting.d.ts +19 -0
- package/dist/lib/browser/scripting.js +92 -0
- package/dist/lib/browser/sync.d.ts +68 -0
- package/dist/lib/browser/sync.js +114 -0
- package/dist/lib/browser/utils.d.ts +5 -0
- package/dist/lib/browser/utils.js +11 -0
- package/dist/lib/config.d.ts +45 -0
- package/dist/lib/config.js +45 -0
- package/dist/lib/validator_set.d.ts +4 -0
- package/dist/lib/validator_set.js +20 -0
- package/dist/lib/webcat/cache.d.ts +200 -0
- package/dist/lib/webcat/cache.js +308 -0
- package/dist/lib/webcat/canonicalize.d.ts +1 -0
- package/dist/lib/webcat/canonicalize.js +58 -0
- package/dist/lib/webcat/db.d.ts +30 -0
- package/dist/lib/webcat/db.js +131 -0
- package/dist/lib/webcat/encoding.d.ts +8 -0
- package/dist/lib/webcat/encoding.js +57 -0
- package/dist/lib/webcat/handler.d.ts +26 -0
- package/dist/lib/webcat/handler.js +419 -0
- package/dist/lib/webcat/hookbuilder.d.ts +47 -0
- package/dist/lib/webcat/hookbuilder.js +170 -0
- package/dist/lib/webcat/interfaces/bundle.d.ts +46 -0
- package/dist/lib/webcat/interfaces/bundle.js +8 -0
- package/dist/lib/webcat/interfaces/database.d.ts +68 -0
- package/dist/lib/webcat/interfaces/database.js +1 -0
- package/dist/lib/webcat/interfaces/errors.d.ts +451 -0
- package/dist/lib/webcat/interfaces/errors.js +109 -0
- package/dist/lib/webcat/interfaces/log.d.ts +14 -0
- package/dist/lib/webcat/interfaces/log.js +10 -0
- package/dist/lib/webcat/interfaces/originstate.d.ts +40 -0
- package/dist/lib/webcat/interfaces/originstate.js +1 -0
- package/dist/lib/webcat/interfaces/requeststate.d.ts +10 -0
- package/dist/lib/webcat/interfaces/requeststate.js +1 -0
- package/dist/lib/webcat/logger.d.ts +64 -0
- package/dist/lib/webcat/logger.js +112 -0
- package/dist/lib/webcat/originstate.d.ts +45 -0
- package/dist/lib/webcat/originstate.js +302 -0
- package/dist/lib/webcat/parsers.d.ts +21 -0
- package/dist/lib/webcat/parsers.js +36 -0
- package/dist/lib/webcat/request.d.ts +11 -0
- package/dist/lib/webcat/request.js +78 -0
- package/dist/lib/webcat/resources.d.ts +3 -0
- package/dist/lib/webcat/resources.js +41 -0
- package/dist/lib/webcat/response.d.ts +39 -0
- package/dist/lib/webcat/response.js +394 -0
- package/dist/lib/webcat/ui.d.ts +70 -0
- package/dist/lib/webcat/ui.js +282 -0
- package/dist/lib/webcat/updater.d.ts +115 -0
- package/dist/lib/webcat/updater.js +296 -0
- package/dist/lib/webcat/utils.d.ts +8 -0
- package/dist/lib/webcat/utils.js +74 -0
- package/dist/lib/webcat/validators.d.ts +16 -0
- package/dist/lib/webcat/validators.js +457 -0
- package/dist/lib/webcat.d.ts +11 -0
- package/dist/lib/webcat.js +130 -0
- package/icons/dark/webcat-error.SVG +1 -0
- package/icons/dark/webcat-ok.SVG +1 -0
- package/icons/dark/webcat.SVG +1 -0
- package/icons/light/webcat-error.SVG +1 -0
- package/icons/light/webcat-ok.SVG +1 -0
- package/icons/light/webcat.SVG +1 -0
- package/package.json +72 -4
- package/pages/error.css +9 -0
- package/pages/error.html +70 -0
- package/pages/error.js +51 -0
- package/pages/popup.css +16 -0
- package/pages/popup.html +14 -0
- package/pages/popup.js +48 -0
- package/README.md +0 -3
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
var __typeError = (msg) => {
|
|
2
|
+
throw TypeError(msg);
|
|
3
|
+
};
|
|
4
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
5
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
6
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
7
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
8
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
9
|
+
var _resolve, _reject, _promise, _resolve2, _details, _responses, _details2, _currentListeners, _RequestHandler_instances, beforeRequest_fn, beforeHeaders_fn, headersReceived_fn, errorOccurred_fn, completed_fn;
|
|
10
|
+
import permissions from "./permissions.js";
|
|
11
|
+
import { buildUrlPatterns } from "./utils.js";
|
|
12
|
+
var __create = Object.create;
|
|
13
|
+
var __defProp = Object.defineProperty;
|
|
14
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
15
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
16
|
+
var __typeError2 = (msg) => {
|
|
17
|
+
throw TypeError(msg);
|
|
18
|
+
};
|
|
19
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
20
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
21
|
+
var __decoratorStart = (base) => [, , , __create(base?.[__knownSymbol("metadata")] ?? null)];
|
|
22
|
+
var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
|
|
23
|
+
var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError2("Function expected") : fn;
|
|
24
|
+
var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError2("Already initialized") : fns.push(__expectFn(fn || null)) });
|
|
25
|
+
var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
|
|
26
|
+
var __runInitializers = (array, flags, self, value) => {
|
|
27
|
+
for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) fns[i].call(self);
|
|
28
|
+
return value;
|
|
29
|
+
};
|
|
30
|
+
var __decorateElement = (array, flags, name, decorators, target, extra) => {
|
|
31
|
+
var it, done, ctx, k = flags & 7, p = false;
|
|
32
|
+
var j = 0;
|
|
33
|
+
var extraInitializers = array[j] || (array[j] = []);
|
|
34
|
+
var desc = k && (target = target.prototype, k < 5 && (k > 3 || !p) && __getOwnPropDesc(target, name));
|
|
35
|
+
__name(target, name);
|
|
36
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
37
|
+
ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
|
|
38
|
+
it = (0, decorators[i])(target, ctx), done._ = 1;
|
|
39
|
+
__expectFn(it) && (target = it);
|
|
40
|
+
}
|
|
41
|
+
return __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
|
|
42
|
+
};
|
|
43
|
+
var _RequestHandler_decorators, _init, _a;
|
|
44
|
+
class RequestDetailsBase {
|
|
45
|
+
constructor() {
|
|
46
|
+
__privateAdd(this, _resolve);
|
|
47
|
+
__privateAdd(this, _reject);
|
|
48
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
49
|
+
promise.catch(() => {
|
|
50
|
+
});
|
|
51
|
+
this.completed = promise;
|
|
52
|
+
__privateSet(this, _resolve, resolve);
|
|
53
|
+
__privateSet(this, _reject, reject);
|
|
54
|
+
}
|
|
55
|
+
/** @internal */
|
|
56
|
+
complete() {
|
|
57
|
+
__privateGet(this, _resolve).call(this);
|
|
58
|
+
}
|
|
59
|
+
/** @internal */
|
|
60
|
+
fail() {
|
|
61
|
+
__privateGet(this, _reject).call(this);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
_resolve = new WeakMap();
|
|
65
|
+
_reject = new WeakMap();
|
|
66
|
+
const dispose = Symbol.dispose ?? Symbol.for("Symbol.dispose");
|
|
67
|
+
class BlockingResponse {
|
|
68
|
+
constructor(details) {
|
|
69
|
+
__privateAdd(this, _promise);
|
|
70
|
+
__privateAdd(this, _resolve2);
|
|
71
|
+
__privateAdd(this, _details);
|
|
72
|
+
this.cancel = true;
|
|
73
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
74
|
+
__privateSet(this, _promise, promise);
|
|
75
|
+
__privateSet(this, _resolve2, resolve);
|
|
76
|
+
__privateSet(this, _details, details);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Implements the {@link Disposable} interface.
|
|
80
|
+
*/
|
|
81
|
+
[dispose]() {
|
|
82
|
+
__privateGet(this, _resolve2).call(this, this);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* @returns A Promise that resolves to this BlockingResponse after disposal.
|
|
86
|
+
*/
|
|
87
|
+
ready() {
|
|
88
|
+
return __privateGet(this, _promise);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* @param value An object whose properties are copied to this BlockingResponse.
|
|
92
|
+
*/
|
|
93
|
+
set(value) {
|
|
94
|
+
Object.assign(this, value);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Sets the response header `name` to `value`, replacing any existing
|
|
98
|
+
* occurrences. Starts from the response's original headers, so the rest
|
|
99
|
+
* pass through unchanged.
|
|
100
|
+
*/
|
|
101
|
+
setHeader(name, value) {
|
|
102
|
+
const lower = name.toLowerCase();
|
|
103
|
+
const original = __privateGet(this, _details) && "responseHeaders" in __privateGet(this, _details) ? __privateGet(this, _details).responseHeaders : void 0;
|
|
104
|
+
this.responseHeaders = [
|
|
105
|
+
...(this.responseHeaders ?? original ?? []).filter(
|
|
106
|
+
(h) => h.name.toLowerCase() !== lower
|
|
107
|
+
),
|
|
108
|
+
{ name, value }
|
|
109
|
+
];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
_promise = new WeakMap();
|
|
113
|
+
_resolve2 = new WeakMap();
|
|
114
|
+
_details = new WeakMap();
|
|
115
|
+
class RequestEvent extends Event {
|
|
116
|
+
/** @internal */
|
|
117
|
+
constructor(type, details) {
|
|
118
|
+
super(type);
|
|
119
|
+
__privateAdd(this, _responses, []);
|
|
120
|
+
this.details = details;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Creates a {@link BlockingResponse} for this event. Each listener creates
|
|
124
|
+
* its own before its first await expression, so that listeners respond
|
|
125
|
+
* independently of each other; see {@link ready} for how the responses are
|
|
126
|
+
* combined.
|
|
127
|
+
*
|
|
128
|
+
* @returns A new BlockingResponse that cancels the request unless the
|
|
129
|
+
* listener sets {@link BlockingResponse.cancel} to false.
|
|
130
|
+
*/
|
|
131
|
+
createBlockingResponse() {
|
|
132
|
+
const response = new BlockingResponse(this.details);
|
|
133
|
+
__privateGet(this, _responses).push(response);
|
|
134
|
+
return response;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Awaits all BlockingResponses created for this event and merges them into
|
|
138
|
+
* a single response. If any of them cancels the request, so does the
|
|
139
|
+
* result; otherwise, their other properties are combined. With no
|
|
140
|
+
* BlockingResponses, the request proceeds unchanged.
|
|
141
|
+
*
|
|
142
|
+
* @returns A Promise that resolves to the merged response.
|
|
143
|
+
* @internal
|
|
144
|
+
*/
|
|
145
|
+
async ready() {
|
|
146
|
+
const responses = await Promise.all(__privateGet(this, _responses).map((r) => r.ready()));
|
|
147
|
+
const merged = Object.assign(
|
|
148
|
+
{},
|
|
149
|
+
...responses
|
|
150
|
+
);
|
|
151
|
+
merged.cancel = responses.some((response) => response.cancel !== false);
|
|
152
|
+
return merged;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
_responses = new WeakMap();
|
|
156
|
+
_RequestHandler_decorators = [permissions.require("webRequest"), permissions.require("webRequestBlocking")];
|
|
157
|
+
class RequestHandler extends (_a = EventTarget) {
|
|
158
|
+
constructor() {
|
|
159
|
+
super(...arguments);
|
|
160
|
+
__privateAdd(this, _RequestHandler_instances);
|
|
161
|
+
__privateAdd(this, _details2, /* @__PURE__ */ new Map());
|
|
162
|
+
__privateAdd(this, _currentListeners, {});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Binds the handler to the given list of FQDNs. When called, the handler
|
|
166
|
+
* starts handling requests for the FQDNs in the list and stops handling
|
|
167
|
+
* requests for any previously bound FQDNs that are not in the new list.
|
|
168
|
+
*
|
|
169
|
+
* @param fqdns A list of fully-qualified domain names to bind to.
|
|
170
|
+
*/
|
|
171
|
+
bind(fqdns) {
|
|
172
|
+
const before = (details) => __privateMethod(this, _RequestHandler_instances, beforeRequest_fn).call(this, details);
|
|
173
|
+
const beforeHeaders = (details) => __privateMethod(this, _RequestHandler_instances, beforeHeaders_fn).call(this, details);
|
|
174
|
+
const headers = (details) => __privateMethod(this, _RequestHandler_instances, headersReceived_fn).call(this, details);
|
|
175
|
+
const errorOccurred = (details) => __privateMethod(this, _RequestHandler_instances, errorOccurred_fn).call(this, details);
|
|
176
|
+
const completed = (details) => __privateMethod(this, _RequestHandler_instances, completed_fn).call(this, details);
|
|
177
|
+
browser.webRequest.onBeforeRequest.addListener(
|
|
178
|
+
before,
|
|
179
|
+
...this.getListenerOptions(fqdns, "beforerequest")
|
|
180
|
+
);
|
|
181
|
+
browser.webRequest.onBeforeSendHeaders.addListener(
|
|
182
|
+
beforeHeaders,
|
|
183
|
+
...this.getListenerOptions(fqdns, "beforeheaders")
|
|
184
|
+
);
|
|
185
|
+
browser.webRequest.onHeadersReceived.addListener(
|
|
186
|
+
headers,
|
|
187
|
+
...this.getListenerOptions(fqdns, "headersreceived")
|
|
188
|
+
);
|
|
189
|
+
browser.webRequest.onErrorOccurred.addListener(
|
|
190
|
+
errorOccurred,
|
|
191
|
+
...this.getListenerOptions(fqdns, "erroroccurred")
|
|
192
|
+
);
|
|
193
|
+
browser.webRequest.onCompleted.addListener(
|
|
194
|
+
completed,
|
|
195
|
+
...this.getListenerOptions(fqdns, "completed")
|
|
196
|
+
);
|
|
197
|
+
const previous = __privateGet(this, _currentListeners);
|
|
198
|
+
__privateSet(this, _currentListeners, {
|
|
199
|
+
before,
|
|
200
|
+
beforeHeaders,
|
|
201
|
+
headers,
|
|
202
|
+
errorOccurred,
|
|
203
|
+
completed
|
|
204
|
+
});
|
|
205
|
+
if (previous.before) {
|
|
206
|
+
browser.webRequest.onBeforeRequest.removeListener(previous.before);
|
|
207
|
+
}
|
|
208
|
+
if (previous.beforeHeaders) {
|
|
209
|
+
browser.webRequest.onBeforeSendHeaders.removeListener(
|
|
210
|
+
previous.beforeHeaders
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
if (previous.headers) {
|
|
214
|
+
browser.webRequest.onHeadersReceived.removeListener(previous.headers);
|
|
215
|
+
}
|
|
216
|
+
if (previous.errorOccurred) {
|
|
217
|
+
browser.webRequest.onErrorOccurred.removeListener(previous.errorOccurred);
|
|
218
|
+
}
|
|
219
|
+
if (previous.completed) {
|
|
220
|
+
browser.webRequest.onCompleted.removeListener(previous.completed);
|
|
221
|
+
}
|
|
222
|
+
console.log(
|
|
223
|
+
`[webcat] RequestHandler.bind: registered listeners for ${fqdns.length} URL(s)`
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
// prettier-ignore
|
|
227
|
+
getListenerOptions(fqdns, type) {
|
|
228
|
+
const urls = buildUrlPatterns(fqdns);
|
|
229
|
+
switch (type) {
|
|
230
|
+
case "beforerequest":
|
|
231
|
+
return [{ urls }, ["blocking"]];
|
|
232
|
+
case "beforeheaders":
|
|
233
|
+
return [{ urls }, ["blocking", "requestHeaders"]];
|
|
234
|
+
case "headersreceived":
|
|
235
|
+
return [{ urls }, ["blocking", "responseHeaders"]];
|
|
236
|
+
case "erroroccurred":
|
|
237
|
+
case "completed":
|
|
238
|
+
return [{ urls }];
|
|
239
|
+
default:
|
|
240
|
+
throw new TypeError(`unrecognized handler type '${type}'`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
_details2 = new WeakMap();
|
|
245
|
+
_currentListeners = new WeakMap();
|
|
246
|
+
_RequestHandler_instances = new WeakSet();
|
|
247
|
+
beforeRequest_fn = async function(d) {
|
|
248
|
+
const details = Object.assign(new RequestDetailsBase(), d);
|
|
249
|
+
__privateGet(this, _details2).set(details.requestId, details);
|
|
250
|
+
const event = new RequestEvent("beforerequest", details);
|
|
251
|
+
this.dispatchEvent(event);
|
|
252
|
+
return await event.ready();
|
|
253
|
+
};
|
|
254
|
+
beforeHeaders_fn = async function(d) {
|
|
255
|
+
const base = __privateGet(this, _details2).get(d.requestId) ?? new RequestDetailsBase();
|
|
256
|
+
const details = Object.assign(base, d);
|
|
257
|
+
const event = new RequestEvent("beforeheaders", details);
|
|
258
|
+
this.dispatchEvent(event);
|
|
259
|
+
return await event.ready();
|
|
260
|
+
};
|
|
261
|
+
headersReceived_fn = async function(d) {
|
|
262
|
+
const base = __privateGet(this, _details2).get(d.requestId) ?? new RequestDetailsBase();
|
|
263
|
+
const details = Object.assign(base, d);
|
|
264
|
+
const event = new RequestEvent("headersreceived", details);
|
|
265
|
+
this.dispatchEvent(event);
|
|
266
|
+
return await event.ready();
|
|
267
|
+
};
|
|
268
|
+
errorOccurred_fn = function(d) {
|
|
269
|
+
const base = __privateGet(this, _details2).get(d.requestId) ?? new RequestDetailsBase();
|
|
270
|
+
const details = Object.assign(base, d);
|
|
271
|
+
details.fail();
|
|
272
|
+
const event = new RequestEvent("erroroccurred", details);
|
|
273
|
+
this.dispatchEvent(event);
|
|
274
|
+
__privateGet(this, _details2).delete(details.requestId);
|
|
275
|
+
};
|
|
276
|
+
completed_fn = function(d) {
|
|
277
|
+
const base = __privateGet(this, _details2).get(d.requestId) ?? new RequestDetailsBase();
|
|
278
|
+
const details = Object.assign(base, d);
|
|
279
|
+
details.complete();
|
|
280
|
+
const event = new RequestEvent("completed", details);
|
|
281
|
+
this.dispatchEvent(event);
|
|
282
|
+
__privateGet(this, _details2).delete(details.requestId);
|
|
283
|
+
};
|
|
284
|
+
_init = __decoratorStart(_a);
|
|
285
|
+
RequestHandler = __decorateElement(_init, 0, "RequestHandler", _RequestHandler_decorators, RequestHandler);
|
|
286
|
+
__runInitializers(_init, 1, RequestHandler);
|
|
287
|
+
export {
|
|
288
|
+
BlockingResponse,
|
|
289
|
+
RequestDetailsBase,
|
|
290
|
+
RequestEvent,
|
|
291
|
+
RequestHandler
|
|
292
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a single content script in a static file.
|
|
3
|
+
*/
|
|
4
|
+
export declare class ContentScript {
|
|
5
|
+
#private;
|
|
6
|
+
/**
|
|
7
|
+
* @param path Path to a script file.
|
|
8
|
+
*/
|
|
9
|
+
constructor(path: string);
|
|
10
|
+
/**
|
|
11
|
+
* Binds the content script to the given list of FQDNs. When called, the
|
|
12
|
+
* content script is registered for the FQDNs in the list and unregistered
|
|
13
|
+
* for all other FQDNS.
|
|
14
|
+
*
|
|
15
|
+
* @param fqdns A list of fully-qualified domain names to bind the script to.
|
|
16
|
+
* @returns A list of the FQDNs that the script was not yet bound to.
|
|
17
|
+
*/
|
|
18
|
+
bind(fqdns: string[]): Promise<string[]>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
var __typeError = (msg) => {
|
|
2
|
+
throw TypeError(msg);
|
|
3
|
+
};
|
|
4
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
5
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
6
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
7
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
8
|
+
var _idPrefix, _path;
|
|
9
|
+
import permissions from "./permissions.js";
|
|
10
|
+
import { buildUrlPatterns } from "./utils.js";
|
|
11
|
+
var __create = Object.create;
|
|
12
|
+
var __defProp = Object.defineProperty;
|
|
13
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
14
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
15
|
+
var __typeError2 = (msg) => {
|
|
16
|
+
throw TypeError(msg);
|
|
17
|
+
};
|
|
18
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
19
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
20
|
+
var __decoratorStart = (base) => [, , , __create(null)];
|
|
21
|
+
var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
|
|
22
|
+
var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError2("Function expected") : fn;
|
|
23
|
+
var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError2("Already initialized") : fns.push(__expectFn(fn || null)) });
|
|
24
|
+
var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
|
|
25
|
+
var __runInitializers = (array, flags, self, value) => {
|
|
26
|
+
for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) fns[i].call(self);
|
|
27
|
+
return value;
|
|
28
|
+
};
|
|
29
|
+
var __decorateElement = (array, flags, name, decorators, target, extra) => {
|
|
30
|
+
var it, done, ctx, k = flags & 7, p = false;
|
|
31
|
+
var j = 0;
|
|
32
|
+
var extraInitializers = array[j] || (array[j] = []);
|
|
33
|
+
var desc = k && (target = target.prototype, k < 5 && (k > 3 || !p) && __getOwnPropDesc(target, name));
|
|
34
|
+
__name(target, name);
|
|
35
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
36
|
+
ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
|
|
37
|
+
it = (0, decorators[i])(target, ctx), done._ = 1;
|
|
38
|
+
__expectFn(it) && (target = it);
|
|
39
|
+
}
|
|
40
|
+
return __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
|
|
41
|
+
};
|
|
42
|
+
var _ContentScript_decorators, _init;
|
|
43
|
+
_ContentScript_decorators = [permissions.require("scripting")];
|
|
44
|
+
class ContentScript {
|
|
45
|
+
/**
|
|
46
|
+
* @param path Path to a script file.
|
|
47
|
+
*/
|
|
48
|
+
constructor(path) {
|
|
49
|
+
__privateAdd(this, _idPrefix);
|
|
50
|
+
__privateAdd(this, _path);
|
|
51
|
+
__privateSet(this, _path, path);
|
|
52
|
+
__privateSet(this, _idPrefix, `webcat-script:${path}:`);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Binds the content script to the given list of FQDNs. When called, the
|
|
56
|
+
* content script is registered for the FQDNs in the list and unregistered
|
|
57
|
+
* for all other FQDNS.
|
|
58
|
+
*
|
|
59
|
+
* @param fqdns A list of fully-qualified domain names to bind the script to.
|
|
60
|
+
* @returns A list of the FQDNs that the script was not yet bound to.
|
|
61
|
+
*/
|
|
62
|
+
async bind(fqdns) {
|
|
63
|
+
const registeredFqdns = (await browser.scripting.getRegisteredContentScripts()).filter((script) => script.id.startsWith(__privateGet(this, _idPrefix))).map((script) => script.id.substring(__privateGet(this, _idPrefix).length));
|
|
64
|
+
const newFqdns = fqdns.filter((fqdn) => {
|
|
65
|
+
return !registeredFqdns.includes(fqdn);
|
|
66
|
+
});
|
|
67
|
+
await browser.scripting.registerContentScripts(
|
|
68
|
+
newFqdns.map((fqdn) => {
|
|
69
|
+
return {
|
|
70
|
+
id: __privateGet(this, _idPrefix) + fqdn,
|
|
71
|
+
js: [__privateGet(this, _path)],
|
|
72
|
+
matches: buildUrlPatterns([fqdn]),
|
|
73
|
+
matchOriginAsFallback: true,
|
|
74
|
+
allFrames: true,
|
|
75
|
+
runAt: "document_start"
|
|
76
|
+
};
|
|
77
|
+
})
|
|
78
|
+
);
|
|
79
|
+
await browser.scripting.unregisterContentScripts({
|
|
80
|
+
ids: registeredFqdns.filter((fqdn) => !fqdns.includes(fqdn)).map((fqdn) => __privateGet(this, _idPrefix) + fqdn)
|
|
81
|
+
});
|
|
82
|
+
return newFqdns;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
_idPrefix = new WeakMap();
|
|
86
|
+
_path = new WeakMap();
|
|
87
|
+
_init = __decoratorStart();
|
|
88
|
+
ContentScript = __decorateElement(_init, 0, "ContentScript", _ContentScript_decorators, ContentScript);
|
|
89
|
+
__runInitializers(_init, 1, ContentScript);
|
|
90
|
+
export {
|
|
91
|
+
ContentScript
|
|
92
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An object that can be held and released by a {@link Lock}.
|
|
3
|
+
*/
|
|
4
|
+
export type Releasable = {
|
|
5
|
+
release(): void;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* A {@link Disposable} that holds a {@link Releasable} (e.g. a {@link Mutex})
|
|
9
|
+
* and releases it when disposed. When multiple scopes hold the same Lock, the
|
|
10
|
+
* Releasable is only released when all holders have disposed.
|
|
11
|
+
*/
|
|
12
|
+
export declare class Lock implements Disposable {
|
|
13
|
+
#private;
|
|
14
|
+
/**
|
|
15
|
+
* The object held by this Lock; usually a {@link Mutex}.
|
|
16
|
+
*/
|
|
17
|
+
readonly mutex: Releasable;
|
|
18
|
+
/**
|
|
19
|
+
* @param mutex The object held by this Lock; usually a {@link Mutex}.
|
|
20
|
+
*/
|
|
21
|
+
constructor(mutex: Releasable);
|
|
22
|
+
/**
|
|
23
|
+
* Implements the {@link Disposable} interface.
|
|
24
|
+
*/
|
|
25
|
+
get [Symbol.dispose](): () => void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A mutex for enforcing execution order in asynchronous code.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* class AsyncThing {
|
|
32
|
+
* #mutex = new Mutex();
|
|
33
|
+
* async doSomeThings(x) { // Guaranteed execution order:
|
|
34
|
+
* using _ = await this.#mutex.acquire(); //
|
|
35
|
+
* await thingNumberOne(x); // 1. t.doSomeThings(1)
|
|
36
|
+
* await thingNumberTwo(x); // 1.1. thingNumberOne(1)
|
|
37
|
+
* } // 1.2. thingNumberTwo(1)
|
|
38
|
+
* } // 2. t.doSomethings(2)
|
|
39
|
+
* // 2.1. thingNumberOne(2)
|
|
40
|
+
* const t = new AsyncThing(); // 2.2. thingNumberTwo(2)
|
|
41
|
+
* t.doSomeThings(1); // 3. t.doSomethings(3)
|
|
42
|
+
* t.doSomeThings(2); // 3.1. thingNumberOne(3)
|
|
43
|
+
* t.doSomeThings(3); // 3.2. thingNumberTwo(3)
|
|
44
|
+
*/
|
|
45
|
+
export declare class Mutex implements Releasable {
|
|
46
|
+
#private;
|
|
47
|
+
/**
|
|
48
|
+
* Locks this Mutex. Calling `await mutex.acquire()` on an unlocked Mutex
|
|
49
|
+
* returns immediately. Calling it on a locked Mutex awaits until the Mutex
|
|
50
|
+
* is released. Calling `await mutex.acquire(lock)` with the lock that is
|
|
51
|
+
* holding the Mutex returns immediately and returns the same lock, which is
|
|
52
|
+
* useful, for example, in recursive algorithms.
|
|
53
|
+
*
|
|
54
|
+
* @param lock An optional Lock that will be used to hold the Mutex.
|
|
55
|
+
* @returns The Lock currently holding the locked Mutex.
|
|
56
|
+
*/
|
|
57
|
+
acquire(lock?: Lock): Promise<Lock>;
|
|
58
|
+
/**
|
|
59
|
+
* Releases this Mutex. Called either directly or by the {@link Lock} holding
|
|
60
|
+
* the Mutex as it gets disposed.
|
|
61
|
+
*/
|
|
62
|
+
release(): void;
|
|
63
|
+
/**
|
|
64
|
+
* @returns A new {@link Lock} for this Mutex. Unlike {@link acquire}, does
|
|
65
|
+
* not lock the Mutex; to use the Lock, pass it to acquire.
|
|
66
|
+
*/
|
|
67
|
+
createLock(): Lock;
|
|
68
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
var __typeError = (msg) => {
|
|
2
|
+
throw TypeError(msg);
|
|
3
|
+
};
|
|
4
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
5
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
6
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
7
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
8
|
+
var __privateWrapper = (obj, member, setter, getter) => ({
|
|
9
|
+
set _(value) {
|
|
10
|
+
__privateSet(obj, member, value, setter);
|
|
11
|
+
},
|
|
12
|
+
get _() {
|
|
13
|
+
return __privateGet(obj, member, getter);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
var _holders, _resolvers, _lock;
|
|
17
|
+
class Lock {
|
|
18
|
+
/**
|
|
19
|
+
* @param mutex The object held by this Lock; usually a {@link Mutex}.
|
|
20
|
+
*/
|
|
21
|
+
constructor(mutex) {
|
|
22
|
+
__privateAdd(this, _holders, 0);
|
|
23
|
+
this.mutex = mutex;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Implements the {@link Disposable} interface.
|
|
27
|
+
*/
|
|
28
|
+
get [Symbol.dispose]() {
|
|
29
|
+
__privateWrapper(this, _holders)._++;
|
|
30
|
+
return () => {
|
|
31
|
+
__privateWrapper(this, _holders)._--;
|
|
32
|
+
if (__privateGet(this, _holders) === 0) {
|
|
33
|
+
this.mutex.release();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
_holders = new WeakMap();
|
|
39
|
+
if (!Symbol.dispose) {
|
|
40
|
+
const { get } = Object.getOwnPropertyDescriptor(
|
|
41
|
+
Lock.prototype,
|
|
42
|
+
Symbol.dispose
|
|
43
|
+
);
|
|
44
|
+
Object.defineProperty(Lock.prototype, Symbol.for("Symbol.dispose"), { get });
|
|
45
|
+
delete Lock.prototype[Symbol.dispose];
|
|
46
|
+
}
|
|
47
|
+
class Mutex {
|
|
48
|
+
constructor() {
|
|
49
|
+
__privateAdd(this, _resolvers, []);
|
|
50
|
+
__privateAdd(this, _lock);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Locks this Mutex. Calling `await mutex.acquire()` on an unlocked Mutex
|
|
54
|
+
* returns immediately. Calling it on a locked Mutex awaits until the Mutex
|
|
55
|
+
* is released. Calling `await mutex.acquire(lock)` with the lock that is
|
|
56
|
+
* holding the Mutex returns immediately and returns the same lock, which is
|
|
57
|
+
* useful, for example, in recursive algorithms.
|
|
58
|
+
*
|
|
59
|
+
* @param lock An optional Lock that will be used to hold the Mutex.
|
|
60
|
+
* @returns The Lock currently holding the locked Mutex.
|
|
61
|
+
*/
|
|
62
|
+
async acquire(lock) {
|
|
63
|
+
if (__privateGet(this, _lock) === void 0) {
|
|
64
|
+
if (lock && lock.mutex == this) {
|
|
65
|
+
__privateSet(this, _lock, lock);
|
|
66
|
+
} else {
|
|
67
|
+
__privateSet(this, _lock, this.createLock());
|
|
68
|
+
}
|
|
69
|
+
return __privateGet(this, _lock);
|
|
70
|
+
} else if (lock && lock === __privateGet(this, _lock)) {
|
|
71
|
+
return __privateGet(this, _lock);
|
|
72
|
+
} else {
|
|
73
|
+
return new Promise((resolve) => {
|
|
74
|
+
__privateGet(this, _resolvers).push([resolve, lock ?? this.createLock()]);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Releases this Mutex. Called either directly or by the {@link Lock} holding
|
|
80
|
+
* the Mutex as it gets disposed.
|
|
81
|
+
*/
|
|
82
|
+
release() {
|
|
83
|
+
if (__privateGet(this, _resolvers).length > 0) {
|
|
84
|
+
const [next, lock] = __privateGet(this, _resolvers).shift();
|
|
85
|
+
__privateSet(this, _lock, lock);
|
|
86
|
+
next(__privateGet(this, _lock));
|
|
87
|
+
while (__privateGet(this, _lock) === lock) {
|
|
88
|
+
const i = __privateGet(this, _resolvers).findIndex(([_, lock2]) => {
|
|
89
|
+
return lock2 === __privateGet(this, _lock);
|
|
90
|
+
});
|
|
91
|
+
if (i === -1) {
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
const [[next2]] = __privateGet(this, _resolvers).splice(i, 1);
|
|
95
|
+
next2(__privateGet(this, _lock));
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
__privateSet(this, _lock, void 0);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* @returns A new {@link Lock} for this Mutex. Unlike {@link acquire}, does
|
|
103
|
+
* not lock the Mutex; to use the Lock, pass it to acquire.
|
|
104
|
+
*/
|
|
105
|
+
createLock() {
|
|
106
|
+
return new Lock(this);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
_resolvers = new WeakMap();
|
|
110
|
+
_lock = new WeakMap();
|
|
111
|
+
export {
|
|
112
|
+
Lock,
|
|
113
|
+
Mutex
|
|
114
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param fqdns An array of fully-qualified domain names.
|
|
3
|
+
* @returns An array of {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns | patterns} that match the FQDNs.
|
|
4
|
+
*/
|
|
5
|
+
export declare function buildUrlPatterns(fqdns: string[]): string[];
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { BrowserChromeControllerConfig, PathTemplateProperties } from "./browser/chrome";
|
|
2
|
+
import { WebcatDatabaseConfig } from "./webcat/db";
|
|
3
|
+
import { HookBuilderConfig } from "./webcat/hookbuilder";
|
|
4
|
+
import { BundleFetcherConfig } from "./webcat/originstate";
|
|
5
|
+
import { EnrollmentUpdaterConfig } from "./webcat/updater";
|
|
6
|
+
/**
|
|
7
|
+
* Global WEBCAT configuration. See {@link defaults}.
|
|
8
|
+
*
|
|
9
|
+
* @interface
|
|
10
|
+
*/
|
|
11
|
+
export type WebcatConfig = BundleFetcherConfig & WebcatDatabaseConfig & HookBuilderConfig & Omit<EnrollmentUpdaterConfig, "database"> & BrowserChromeControllerConfig;
|
|
12
|
+
/** Default {@link WebcatConfig} values. */
|
|
13
|
+
export declare const defaults: {
|
|
14
|
+
/** {@inheritDoc WebcatConfig.namespace} */
|
|
15
|
+
readonly namespace: "WEBCAT";
|
|
16
|
+
/** {@inheritDoc WebcatConfig.originCacheSize} */
|
|
17
|
+
readonly originCacheSize: 32;
|
|
18
|
+
/** {@inheritDoc WebcatConfig.nonOriginCacheSize} */
|
|
19
|
+
readonly nonOriginCacheSize: 8192;
|
|
20
|
+
/** {@inheritDoc WebcatConfig.bundlePath} */
|
|
21
|
+
readonly bundlePath: "/.well-known/webcat/bundle.json";
|
|
22
|
+
/** {@inheritDoc WebcatConfig.bundlePrevPath} */
|
|
23
|
+
readonly bundlePrevPath: "/.well-known/webcat/bundle-prev.json";
|
|
24
|
+
/** {@inheritDoc WebcatConfig.endpoint} */
|
|
25
|
+
readonly endpoint: "https://webcat.freedom.press/";
|
|
26
|
+
/** {@inheritDoc WebcatConfig.localDataPath} */
|
|
27
|
+
readonly localDataPath: "data";
|
|
28
|
+
/** {@inheritDoc WebcatConfig.validatorSet} */
|
|
29
|
+
readonly validatorSet: import("@freedomofpress/cometbft/dist/types.js").ValidatorJson;
|
|
30
|
+
readonly chainId: "webcat-test-02";
|
|
31
|
+
/** {@inheritDoc WebcatConfig.updateInterval} */
|
|
32
|
+
readonly updateInterval: number;
|
|
33
|
+
/** {@inheritDoc WebcatConfig.checkInterval} */
|
|
34
|
+
readonly checkInterval: number;
|
|
35
|
+
/** {@inheritDoc WebcatConfig.fetchTimeout} */
|
|
36
|
+
readonly fetchTimeout: 3000;
|
|
37
|
+
/** {@inheritDoc WebcatConfig.staticHookPath} */
|
|
38
|
+
readonly staticHookPath: "dist/hooks/content.js";
|
|
39
|
+
/** {@inheritDoc WebcatConfig.iconPaths} */
|
|
40
|
+
readonly iconPaths: (p: PathTemplateProperties) => string;
|
|
41
|
+
/** {@inheritDoc WebcatConfig.pagePaths} */
|
|
42
|
+
readonly pagePaths: (p: PathTemplateProperties) => string;
|
|
43
|
+
};
|
|
44
|
+
/** @internal */
|
|
45
|
+
export declare const test: WebcatConfig;
|