Skip to content

Commit 8cc4a81

Browse files
committed
TDS Override via contentBlocking subfeature
1 parent fe78142 commit 8cc4a81

File tree

1 file changed

+43
-1
lines changed
  • shared/js/background/components

1 file changed

+43
-1
lines changed

shared/js/background/components/tds.js

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import constants from '../../../data/constants';
66
* @typedef {import('./remote-config.js').default} RemoteConfig
77
*/
88

9+
const TDS_OVERRIDE_SETTINGS_KEY = 'tdsOverride';
10+
const CONTENT_BLOCKING = 'contentBlocking';
11+
912
export default class TDSStorage {
1013
/**
1114
* @param {{
@@ -14,6 +17,7 @@ export default class TDSStorage {
1417
* }} opts
1518
*/
1619
constructor({ settings, remoteConfig }) {
20+
this.settings = settings;
1721
this.remoteConfig = remoteConfig;
1822
/** @deprecated config is an alias of remoteConfig */
1923
this.config = this.remoteConfig;
@@ -28,14 +32,52 @@ export default class TDSStorage {
2832
this.tds = new ResourceLoader(
2933
{
3034
name: 'tds',
31-
remoteUrl: constants.tdsLists[1].url,
35+
remoteUrl: this.getTDSUrl.bind(this),
3236
updateIntervalMinutes: 15,
3337
},
3438
{ settings },
3539
);
40+
this.remoteConfig.onUpdate(this.checkShouldOverrideTDS.bind(this));
3641
}
3742

3843
ready() {
3944
return Promise.all([this.tds.ready, this.surrogates.ready, this.remoteConfig.ready]);
4045
}
46+
47+
async getTDSUrl() {
48+
await this.config.ready;
49+
const overridePath = this.settings.getSetting(TDS_OVERRIDE_SETTINGS_KEY);
50+
if (overridePath) {
51+
return `https://staticcdn.duckduckgo.com/trackerblocking/${overridePath}`;
52+
}
53+
return constants.tdsLists[1].url;
54+
}
55+
56+
checkShouldOverrideTDS() {
57+
const contentBlockingSubFeatures = this.config.config?.features[CONTENT_BLOCKING].features || {};
58+
const enabledBlocklistOverrides = Object.keys(contentBlockingSubFeatures).filter(
59+
(k) => k.startsWith('TDS') && this.config.isSubFeatureEnabled(CONTENT_BLOCKING, k),
60+
);
61+
if (enabledBlocklistOverrides.length > 0) {
62+
const subFeatureName = enabledBlocklistOverrides[0]
63+
const overrideSubFeature = contentBlockingSubFeatures[subFeatureName]
64+
// If this is enabled via an experiment, the override URL is defined as `${cohortName}Url`, otherwise, for a normal rollout use `nextUrl`.
65+
const settingsKey = `${this.remoteConfig.getCohortName(CONTENT_BLOCKING, subFeatureName) || 'next'}Url`
66+
const overridePath = overrideSubFeature.settings && overrideSubFeature.settings[settingsKey]
67+
if (!overridePath) {
68+
console.warn(`Couldn't find TDS override path in subfeature settings.`)
69+
return
70+
}
71+
if (overridePath !== this.settings.getSetting(TDS_OVERRIDE_SETTINGS_KEY)) {
72+
console.log('TDS URL override changed to ', overridePath);
73+
this.settings.updateSetting(TDS_OVERRIDE_SETTINGS_KEY, overridePath);
74+
this.tds.checkForUpdates(true);
75+
}
76+
this.remoteConfig.markExperimentEnrolled(CONTENT_BLOCKING, subFeatureName)
77+
} else if (this.settings.getSetting(TDS_OVERRIDE_SETTINGS_KEY)) {
78+
// User removed from experiment/rollout, reset TDS override and fetch default list
79+
this.settings.removeSetting(TDS_OVERRIDE_SETTINGS_KEY)
80+
this.tds.checkForUpdates(true);
81+
}
82+
}
4183
}

0 commit comments

Comments
 (0)