Skip to content

Commit a99e1f5

Browse files
IAB Data Deletion Request Framework (#144)
* IAB DSR draft * cleanup + docs * duplicated stringify * promise on top level * format * parse error handling * cleanup * only required items * stringify result
1 parent 6c898c6 commit a99e1f5

File tree

1 file changed

+76
-1
lines changed

1 file changed

+76
-1
lines changed

dist/privacy.js

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,68 @@ function testPropertyStringInResponseBodies(pattern) {
2525
}
2626
}
2727

28-
return JSON.stringify({
28+
/**
29+
* @param {string} url - The URL to fetch.
30+
* @param {function} parser - The function to parse the response.
31+
* @returns {Promise<Object>} The parsed response or an error object.
32+
*/
33+
const fetchAndParse = async (url, parser) => {
34+
const timeout = 5000;
35+
const controller = new AbortController();
36+
const { signal } = controller;
37+
setTimeout(() => controller.abort(), timeout);
38+
39+
try {
40+
const response = await fetch(url, { signal });
41+
return parser(response);
42+
} catch (error) {
43+
return {
44+
status: -1,
45+
present: false,
46+
error: error.message
47+
};
48+
}
49+
};
50+
51+
/**
52+
* Checks if the response URL ends with any of the specified endings and if the response is OK.
53+
* @param {Response} response - The fetch response object.
54+
* @param {string[]} endings - An array of URL endings to check against.
55+
* @returns {boolean} - Returns true if the response is OK and the URL ends with one of the specified endings.
56+
*/
57+
const isPresent = (response, endings) => response.ok && endings.some(ending => response.url.endsWith(ending));
58+
59+
/**
60+
* Parses the response from a DSR delete request.
61+
* @param {Response} response - The response object from the fetch request.
62+
* @returns {Promise<Object>} A promise that resolves to an object containing the parsed response data.
63+
*/
64+
const parseDSRdelete = async (response) => {
65+
let result = {
66+
present: isPresent(response, ['/dsrdelete.json']),
67+
status: response.status,
68+
};
69+
Object.assign(result, result.present ? { redirected: response.redirected } : {});
70+
71+
try {
72+
let content = JSON.parse(await response.text());
73+
if (result.present && content) {
74+
for (const element of content.identifiers) {
75+
delete element.id;
76+
}
77+
Object.assign(result, content.identifiers ? { identifiers: content.identifiers } : {});
78+
Object.assign(result, response.redirected ? { endpointOrigin: new URL(content.endpoint).origin } : {});
79+
Object.assign(result, content.vendorScript ? { vendorScriptPresent: true } : {});
80+
Object.assign(result, content.vendorScriptRequirement ? { vendorScriptRequirement: true } : {});
81+
}
82+
} catch (error) {
83+
Object.assign(result, result.present ? { error: error.message } : {});
84+
} finally {
85+
return Promise.resolve(result);
86+
}
87+
}
88+
89+
let sync_metrics = {
2990
/**
3091
* Privacy policies
3192
* Wording sourced from: https://github.com/RUB-SysSec/we-value-your-privacy/blob/master/privacy_wording.json
@@ -511,4 +572,18 @@ return JSON.stringify({
511572
return CCPAdata
512573
})()
513574

575+
};
576+
577+
578+
/**
579+
* IAB: Data Deletion Request Framework
580+
* https://github.com/InteractiveAdvertisingBureau/Data-Subject-Rights/blob/main/Data%20Deletion%20Request%20Framework.md
581+
*/
582+
let iab_ddr = fetchAndParse("/dsrdelete.json", parseDSRdelete);
583+
584+
return Promise.all([iab_ddr]).then(([iab_ddr]) => {
585+
return JSON.stringify({
586+
...sync_metrics,
587+
...{ iab_ddr: iab_ddr }
588+
});
514589
});

0 commit comments

Comments
 (0)