Skip to content

Commit

Permalink
fix(do-not-track): window object can be undefined #479
Browse files Browse the repository at this point in the history
  • Loading branch information
GermainBergeron authored Oct 29, 2024
2 parents 7d6618f + bdb22f6 commit d82bcaf
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 28 deletions.
56 changes: 39 additions & 17 deletions src/donottrack.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ describe('doNotTrack', () => {
let doNotTrack: () => boolean;
function initModule(
hasNav: boolean,
hasWin: boolean,
options?: {
navigatorGlobalPrivacyControl?: any;
navigatorDoNotTrack?: any;
Expand All @@ -12,6 +13,7 @@ describe('doNotTrack', () => {
jest.resetModules();
jest.mock('./detector', () => ({
hasNavigator: () => hasNav,
hasWindow: () => hasWin,
}));
if (hasNav) {
Object.defineProperty(<any>navigator, 'globalPrivacyControl', {
Expand All @@ -32,6 +34,8 @@ describe('doNotTrack', () => {
},
configurable: true,
});
}
if (hasWin) {
Object.defineProperty(<any>window, 'doNotTrack', {
get() {
return options!.windowDoNotTrack;
Expand All @@ -41,30 +45,30 @@ describe('doNotTrack', () => {
}
doNotTrack = require('./donottrack').doNotTrack;
}
describe('without a Navigator', () => {
describe('without a Navigator and without window', () => {
it('should be false', () => {
initModule(false);
initModule(false, false);

expect(doNotTrack()).toBeFalsy();
});
});
describe('with a Navigator', () => {
it('should respect GPC false', () => {
initModule(true, {
initModule(true, false, {
navigatorGlobalPrivacyControl: false,
});

expect(doNotTrack()).toBeFalsy();
});
it('should respect GPC true', () => {
initModule(true, {
initModule(true, false, {
navigatorGlobalPrivacyControl: true,
});

expect(doNotTrack()).toBeTruthy();
});
it('should respect GPC undefined', () => {
initModule(true, {
initModule(true, false, {
navigatorGlobalPrivacyControl: undefined,
});

Expand All @@ -73,50 +77,68 @@ describe('doNotTrack', () => {

[true, 'yes', '1'].forEach((value) => {
it('should fallback on `navigator.doNotTrack`: ' + JSON.stringify(value), () => {
initModule(true, {
initModule(true, false, {
navigatorDoNotTrack: value,
});

expect(doNotTrack()).toBeTruthy();
});

it('should fallback on `navigator.msDoNotTrack`: ' + JSON.stringify(value), () => {
initModule(true, {
initModule(true, false, {
navigatorMsDoNotTrack: value,
});
expect(doNotTrack()).toBeTruthy();
});

it('should fallback on `window.doNotTrack`: ' + JSON.stringify(value), () => {
initModule(true, {
windowDoNotTrack: value,
});
expect(doNotTrack()).toBeTruthy();
});
});

[false, 'no', '0', 'unspecified'].forEach((value) => {
it('should fallback on `navigator.doNotTrack`: ' + JSON.stringify(value), () => {
initModule(true, {
initModule(true, false, {
navigatorDoNotTrack: value,
});

expect(doNotTrack()).toBeFalsy();
});

it('should fallback on `navigator.msDoNotTrack`: ' + JSON.stringify(value), () => {
initModule(true, {
initModule(true, false, {
navigatorMsDoNotTrack: value,
});
expect(doNotTrack()).toBeFalsy();
});
});
});

describe('with a Window', () => {
[true, 'yes', '1'].forEach((value) => {
it('should fallback on `window.doNotTrack`: ' + JSON.stringify(value), () => {
initModule(false, true, {
windowDoNotTrack: value,
});
expect(doNotTrack()).toBeTruthy();
});
});

[false, 'no', '0', 'unspecified'].forEach((value) => {
it('should fallback on `window.doNotTrack`: ' + JSON.stringify(value), () => {
initModule(true, {
initModule(false, true, {
windowDoNotTrack: value,
});
expect(doNotTrack()).toBeFalsy();
});
});
});

describe('with a Navigator and a Window', () => {
it('should fallback on `window.doNotTrack` if all navigator properties are falsy', () => {
initModule(true, true, {
navigatorDoNotTrack: false,
navigatorGlobalPrivacyControl: undefined,
navigatorMsDoNotTrack: '0',
windowDoNotTrack: 1,
});
expect(doNotTrack()).toBeTruthy();
});
});
});
21 changes: 10 additions & 11 deletions src/donottrack.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
// Read the Mozilla Do Not Track Field Guide
// (https://developer.mozilla.org/en-US/docs/Web/Security/Do_not_track_field_guide),
// for information on how to use the donottrack
// gathering data of actions of an user as long as it is not associated to the
// gathering data of actions of a user as long as it is not associated to the
// identity of that user, doNotTrack is not enabled here.

import {hasNavigator} from './detector';
import {hasNavigator, hasWindow} from './detector';

const doNotTrackValues = ['1', 1, 'yes', true];

export function doNotTrack(): boolean {
return (
hasNavigator() &&
[
(<any>navigator).globalPrivacyControl,
(<any>navigator).doNotTrack,
(<any>navigator).msDoNotTrack,
(<any>window).doNotTrack,
].some((value) => doNotTrackValues.indexOf(value) !== -1)
);
const checks: any[] = [];
if (hasWindow()) {
checks.push((<any>window).doNotTrack);
}
if (hasNavigator()) {
checks.push((<any>navigator).doNotTrack, (<any>navigator).msDoNotTrack, (<any>navigator).globalPrivacyControl);
}
return checks.some((value) => doNotTrackValues.indexOf(value) !== -1);
}

export default doNotTrack;

0 comments on commit d82bcaf

Please sign in to comment.