Skip to content

Commit 399ce49

Browse files
Support modifying cookies (#1384)
* Support modifying cookies * Add test for path
1 parent d302d8d commit 399ce49

File tree

7 files changed

+140
-206
lines changed

7 files changed

+140
-206
lines changed

injected/integration-test/pages.spec.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,14 @@ test.describe('Test integration pages', () => {
5656
`./integration-test/test-pages/webcompat/config/modify-localstorage.json`,
5757
);
5858
});
59+
60+
test('Properly modifies cookies', async ({ page }, testInfo) => {
61+
// prettier-ignore
62+
await testPage(
63+
page,
64+
testInfo,
65+
'webcompat/pages/modify-cookies.html',
66+
`./integration-test/test-pages/webcompat/config/modify-cookies.json`,
67+
);
68+
});
5969
});
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"unprotectedTemporary": [],
3+
"features": {
4+
"webCompat": {
5+
"exceptions": [],
6+
"state": "enabled",
7+
"settings": {
8+
"modifyCookies": {
9+
"state": "enabled",
10+
"changes": []
11+
},
12+
"domains": [
13+
{
14+
"domain": ["localhost", "privacy-test-pages.site"],
15+
"patchSettings": [
16+
{
17+
"op": "add",
18+
"path": "/modifyCookies/changes/-",
19+
"value": {
20+
"key": "keyToBeDeleted",
21+
"action": "delete"
22+
}
23+
},
24+
{
25+
"op": "add",
26+
"path": "/modifyCookies/changes/-",
27+
"value": {
28+
"key": "pathCookie",
29+
"action": "delete"
30+
}
31+
},
32+
{
33+
"op": "add",
34+
"path": "/modifyCookies/changes/-",
35+
"value": {
36+
"key": "pathCookieWithPath",
37+
"path": "/webcompat/pages/",
38+
"action": "delete"
39+
}
40+
},
41+
{
42+
"op": "add",
43+
"path": "/modifyCookies/changes/-",
44+
"value": {
45+
"key": "nonexistentKey",
46+
"action": "delete"
47+
}
48+
}
49+
]
50+
}
51+
]
52+
}
53+
}
54+
}
55+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width">
6+
<title>Modify Cookies</title>
7+
<link rel="stylesheet" href="../../shared/style.css">
8+
<script>
9+
// Current file path
10+
let path = '/webcompat/pages/'
11+
document.cookie = 'keyToBeDeleted="valueToBeDeleted"'
12+
document.cookie = 'pathCookie="valueToBeDeleted"; path=' + path
13+
document.cookie = 'pathCookieWithPath="valueToBeDeleted"; path=' + path
14+
document.cookie = 'otherKey="valueToRemain"'
15+
</script>
16+
</head>
17+
<body>
18+
<script src="../../shared/utils.js"></script>
19+
<p><a href="../index.html">[WebCompat]</a></p>
20+
21+
<p>This page verifies that cookie modifications work properly given the <a href="../config/modify-cookies.json">config</a>. At this time, only deletion is supported.</p>
22+
23+
<script>
24+
// Copy from: https://stackoverflow.com/a/2144404
25+
function hasCookie(name){
26+
return document.cookie.split(';').some(c => {
27+
return c.trim().startsWith(name + '=');
28+
});
29+
}
30+
31+
// eslint-disable-next-line no-undef
32+
test('Only specified cookies should be removed', async () => {
33+
const specifiedKey = hasCookie('keyToBeDeleted')
34+
const pathKey = hasCookie('pathCookie')
35+
const pathKey2 = hasCookie('pathCookie2')
36+
const pathKey3 = hasCookie('pathCookieWithPath')
37+
const nonexistentKey = hasCookie('nonexistentKey')
38+
const otherKey = hasCookie('otherKey')
39+
40+
return [
41+
{ name: 'specified cookie entry deleted', result: specifiedKey, expected: false },
42+
{ name: 'specified cookie entry with path not deleted', result: pathKey, expected: true },
43+
{ name: `specified cookie entry with correct path (${path}) deleted`, result: pathKey3, expected: false },
44+
{ name: 'specified cookie entry that is not present on page load', result: nonexistentKey, expected: false },
45+
{ name: 'other cookie entry untouched', result: otherKey, expected: true }
46+
];
47+
});
48+
49+
// eslint-disable-next-line no-undef
50+
renderResults();
51+
</script>
52+
</body>
53+
</html>

injected/src/features/web-compat.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ export class WebCompat extends ContentFeature {
122122
if (this.getFeatureSettingEnabled('modifyLocalStorage')) {
123123
this.modifyLocalStorage();
124124
}
125+
126+
if (this.getFeatureSettingEnabled('modifyCookies')) {
127+
this.modifyCookies();
128+
}
125129
}
126130

127131
/** Shim Web Share API in Android WebView */
@@ -583,6 +587,24 @@ export class WebCompat extends ContentFeature {
583587
});
584588
}
585589

590+
/**
591+
* Support for modifying cookies
592+
*/
593+
modifyCookies() {
594+
/** @type {import('@duckduckgo/privacy-configuration/schema/features/webcompat').WebCompatSettings['modifyCookies']} */
595+
const settings = this.getFeatureSetting('modifyCookies');
596+
597+
if (!settings || !settings.changes) return;
598+
599+
settings.changes.forEach((change) => {
600+
if (change.action === 'delete') {
601+
const pathValue = change.path ? `; path=${change.path}` : '';
602+
const domainValue = change.domain ? `; domain=${change.domain}` : '';
603+
document.cookie = `${change.key}=; expires=Thu, 01 Jan 1970 00:00:00 GMT${pathValue}${domainValue}`;
604+
}
605+
});
606+
}
607+
586608
/**
587609
* Support for proxying `window.webkit.messageHandlers`
588610
*/

injected/src/types/duckplayer-settings.d.ts

Lines changed: 0 additions & 121 deletions
This file was deleted.

injected/src/types/webcompat-settings.d.ts

Lines changed: 0 additions & 84 deletions
This file was deleted.

tsconfig.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
"playwright.config.js",
3030
"injected",
3131
"injected/src/globals.d.ts",
32-
"injected/src/features/duckplayer/duckplayer-settings.ts",
3332
"typedoc.js",
3433
".github/scripts"
3534
],

0 commit comments

Comments
 (0)