Skip to content

Commit d61720e

Browse files
committed
Initial PoC changes for testing
1 parent 089d908 commit d61720e

File tree

6 files changed

+44
-12
lines changed

6 files changed

+44
-12
lines changed

injected/src/content-feature.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,12 @@ export default class ContentFeature extends ConfigFeature {
235235
/**
236236
* Define a property descriptor with debug flags.
237237
* Mainly used for defining new properties. For overriding existing properties, consider using wrapProperty(), wrapMethod() and wrapConstructor().
238-
* @param {any} object - object whose property we are wrapping (most commonly a prototype, e.g. globalThis.BatteryManager.prototype)
239-
* @param {string} propertyName
240-
* @param {import('./wrapper-utils').StrictPropertyDescriptor} descriptor - requires all descriptor options to be defined because we can't validate correctness based on TS types
241-
*/
238+
* @template Obj
239+
* @template {keyof Obj} Key
240+
* @param {Obj} object - object whose property we are wrapping (most commonly a prototype, e.g. globalThis.BatteryManager.prototype)
241+
* @param {Key} propertyName
242+
* @param {import('./wrapper-utils.js').StrictPropertyDescriptorGeneric<Obj, Key>} descriptor - requires all descriptor options to be defined because we can't validate correctness based on TS types
243+
*/
242244
defineProperty(object, propertyName, descriptor) {
243245
// make sure to send a debug flag when the property is used
244246
// NOTE: properties passing data in `value` would not be caught by this
@@ -247,16 +249,16 @@ export default class ContentFeature extends ConfigFeature {
247249
if (typeof descriptorProp === 'function') {
248250
const addDebugFlag = this.addDebugFlag.bind(this);
249251
const wrapper = new Proxy(descriptorProp, {
250-
apply(_, thisArg, argumentsList) {
252+
apply(target, thisArg, argumentsList) {
251253
addDebugFlag();
252-
return Reflect.apply(descriptorProp, thisArg, argumentsList);
254+
return target.apply(thisArg, argumentsList);
253255
},
254256
});
255257
descriptor[k] = wrapToString(wrapper, descriptorProp);
256258
}
257259
});
258260

259-
return defineProperty(object, propertyName, descriptor);
261+
return defineProperty(object, String(propertyName), /** @type {any} */ (descriptor));
260262
}
261263

262264
/**

injected/src/features/fingerprinting-temporary-storage.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default class FingerprintingTemporaryStorage extends ContentFeature {
2626
// @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f
2727
org.call(navigator.webkitTemporaryStorage, modifiedCallback, err);
2828
};
29+
// @ts-expect-error This doesn't exist in the DOM lib
2930
this.defineProperty(Navigator.prototype, 'webkitTemporaryStorage', {
3031
get: () => tStorage,
3132
enumerable: true,

injected/src/features/gpc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export default class GlobalPrivacyControl extends ContentFeature {
88
if (args.globalPrivacyControlValue) {
99
// @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f
1010
if (navigator.globalPrivacyControl) return;
11+
// @ts-expect-error This doesn't exist in the DOM lib
1112
this.defineProperty(Navigator.prototype, 'globalPrivacyControl', {
1213
get: () => true,
1314
configurable: true,
@@ -18,6 +19,7 @@ export default class GlobalPrivacyControl extends ContentFeature {
1819
// this may be overwritten by the user agent or other extensions
1920
// @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f
2021
if (typeof navigator.globalPrivacyControl !== 'undefined') return;
22+
// @ts-expect-error This doesn't exist in the DOM lib
2123
this.defineProperty(Navigator.prototype, 'globalPrivacyControl', {
2224
get: () => false,
2325
configurable: true,

injected/src/features/navigator-interface.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export default class NavigatorInterface extends ContentFeature {
2424
if (!args.platform || !args.platform.name) {
2525
return;
2626
}
27+
// @ts-expect-error This doesn't exist in the DOM lib
2728
this.defineProperty(Navigator.prototype, 'duckduckgo', {
2829
value: {
2930
platform: args.platform.name,

injected/src/features/web-compat.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// TypeScript is disabled for this file due to intentional DOM polyfills (e.g., Notification) that are incompatible with the DOM lib types.
12
import ContentFeature from '../content-feature.js';
23
// eslint-disable-next-line no-redeclare
34
import { URL } from '../captured-globals.js';
@@ -192,6 +193,7 @@ export class WebCompat extends ContentFeature {
192193
return;
193194
}
194195
// Expose the API
196+
// window.Notification polyfill is intentionally incompatible with DOM lib types
195197
this.defineProperty(window, 'Notification', {
196198
value: () => {
197199
// noop
@@ -200,8 +202,8 @@ export class WebCompat extends ContentFeature {
200202
configurable: true,
201203
enumerable: false,
202204
});
203-
204-
this.defineProperty(window.Notification, 'requestPermission', {
205+
// window.Notification polyfill is intentionally incompatible with DOM lib types
206+
this.defineProperty(/** @type {any} */ (window.Notification), 'requestPermission', {
205207
value: () => {
206208
return Promise.resolve('denied');
207209
},
@@ -210,13 +212,13 @@ export class WebCompat extends ContentFeature {
210212
enumerable: true,
211213
});
212214

213-
this.defineProperty(window.Notification, 'permission', {
215+
this.defineProperty(/** @type {any} */ (window.Notification), 'permission', {
214216
get: () => 'denied',
215217
configurable: true,
216218
enumerable: false,
217219
});
218220

219-
this.defineProperty(window.Notification, 'maxActions', {
221+
this.defineProperty(/** @type {any} */ (window.Notification), 'maxActions', {
220222
get: () => 2,
221223
configurable: true,
222224
enumerable: true,
@@ -400,6 +402,7 @@ export class WebCompat extends ContentFeature {
400402
};
401403
// TODO: original property is an accessor descriptor
402404
this.defineProperty(Navigator.prototype, 'credentials', {
405+
// validate this
403406
value,
404407
configurable: true,
405408
enumerable: true,
@@ -416,6 +419,7 @@ export class WebCompat extends ContentFeature {
416419
if (window.safari) {
417420
return;
418421
}
422+
// @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f
419423
this.defineProperty(window, 'safari', {
420424
value: {},
421425
writable: true,

injected/src/wrapper-utils.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,16 +366,38 @@ export function shimProperty(baseObject, propertyName, implInstance, readOnly, d
366366
*/
367367

368368
/**
369-
* @typedef {Object} BaseStrictPropertyDescriptor
369+
* A generic property descriptor for a property of an object, with correct `this` context for accessors.
370+
*
371+
* @template Obj The object type
372+
* @template {keyof Obj} Key The property key
373+
* @typedef {Object} StrictPropertyDescriptorGeneric
370374
* @property {boolean} configurable
371375
* @property {boolean} enumerable
376+
* @property {boolean} [writable]
377+
* @property {(function(this: Obj): Obj[Key]) |Obj[Key]} [value]
378+
* @property {(function(this: Obj): Obj[Key])} [get]
379+
* @property {(function(this: Obj, Obj[Key]): void)} [set]
372380
*/
373381

382+
383+
/**
384+
* @typedef {Object} BaseStrictPropertyDescriptor
385+
* @property {boolean} configurable
386+
* @property {boolean} enumerable
387+
* */
374388
/**
375389
* @typedef {BaseStrictPropertyDescriptor & { value: any; writable: boolean }} StrictDataDescriptor
390+
* */
391+
/**
376392
* @typedef {BaseStrictPropertyDescriptor & { get: () => any; set: (v: any) => void }} StrictAccessorDescriptor
393+
* */
394+
/**
377395
* @typedef {BaseStrictPropertyDescriptor & { get: () => any }} StrictGetDescriptor
396+
* */
397+
/**
378398
* @typedef {BaseStrictPropertyDescriptor & { set: (v: any) => void }} StrictSetDescriptor
399+
* */
400+
/**
379401
* @typedef {StrictDataDescriptor | StrictAccessorDescriptor | StrictGetDescriptor | StrictSetDescriptor} StrictPropertyDescriptor
380402
*/
381403

0 commit comments

Comments
 (0)