Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@duckduckgo/autoconsent

Package Overview
Dependencies
Maintainers
6
Versions
100
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@duckduckgo/autoconsent - npm Package Compare versions

Comparing version 1.0.5 to 1.0.6

lib/cmps/onetrust.js

115

dist/autoconsent.cjs.js

@@ -5,2 +5,4 @@ 'use strict';

const enableLogs = false; // change this to enable debug logs
/* eslint-disable no-restricted-syntax,no-await-in-loop,no-underscore-dangle */

@@ -21,3 +23,3 @@ async function waitFor(predicate, maxTimes, interval) {

if (!result) {
throw new Error(`Action failed: ${action}`);
throw new Error(`Action failed: ${action} ${result}`);
}

@@ -186,3 +188,2 @@ return result;

async elementExists(selector, frameId = 0) {
console.log(`check for ${selector} in tab ${this.id}, frame ${frameId}`);
return this.sendContentMessage(this.id, {

@@ -196,3 +197,2 @@ type: "elemExists",

async clickElement(selector, frameId = 0) {
console.log(`click element ${selector} in tab ${this.id}`);
return this.sendContentMessage(this.id, {

@@ -206,3 +206,2 @@ type: "click",

async clickElements(selector, frameId = 0) {
console.log(`click elements ${selector} in tab ${this.id}`);
return this.sendContentMessage(this.id, {

@@ -250,6 +249,7 @@ type: "click",

}
async hideElements(selectors, frameId = 0) {
async hideElements(selectors, frameId = 0, method = 'display') {
return this.sendContentMessage(this.id, {
type: "hide",
selectors
selectors,
method,
}, { frameId });

@@ -270,3 +270,5 @@ }

return new Promise(resolve => {
setTimeout(() => resolve(true), ms);
setTimeout(() => {
resolve(true);
}, ms);
});

@@ -655,5 +657,33 @@ }

// get or create a style container for CSS overrides
function getStyleElementUtil() {
const styleOverrideElementId = "autoconsent-css-rules";
const styleSelector = `style#${styleOverrideElementId}`;
const existingElement = document.querySelector(styleSelector);
if (existingElement && existingElement instanceof HTMLStyleElement) {
return existingElement;
}
else {
const parent = document.head ||
document.getElementsByTagName("head")[0] ||
document.documentElement;
const css = document.createElement("style");
css.id = styleOverrideElementId;
parent.appendChild(css);
return css;
}
}
// hide elements with a CSS rule
function hideElementsUtil(selectors, method) {
const hidingSnippet = method === 'display' ? `display: none` : `opacity: 0`;
const rule = `${selectors.join(",")} { ${hidingSnippet} !important; z-index: -1 !important; pointer-events: none !important; } `;
const styleEl = getStyleElementUtil();
if (styleEl instanceof HTMLStyleElement) {
styleEl.innerText += rule;
return selectors.length > 0;
}
return false;
}
let actionQueue = Promise.resolve(null);
const styleOverrideElementId = "autoconsent-css-rules";
const styleSelector = `style#${styleOverrideElementId}`;
function handleMessage(message, debug = false) {

@@ -682,4 +712,5 @@ if (message.type === "click") {

elem.forEach((e, i) => {
results[i] = e.offsetParent !== null || window.getComputedStyle(e).display !== "none" || e.style?.display !== "none";
results[i] = e.offsetParent !== null || window.getComputedStyle(e).display !== "none"; // TODO: handle visibility and z-index?
});
debug && console.log("[visible?]", message.selector, elem, results);
if (results.length === 0) {

@@ -699,2 +730,3 @@ return false;

const elem = document.querySelector(message.selector);
debug && console.log("[getAttribute]", message.selector, elem);
if (!elem) {

@@ -707,27 +739,12 @@ return false;

// TODO: chrome support
debug && console.log("about to [eval]", message.script); // this will not show in Webkit console
const result = window.eval(message.script); // eslint-disable-line no-eval
debug && console.log("[eval]", message.script, result);
return result;
}
else if (message.type === "hide") {
const parent = document.head ||
document.getElementsByTagName("head")[0] ||
document.documentElement;
const rule = `${message.selectors.join(",")} { display: none !important; z-index: -1 !important; } `;
const existingElement = document.querySelector(styleSelector);
debug && console.log("[hide]", message.selectors, !!existingElement);
if (existingElement && existingElement instanceof HTMLStyleElement) {
existingElement.innerText += rule;
}
else {
const css = document.createElement("style");
css.type = "text/css";
css.id = styleOverrideElementId;
css.appendChild(document.createTextNode(rule));
parent.appendChild(css);
}
return message.selectors.length > 0;
debug && console.log("[hide]", message.selectors);
return hideElementsUtil(message.selectors, message.method);
}
else if (message.type === "undohide") {
const existingElement = document.querySelector(styleSelector);
const existingElement = getStyleElementUtil();
debug && console.log("[unhide]", !!existingElement);

@@ -741,5 +758,7 @@ if (existingElement) {

const matched = matches(message.config);
debug && console.log("[matches?]", message.config.type, JSON.stringify(message.config), matched);
return matched;
}
else if (message.type === "executeAction") {
debug && console.log("[executeAction]", message);
actionQueue = actionQueue.then(() => executeAction(message.config, message.param));

@@ -773,2 +792,3 @@ return true;

try {
enableLogs && console.log(`doing opt out ${this.getCMPName()} in tab ${this.tab.id}`);
this.optOutStatus = await this.rule.optOut(this.tab);

@@ -778,2 +798,3 @@ return this.optOutStatus;

catch (e) {
console.error('error during opt out', e);
this.optOutStatus = e;

@@ -823,2 +844,3 @@ throw e;

earlyReturn = true;
enableLogs && console.log(`Found CMP in [${tab.id}]: ${r.name}`);
resolve(index);

@@ -1164,2 +1186,34 @@ }

class Onetrust extends AutoConsentBase {
constructor() {
super("Onetrust");
this.prehideSelectors = ["#onetrust-banner-sdk,#onetrust-consent-sdk,.optanon-alert-box-wrapper,.onetrust-pc-dark-filter,.js-consent-banner"];
}
detectCmp(tab) {
return tab.elementExists("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
}
detectPopup(tab) {
return tab.elementsAreVisible("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
}
async optOut(tab) {
if (await tab.elementExists("#onetrust-pc-btn-handler")) { // "show purposes" button inside a popup
await success(tab.clickElement("#onetrust-pc-btn-handler"));
}
else { // otherwise look for a generic "show settings" button
await success(tab.clickElement(".ot-sdk-show-settings,button.js-cookie-settings"));
}
await success(tab.waitForElement("#onetrust-consent-sdk", 2000));
await success(tab.wait(1000));
await tab.clickElements("#onetrust-consent-sdk input.category-switch-handler:checked,.js-editor-toggle-state:checked"); // optional step
await success(tab.waitForThenClick(".save-preference-btn-handler,.js-consent-save", 1000));
return true;
}
async optIn(tab) {
return tab.clickElement("onetrust-accept-btn-handler,js-accept-cookies");
}
async test(tab) {
return tab.eval("window.OnetrustActiveGroups.split(',').filter(s => s.length > 0).length <= 1");
}
}
const rules = [

@@ -1171,2 +1225,3 @@ new TrustArc(),

new Evidon(),
new Onetrust(),
];

@@ -1243,3 +1298,3 @@ function createAutoCMP(config) {

}, globalHidden);
await tab.hideElements(selectors);
await tab.hideElements(selectors, undefined, 'opacity');
}

@@ -1246,0 +1301,0 @@

@@ -0,1 +1,3 @@

const enableLogs = false; // change this to enable debug logs
/* eslint-disable no-restricted-syntax,no-await-in-loop,no-underscore-dangle */

@@ -16,3 +18,3 @@ async function waitFor(predicate, maxTimes, interval) {

if (!result) {
throw new Error(`Action failed: ${action}`);
throw new Error(`Action failed: ${action} ${result}`);
}

@@ -181,3 +183,2 @@ return result;

async elementExists(selector, frameId = 0) {
console.log(`check for ${selector} in tab ${this.id}, frame ${frameId}`);
return this.sendContentMessage(this.id, {

@@ -191,3 +192,2 @@ type: "elemExists",

async clickElement(selector, frameId = 0) {
console.log(`click element ${selector} in tab ${this.id}`);
return this.sendContentMessage(this.id, {

@@ -201,3 +201,2 @@ type: "click",

async clickElements(selector, frameId = 0) {
console.log(`click elements ${selector} in tab ${this.id}`);
return this.sendContentMessage(this.id, {

@@ -245,6 +244,7 @@ type: "click",

}
async hideElements(selectors, frameId = 0) {
async hideElements(selectors, frameId = 0, method = 'display') {
return this.sendContentMessage(this.id, {
type: "hide",
selectors
selectors,
method,
}, { frameId });

@@ -265,3 +265,5 @@ }

return new Promise(resolve => {
setTimeout(() => resolve(true), ms);
setTimeout(() => {
resolve(true);
}, ms);
});

@@ -650,5 +652,33 @@ }

// get or create a style container for CSS overrides
function getStyleElementUtil() {
const styleOverrideElementId = "autoconsent-css-rules";
const styleSelector = `style#${styleOverrideElementId}`;
const existingElement = document.querySelector(styleSelector);
if (existingElement && existingElement instanceof HTMLStyleElement) {
return existingElement;
}
else {
const parent = document.head ||
document.getElementsByTagName("head")[0] ||
document.documentElement;
const css = document.createElement("style");
css.id = styleOverrideElementId;
parent.appendChild(css);
return css;
}
}
// hide elements with a CSS rule
function hideElementsUtil(selectors, method) {
const hidingSnippet = method === 'display' ? `display: none` : `opacity: 0`;
const rule = `${selectors.join(",")} { ${hidingSnippet} !important; z-index: -1 !important; pointer-events: none !important; } `;
const styleEl = getStyleElementUtil();
if (styleEl instanceof HTMLStyleElement) {
styleEl.innerText += rule;
return selectors.length > 0;
}
return false;
}
let actionQueue = Promise.resolve(null);
const styleOverrideElementId = "autoconsent-css-rules";
const styleSelector = `style#${styleOverrideElementId}`;
function handleMessage(message, debug = false) {

@@ -677,4 +707,5 @@ if (message.type === "click") {

elem.forEach((e, i) => {
results[i] = e.offsetParent !== null || window.getComputedStyle(e).display !== "none" || e.style?.display !== "none";
results[i] = e.offsetParent !== null || window.getComputedStyle(e).display !== "none"; // TODO: handle visibility and z-index?
});
debug && console.log("[visible?]", message.selector, elem, results);
if (results.length === 0) {

@@ -694,2 +725,3 @@ return false;

const elem = document.querySelector(message.selector);
debug && console.log("[getAttribute]", message.selector, elem);
if (!elem) {

@@ -702,27 +734,12 @@ return false;

// TODO: chrome support
debug && console.log("about to [eval]", message.script); // this will not show in Webkit console
const result = window.eval(message.script); // eslint-disable-line no-eval
debug && console.log("[eval]", message.script, result);
return result;
}
else if (message.type === "hide") {
const parent = document.head ||
document.getElementsByTagName("head")[0] ||
document.documentElement;
const rule = `${message.selectors.join(",")} { display: none !important; z-index: -1 !important; } `;
const existingElement = document.querySelector(styleSelector);
debug && console.log("[hide]", message.selectors, !!existingElement);
if (existingElement && existingElement instanceof HTMLStyleElement) {
existingElement.innerText += rule;
}
else {
const css = document.createElement("style");
css.type = "text/css";
css.id = styleOverrideElementId;
css.appendChild(document.createTextNode(rule));
parent.appendChild(css);
}
return message.selectors.length > 0;
debug && console.log("[hide]", message.selectors);
return hideElementsUtil(message.selectors, message.method);
}
else if (message.type === "undohide") {
const existingElement = document.querySelector(styleSelector);
const existingElement = getStyleElementUtil();
debug && console.log("[unhide]", !!existingElement);

@@ -736,5 +753,7 @@ if (existingElement) {

const matched = matches(message.config);
debug && console.log("[matches?]", message.config.type, JSON.stringify(message.config), matched);
return matched;
}
else if (message.type === "executeAction") {
debug && console.log("[executeAction]", message);
actionQueue = actionQueue.then(() => executeAction(message.config, message.param));

@@ -768,2 +787,3 @@ return true;

try {
enableLogs && console.log(`doing opt out ${this.getCMPName()} in tab ${this.tab.id}`);
this.optOutStatus = await this.rule.optOut(this.tab);

@@ -773,2 +793,3 @@ return this.optOutStatus;

catch (e) {
console.error('error during opt out', e);
this.optOutStatus = e;

@@ -818,2 +839,3 @@ throw e;

earlyReturn = true;
enableLogs && console.log(`Found CMP in [${tab.id}]: ${r.name}`);
resolve(index);

@@ -1159,2 +1181,34 @@ }

class Onetrust extends AutoConsentBase {
constructor() {
super("Onetrust");
this.prehideSelectors = ["#onetrust-banner-sdk,#onetrust-consent-sdk,.optanon-alert-box-wrapper,.onetrust-pc-dark-filter,.js-consent-banner"];
}
detectCmp(tab) {
return tab.elementExists("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
}
detectPopup(tab) {
return tab.elementsAreVisible("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
}
async optOut(tab) {
if (await tab.elementExists("#onetrust-pc-btn-handler")) { // "show purposes" button inside a popup
await success(tab.clickElement("#onetrust-pc-btn-handler"));
}
else { // otherwise look for a generic "show settings" button
await success(tab.clickElement(".ot-sdk-show-settings,button.js-cookie-settings"));
}
await success(tab.waitForElement("#onetrust-consent-sdk", 2000));
await success(tab.wait(1000));
await tab.clickElements("#onetrust-consent-sdk input.category-switch-handler:checked,.js-editor-toggle-state:checked"); // optional step
await success(tab.waitForThenClick(".save-preference-btn-handler,.js-consent-save", 1000));
return true;
}
async optIn(tab) {
return tab.clickElement("onetrust-accept-btn-handler,js-accept-cookies");
}
async test(tab) {
return tab.eval("window.OnetrustActiveGroups.split(',').filter(s => s.length > 0).length <= 1");
}
}
const rules = [

@@ -1166,2 +1220,3 @@ new TrustArc(),

new Evidon(),
new Onetrust(),
];

@@ -1238,3 +1293,3 @@ function createAutoCMP(config) {

}, globalHidden);
await tab.hideElements(selectors);
await tab.hideElements(selectors, undefined, 'opacity');
}

@@ -1241,0 +1296,0 @@

@@ -5,2 +5,4 @@ 'use strict';

const enableLogs = false; // change this to enable debug logs
/* eslint-disable no-restricted-syntax,no-await-in-loop,no-underscore-dangle */

@@ -21,3 +23,3 @@ async function waitFor(predicate, maxTimes, interval) {

if (!result) {
throw new Error(`Action failed: ${action}`);
throw new Error(`Action failed: ${action} ${result}`);
}

@@ -366,2 +368,32 @@ return result;

// get or create a style container for CSS overrides
function getStyleElementUtil() {
const styleOverrideElementId = "autoconsent-css-rules";
const styleSelector = `style#${styleOverrideElementId}`;
const existingElement = document.querySelector(styleSelector);
if (existingElement && existingElement instanceof HTMLStyleElement) {
return existingElement;
}
else {
const parent = document.head ||
document.getElementsByTagName("head")[0] ||
document.documentElement;
const css = document.createElement("style");
css.id = styleOverrideElementId;
parent.appendChild(css);
return css;
}
}
// hide elements with a CSS rule
function hideElementsUtil(selectors, method) {
const hidingSnippet = method === 'display' ? `display: none` : `opacity: 0`;
const rule = `${selectors.join(",")} { ${hidingSnippet} !important; z-index: -1 !important; pointer-events: none !important; } `;
const styleEl = getStyleElementUtil();
if (styleEl instanceof HTMLStyleElement) {
styleEl.innerText += rule;
return selectors.length > 0;
}
return false;
}
const DEBUG = false;

@@ -375,2 +407,6 @@ class Tab {

this.frames = frames;
this._utilsSnippet = `
${getStyleElementUtil.toString()}
${hideElementsUtil.toString()}
`;
}

@@ -447,5 +483,7 @@ async elementExists(selector, frameId = 0) {

}
async hideElements(selectors, frameId = 0) {
// TODO implement this
return Promise.resolve(true);
async hideElements(selectors, frameId = 0, method = 'display') {
return await this.frames[frameId].evaluate(`(() => {
${this._utilsSnippet}
return hideElementsUtil(${JSON.stringify(selectors)}, '${method}');
})()`);
}

@@ -485,2 +523,3 @@ undoHideElements(frameId) {

earlyReturn = true;
enableLogs && console.log(`Found CMP in [${tab.id}]: ${r.name}`);
resolve(index);

@@ -530,2 +569,3 @@ }

try {
enableLogs && console.log(`doing opt out ${this.getCMPName()} in tab ${this.tab.id}`);
this.optOutStatus = await this.rule.optOut(this.tab);

@@ -535,2 +575,3 @@ return this.optOutStatus;

catch (e) {
console.error('error during opt out', e);
this.optOutStatus = e;

@@ -572,2 +613,16 @@ throw e;

// hide rules not specific to a single CMP rule
const globalHidden = [
"#didomi-popup,.didomi-popup-container,.didomi-popup-notice,.didomi-consent-popup-preferences,#didomi-notice,.didomi-popup-backdrop,.didomi-screen-medium",
];
async function prehideElements(tab, rules) {
const selectors = rules.reduce((selectorList, rule) => {
if (rule.prehideSelectors) {
return [...selectorList, ...rule.prehideSelectors];
}
return selectorList;
}, globalHidden);
await tab.hideElements(selectors, undefined, 'opacity');
}
class TrustArc extends AutoConsentBase {

@@ -891,2 +946,34 @@ constructor() {

class Onetrust extends AutoConsentBase {
constructor() {
super("Onetrust");
this.prehideSelectors = ["#onetrust-banner-sdk,#onetrust-consent-sdk,.optanon-alert-box-wrapper,.onetrust-pc-dark-filter,.js-consent-banner"];
}
detectCmp(tab) {
return tab.elementExists("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
}
detectPopup(tab) {
return tab.elementsAreVisible("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
}
async optOut(tab) {
if (await tab.elementExists("#onetrust-pc-btn-handler")) { // "show purposes" button inside a popup
await success(tab.clickElement("#onetrust-pc-btn-handler"));
}
else { // otherwise look for a generic "show settings" button
await success(tab.clickElement(".ot-sdk-show-settings,button.js-cookie-settings"));
}
await success(tab.waitForElement("#onetrust-consent-sdk", 2000));
await success(tab.wait(1000));
await tab.clickElements("#onetrust-consent-sdk input.category-switch-handler:checked,.js-editor-toggle-state:checked"); // optional step
await success(tab.waitForThenClick(".save-preference-btn-handler,.js-consent-save", 1000));
return true;
}
async optIn(tab) {
return tab.clickElement("onetrust-accept-btn-handler,js-accept-cookies");
}
async test(tab) {
return tab.eval("window.OnetrustActiveGroups.split(',').filter(s => s.length > 0).length <= 1");
}
}
const rules = [

@@ -898,2 +985,3 @@ new TrustArc(),

new Evidon(),
new Onetrust(),
];

@@ -959,6 +1047,7 @@ function createAutoCMP(config) {

function attachToPage(page, url, rules, retries = 1) {
const frames = {};
function attachToPage(page, url, rules, retries = 1, prehide = true) {
const frames = {
0: page.mainFrame(),
};
const tab = new Tab(page, url, frames);
frames[0] = page.mainFrame();
async function onFrame(frame) {

@@ -982,2 +1071,5 @@ const allFrames = await page.frames();

page.frames().forEach(onFrame);
if (prehide) {
prehideElements(tab, rules);
}
return new TabConsent(tab, detectDialog(tab, retries, rules));

@@ -984,0 +1076,0 @@ }

@@ -7,2 +7,3 @@ import { AutoConsent } from './base';

import Evidon from './evidon';
import Onetrust from './onetrust';
const rules = [

@@ -14,2 +15,3 @@ new TrustArc(),

new Evidon(),
new Onetrust(),
];

@@ -16,0 +18,0 @@ export function createAutoCMP(config) {

@@ -8,2 +8,3 @@ import { AutoConsent } from './base';

import { AutoConsentCMPRule } from '../rules';
import Onetrust from './onetrust';

@@ -16,2 +17,3 @@ const rules = [

new Evidon(),
new Onetrust(),
];

@@ -18,0 +20,0 @@

/* eslint-disable no-restricted-syntax,no-await-in-loop,no-underscore-dangle */
import { enableLogs } from "../config";
export async function waitFor(predicate, maxTimes, interval) {

@@ -16,3 +17,3 @@ let result = await predicate();

if (!result) {
throw new Error(`Action failed: ${action}`);
throw new Error(`Action failed: ${action} ${result}`);
}

@@ -122,3 +123,5 @@ return result;

for (const rule of rules) {
enableLogs && console.log('Running rule...', rule, tab.id);
const result = await evaluateRule(rule, tab);
enableLogs && console.log('...rule result', result);
if (!result && !rule.optional) {

@@ -150,2 +153,3 @@ return false;

if (this.config.optOut) {
enableLogs && console.log('Initiated optOut()', this.config.optOut);
return this._runRulesSequentially(tab, this.config.optOut);

@@ -152,0 +156,0 @@ }

@@ -5,2 +5,3 @@ /* eslint-disable no-restricted-syntax,no-await-in-loop,no-underscore-dangle */

import { AutoConsentCMPRule, AutoConsentRuleStep } from "../rules";
import { enableLogs } from "../config";

@@ -23,3 +24,3 @@ export async function waitFor(predicate: () => Promise<boolean> | boolean, maxTimes: number, interval: number): Promise<boolean> {

if (!result) {
throw new Error(`Action failed: ${action}`)
throw new Error(`Action failed: ${action} ${result}`)
}

@@ -145,3 +146,5 @@ return result

for (const rule of rules) {
enableLogs && console.log('Running rule...', rule, tab.id);
const result = await evaluateRule(rule, tab);
enableLogs && console.log('...rule result', result);
if (!result && !rule.optional) {

@@ -177,2 +180,3 @@ return false;

if (this.config.optOut) {
enableLogs && console.log('Initiated optOut()', this.config.optOut);
return this._runRulesSequentially(tab, this.config.optOut);

@@ -179,0 +183,0 @@ }

@@ -0,1 +1,2 @@

import { enableLogs } from './config';
export default async function detectDialog(tab, retries, rules) {

@@ -5,2 +6,3 @@ let breakEarly = false;

let earlyReturn = false;
enableLogs && console.log(`${new Date()} [${tab.id}] Detecting CMPs (${rules.length} rules)`);
await Promise.all(rules.map(async (r, index) => {

@@ -10,2 +12,3 @@ try {

earlyReturn = true;
enableLogs && console.log(`Found CMP in [${tab.id}]: ${r.name}`);
resolve(index);

@@ -22,2 +25,3 @@ }

});
enableLogs && console.log(`${new Date()} CMP detection finished in [${tab.id}], found rule #${found}`);
if (found === -1 && retries > 0 && !breakEarly) {

@@ -24,0 +28,0 @@ return new Promise((resolve) => {

@@ -0,1 +1,2 @@

import { enableLogs } from './config';
import { AutoCMP, TabActor } from './types';

@@ -7,2 +8,3 @@

let earlyReturn = false;
enableLogs && console.log(`${new Date()} [${tab.id}] Detecting CMPs (${rules.length} rules)`);
await Promise.all(rules.map(async (r, index) => {

@@ -12,2 +14,3 @@ try {

earlyReturn = true;
enableLogs && console.log(`Found CMP in [${tab.id}]: ${r.name}`);
resolve(index)

@@ -23,2 +26,3 @@ }

})
enableLogs && console.log(`${new Date()} CMP detection finished in [${tab.id}], found rule #${found}`);
if (found === -1 && retries > 0 && !breakEarly) {

@@ -25,0 +29,0 @@ return new Promise((resolve) => {

@@ -12,3 +12,3 @@ // hide rules not specific to a single CMP rule

}, globalHidden);
await tab.hideElements(selectors);
await tab.hideElements(selectors, undefined, 'opacity');
}

@@ -15,3 +15,3 @@ import { AutoCMP, TabActor } from './types';

}, globalHidden);
await tab.hideElements(selectors);
await tab.hideElements(selectors, undefined, 'opacity');
}

@@ -12,2 +12,4 @@ export type ContentScriptMessage =

export type HideMethod = 'display' | 'opacity';
type ClickMessage = {

@@ -44,2 +46,3 @@ type: "click";

selectors: string[];
method: HideMethod;
};

@@ -46,0 +49,0 @@

import Tab from './puppet/tab';
import detectDialog from './detector';
import TabConsent from './tabwrapper';
import prehideElements from './hider';
export * from './index';
export { ConsentOMaticCMP } from './consentomatic/index';
export { Tab, detectDialog, TabConsent, };
export function attachToPage(page, url, rules, retries = 1) {
const frames = {};
export function attachToPage(page, url, rules, retries = 1, prehide = true) {
const frames = {
0: page.mainFrame(),
};
const tab = new Tab(page, url, frames);
frames[0] = page.mainFrame();
async function onFrame(frame) {

@@ -29,3 +31,6 @@ const allFrames = await page.frames();

page.frames().forEach(onFrame);
if (prehide) {
prehideElements(tab, rules);
}
return new TabConsent(tab, detectDialog(tab, retries, rules));
}

@@ -5,2 +5,3 @@ import Tab from './puppet/tab';

import { AutoCMP } from './types';
import prehideElements from './hider';

@@ -15,7 +16,8 @@ export * from './index';

export function attachToPage(page: any, url: string, rules: AutoCMP[], retries = 1) {
const frames: { [id: number]: any } = {};
export function attachToPage(page: any, url: string, rules: AutoCMP[], retries = 1, prehide = true) {
const frames: { [id: number]: any } = {
0: page.mainFrame(),
};
const tab = new Tab(page, url, frames);
frames[0] = page.mainFrame();
async function onFrame(frame: any) {

@@ -39,3 +41,6 @@ const allFrames: any[] = await page.frames();

page.frames().forEach(onFrame);
return new TabConsent(tab, detectDialog(tab, retries, rules))
if (prehide) {
prehideElements(tab, rules);
}
return new TabConsent(tab, detectDialog(tab, retries, rules));
}
import { waitFor } from '../cmps/base';
import Tools from '../web/consentomatic/tools';
import { matches } from '../web/consentomatic/index';
import { hideElementsUtil, getStyleElementUtil } from '../web/content-utils';
const DEBUG = false;

@@ -12,2 +13,6 @@ export default class Tab {

this.frames = frames;
this._utilsSnippet = `
${getStyleElementUtil.toString()}
${hideElementsUtil.toString()}
`;
}

@@ -88,5 +93,7 @@ async elementExists(selector, frameId = 0) {

}
async hideElements(selectors, frameId = 0) {
// TODO implement this
return Promise.resolve(true);
async hideElements(selectors, frameId = 0, method = 'display') {
return await this.frames[frameId].evaluate(`(() => {
${this._utilsSnippet}
return hideElementsUtil(${JSON.stringify(selectors)}, '${method}');
})()`);
}

@@ -93,0 +100,0 @@ undoHideElements(frameId) {

@@ -5,2 +5,4 @@ import { waitFor } from '../cmps/base';

import { matches } from '../web/consentomatic/index';
import { HideMethod } from '../messages';
import { hideElementsUtil, getStyleElementUtil } from '../web/content-utils';

@@ -21,2 +23,4 @@ const DEBUG = false;

_utilsSnippet: string // serialized RPC functions borrowed from content script
constructor(page: any, url: string, frames: { [id: number]: any }) {

@@ -26,2 +30,6 @@ this.page = page;

this.frames = frames;
this._utilsSnippet = `
${getStyleElementUtil.toString()}
${hideElementsUtil.toString()}
`;
}

@@ -107,5 +115,7 @@

async hideElements(selectors: string[], frameId = 0) {
// TODO implement this
return Promise.resolve(true)
async hideElements(selectors: string[], frameId = 0, method: HideMethod = 'display') {
return await this.frames[frameId].evaluate(`(() => {
${this._utilsSnippet}
return hideElementsUtil(${JSON.stringify(selectors)}, '${method}');
})()`);
}

@@ -112,0 +122,0 @@

@@ -0,1 +1,2 @@

import { enableLogs } from './config';
export default class TabConsent {

@@ -15,2 +16,3 @@ constructor(tab, ruleCheckPromise) {

async isPopupOpen(retries = 1, interval = 1000) {
enableLogs && console.log('checking if popup is open...', this.tab.id, this.rule.name);
const isOpen = await this.rule.detectPopup(this.tab);

@@ -20,2 +22,3 @@ if (!isOpen && retries > 0) {

}
enableLogs && console.log(`popup is ${isOpen ? 'open' : 'not open'}`);
return isOpen;

@@ -25,2 +28,3 @@ }

try {
enableLogs && console.log(`doing opt out ${this.getCMPName()} in tab ${this.tab.id}`);
this.optOutStatus = await this.rule.optOut(this.tab);

@@ -30,2 +34,3 @@ return this.optOutStatus;

catch (e) {
console.error('error during opt out', e);
this.optOutStatus = e;

@@ -36,2 +41,3 @@ throw e;

if (!this.rule.isHidingRule) {
enableLogs && console.log('unhiding elements');
if (this.getCMPName().startsWith('com_')) {

@@ -38,0 +44,0 @@ this.tab.wait(5000).then(() => this.tab.undoHideElements());

@@ -0,1 +1,2 @@

import { enableLogs } from './config';
import { AutoCMP, TabActor } from './types';

@@ -21,2 +22,3 @@

async isPopupOpen(retries = 1, interval = 1000): Promise<boolean> {
enableLogs && console.log('checking if popup is open...', this.tab.id, this.rule.name);
const isOpen = await this.rule.detectPopup(this.tab);

@@ -26,2 +28,3 @@ if (!isOpen && retries > 0) {

}
enableLogs && console.log(`popup is ${isOpen ? 'open' : 'not open'}`);
return isOpen;

@@ -32,5 +35,7 @@ }

try {
enableLogs && console.log(`doing opt out ${this.getCMPName()} in tab ${this.tab.id}`);
this.optOutStatus = await this.rule.optOut(this.tab);
return this.optOutStatus;
} catch (e) {
console.error('error during opt out', e);
this.optOutStatus = e;

@@ -40,2 +45,3 @@ throw e;

if (!this.rule.isHidingRule) {
enableLogs && console.log('unhiding elements');
if (this.getCMPName().startsWith('com_')) {

@@ -42,0 +48,0 @@ this.tab.wait(5000).then(() => this.tab.undoHideElements())

@@ -1,2 +0,2 @@

import { ContentScriptMessage } from "./messages";
import { ContentScriptMessage, HideMethod } from "./messages";

@@ -30,3 +30,3 @@ type Tab = {

waitForThenClick(selector: string, timeout?: number, frameId?: number): Promise<boolean>
hideElements(selectors: string[], frameId?: number): Promise<boolean>
hideElements(selectors: string[], frameId?: number, method?: HideMethod): Promise<boolean>
undoHideElements(frameId?: number): Promise<boolean>

@@ -33,0 +33,0 @@ goto(url: string): Promise<void>

@@ -8,2 +8,3 @@ import Tab from './web/tab';

import prehideElements from './hider';
import { enableLogs } from './config';
export * from './index';

@@ -33,2 +34,3 @@ export { Tab, handleContentMessage, };

async checkTab(tabId, prehide = true) {
enableLogs && console.log('checking tab', tabId, this.consentFrames, this.tabCmps);
const tab = this.createTab(tabId);

@@ -44,2 +46,3 @@ if (prehide) {

const frame = this.consentFrames.get(tabId);
enableLogs && console.log(`Found ${rule.name} in a nested iframe ${frame.id} inside tab ${tabId}`);
if (frame.type === rule.name) {

@@ -49,4 +52,6 @@ consent.tab.frame = frame;

}
enableLogs && console.log('finished checking tab', tabId, this.consentFrames, this.tabCmps);
// no CMP detected, undo hiding
if (!rule && prehide) {
enableLogs && console.log('no CMP detected, undo hiding');
tab.undoHideElements();

@@ -53,0 +58,0 @@ }

@@ -10,2 +10,3 @@ import Tab from './web/tab';

import prehideElements from './hider';
import { enableLogs } from './config';

@@ -48,2 +49,3 @@ export * from './index';

async checkTab(tabId: number, prehide = true) {
enableLogs && console.log('checking tab', tabId, this.consentFrames, this.tabCmps);
const tab = this.createTab(tabId);

@@ -59,2 +61,3 @@ if (prehide) {

const frame = this.consentFrames.get(tabId);
enableLogs && console.log(`Found ${rule.name} in a nested iframe ${frame.id} inside tab ${tabId}`);
if (frame.type === rule.name) {

@@ -64,4 +67,6 @@ consent.tab.frame = frame;

}
enableLogs && console.log('finished checking tab', tabId, this.consentFrames, this.tabCmps);
// no CMP detected, undo hiding
if (!rule && prehide) {
enableLogs && console.log('no CMP detected, undo hiding');
tab.undoHideElements();

@@ -68,0 +73,0 @@ }

import { matches, executeAction } from "./consentomatic/index";
import { hideElementsUtil, getStyleElementUtil } from "./content-utils";
let actionQueue = Promise.resolve(null);
const styleOverrideElementId = "autoconsent-css-rules";
const styleSelector = `style#${styleOverrideElementId}`;
export default function handleMessage(message, debug = false) {

@@ -28,4 +27,5 @@ if (message.type === "click") {

elem.forEach((e, i) => {
results[i] = e.offsetParent !== null || window.getComputedStyle(e).display !== "none" || e.style?.display !== "none";
results[i] = e.offsetParent !== null || window.getComputedStyle(e).display !== "none"; // TODO: handle visibility and z-index?
});
debug && console.log("[visible?]", message.selector, elem, results);
if (results.length === 0) {

@@ -45,2 +45,3 @@ return false;

const elem = document.querySelector(message.selector);
debug && console.log("[getAttribute]", message.selector, elem);
if (!elem) {

@@ -53,27 +54,12 @@ return false;

// TODO: chrome support
debug && console.log("about to [eval]", message.script); // this will not show in Webkit console
const result = window.eval(message.script); // eslint-disable-line no-eval
debug && console.log("[eval]", message.script, result);
return result;
}
else if (message.type === "hide") {
const parent = document.head ||
document.getElementsByTagName("head")[0] ||
document.documentElement;
const rule = `${message.selectors.join(",")} { display: none !important; z-index: -1 !important; } `;
const existingElement = document.querySelector(styleSelector);
debug && console.log("[hide]", message.selectors, !!existingElement);
if (existingElement && existingElement instanceof HTMLStyleElement) {
existingElement.innerText += rule;
}
else {
const css = document.createElement("style");
css.type = "text/css";
css.id = styleOverrideElementId;
css.appendChild(document.createTextNode(rule));
parent.appendChild(css);
}
return message.selectors.length > 0;
debug && console.log("[hide]", message.selectors);
return hideElementsUtil(message.selectors, message.method);
}
else if (message.type === "undohide") {
const existingElement = document.querySelector(styleSelector);
const existingElement = getStyleElementUtil();
debug && console.log("[unhide]", !!existingElement);

@@ -87,5 +73,7 @@ if (existingElement) {

const matched = matches(message.config);
debug && console.log("[matches?]", message.config.type, JSON.stringify(message.config), matched);
return matched;
}
else if (message.type === "executeAction") {
debug && console.log("[executeAction]", message);
actionQueue = actionQueue.then(() => executeAction(message.config, message.param));

@@ -92,0 +80,0 @@ return true;

import { matches, executeAction } from "./consentomatic/index";
import { ContentScriptMessage } from "../messages";
import { hideElementsUtil, getStyleElementUtil } from "./content-utils";
let actionQueue = Promise.resolve(null);
const styleOverrideElementId = "autoconsent-css-rules";
const styleSelector = `style#${styleOverrideElementId}`;

@@ -28,4 +27,5 @@ export default function handleMessage(message: ContentScriptMessage, debug = false) {

elem.forEach((e, i) => {
results[i] = e.offsetParent !== null || window.getComputedStyle(e).display !== "none" || e.style?.display !== "none";
results[i] = e.offsetParent !== null || window.getComputedStyle(e).display !== "none"; // TODO: handle visibility and z-index?
});
debug && console.log("[visible?]", message.selector, elem, results);
if (results.length === 0) {

@@ -42,2 +42,3 @@ return false;

const elem = document.querySelector(message.selector);
debug && console.log("[getAttribute]", message.selector, elem);
if (!elem) {

@@ -49,25 +50,10 @@ return false;

// TODO: chrome support
debug && console.log("about to [eval]", message.script); // this will not show in Webkit console
const result = window.eval(message.script); // eslint-disable-line no-eval
debug && console.log("[eval]", message.script, result);
return result;
} else if (message.type === "hide") {
const parent =
document.head ||
document.getElementsByTagName("head")[0] ||
document.documentElement;
const rule = `${message.selectors.join(",")} { display: none !important; z-index: -1 !important; } `;
const existingElement = document.querySelector(styleSelector);
debug && console.log("[hide]", message.selectors, !!existingElement);
if (existingElement && existingElement instanceof HTMLStyleElement) {
existingElement.innerText += rule;
} else {
const css = document.createElement("style");
css.type = "text/css";
css.id = styleOverrideElementId;
css.appendChild(document.createTextNode(rule));
parent.appendChild(css);
}
return message.selectors.length > 0;
debug && console.log("[hide]", message.selectors);
return hideElementsUtil(message.selectors, message.method);
} else if (message.type === "undohide") {
const existingElement = document.querySelector(styleSelector);
const existingElement = getStyleElementUtil();
debug && console.log("[unhide]", !!existingElement);

@@ -80,4 +66,6 @@ if (existingElement) {

const matched = matches(message.config);
debug && console.log("[matches?]", message.config.type, JSON.stringify(message.config), matched);
return matched;
} else if (message.type === "executeAction") {
debug && console.log("[executeAction]", message);
actionQueue = actionQueue.then(() => executeAction(message.config, message.param));

@@ -84,0 +72,0 @@ return true;

import { waitFor } from "../cmps/base";
import { enableLogs } from "../config";
export default class TabActions {

@@ -10,3 +11,2 @@ constructor(tabId, frame, sendContentMessage, browser) {

async elementExists(selector, frameId = 0) {
console.log(`check for ${selector} in tab ${this.id}, frame ${frameId}`);
return this.sendContentMessage(this.id, {

@@ -20,3 +20,3 @@ type: "elemExists",

async clickElement(selector, frameId = 0) {
console.log(`click element ${selector} in tab ${this.id}`);
enableLogs && console.log(`click element ${selector} in tab ${this.id}`);
return this.sendContentMessage(this.id, {

@@ -30,3 +30,3 @@ type: "click",

async clickElements(selector, frameId = 0) {
console.log(`click elements ${selector} in tab ${this.id}`);
enableLogs && console.log(`click elements ${selector} in tab ${this.id}`);
return this.sendContentMessage(this.id, {

@@ -74,6 +74,8 @@ type: "click",

}
async hideElements(selectors, frameId = 0) {
async hideElements(selectors, frameId = 0, method = 'display') {
enableLogs && console.log('Sending hide elements to', this.id, selectors);
return this.sendContentMessage(this.id, {
type: "hide",
selectors
selectors,
method,
}, { frameId });

@@ -93,4 +95,8 @@ }

wait(ms) {
enableLogs && console.log(`waiting for ${ms}ms in tab ${this.id}`);
return new Promise(resolve => {
setTimeout(() => resolve(true), ms);
setTimeout(() => {
enableLogs && console.log(`done waiting in tab ${this.id}`);
resolve(true);
}, ms);
});

@@ -97,0 +103,0 @@ }

import { waitFor } from "../cmps/base";
import { enableLogs } from "../config";
import { HideMethod } from "../messages";
import { TabActor, MessageSender, Browser } from "../types";

@@ -17,3 +19,2 @@

async elementExists(selector: string, frameId = 0) {
console.log(`check for ${selector} in tab ${this.id}, frame ${frameId}`);
return this.sendContentMessage(

@@ -32,3 +33,3 @@ this.id,

async clickElement(selector: string, frameId = 0) {
console.log(`click element ${selector} in tab ${this.id}`);
enableLogs && console.log(`click element ${selector} in tab ${this.id}`);
return this.sendContentMessage(

@@ -47,3 +48,3 @@ this.id,

async clickElements(selector: string, frameId = 0) {
console.log(`click elements ${selector} in tab ${this.id}`);
enableLogs && console.log(`click elements ${selector} in tab ${this.id}`);
return this.sendContentMessage(

@@ -117,3 +118,4 @@ this.id,

async hideElements(selectors: string[], frameId = 0) {
async hideElements(selectors: string[], frameId = 0, method: HideMethod = 'display') {
enableLogs && console.log('Sending hide elements to', this.id, selectors);
return this.sendContentMessage(

@@ -123,3 +125,4 @@ this.id,

type: "hide",
selectors
selectors,
method,
},

@@ -149,4 +152,8 @@ { frameId }

wait(ms: number): Promise<true> {
enableLogs && console.log(`waiting for ${ms}ms in tab ${this.id}`);
return new Promise(resolve => {
setTimeout(() => resolve(true), ms);
setTimeout(() => {
enableLogs && console.log(`done waiting in tab ${this.id}`);
resolve(true);
}, ms);
});

@@ -153,0 +160,0 @@ }

{
"name": "@duckduckgo/autoconsent",
"version": "1.0.5",
"version": "1.0.6",
"description": "",

@@ -5,0 +5,0 @@ "main": "dist/autoconsent.cjs.js",

@@ -87,3 +87,3 @@ ## Autoconsent

```
Evaluates `code` in the context of the page and returns the truthiness of the result.
Evaluates `code` in the context of the page. NB: the result of this action depends on the truthiness of the evaluated expression, make sure it returns `true` in case of success.

@@ -90,0 +90,0 @@ #### Wait for element

@@ -15,1 +15,7 @@ import generateCMPTests from "./runner";

});
generateCMPTests('Onetrust', [
"https://www.newyorker.com/",
], {
skipRegions: ['US']
});

@@ -42,3 +42,3 @@ import fs from 'fs/promises';

const tab = autoconsent.attachToPage(page, url, rules, 20);
const tab = autoconsent.attachToPage(page, url, rules, 20, true);
await tab.checked;

@@ -45,0 +45,0 @@ expect(tab.getCMPName()).toBe(expectedCmp);

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc