From 5b0dc33d3fc8c95e11efb1ba971fb827224370d6 Mon Sep 17 00:00:00 2001 From: Jonathan Kingston Date: Fri, 10 Jan 2025 15:10:32 +0000 Subject: [PATCH] Support modifying cookies --- injected/integration-test/pages.spec.js | 10 ++ .../webcompat/config/modify-cookies.json | 38 ++++++ .../webcompat/pages/modify-cookies.html | 44 +++++++ injected/src/features/web-compat.js | 22 ++++ injected/src/types/duckplayer-settings.d.ts | 121 ------------------ injected/src/types/webcompat-settings.d.ts | 84 ------------ tsconfig.json | 1 - 7 files changed, 114 insertions(+), 206 deletions(-) create mode 100644 injected/integration-test/test-pages/webcompat/config/modify-cookies.json create mode 100644 injected/integration-test/test-pages/webcompat/pages/modify-cookies.html delete mode 100644 injected/src/types/duckplayer-settings.d.ts delete mode 100644 injected/src/types/webcompat-settings.d.ts diff --git a/injected/integration-test/pages.spec.js b/injected/integration-test/pages.spec.js index bb720acff..982e5f7d4 100644 --- a/injected/integration-test/pages.spec.js +++ b/injected/integration-test/pages.spec.js @@ -56,4 +56,14 @@ test.describe('Test integration pages', () => { `./integration-test/test-pages/webcompat/config/modify-localstorage.json`, ); }); + + test('Properly modifies cookies', async ({ page }, testInfo) => { + // prettier-ignore + await testPage( + page, + testInfo, + 'webcompat/pages/modify-cookies.html', + `./integration-test/test-pages/webcompat/config/modify-cookies.json`, + ); + }); }); diff --git a/injected/integration-test/test-pages/webcompat/config/modify-cookies.json b/injected/integration-test/test-pages/webcompat/config/modify-cookies.json new file mode 100644 index 000000000..064aa5e49 --- /dev/null +++ b/injected/integration-test/test-pages/webcompat/config/modify-cookies.json @@ -0,0 +1,38 @@ +{ + "unprotectedTemporary": [], + "features": { + "webCompat": { + "exceptions": [], + "state": "enabled", + "settings": { + "modifyCookies": { + "state": "enabled", + "changes": [] + }, + "domains": [ + { + "domain": ["localhost", "privacy-test-pages.site"], + "patchSettings": [ + { + "op": "add", + "path": "/modifyCookies/changes/-", + "value": { + "key": "keyToBeDeleted", + "action": "delete" + } + }, + { + "op": "add", + "path": "/modifyCookies/changes/-", + "value": { + "key": "nonexistentKey", + "action": "delete" + } + } + ] + } + ] + } + } + } +} diff --git a/injected/integration-test/test-pages/webcompat/pages/modify-cookies.html b/injected/integration-test/test-pages/webcompat/pages/modify-cookies.html new file mode 100644 index 000000000..715aebbcd --- /dev/null +++ b/injected/integration-test/test-pages/webcompat/pages/modify-cookies.html @@ -0,0 +1,44 @@ + + + + + + Modify Cookies + + + + + +

[WebCompat]

+ +

This page verifies that cookie modifications work properly given the config. At this time, only deletion is supported.

+ + + + diff --git a/injected/src/features/web-compat.js b/injected/src/features/web-compat.js index 9a216ffef..d76156410 100644 --- a/injected/src/features/web-compat.js +++ b/injected/src/features/web-compat.js @@ -122,6 +122,10 @@ export class WebCompat extends ContentFeature { if (this.getFeatureSettingEnabled('modifyLocalStorage')) { this.modifyLocalStorage(); } + + if (this.getFeatureSettingEnabled('modifyCookies')) { + this.modifyCookies(); + } } /** Shim Web Share API in Android WebView */ @@ -583,6 +587,24 @@ export class WebCompat extends ContentFeature { }); } + /** + * Support for modifying cookies + */ + modifyCookies() { + /** @type {import('@duckduckgo/privacy-configuration/schema/features/webcompat').WebCompatSettings['modifyCookies']} */ + const settings = this.getFeatureSetting('modifyCookies'); + + if (!settings || !settings.changes) return; + + settings.changes.forEach((change) => { + if (change.action === 'delete') { + const pathValue = change.path ? `; path=${change.path}` : ''; + const domainValue = change.domain ? `; domain=${change.domain}` : ''; + document.cookie = `${change.key}=; expires=Thu, 01 Jan 1970 00:00:00 GMT${pathValue}${domainValue}`; + } + }); + } + /** * Support for proxying `window.webkit.messageHandlers` */ diff --git a/injected/src/types/duckplayer-settings.d.ts b/injected/src/types/duckplayer-settings.d.ts deleted file mode 100644 index d83e9e053..000000000 --- a/injected/src/types/duckplayer-settings.d.ts +++ /dev/null @@ -1,121 +0,0 @@ -/** - * - * These types are auto-generated from schema files. - * scripts/build-types.mjs is responsible for type generation. - * See the privacy-configuration repo for the schema files: - * https://github.com/duckduckgo/privacy-configuration - * **DO NOT** edit this file directly as your changes will be lost. - * - * @module Duckplayer Settings Schema - */ - -export type State = "enabled" | "disabled"; - -/** - * Settings configuration for video player - */ -export interface DuckPlayerSettings { - overlays: Overlays; - /** - * List of domains with specific patch settings - */ - domains: Domain[]; -} -/** - * Specific configurations for different overlay types - */ -export interface Overlays { - youtube: YouTubeOverlay; - serpProxy: SERPProxy; -} -/** - * Configuration specific to YouTube overlays - */ -export interface YouTubeOverlay { - state: State; - selectors: Selectors; - thumbnailOverlays: ThumbnailOverlays; - clickInterception: ClickInterception; - videoOverlays: VideoOverlays; -} -/** - * CSS selectors for identifying specific HTML elements on a YouTube page - */ -export interface Selectors { - /** - * CSS selector for YouTube thumbnail links - */ - thumbLink: string; - /** - * CSS selectors for regions to exclude from hover/click interactions - */ - excludedRegions: string[]; - /** - * CSS selectors for elements that should prevent side effects from hovers - */ - hoverExcluded: string[]; - /** - * CSS selectors for elements that should prevent side effects from clicks - */ - clickExcluded: string[]; - /** - * CSS selectors to explicitly allow known event targets for hovers/clicks. For example, preview overlays. - */ - allowedEventTargets: string[]; - /** - * CSS selector for the video element on YouTube - */ - videoElement: string; - /** - * CSS selector for the container of the video element - */ - videoElementContainer: string; -} -/** - * Settings related to the display of thumbnail overlays - */ -export interface ThumbnailOverlays { - state: State; -} -/** - * Settings for intercepting click events - */ -export interface ClickInterception { - state: State; -} -/** - * Settings related to the display of video overlays - */ -export interface VideoOverlays { - state: State; -} -/** - * Configuration for the SERP (Search Engine Results Page) proxy - */ -export interface SERPProxy { - state: State; -} -export interface Domain { - /** - * Domain name - */ - domain: string; - /** - * List of operations to be applied on the settings for a specific domain - */ - patchSettings: PatchSetting[]; -} -export interface PatchSetting { - /** - * The operation to be performed - */ - op: string; - /** - * The path of the setting to be patched - */ - path: string; - /** - * The value to replace at the specified path - */ - value: string; -} diff --git a/injected/src/types/webcompat-settings.d.ts b/injected/src/types/webcompat-settings.d.ts deleted file mode 100644 index 9d4cb2427..000000000 --- a/injected/src/types/webcompat-settings.d.ts +++ /dev/null @@ -1,84 +0,0 @@ -/** - * - * These types are auto-generated from schema files. - * scripts/build-types.mjs is responsible for type generation. - * See the privacy-configuration repo for the schema files: - * https://github.com/duckduckgo/privacy-configuration - * **DO NOT** edit this file directly as your changes will be lost. - * - * @module Webcompat Settings Schema - */ - -export type State = "enabled" | "disabled"; -/** - * List of domains with specific patch settings - */ -export type Domains = Domain[]; - -/** - * Settings configuration for Web Compat - */ -export interface WebCompatSettings { - windowSizing?: State; - navigatorCredentials?: State; - safariObject?: State; - messageHandlers?: { - state: State; - handlerStrategies: { - reflect: string[]; - polyfill: string[]; - undefined: string[]; - }; - }; - modifyLocalStorage?: { - state: State; - changes: { - key: string; - action: string; - }[]; - }; - notification?: { - state: State; - }; - permissions?: { - state: State; - supportedPermissions: {}; - }; - mediaSession?: State; - presentation?: State; - webShare?: State; - viewportWidth?: - | State - | { - state: State; - forcedDesktopValue?: string; - forcedMobileValue?: string; - }; - screenLock?: State; - domains?: Domains; - plainTextViewPort?: State; -} -export interface Domain { - /** - * Domain name - */ - domain: string | string[]; - /** - * List of operations to be applied on the settings for a specific domain - */ - patchSettings: PatchSetting[]; -} -export interface PatchSetting { - /** - * The operation to be performed - */ - op: string; - /** - * The path of the setting to be patched - */ - path: string; - /** - * The value to replace at the specified path - */ - value: string | unknown[] | {} | number; -} diff --git a/tsconfig.json b/tsconfig.json index b3aed1e0a..d417e9fb4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,7 +29,6 @@ "playwright.config.js", "injected", "injected/src/globals.d.ts", - "injected/src/features/duckplayer/duckplayer-settings.ts", "typedoc.js", ".github/scripts" ],