Skip to content

allow non-protection features to survive protections toggle #1564

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions injected/entry-points/android.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @module Android integration
*/
import { load, init } from '../src/content-scope-features.js';
import { processConfig, isGloballyDisabled } from './../src/utils';
import { processConfig } from './../src/utils';
import { AndroidMessagingConfig } from '../../messaging/index.js';

function initCode() {
Expand All @@ -14,9 +14,6 @@ function initCode() {
const userPreferences = $USER_PREFERENCES$;

const processedConfig = processConfig(config, userUnprotectedDomains, userPreferences);
if (isGloballyDisabled(processedConfig)) {
return;
}

const configConstruct = processedConfig;
const messageCallback = configConstruct.messageCallback;
Expand Down
6 changes: 1 addition & 5 deletions injected/entry-points/apple.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @module Apple integration
*/
import { load, init } from '../src/content-scope-features.js';
import { processConfig, isGloballyDisabled, platformSpecificFeatures } from './../src/utils';
import { processConfig, platformSpecificFeatures } from './../src/utils';
import { WebkitMessagingConfig, TestTransportConfig } from '../../messaging/index.js';

function initCode() {
Expand All @@ -15,10 +15,6 @@ function initCode() {

const processedConfig = processConfig(config, userUnprotectedDomains, userPreferences, platformSpecificFeatures);

if (isGloballyDisabled(processedConfig)) {
return;
}

if (import.meta.injectName === 'apple-isolated') {
processedConfig.messagingConfig = new WebkitMessagingConfig({
webkitMessageHandlerNames: ['contentScopeScriptsIsolated'],
Expand Down
9 changes: 8 additions & 1 deletion injected/entry-points/integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@ function generateConfig() {
domain: topLevelUrl.hostname,
isBroken: false,
allowlisted: false,
enabledFeatures: ['fingerprintingCanvas', 'fingerprintingScreenSize', 'navigatorInterface', 'cookie'],
enabledFeatures: [
'fingerprintingCanvas',
'fingerprintingScreenSize',
'navigatorInterface',
'cookie',
'webCompat',
'apiManipulation',
],
},
};
}
Expand Down
6 changes: 2 additions & 4 deletions injected/entry-points/windows.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @module Windows integration
*/
import { load, init } from '../src/content-scope-features.js';
import { processConfig, isGloballyDisabled, platformSpecificFeatures } from './../src/utils';
import { processConfig, platformSpecificFeatures } from './../src/utils';
import { WindowsMessagingConfig } from '../../messaging/index.js';

function initCode() {
Expand All @@ -14,9 +14,7 @@ function initCode() {
const userPreferences = $USER_PREFERENCES$;

const processedConfig = processConfig(config, userUnprotectedDomains, userPreferences, platformSpecificFeatures);
if (isGloballyDisabled(processedConfig)) {
return;
}

processedConfig.messagingConfig = new WindowsMessagingConfig({
methods: {
// @ts-expect-error - Type 'unknown' is not assignable to type...
Expand Down
2 changes: 1 addition & 1 deletion injected/integration-test/navigator-interface.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const test = testContextForExtension(base);

test.describe('Ensure navigator interface is injected', () => {
test('should expose navigator.navigator.isDuckDuckGo(): Promise<boolean> and platform === "extension"', async ({ page }) => {
await gotoAndWait(page, '/blank.html', { platform: { name: 'extension' } });
await gotoAndWait(page, '/blank.html');
const isDuckDuckGoResult = await page.evaluate(() => {
// @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f
const fn = navigator.duckduckgo?.isDuckDuckGo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ export class ResultsCollector {
*/
static create(page, use) {
// Read the configuration object to determine which platform we're testing against
page.on('console', (msg) => console[msg.type()](msg.text()));
const { platformInfo, build } = perPlatform(use);
return new ResultsCollector(page, build, platformInfo);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"unprotectedTemporary": [],
"features": {
"apiManipulation": {
"state": "enabled",
Expand Down
2 changes: 1 addition & 1 deletion injected/integration-test/utils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const test = testContextForExtension(base);

test.describe('Ensure utils behave as expected', () => {
test('should toString DDGProxy correctly', async ({ page }) => {
await gotoAndWait(page, '/blank.html', { platform: { name: 'extension' } });
await gotoAndWait(page, '/blank.html');
const toStringResult = await page.evaluate('HTMLCanvasElement.prototype.getContext.toString()');
expect(toStringResult).toEqual('function getContext() { [native code] }');

Expand Down
1 change: 0 additions & 1 deletion injected/integration-test/web-compat-android.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ test.describe('Web Share API', () => {
const result = await page.evaluate(payload).catch((e) => {
return { threw: e };
});
console.log('check share', result);
const message = await page.evaluate(() => {
console.log('did read?');
return globalThis.shareReq;
Expand Down
24 changes: 17 additions & 7 deletions injected/src/content-scope-features.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { initStringExemptionLists, isFeatureBroken, registerMessageSecret } from './utils';
import { initStringExemptionLists, isFeatureBroken, isGloballyDisabled, platformSpecificFeatures, registerMessageSecret } from './utils';
import { platformSupport } from './features';
import { PerformanceMonitor } from './performance';
import platformFeatures from 'ddg:platformFeatures';
Expand Down Expand Up @@ -41,13 +41,23 @@ export function load(args) {
injectName: import.meta.injectName,
};

const featureNames = typeof importConfig.injectName === 'string' ? platformSupport[importConfig.injectName] : [];
const bundledFeatureNames = typeof importConfig.injectName === 'string' ? platformSupport[importConfig.injectName] : [];

for (const featureName of featureNames) {
const ContentFeature = platformFeatures['ddg_feature_' + featureName];
const featureInstance = new ContentFeature(featureName, importConfig, args);
featureInstance.callLoad();
features.push({ featureName, featureInstance });
// prettier-ignore
const featuresToLoad = isGloballyDisabled(args)
// if we're globally disabled, only allow `platformSpecificFeatures`
? platformSpecificFeatures
// if available, use `site.enabledFeatures`. The extension doesn't have `site.enabledFeatures` at this
// point, which is why we fall back to `bundledFeatureNames`.
: args.site.enabledFeatures || bundledFeatureNames;

for (const featureName of bundledFeatureNames) {
if (featuresToLoad.includes(featureName)) {
const ContentFeature = platformFeatures['ddg_feature_' + featureName];
const featureInstance = new ContentFeature(featureName, importConfig, args);
featureInstance.callLoad();
features.push({ featureName, featureInstance });
}
}
mark.end();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ export function ActivityBody({ canBurn, visibility }) {

return (
<ul class={styles.activity} data-busy={busy}>
ts{' '}
{keys.value.map((id, _index) => {
if (canBurn && !isReducedMotion) return <BurnableItem id={id} key={id} documentVisibility={visibility} />;
return <RemovableItem id={id} key={id} canBurn={canBurn} documentVisibility={visibility} />;
Expand Down
Loading