diff --git a/.github/codeql/queries/autogen_2d_RenderingContext_getImageData.ql b/.github/codeql/queries/autogen_2d_RenderingContext_getImageData.ql new file mode 100644 index 000000000..9323058df --- /dev/null +++ b/.github/codeql/queries/autogen_2d_RenderingContext_getImageData.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/2d-getimagedata + * @name Access to 2d rendering context getImageData + * @kind problem + * @problem.severity warning + * @description Finds uses of 2d RenderingContext.getImageData + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("2d") and + api = invocation.getAPropertyRead("getImageData") +select api, "getImageData is an indicator of fingerprinting, weighed 38.11 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_2d_RenderingContext_isPointInPath.ql b/.github/codeql/queries/autogen_2d_RenderingContext_isPointInPath.ql new file mode 100644 index 000000000..2318a0c84 --- /dev/null +++ b/.github/codeql/queries/autogen_2d_RenderingContext_isPointInPath.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/2d-ispointinpath + * @name Access to 2d rendering context isPointInPath + * @kind problem + * @problem.severity warning + * @description Finds uses of 2d RenderingContext.isPointInPath + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("2d") and + api = invocation.getAPropertyRead("isPointInPath") +select api, "isPointInPath is an indicator of fingerprinting, weighed 4216.23 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_2d_RenderingContext_measureText.ql b/.github/codeql/queries/autogen_2d_RenderingContext_measureText.ql new file mode 100644 index 000000000..b862cd21b --- /dev/null +++ b/.github/codeql/queries/autogen_2d_RenderingContext_measureText.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/2d-measuretext + * @name Access to 2d rendering context measureText + * @kind problem + * @problem.severity warning + * @description Finds uses of 2d RenderingContext.measureText + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("2d") and + api = invocation.getAPropertyRead("measureText") +select api, "measureText is an indicator of fingerprinting, weighed 48.2 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_AudioWorkletNode.ql b/.github/codeql/queries/autogen_AudioWorkletNode.ql new file mode 100644 index 000000000..de9f13c21 --- /dev/null +++ b/.github/codeql/queries/autogen_AudioWorkletNode.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/audioworkletnode + * @name Use of AudioWorkletNode + * @kind problem + * @problem.severity warning + * @description Finds uses of AudioWorkletNode + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = instantiationOf("AudioWorkletNode") +select api, "AudioWorkletNode is an indicator of fingerprinting, weighed 32.68 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_Date_getTimezoneOffset.ql b/.github/codeql/queries/autogen_Date_getTimezoneOffset.ql new file mode 100644 index 000000000..43c4a8bce --- /dev/null +++ b/.github/codeql/queries/autogen_Date_getTimezoneOffset.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/date-gettimezoneoffset + * @name Access to Date.getTimezoneOffset + * @kind problem + * @problem.severity warning + * @description Finds uses of Date.getTimezoneOffset + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode inst, SourceNode api +where + inst = instantiationOf("Date") and + api = inst.getAPropertyRead("getTimezoneOffset") +select api, "getTimezoneOffset is an indicator of fingerprinting, weighed 16.79 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_DeviceMotionEvent_acceleration.ql b/.github/codeql/queries/autogen_DeviceMotionEvent_acceleration.ql new file mode 100644 index 000000000..21a268b3f --- /dev/null +++ b/.github/codeql/queries/autogen_DeviceMotionEvent_acceleration.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/devicemotionevent-acceleration + * @name Potential access to DeviceMotionEvent.acceleration + * @kind problem + * @problem.severity warning + * @description Finds uses of acceleration + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from PropRef api +where + api.getPropertyName() = "acceleration" +select api, "acceleration is an indicator of fingerprinting, weighed 59.51 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_DeviceMotionEvent_accelerationIncludingGravity.ql b/.github/codeql/queries/autogen_DeviceMotionEvent_accelerationIncludingGravity.ql new file mode 100644 index 000000000..1c970bca6 --- /dev/null +++ b/.github/codeql/queries/autogen_DeviceMotionEvent_accelerationIncludingGravity.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/devicemotionevent-accelerationincludinggravity + * @name Potential access to DeviceMotionEvent.accelerationIncludingGravity + * @kind problem + * @problem.severity warning + * @description Finds uses of accelerationIncludingGravity + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from PropRef api +where + api.getPropertyName() = "accelerationIncludingGravity" +select api, "accelerationIncludingGravity is an indicator of fingerprinting, weighed 166.43 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_DeviceMotionEvent_rotationRate.ql b/.github/codeql/queries/autogen_DeviceMotionEvent_rotationRate.ql new file mode 100644 index 000000000..5256f3295 --- /dev/null +++ b/.github/codeql/queries/autogen_DeviceMotionEvent_rotationRate.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/devicemotionevent-rotationrate + * @name Potential access to DeviceMotionEvent.rotationRate + * @kind problem + * @problem.severity warning + * @description Finds uses of rotationRate + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from PropRef api +where + api.getPropertyName() = "rotationRate" +select api, "rotationRate is an indicator of fingerprinting, weighed 59.32 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_Gyroscope.ql b/.github/codeql/queries/autogen_Gyroscope.ql new file mode 100644 index 000000000..d57c464e0 --- /dev/null +++ b/.github/codeql/queries/autogen_Gyroscope.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/gyroscope + * @name Use of Gyroscope + * @kind problem + * @problem.severity warning + * @description Finds uses of Gyroscope + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = instantiationOf("Gyroscope") +select api, "Gyroscope is an indicator of fingerprinting, weighed 189.7 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_Gyroscope_x.ql b/.github/codeql/queries/autogen_Gyroscope_x.ql new file mode 100644 index 000000000..3344b446d --- /dev/null +++ b/.github/codeql/queries/autogen_Gyroscope_x.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/gyroscope-x + * @name Access to Gyroscope.x + * @kind problem + * @problem.severity warning + * @description Finds uses of Gyroscope.x + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode inst, SourceNode api +where + inst = instantiationOf("Gyroscope") and + api = inst.getAPropertyRead("x") +select api, "x is an indicator of fingerprinting, weighed 4216.23 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_Gyroscope_y.ql b/.github/codeql/queries/autogen_Gyroscope_y.ql new file mode 100644 index 000000000..b5b75a1c5 --- /dev/null +++ b/.github/codeql/queries/autogen_Gyroscope_y.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/gyroscope-y + * @name Access to Gyroscope.y + * @kind problem + * @problem.severity warning + * @description Finds uses of Gyroscope.y + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode inst, SourceNode api +where + inst = instantiationOf("Gyroscope") and + api = inst.getAPropertyRead("y") +select api, "y is an indicator of fingerprinting, weighed 4216.23 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_Gyroscope_z.ql b/.github/codeql/queries/autogen_Gyroscope_z.ql new file mode 100644 index 000000000..417556ad8 --- /dev/null +++ b/.github/codeql/queries/autogen_Gyroscope_z.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/gyroscope-z + * @name Access to Gyroscope.z + * @kind problem + * @problem.severity warning + * @description Finds uses of Gyroscope.z + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode inst, SourceNode api +where + inst = instantiationOf("Gyroscope") and + api = inst.getAPropertyRead("z") +select api, "z is an indicator of fingerprinting, weighed 4216.23 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_Notification_permission.ql b/.github/codeql/queries/autogen_Notification_permission.ql new file mode 100644 index 000000000..555cb9b81 --- /dev/null +++ b/.github/codeql/queries/autogen_Notification_permission.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/notification-permission + * @name Access to Notification.permission + * @kind problem + * @problem.severity warning + * @description Finds uses of Notification.permission + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("Notification") and + api = prop.getAPropertyRead("permission") +select api, "permission is an indicator of fingerprinting, weighed 21.19 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_OfflineAudioContext.ql b/.github/codeql/queries/autogen_OfflineAudioContext.ql new file mode 100644 index 000000000..c3406125a --- /dev/null +++ b/.github/codeql/queries/autogen_OfflineAudioContext.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/offlineaudiocontext + * @name Use of OfflineAudioContext + * @kind problem + * @problem.severity warning + * @description Finds uses of OfflineAudioContext + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = instantiationOf("OfflineAudioContext") +select api, "OfflineAudioContext is an indicator of fingerprinting, weighed 1062.57 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_RTCPeerConnection.ql b/.github/codeql/queries/autogen_RTCPeerConnection.ql new file mode 100644 index 000000000..8d7e80174 --- /dev/null +++ b/.github/codeql/queries/autogen_RTCPeerConnection.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/rtcpeerconnection + * @name Use of RTCPeerConnection + * @kind problem + * @problem.severity warning + * @description Finds uses of RTCPeerConnection + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = instantiationOf("RTCPeerConnection") +select api, "RTCPeerConnection is an indicator of fingerprinting, weighed 47.04 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_SharedWorker.ql b/.github/codeql/queries/autogen_SharedWorker.ql new file mode 100644 index 000000000..1b2859b85 --- /dev/null +++ b/.github/codeql/queries/autogen_SharedWorker.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/sharedworker + * @name Use of SharedWorker + * @kind problem + * @problem.severity warning + * @description Finds uses of SharedWorker + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = instantiationOf("SharedWorker") +select api, "SharedWorker is an indicator of fingerprinting, weighed 56.71 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_appCodeName.ql b/.github/codeql/queries/autogen_navigator_appCodeName.ql new file mode 100644 index 000000000..f6a5cd10b --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_appCodeName.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-appcodename + * @name Access to navigator.appCodeName + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.appCodeName + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("appCodeName") +select api, "appCodeName is an indicator of fingerprinting, weighed 127.81 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_deviceMemory.ql b/.github/codeql/queries/autogen_navigator_deviceMemory.ql new file mode 100644 index 000000000..476a2927f --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_deviceMemory.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-devicememory + * @name Access to navigator.deviceMemory + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.deviceMemory + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("deviceMemory") +select api, "deviceMemory is an indicator of fingerprinting, weighed 78.47 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_getBattery.ql b/.github/codeql/queries/autogen_navigator_getBattery.ql new file mode 100644 index 000000000..a039ebd29 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_getBattery.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-getbattery + * @name Access to navigator.getBattery + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.getBattery + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("getBattery") +select api, "getBattery is an indicator of fingerprinting, weighed 117.75 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_getGamepads.ql b/.github/codeql/queries/autogen_navigator_getGamepads.ql new file mode 100644 index 000000000..491b398a4 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_getGamepads.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-getgamepads + * @name Access to navigator.getGamepads + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.getGamepads + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("getGamepads") +select api, "getGamepads is an indicator of fingerprinting, weighed 256.1 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_hardwareConcurrency.ql b/.github/codeql/queries/autogen_navigator_hardwareConcurrency.ql new file mode 100644 index 000000000..dfb685511 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_hardwareConcurrency.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-hardwareconcurrency + * @name Access to navigator.hardwareConcurrency + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.hardwareConcurrency + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("hardwareConcurrency") +select api, "hardwareConcurrency is an indicator of fingerprinting, weighed 62.49 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_keyboard.ql b/.github/codeql/queries/autogen_navigator_keyboard.ql new file mode 100644 index 000000000..9a941c755 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_keyboard.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-keyboard + * @name Access to navigator.keyboard + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.keyboard + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("keyboard") +select api, "keyboard is an indicator of fingerprinting, weighed 1296.7 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_mediaCapabilities.ql b/.github/codeql/queries/autogen_navigator_mediaCapabilities.ql new file mode 100644 index 000000000..7547d6aa8 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_mediaCapabilities.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-mediacapabilities + * @name Access to navigator.mediaCapabilities + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.mediaCapabilities + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("mediaCapabilities") +select api, "mediaCapabilities is an indicator of fingerprinting, weighed 115.38 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_mediaDevices.ql b/.github/codeql/queries/autogen_navigator_mediaDevices.ql new file mode 100644 index 000000000..de8b5c470 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_mediaDevices.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-mediadevices + * @name Access to navigator.mediaDevices + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.mediaDevices + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("mediaDevices") +select api, "mediaDevices is an indicator of fingerprinting, weighed 110.44 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_onLine.ql b/.github/codeql/queries/autogen_navigator_onLine.ql new file mode 100644 index 000000000..18061b298 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_onLine.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-online + * @name Access to navigator.onLine + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.onLine + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("onLine") +select api, "onLine is an indicator of fingerprinting, weighed 19.11 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_permissions.ql b/.github/codeql/queries/autogen_navigator_permissions.ql new file mode 100644 index 000000000..dcc0c2930 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_permissions.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-permissions + * @name Access to navigator.permissions + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.permissions + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("permissions") +select api, "permissions is an indicator of fingerprinting, weighed 72.06 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_productSub.ql b/.github/codeql/queries/autogen_navigator_productSub.ql new file mode 100644 index 000000000..ca28abef4 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_productSub.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-productsub + * @name Access to navigator.productSub + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.productSub + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("productSub") +select api, "productSub is an indicator of fingerprinting, weighed 475.08 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_requestMediaKeySystemAccess.ql b/.github/codeql/queries/autogen_navigator_requestMediaKeySystemAccess.ql new file mode 100644 index 000000000..3d99aae11 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_requestMediaKeySystemAccess.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-requestmediakeysystemaccess + * @name Access to navigator.requestMediaKeySystemAccess + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.requestMediaKeySystemAccess + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("requestMediaKeySystemAccess") +select api, "requestMediaKeySystemAccess is an indicator of fingerprinting, weighed 15.3 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_storage.ql b/.github/codeql/queries/autogen_navigator_storage.ql new file mode 100644 index 000000000..5c96fc535 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_storage.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-storage + * @name Access to navigator.storage + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.storage + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("storage") +select api, "storage is an indicator of fingerprinting, weighed 143.61 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_vendorSub.ql b/.github/codeql/queries/autogen_navigator_vendorSub.ql new file mode 100644 index 000000000..cca8739f8 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_vendorSub.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-vendorsub + * @name Access to navigator.vendorSub + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.vendorSub + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("vendorSub") +select api, "vendorSub is an indicator of fingerprinting, weighed 1543.86 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_webdriver.ql b/.github/codeql/queries/autogen_navigator_webdriver.ql new file mode 100644 index 000000000..c6e5f5aff --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_webdriver.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-webdriver + * @name Access to navigator.webdriver + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.webdriver + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("webdriver") +select api, "webdriver is an indicator of fingerprinting, weighed 32.18 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_webkitPersistentStorage.ql b/.github/codeql/queries/autogen_navigator_webkitPersistentStorage.ql new file mode 100644 index 000000000..646c73b83 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_webkitPersistentStorage.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-webkitpersistentstorage + * @name Access to navigator.webkitPersistentStorage + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.webkitPersistentStorage + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("webkitPersistentStorage") +select api, "webkitPersistentStorage is an indicator of fingerprinting, weighed 132.06 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_navigator_webkitTemporaryStorage.ql b/.github/codeql/queries/autogen_navigator_webkitTemporaryStorage.ql new file mode 100644 index 000000000..1dee42c32 --- /dev/null +++ b/.github/codeql/queries/autogen_navigator_webkitTemporaryStorage.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/navigator-webkittemporarystorage + * @name Access to navigator.webkitTemporaryStorage + * @kind problem + * @problem.severity warning + * @description Finds uses of navigator.webkitTemporaryStorage + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("navigator") and + api = prop.getAPropertyRead("webkitTemporaryStorage") +select api, "webkitTemporaryStorage is an indicator of fingerprinting, weighed 42.05 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_screen_availHeight.ql b/.github/codeql/queries/autogen_screen_availHeight.ql new file mode 100644 index 000000000..e0ca9acf3 --- /dev/null +++ b/.github/codeql/queries/autogen_screen_availHeight.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/screen-availheight + * @name Access to screen.availHeight + * @kind problem + * @problem.severity warning + * @description Finds uses of screen.availHeight + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("screen") and + api = prop.getAPropertyRead("availHeight") +select api, "availHeight is an indicator of fingerprinting, weighed 72.8 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_screen_availLeft.ql b/.github/codeql/queries/autogen_screen_availLeft.ql new file mode 100644 index 000000000..f8cafbee0 --- /dev/null +++ b/.github/codeql/queries/autogen_screen_availLeft.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/screen-availleft + * @name Access to screen.availLeft + * @kind problem + * @problem.severity warning + * @description Finds uses of screen.availLeft + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("screen") and + api = prop.getAPropertyRead("availLeft") +select api, "availLeft is an indicator of fingerprinting, weighed 665.2 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_screen_availTop.ql b/.github/codeql/queries/autogen_screen_availTop.ql new file mode 100644 index 000000000..8fb1cfa15 --- /dev/null +++ b/.github/codeql/queries/autogen_screen_availTop.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/screen-availtop + * @name Access to screen.availTop + * @kind problem + * @problem.severity warning + * @description Finds uses of screen.availTop + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("screen") and + api = prop.getAPropertyRead("availTop") +select api, "availTop is an indicator of fingerprinting, weighed 1527.75 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_screen_availWidth.ql b/.github/codeql/queries/autogen_screen_availWidth.ql new file mode 100644 index 000000000..33445cafa --- /dev/null +++ b/.github/codeql/queries/autogen_screen_availWidth.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/screen-availwidth + * @name Access to screen.availWidth + * @kind problem + * @problem.severity warning + * @description Finds uses of screen.availWidth + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("screen") and + api = prop.getAPropertyRead("availWidth") +select api, "availWidth is an indicator of fingerprinting, weighed 66.83 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_screen_colorDepth.ql b/.github/codeql/queries/autogen_screen_colorDepth.ql new file mode 100644 index 000000000..d60e95e1f --- /dev/null +++ b/.github/codeql/queries/autogen_screen_colorDepth.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/screen-colordepth + * @name Access to screen.colorDepth + * @kind problem + * @problem.severity warning + * @description Finds uses of screen.colorDepth + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("screen") and + api = prop.getAPropertyRead("colorDepth") +select api, "colorDepth is an indicator of fingerprinting, weighed 33.93 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_screen_orientation.ql b/.github/codeql/queries/autogen_screen_orientation.ql new file mode 100644 index 000000000..4dff29ca8 --- /dev/null +++ b/.github/codeql/queries/autogen_screen_orientation.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/screen-orientation + * @name Access to screen.orientation + * @kind problem + * @problem.severity warning + * @description Finds uses of screen.orientation + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("screen") and + api = prop.getAPropertyRead("orientation") +select api, "orientation is an indicator of fingerprinting, weighed 43.44 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_screen_pixelDepth.ql b/.github/codeql/queries/autogen_screen_pixelDepth.ql new file mode 100644 index 000000000..8848e6149 --- /dev/null +++ b/.github/codeql/queries/autogen_screen_pixelDepth.ql @@ -0,0 +1,16 @@ +/** + * @id prebid/screen-pixeldepth + * @name Access to screen.pixelDepth + * @kind problem + * @problem.severity warning + * @description Finds uses of screen.pixelDepth + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("screen") and + api = prop.getAPropertyRead("pixelDepth") +select api, "pixelDepth is an indicator of fingerprinting, weighed 34.57 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_webgl2_RenderingContext_getContextAttributes.ql b/.github/codeql/queries/autogen_webgl2_RenderingContext_getContextAttributes.ql new file mode 100644 index 000000000..907d2af6b --- /dev/null +++ b/.github/codeql/queries/autogen_webgl2_RenderingContext_getContextAttributes.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/webgl2-getcontextattributes + * @name Access to webgl2 rendering context getContextAttributes + * @kind problem + * @problem.severity warning + * @description Finds uses of webgl2 RenderingContext.getContextAttributes + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("webgl2") and + api = invocation.getAPropertyRead("getContextAttributes") +select api, "getContextAttributes is an indicator of fingerprinting, weighed 175.29 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_webgl2_RenderingContext_getExtension.ql b/.github/codeql/queries/autogen_webgl2_RenderingContext_getExtension.ql new file mode 100644 index 000000000..97deebacb --- /dev/null +++ b/.github/codeql/queries/autogen_webgl2_RenderingContext_getExtension.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/webgl2-getextension + * @name Access to webgl2 rendering context getExtension + * @kind problem + * @problem.severity warning + * @description Finds uses of webgl2 RenderingContext.getExtension + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("webgl2") and + api = invocation.getAPropertyRead("getExtension") +select api, "getExtension is an indicator of fingerprinting, weighed 44.76 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_webgl2_RenderingContext_getParameter.ql b/.github/codeql/queries/autogen_webgl2_RenderingContext_getParameter.ql new file mode 100644 index 000000000..77a25606b --- /dev/null +++ b/.github/codeql/queries/autogen_webgl2_RenderingContext_getParameter.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/webgl2-getparameter + * @name Access to webgl2 rendering context getParameter + * @kind problem + * @problem.severity warning + * @description Finds uses of webgl2 RenderingContext.getParameter + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("webgl2") and + api = invocation.getAPropertyRead("getParameter") +select api, "getParameter is an indicator of fingerprinting, weighed 42.17 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_webgl2_RenderingContext_getShaderPrecisionFormat.ql b/.github/codeql/queries/autogen_webgl2_RenderingContext_getShaderPrecisionFormat.ql new file mode 100644 index 000000000..f2b0de4d5 --- /dev/null +++ b/.github/codeql/queries/autogen_webgl2_RenderingContext_getShaderPrecisionFormat.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/webgl2-getshaderprecisionformat + * @name Access to webgl2 rendering context getShaderPrecisionFormat + * @kind problem + * @problem.severity warning + * @description Finds uses of webgl2 RenderingContext.getShaderPrecisionFormat + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("webgl2") and + api = invocation.getAPropertyRead("getShaderPrecisionFormat") +select api, "getShaderPrecisionFormat is an indicator of fingerprinting, weighed 105.96 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_webgl2_RenderingContext_getSupportedExtensions.ql b/.github/codeql/queries/autogen_webgl2_RenderingContext_getSupportedExtensions.ql new file mode 100644 index 000000000..5039c5929 --- /dev/null +++ b/.github/codeql/queries/autogen_webgl2_RenderingContext_getSupportedExtensions.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/webgl2-getsupportedextensions + * @name Access to webgl2 rendering context getSupportedExtensions + * @kind problem + * @problem.severity warning + * @description Finds uses of webgl2 RenderingContext.getSupportedExtensions + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("webgl2") and + api = invocation.getAPropertyRead("getSupportedExtensions") +select api, "getSupportedExtensions is an indicator of fingerprinting, weighed 495.53 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_webgl2_RenderingContext_readPixels.ql b/.github/codeql/queries/autogen_webgl2_RenderingContext_readPixels.ql new file mode 100644 index 000000000..1b89fb6b8 --- /dev/null +++ b/.github/codeql/queries/autogen_webgl2_RenderingContext_readPixels.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/webgl2-readpixels + * @name Access to webgl2 rendering context readPixels + * @kind problem + * @problem.severity warning + * @description Finds uses of webgl2 RenderingContext.readPixels + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("webgl2") and + api = invocation.getAPropertyRead("readPixels") +select api, "readPixels is an indicator of fingerprinting, weighed 61.17 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_webgl_RenderingContext_getContextAttributes.ql b/.github/codeql/queries/autogen_webgl_RenderingContext_getContextAttributes.ql new file mode 100644 index 000000000..1ad0af716 --- /dev/null +++ b/.github/codeql/queries/autogen_webgl_RenderingContext_getContextAttributes.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/webgl-getcontextattributes + * @name Access to webgl rendering context getContextAttributes + * @kind problem + * @problem.severity warning + * @description Finds uses of webgl RenderingContext.getContextAttributes + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("webgl") and + api = invocation.getAPropertyRead("getContextAttributes") +select api, "getContextAttributes is an indicator of fingerprinting, weighed 2131.59 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_webgl_RenderingContext_getExtension.ql b/.github/codeql/queries/autogen_webgl_RenderingContext_getExtension.ql new file mode 100644 index 000000000..87922396a --- /dev/null +++ b/.github/codeql/queries/autogen_webgl_RenderingContext_getExtension.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/webgl-getextension + * @name Access to webgl rendering context getExtension + * @kind problem + * @problem.severity warning + * @description Finds uses of webgl RenderingContext.getExtension + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("webgl") and + api = invocation.getAPropertyRead("getExtension") +select api, "getExtension is an indicator of fingerprinting, weighed 19.17 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_webgl_RenderingContext_getParameter.ql b/.github/codeql/queries/autogen_webgl_RenderingContext_getParameter.ql new file mode 100644 index 000000000..2a5e408e6 --- /dev/null +++ b/.github/codeql/queries/autogen_webgl_RenderingContext_getParameter.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/webgl-getparameter + * @name Access to webgl rendering context getParameter + * @kind problem + * @problem.severity warning + * @description Finds uses of webgl RenderingContext.getParameter + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("webgl") and + api = invocation.getAPropertyRead("getParameter") +select api, "getParameter is an indicator of fingerprinting, weighed 21.25 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_webgl_RenderingContext_getShaderPrecisionFormat.ql b/.github/codeql/queries/autogen_webgl_RenderingContext_getShaderPrecisionFormat.ql new file mode 100644 index 000000000..ac6972b34 --- /dev/null +++ b/.github/codeql/queries/autogen_webgl_RenderingContext_getShaderPrecisionFormat.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/webgl-getshaderprecisionformat + * @name Access to webgl rendering context getShaderPrecisionFormat + * @kind problem + * @problem.severity warning + * @description Finds uses of webgl RenderingContext.getShaderPrecisionFormat + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("webgl") and + api = invocation.getAPropertyRead("getShaderPrecisionFormat") +select api, "getShaderPrecisionFormat is an indicator of fingerprinting, weighed 750.75 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_webgl_RenderingContext_getSupportedExtensions.ql b/.github/codeql/queries/autogen_webgl_RenderingContext_getSupportedExtensions.ql new file mode 100644 index 000000000..6c6cf4855 --- /dev/null +++ b/.github/codeql/queries/autogen_webgl_RenderingContext_getSupportedExtensions.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/webgl-getsupportedextensions + * @name Access to webgl rendering context getSupportedExtensions + * @kind problem + * @problem.severity warning + * @description Finds uses of webgl RenderingContext.getSupportedExtensions + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("webgl") and + api = invocation.getAPropertyRead("getSupportedExtensions") +select api, "getSupportedExtensions is an indicator of fingerprinting, weighed 1058.69 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_webgl_RenderingContext_readPixels.ql b/.github/codeql/queries/autogen_webgl_RenderingContext_readPixels.ql new file mode 100644 index 000000000..efd2e9515 --- /dev/null +++ b/.github/codeql/queries/autogen_webgl_RenderingContext_readPixels.ql @@ -0,0 +1,17 @@ +/** + * @id prebid/webgl-readpixels + * @name Access to webgl rendering context readPixels + * @kind problem + * @problem.severity warning + * @description Finds uses of webgl RenderingContext.readPixels + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("webgl") and + api = invocation.getAPropertyRead("readPixels") +select api, "readPixels is an indicator of fingerprinting, weighed 20.37 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_window_devicePixelRatio.ql b/.github/codeql/queries/autogen_window_devicePixelRatio.ql new file mode 100644 index 000000000..7d6cca215 --- /dev/null +++ b/.github/codeql/queries/autogen_window_devicePixelRatio.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/window-devicepixelratio + * @name Access to window.devicePixelRatio + * @kind problem + * @problem.severity warning + * @description Finds uses of window.devicePixelRatio + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = windowPropertyRead("devicePixelRatio") +select api, "devicePixelRatio is an indicator of fingerprinting, weighed 18.68 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_window_indexedDB.ql b/.github/codeql/queries/autogen_window_indexedDB.ql new file mode 100644 index 000000000..4ce36d5a5 --- /dev/null +++ b/.github/codeql/queries/autogen_window_indexedDB.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/window-indexeddb + * @name Access to window.indexedDB + * @kind problem + * @problem.severity warning + * @description Finds uses of window.indexedDB + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = windowPropertyRead("indexedDB") +select api, "indexedDB is an indicator of fingerprinting, weighed 18.13 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_window_openDatabase.ql b/.github/codeql/queries/autogen_window_openDatabase.ql new file mode 100644 index 000000000..d90f5b491 --- /dev/null +++ b/.github/codeql/queries/autogen_window_openDatabase.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/window-opendatabase + * @name Access to window.openDatabase + * @kind problem + * @problem.severity warning + * @description Finds uses of window.openDatabase + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = windowPropertyRead("openDatabase") +select api, "openDatabase is an indicator of fingerprinting, weighed 139.85 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_window_outerHeight.ql b/.github/codeql/queries/autogen_window_outerHeight.ql new file mode 100644 index 000000000..4c4b64e94 --- /dev/null +++ b/.github/codeql/queries/autogen_window_outerHeight.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/window-outerheight + * @name Access to window.outerHeight + * @kind problem + * @problem.severity warning + * @description Finds uses of window.outerHeight + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = windowPropertyRead("outerHeight") +select api, "outerHeight is an indicator of fingerprinting, weighed 200.62 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_window_outerWidth.ql b/.github/codeql/queries/autogen_window_outerWidth.ql new file mode 100644 index 000000000..4313c7cc9 --- /dev/null +++ b/.github/codeql/queries/autogen_window_outerWidth.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/window-outerwidth + * @name Access to window.outerWidth + * @kind problem + * @problem.severity warning + * @description Finds uses of window.outerWidth + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = windowPropertyRead("outerWidth") +select api, "outerWidth is an indicator of fingerprinting, weighed 107.23 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_window_screenLeft.ql b/.github/codeql/queries/autogen_window_screenLeft.ql new file mode 100644 index 000000000..0e39d0726 --- /dev/null +++ b/.github/codeql/queries/autogen_window_screenLeft.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/window-screenleft + * @name Access to window.screenLeft + * @kind problem + * @problem.severity warning + * @description Finds uses of window.screenLeft + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = windowPropertyRead("screenLeft") +select api, "screenLeft is an indicator of fingerprinting, weighed 286.83 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_window_screenTop.ql b/.github/codeql/queries/autogen_window_screenTop.ql new file mode 100644 index 000000000..517da52b3 --- /dev/null +++ b/.github/codeql/queries/autogen_window_screenTop.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/window-screentop + * @name Access to window.screenTop + * @kind problem + * @problem.severity warning + * @description Finds uses of window.screenTop + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = windowPropertyRead("screenTop") +select api, "screenTop is an indicator of fingerprinting, weighed 286.72 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_window_screenX.ql b/.github/codeql/queries/autogen_window_screenX.ql new file mode 100644 index 000000000..24e470269 --- /dev/null +++ b/.github/codeql/queries/autogen_window_screenX.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/window-screenx + * @name Access to window.screenX + * @kind problem + * @problem.severity warning + * @description Finds uses of window.screenX + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = windowPropertyRead("screenX") +select api, "screenX is an indicator of fingerprinting, weighed 337.97 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/autogen_window_screenY.ql b/.github/codeql/queries/autogen_window_screenY.ql new file mode 100644 index 000000000..23675d4d8 --- /dev/null +++ b/.github/codeql/queries/autogen_window_screenY.ql @@ -0,0 +1,15 @@ +/** + * @id prebid/window-screeny + * @name Access to window.screenY + * @kind problem + * @problem.severity warning + * @description Finds uses of window.screenY + */ + +// this file is autogenerated, see fingerprintApis.mjs + +import prebid +from SourceNode api +where + api = windowPropertyRead("screenY") +select api, "screenY is an indicator of fingerprinting, weighed 324.59 in https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json" diff --git a/.github/codeql/queries/deviceMemory.ql b/.github/codeql/queries/deviceMemory.ql deleted file mode 100644 index 6f650abf0..000000000 --- a/.github/codeql/queries/deviceMemory.ql +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @id prebid/device-memory - * @name Access to navigator.deviceMemory - * @kind problem - * @problem.severity warning - * @description Finds uses of deviceMemory - */ - -import prebid - -from SourceNode nav -where - nav = windowPropertyRead("navigator") -select nav.getAPropertyRead("deviceMemory"), "deviceMemory is an indicator of fingerprinting" diff --git a/.github/codeql/queries/hardwareConcurrency.ql b/.github/codeql/queries/hardwareConcurrency.ql deleted file mode 100644 index 350dbd1ae..000000000 --- a/.github/codeql/queries/hardwareConcurrency.ql +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @id prebid/hardware-concurrency - * @name Access to navigator.hardwareConcurrency - * @kind problem - * @problem.severity warning - * @description Finds uses of hardwareConcurrency - */ - -import prebid - -from SourceNode nav -where - nav = windowPropertyRead("navigator") -select nav.getAPropertyRead("hardwareConcurrency"), "hardwareConcurrency is an indicator of fingerprinting" diff --git a/.github/codeql/queries/prebid.qll b/.github/codeql/queries/prebid.qll index 02fb5adc9..0bcf68cfb 100644 --- a/.github/codeql/queries/prebid.qll +++ b/.github/codeql/queries/prebid.qll @@ -34,3 +34,8 @@ SourceNode windowPropertyRead(string prop) { result = globalVarRef(prop) or result = anyWindow().getAPropertyRead(prop) } + +SourceNode instantiationOf(string ctr) { + result = windowPropertyRead(ctr).getAnInstantiation() +} + diff --git a/eslint.config.js b/eslint.config.js index 055ee5ec2..baea97164 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -66,6 +66,7 @@ module.exports = [ 'integrationExamples/**/*', // do not lint build-related stuff '*.js', + '*.mjs', 'metadata/**/*', 'customize/**/*', ...jsPattern('plugins'), diff --git a/fingerprintApis.mjs b/fingerprintApis.mjs new file mode 100644 index 000000000..469404292 --- /dev/null +++ b/fingerprintApis.mjs @@ -0,0 +1,189 @@ +import _ from 'lodash'; +const weightsUrl = `https://raw.githubusercontent.com/duckduckgo/tracker-radar/refs/heads/main/build-data/generated/api_fingerprint_weights.json`; +import fs from 'fs/promises'; +import path from 'path'; + +const MIN_WEIGHT = 15; +const QUERY_DIR = path.join(import.meta.dirname, '.github/codeql/queries'); +const QUERY_FILE_PREFIX = 'autogen_'; + +async function fetchWeights() { + const weights = await fetch(weightsUrl).then(res => res.json()); + return Object.fromEntries( + Object.entries(weights).filter(([api, weight]) => weight >= MIN_WEIGHT) + ); +} + +const QUERY_FILE_TPL = _.template(`/** + * @id prebid/<%= id %> + * @name <%= name %> + * @kind problem + * @problem.severity warning + * @description <%= description %> + */ + +// this file is autogenerated, see fingerprintApis.mjs + +<%= query %> +`); + +function message(weight, api) { + return `"${api} is an indicator of fingerprinting, weighed ${weight} in ${weightsUrl}"` +} + +function windowProp(weight, api) { + return [ + `window_${api}`, + QUERY_FILE_TPL({ + id: `window-${api}`.toLowerCase(), + name: `Access to window.${api}`, + description: `Finds uses of window.${api}`, + query: `import prebid +from SourceNode api +where + api = windowPropertyRead("${api}") +select api, ${message(weight, api)}` + }) + ] +} + +function globalProp(prop) { + return function (weight, api) { + return [ + `${prop}_${api}`, + QUERY_FILE_TPL({ + id: `${prop}-${api}`.toLowerCase(), + name: `Access to ${prop}.${api}`, + description: `Finds uses of ${prop}.${api}`, + query: `import prebid +from SourceNode prop, SourceNode api +where + prop = windowPropertyRead("${prop}") and + api = prop.getAPropertyRead("${api}") +select api, ${message(weight, api)}` + }) + ] + } +} + +function globalConstructor(weight, ctr) { + return [ + `${ctr}`, + QUERY_FILE_TPL({ + id: `${ctr}`.toLowerCase(), + name: `Use of ${ctr}`, + description: `Finds uses of ${ctr}`, + query: `import prebid +from SourceNode api +where + api = instantiationOf("${ctr}") +select api, ${message(weight, ctr)}` + }) + ] +} + +function globalConstructorProperty(weight, ctr, api) { + return [ + `${ctr}_${api}`, + QUERY_FILE_TPL({ + id: `${ctr}-${api}`.toLowerCase(), + name: `Access to ${ctr}.${api}`, + description: `Finds uses of ${ctr}.${api}`, + query: `import prebid +from SourceNode inst, SourceNode api +where + inst = instantiationOf("${ctr}") and + api = inst.getAPropertyRead("${api}") +select api, ${message(weight, api)}` + }) + ] +} + +function simplePropertyMatch(weight, target, prop) { + return [ + `${target}_${prop}`, + QUERY_FILE_TPL({ + id: `${target}-${prop}`.toLowerCase(), + name: `Potential access to ${target}.${prop}`, + description: `Finds uses of ${prop}`, + query: `import prebid +from PropRef api +where + api.getPropertyName() = "${prop}" +select api, ${message(weight, prop)}` + }) + ] +} +function glContextMatcher(contextType) { + return function(weight, api) { + return [ + `${contextType}_RenderingContext_${api}`, + QUERY_FILE_TPL({ + id: `${contextType}-${api}`.toLowerCase(), + name: `Access to ${contextType} rendering context ${api}`, + description: `Finds uses of ${contextType} RenderingContext.${api}`, + query: `import prebid +from InvokeNode invocation, SourceNode api +where + invocation.getCalleeName() = "getContext" and + invocation.getArgument(0).mayHaveStringValue("${contextType}") and + api = invocation.getAPropertyRead("${api}") +select api, ${message(weight, api)}` + }) + ] + } +} + +const API_MATCHERS = [ + [/^([^.]+)\.prototype.constructor$/, globalConstructor], + [/^Screen\.prototype\.(.*)$/, globalProp('screen')], + [/^Notification\.([^.]+)$/, globalProp('Notification')], + [/^window\.(.*)$/, windowProp], + [/^Navigator.prototype\.(.*)$/, globalProp('navigator')], + [/^(Date|Gyroscope)\.prototype\.(.*)$/, globalConstructorProperty], + [/^(DeviceMotionEvent)\.prototype\.(.*)$/, simplePropertyMatch], + [/^WebGLRenderingContext\.prototype\.(.*)$/, glContextMatcher('webgl')], + [/^WebGL2RenderingContext\.prototype\.(.*)$/, glContextMatcher('webgl2')], + [/^CanvasRenderingContext2D\.prototype\.(.*)$/, glContextMatcher('2d')], +]; + +async function generateQueries() { + const weights = await fetchWeights(); + const queries = {}; + Object.entries(weights).filter(([identifier, weight]) => { + for (const [matcher, queryGen] of API_MATCHERS) { + const match = matcher.exec(identifier); + if (match) { + const [name, query] = queryGen(weight, ...match.slice(1)); + queries[name] = query; + delete weights[identifier]; + break; + } + } + }) + const unmatched = Object.keys(weights); + if (Object.keys(weights).length > 0) { + console.warn(`The following APIs are weighed more than ${MIN_WEIGHT}, but no query was generated for them:`, JSON.stringify(weights, null, 2)) + } + return queries; +} + +async function clearFiles() { + for (const file of await fs.readdir(QUERY_DIR)) { + if (file.startsWith(QUERY_FILE_PREFIX)) { + await fs.rm(path.join(QUERY_DIR, file)) + } + } +} + +async function generateQueryFiles() { + for (const [name, query] of Object.entries(await generateQueries())) { + await fs.writeFile(path.join(QUERY_DIR, `autogen_${name}.ql`), query); + } +} + +export async function updateQueries() { + await clearFiles(); + await generateQueryFiles(); +} + diff --git a/gulpfile.js b/gulpfile.js index 57c67cccd..dc1cc51f6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -531,10 +531,16 @@ gulp.task('test', gulp.series(clean, lint, 'test-all-features-disabled', 'test-o gulp.task('test-coverage', gulp.series(clean, precompile(), testCoverage)); +gulp.task('update-codeql', function (done) { + import('./fingerprintApis.mjs').then(({updateQueries}) => { + updateQueries().then(() => done(), done); + }) +}) + // npm will by default use .gitignore, so create an .npmignore that is a copy of it except it includes "dist" gulp.task('setup-npmignore', execaTask("sed 's/^\\/\\?dist\\/\\?$//g;w .npmignore' .gitignore", {quiet: true})); gulp.task('build', gulp.series(clean, 'build-bundle-prod', setupDist)); -gulp.task('build-release', gulp.series('build', updateCreativeExample, 'update-browserslist', 'setup-npmignore')); +gulp.task('build-release', gulp.series('update-codeql', 'build', updateCreativeExample, 'update-browserslist', 'setup-npmignore')); gulp.task('build-postbid', gulp.series(escapePostbidConfig, buildPostbid)); gulp.task('serve', gulp.series(clean, lint, precompile(), gulp.parallel('build-bundle-dev-no-precomp', watch, test))); diff --git a/modules/atsAnalyticsAdapter.js b/modules/atsAnalyticsAdapter.js index e09c045e4..389a51fa3 100644 --- a/modules/atsAnalyticsAdapter.js +++ b/modules/atsAnalyticsAdapter.js @@ -340,9 +340,8 @@ atsAnalyticsAdapter.enableAnalytics = function (config) { pid: config.options.pid, bidWonTimeout: config.options.bidWonTimeout }; - const initOptions = config.options; logInfo('ATS Analytics - adapter enabled! '); - atsAnalyticsAdapter.originEnableAnalytics(initOptions); // call the base class function + atsAnalyticsAdapter.originEnableAnalytics(config); }; atsAnalyticsAdapter.callHandler = function (evtype, args) { diff --git a/modules/id5AnalyticsAdapter.js b/modules/id5AnalyticsAdapter.js index b2b2af6f5..f1db78908 100644 --- a/modules/id5AnalyticsAdapter.js +++ b/modules/id5AnalyticsAdapter.js @@ -1,16 +1,14 @@ import buildAdapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import { EVENTS } from '../src/constants.js'; +import {EVENTS} from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; -import { ajax } from '../src/ajax.js'; -import { logInfo, logError } from '../src/utils.js'; +import {ajax} from '../src/ajax.js'; +import {logError, logInfo} from '../src/utils.js'; import * as events from '../src/events.js'; const { AUCTION_END, TCF2_ENFORCEMENT, - BID_WON, - BID_VIEWABLE, - AD_RENDER_FAILED + BID_WON } = EVENTS const GVLID = 131; @@ -21,15 +19,6 @@ const STANDARD_EVENTS_TO_TRACK = [ BID_WON, ]; -// These events cause the buffered events to be sent over -const FLUSH_EVENTS = [ - TCF2_ENFORCEMENT, - AUCTION_END, - BID_WON, - BID_VIEWABLE, - AD_RENDER_FAILED -]; - const CONFIG_URL_PREFIX = 'https://api.id5-sync.com/analytics' const TZ = new Date().getTimezoneOffset(); const PBJS_VERSION = 'v' + '$prebid.version$'; @@ -37,9 +26,6 @@ const ID5_REDACTED = '__ID5_REDACTED__'; const isArray = Array.isArray; const id5Analytics = Object.assign(buildAdapter({analyticsType: 'endpoint'}), { - // Keeps an array of events for each auction - eventBuffer: {}, - eventsToTrack: STANDARD_EVENTS_TO_TRACK, track: (event) => { @@ -50,31 +36,16 @@ const id5Analytics = Object.assign(buildAdapter({analyticsType: 'endpoint'}), { } try { - const auctionId = event.args.auctionId; - _this.eventBuffer[auctionId] = _this.eventBuffer[auctionId] || []; - - // Collect events and send them in a batch when the auction ends - const que = _this.eventBuffer[auctionId]; - que.push(_this.makeEvent(event.eventType, event.args)); - - if (FLUSH_EVENTS.indexOf(event.eventType) >= 0) { - // Auction ended. Send the batch of collected events - _this.sendEvents(que); - - // From now on just send events to server side as they come - que.push = (pushedEvent) => _this.sendEvents([pushedEvent]); - } + _this.sendEvent(_this.makeEvent(event.eventType, event.args)); } catch (error) { logError('id5Analytics: ERROR', error); _this.sendErrorEvent(error); } }, - sendEvents: (eventsToSend) => { - const _this = id5Analytics; + sendEvent: (eventToSend) => { // By giving some content this will be automatically a POST - eventsToSend.forEach((event) => - ajax(_this.options.ingestUrl, null, JSON.stringify(event))); + ajax(id5Analytics.options.ingestUrl, null, JSON.stringify(eventToSend)); }, makeEvent: (event, payload) => { @@ -96,7 +67,7 @@ const id5Analytics = Object.assign(buildAdapter({analyticsType: 'endpoint'}), { sendErrorEvent: (error) => { const _this = id5Analytics; - _this.sendEvents([ + _this.sendEvent([ _this.makeEvent('analyticsError', { message: error.message, stack: error.stack, @@ -141,18 +112,10 @@ const ENABLE_FUNCTION = (config) => { // Init the module only if we got lucky logInfo('id5Analytics: Selected by sampling. Starting up!'); - // Clean start - _this.eventBuffer = {}; - - // Replay all events until now - if (!config.disablePastEventsProcessing) { - events.getEvents().forEach((event) => { - if (event && _this.eventsToTrack.indexOf(event.eventType) >= 0) { - _this.track(event); - } - }); + // allow for replacing cleanup rules - remove existing ones and apply from server + if (configFromServer.replaceCleanupRules) { + cleanupRules = {}; } - // Merge in additional cleanup rules if (configFromServer.additionalCleanupRules) { const newRules = configFromServer.additionalCleanupRules; @@ -165,7 +128,20 @@ const ENABLE_FUNCTION = (config) => { (eventRules.apply in TRANSFORM_FUNCTIONS)) ) { logInfo('id5Analytics: merging additional cleanup rules for event ' + key); - CLEANUP_RULES[key].push(...newRules[key]); + if (!Array.isArray(cleanupRules[key])) { + cleanupRules[key] = newRules[key]; + } else { + cleanupRules[key].push(...newRules[key]); + } + } + }); + } + + // Replay all events until now + if (!config.disablePastEventsProcessing) { + events.getEvents().forEach((event) => { + if (event && _this.eventsToTrack.indexOf(event.eventType) >= 0) { + _this.track(event); } }); } @@ -243,8 +219,8 @@ function deepTransformingClone(obj, transform, currentPath = []) { // In case of array, it represents alternatives which all would match. // Special path part '*' matches any subproperty or array index. // Prefixing a part with "!" makes it negative match (doesn't work with multiple alternatives) -const CLEANUP_RULES = {}; -CLEANUP_RULES[AUCTION_END] = [{ +let cleanupRules = {}; +cleanupRules[AUCTION_END] = [{ match: [['adUnits', 'bidderRequests'], '*', 'bids', '*', ['userId', 'crumbs'], '!id5id'], apply: 'redact' }, { @@ -267,7 +243,7 @@ CLEANUP_RULES[AUCTION_END] = [{ apply: 'redact' }]; -CLEANUP_RULES[BID_WON] = [{ +cleanupRules[BID_WON] = [{ match: [['ad', 'native']], apply: 'erase' }]; @@ -279,7 +255,7 @@ const TRANSFORM_FUNCTIONS = { // Builds a rule function depending on the event type function transformFnFromCleanupRules(eventType) { - const rules = CLEANUP_RULES[eventType] || []; + const rules = cleanupRules[eventType] || []; return (path, obj, key) => { for (let i = 0; i < rules.length; i++) { let match = true; diff --git a/modules/scope3RtdProvider.ts b/modules/scope3RtdProvider.ts index bb942fd0d..620ae3610 100644 --- a/modules/scope3RtdProvider.ts +++ b/modules/scope3RtdProvider.ts @@ -5,13 +5,15 @@ * real-time contextual signals for programmatic advertising optimization. */ +import { auctionManager } from '../src/auctionManager.js'; import { submodule } from '../src/hook.js'; -import { logMessage, logError, logWarn, deepClone, isEmpty, getBidderCodes } from '../src/utils.js'; -import { ajax } from '../src/ajax.js'; +import { logMessage, logError, logWarn, deepClone, isEmpty, getBidderCodes, mergeDeep } from '../src/utils.js'; +import { ajaxBuilder } from '../src/ajax.js'; import { getStorageManager } from '../src/storageManager.js'; import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; import type { RtdProviderSpec } from './rtdModule/spec.ts'; import type { StartAuctionOptions } from '../src/prebid.ts'; +import type { ORTBFragments } from '../src/types/common.d.ts'; declare module './rtdModule/spec' { interface ProviderConfig { @@ -180,7 +182,7 @@ function getCachedData(cacheKey: string): AEESignals | null { const cached = responseCache.get(cacheKey); if (cached) { const now = Date.now(); - if (now - cached.timestamp < (moduleConfig.cacheTtl || DEFAULT_CACHE_TTL)) { + if (now - cached.timestamp < moduleConfig.cacheTtl) { logMessage('Scope3 RTD: Using cached data for key', cacheKey); return cached.data; } else { @@ -205,9 +207,8 @@ function setCachedData(cacheKey: string, data: AEESignals): void { // Clean up old cache entries const now = Date.now(); - const ttl = moduleConfig.cacheTtl || DEFAULT_CACHE_TTL; responseCache.forEach((entry, key) => { - if (now - entry.timestamp > ttl) { + if (now - entry.timestamp > moduleConfig.cacheTtl) { responseCache.delete(key); } }); @@ -391,7 +392,7 @@ export const scope3SubModule: RtdProviderSpec<'scope3'> = { const payload = preparePayload(ortb2Data, reqBidsConfigObj); // Make API request - ajax( + ajaxBuilder(moduleConfig.timeout)( moduleConfig.endpoint!, { success: (response: string) => { @@ -429,7 +430,54 @@ export const scope3SubModule: RtdProviderSpec<'scope3'> = { logError('Scope3 RTD: Error in getBidRequestData', e); callback(); } - } + }, + + getTargetingData(adUnits, config, consent, auction) { + const targetingData = {}; + + const ortb: ORTBFragments = auctionManager.index + .getAuction(auction) + .getFPD().global; + const cacheKey = generateCacheKey(ortb); + const cachedData = getCachedData(cacheKey); + + if (!cachedData) { + return targetingData; + } + + const mappedCachedData = {}; + if (cachedData.include) { + mappedCachedData[moduleConfig.includeKey] = cachedData.include; + } + if (cachedData.exclude) { + mappedCachedData[moduleConfig.excludeKey] = cachedData.exclude; + } + if (cachedData.macro) { + mappedCachedData[moduleConfig.macroKey] = cachedData.macro; + } + + // Merge the targeting data into the ad units + adUnits.forEach((adUnit) => { + targetingData[adUnit] = targetingData[adUnit] || {}; + mergeDeep(targetingData[adUnit], mappedCachedData); + }); + + // If the key contains no data, remove it + Object.keys(targetingData).forEach((adUnit) => { + Object.keys(targetingData[adUnit]).forEach((key) => { + if (!targetingData[adUnit][key] || !targetingData[adUnit][key].length) { + delete targetingData[adUnit][key]; + } + }); + + // If the ad unit contains no data, remove it + if (!Object.keys(targetingData[adUnit]).length) { + delete targetingData[adUnit]; + } + }); + + return targetingData; + }, }; // Register the submodule diff --git a/modules/semantiqRtdProvider.js b/modules/semantiqRtdProvider.js index 5a46b019c..3ee6d986c 100644 --- a/modules/semantiqRtdProvider.js +++ b/modules/semantiqRtdProvider.js @@ -25,13 +25,13 @@ export const storage = getStorageManager({ }); /** - * Gets SemantIQ keywords from local storage. + * Gets SemantIQ keywords from session storage. * @param {string} pageUrl * @returns {Object.} */ const getStorageKeywords = (pageUrl) => { try { - const storageValue = JSON.parse(storage.getDataFromLocalStorage(STORAGE_KEY)); + const storageValue = JSON.parse(storage.getDataFromSessionStorage(STORAGE_KEY)); if (storageValue?.url === pageUrl) { return storageValue.keywords; @@ -39,7 +39,7 @@ const getStorageKeywords = (pageUrl) => { return null; } catch (error) { - logError('Unable to get SemantiQ keywords from local storage', error); + logError('Unable to get SemantiQ keywords from session storage', error); return null; } @@ -97,7 +97,7 @@ const getKeywords = (params) => new Promise((resolve, reject) => { throw new Error('Failed to parse the response'); } - storage.setDataInLocalStorage(STORAGE_KEY, JSON.stringify({ url: pageUrl, keywords: data })); + storage.setDataInSessionStorage(STORAGE_KEY, JSON.stringify({ url: pageUrl, keywords: data })); resolve(data); } catch (error) { reject(error); diff --git a/modules/utiqIdSystem.js b/modules/utiqIdSystem.js index f9790713f..897791890 100644 --- a/modules/utiqIdSystem.js +++ b/modules/utiqIdSystem.js @@ -9,6 +9,7 @@ import { submodule } from '../src/hook.js'; import { getStorageManager } from '../src/storageManager.js'; import { MODULE_TYPE_UID } from '../src/activities/modules.js'; import { findUtiqService } from "../libraries/utiqUtils/utiqUtils.ts"; +import { getGlobal } from '../src/prebidGlobal.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -153,5 +154,9 @@ export const utiqIdSubmodule = { } }; -findUtiqService(storage, window.pbjs.refreshUserIds, LOG_PREFIX, MODULE_NAME); +const pbjsGlobal = getGlobal(); +const refreshUserIds = pbjsGlobal && typeof pbjsGlobal.refreshUserIds === 'function' + ? pbjsGlobal.refreshUserIds.bind(pbjsGlobal) + : () => {}; +findUtiqService(storage, refreshUserIds, LOG_PREFIX, MODULE_NAME); submodule('userId', utiqIdSubmodule); diff --git a/modules/utiqMtpIdSystem.js b/modules/utiqMtpIdSystem.js index 03f06f449..865d68e40 100644 --- a/modules/utiqMtpIdSystem.js +++ b/modules/utiqMtpIdSystem.js @@ -9,6 +9,7 @@ import { submodule } from '../src/hook.js'; import { getStorageManager } from '../src/storageManager.js'; import { MODULE_TYPE_UID } from '../src/activities/modules.js'; import { findUtiqService } from "../libraries/utiqUtils/utiqUtils.ts"; +import { getGlobal } from '../src/prebidGlobal.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -140,5 +141,9 @@ export const utiqMtpIdSubmodule = { } }; -findUtiqService(storage, window.pbjs.refreshUserIds, LOG_PREFIX, MODULE_NAME); +const pbjsGlobal = getGlobal(); +const refreshUserIds = pbjsGlobal && typeof pbjsGlobal.refreshUserIds === 'function' + ? pbjsGlobal.refreshUserIds.bind(pbjsGlobal) + : () => {}; +findUtiqService(storage, refreshUserIds, LOG_PREFIX, MODULE_NAME); submodule('userId', utiqMtpIdSubmodule); diff --git a/package-lock.json b/package-lock.json index b051f1489..6cd23d0a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { - "name": "prebid.js", - "version": "10.11.0", + "name": "openads.js", + "version": "10.12.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "prebid.js", - "version": "10.11.0", + "name": "openads.js", + "version": "10.12.0", "license": "Apache-2.0", "dependencies": { "@babel/core": "^7.28.3", "@babel/plugin-transform-runtime": "^7.18.9", - "@babel/preset-env": "^7.27.2", + "@babel/preset-env": "^7.28.3", "@babel/preset-typescript": "^7.26.0", "@babel/runtime": "^7.28.3", "core-js": "^3.45.1", @@ -33,7 +33,7 @@ "@babel/plugin-transform-runtime": "^7.27.4", "@babel/register": "^7.28.3", "@eslint/compat": "^1.3.2", - "@types/google-publisher-tag": "^1.20250811.0", + "@types/google-publisher-tag": "^1.20250811.1", "@wdio/browserstack-service": "^9.19.1", "@wdio/cli": "^9.19.1", "@wdio/concise-reporter": "^8.29.0", @@ -101,14 +101,14 @@ "through2": "^4.0.2", "typescript": "^5.8.2", "typescript-eslint": "^8.26.1", - "url": "^0.11.0", + "url": "^0.11.4", "url-parse": "^1.0.5", "video.js": "^7.21.7", "videojs-contrib-ads": "^6.9.0", "videojs-ima": "^2.4.0", "videojs-playlist": "^5.2.0", "webdriver": "^9.19.2", - "webdriverio": "^9.18.4", + "webdriverio": "^9.20.0", "webpack": "^5.101.3", "webpack-bundle-analyzer": "^4.5.0", "webpack-manifest-plugin": "^5.0.1", @@ -149,7 +149,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.27.5", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -245,15 +247,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.27.1", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", + "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.27.1", + "@babel/traverse": "^7.28.3", "semver": "^6.3.1" }, "engines": { @@ -279,19 +283,44 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.4", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" + "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/@babel/helper-globals": { "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", @@ -445,12 +474,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz", - "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.2" + "@babel/types": "^7.28.4" }, "bin": { "parser": "bin/babel-parser.js" @@ -515,11 +544,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.27.1", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", + "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/traverse": "^7.28.3" }, "engines": { "node": ">=6.9.0" @@ -620,12 +651,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.27.1", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", + "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/traverse": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -663,7 +696,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.27.5", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.4.tgz", + "integrity": "sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -690,10 +725,12 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.27.1", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", + "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { @@ -704,15 +741,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.27.1", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", + "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.27.1", - "globals": "^11.1.0" + "@babel/traverse": "^7.28.4" }, "engines": { "node": ">=6.9.0" @@ -721,13 +760,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-classes/node_modules/globals": { - "version": "11.12.0", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.27.1", "license": "MIT", @@ -743,10 +775,13 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.27.3", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz", + "integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -809,6 +844,22 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", + "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.27.1", "license": "MIT", @@ -1028,13 +1079,16 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.27.3", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", + "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.27.3", - "@babel/plugin-transform-parameters": "^7.27.1" + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.4" }, "engines": { "node": ">=6.9.0" @@ -1085,7 +1139,9 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.27.1", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1140,7 +1196,9 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.27.5", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", + "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1338,10 +1396,12 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.27.2", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.3.tgz", + "integrity": "sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", + "@babel/compat-data": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", @@ -1349,25 +1409,26 @@ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", - "@babel/plugin-transform-async-generator-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", - "@babel/plugin-transform-block-scoping": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.0", "@babel/plugin-transform-class-properties": "^7.27.1", - "@babel/plugin-transform-class-static-block": "^7.27.1", - "@babel/plugin-transform-classes": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.28.3", + "@babel/plugin-transform-classes": "^7.28.3", "@babel/plugin-transform-computed-properties": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.0", "@babel/plugin-transform-exponentiation-operator": "^7.27.1", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", @@ -1384,15 +1445,15 @@ "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", - "@babel/plugin-transform-object-rest-spread": "^7.27.2", + "@babel/plugin-transform-object-rest-spread": "^7.28.0", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1", - "@babel/plugin-transform-parameters": "^7.27.1", + "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.28.3", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", @@ -1405,10 +1466,10 @@ "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.11.0", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.40.0", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "engines": { @@ -1418,6 +1479,19 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/@babel/preset-modules": { "version": "0.1.6-no-external-plugins", "license": "MIT", @@ -1584,17 +1658,17 @@ } }, "node_modules/@babel/traverse": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.3.tgz", - "integrity": "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.3", + "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", - "@babel/types": "^7.28.2", + "@babel/types": "^7.28.4", "debug": "^4.3.1" }, "engines": { @@ -1602,9 +1676,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -3111,9 +3185,9 @@ "license": "MIT" }, "node_modules/@types/google-publisher-tag": { - "version": "1.20250811.0", - "resolved": "https://registry.npmjs.org/@types/google-publisher-tag/-/google-publisher-tag-1.20250811.0.tgz", - "integrity": "sha512-miINDr/2XSYJzaSs7qK+7Utz4TC6SMwUIN/1oCSzweYbWNq/LOeFxkRZRHvn6XP/xaQ4GzXkESMnEYuvsCvQLg==", + "version": "1.20250811.1", + "resolved": "https://registry.npmjs.org/@types/google-publisher-tag/-/google-publisher-tag-1.20250811.1.tgz", + "integrity": "sha512-35rEuUfoCENB5aCt2mQIfLomoSfGtp/DwcAZMQ1dSFyEceXEsz7TmPuRGz4lwoZiSq991ZaDz49MNawtPy5XPw==", "dev": true, "license": "MIT" }, @@ -3880,6 +3954,24 @@ "@wdio/cli": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, + "node_modules/@wdio/browserstack-service/node_modules/@wdio/config": { + "version": "9.19.1", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.19.1.tgz", + "integrity": "sha512-BeTB2paSjaij3cf1NXQzX9CZmdj5jz2/xdUhkJlCeGmGn1KjWu5BjMO+exuiy+zln7dOJjev8f0jlg8e8f1EbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/logger": "9.18.0", + "@wdio/types": "9.19.1", + "@wdio/utils": "9.19.1", + "deepmerge-ts": "^7.0.3", + "glob": "^10.2.2", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, "node_modules/@wdio/browserstack-service/node_modules/@wdio/logger": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-9.18.0.tgz", @@ -3897,6 +3989,26 @@ "node": ">=18.20.0" } }, + "node_modules/@wdio/browserstack-service/node_modules/@wdio/protocols": { + "version": "9.16.2", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-9.16.2.tgz", + "integrity": "sha512-h3k97/lzmyw5MowqceAuY3HX/wGJojXHkiPXA3WlhGPCaa2h4+GovV2nJtRvknCKsE7UHA1xB5SWeI8MzloBew==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wdio/browserstack-service/node_modules/@wdio/repl": { + "version": "9.16.2", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-9.16.2.tgz", + "integrity": "sha512-FLTF0VL6+o5BSTCO7yLSXocm3kUnu31zYwzdsz4n9s5YWt83sCtzGZlZpt7TaTzb3jVUfxuHNQDTb8UMkCu0lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, "node_modules/@wdio/browserstack-service/node_modules/@wdio/reporter": { "version": "9.19.1", "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-9.19.1.tgz", @@ -3927,6 +4039,42 @@ "node": ">=18.20.0" } }, + "node_modules/@wdio/browserstack-service/node_modules/@wdio/utils": { + "version": "9.19.1", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.19.1.tgz", + "integrity": "sha512-wWx5uPCgdZQxFIemAFVk/aa3JLwqrTsvEJsPlV3lCRpLeQ67V8aUPvvNAzE+RhX67qvelwwsvX8RrPdLDfnnYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@puppeteer/browsers": "^2.2.0", + "@wdio/logger": "9.18.0", + "@wdio/types": "9.19.1", + "decamelize": "^6.0.0", + "deepmerge-ts": "^7.0.3", + "edgedriver": "^6.1.2", + "geckodriver": "^5.0.0", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.2.24", + "mitt": "^3.0.1", + "safaridriver": "^1.0.0", + "split2": "^4.2.0", + "wait-port": "^1.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/browserstack-service/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/@wdio/browserstack-service/node_modules/chalk": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz", @@ -3950,6 +4098,20 @@ "node": ">=0.3.1" } }, + "node_modules/@wdio/browserstack-service/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@wdio/browserstack-service/node_modules/uuid": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", @@ -3964,6 +4126,74 @@ "uuid": "dist/esm/bin/uuid" } }, + "node_modules/@wdio/browserstack-service/node_modules/webdriver": { + "version": "9.19.1", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.19.1.tgz", + "integrity": "sha512-cvccIZ3QaUZxxrA81a3rqqgxKt6VzVrZupMc+eX9J40qfGrV3NtdLb/m4AA1PmeTPGN5O3/4KrzDpnVZM4WUnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0", + "@types/ws": "^8.5.3", + "@wdio/config": "9.19.1", + "@wdio/logger": "9.18.0", + "@wdio/protocols": "9.16.2", + "@wdio/types": "9.19.1", + "@wdio/utils": "9.19.1", + "deepmerge-ts": "^7.0.3", + "https-proxy-agent": "^7.0.6", + "undici": "^6.21.3", + "ws": "^8.8.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/browserstack-service/node_modules/webdriverio": { + "version": "9.19.1", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.19.1.tgz", + "integrity": "sha512-hpGgK6d9QNi3AaLFWIPQaEMqJhXF048XAIsV5i5mkL0kjghV1opcuhKgbbG+7pcn8JSpiq6mh7o3MDYtapw90w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.11.30", + "@types/sinonjs__fake-timers": "^8.1.5", + "@wdio/config": "9.19.1", + "@wdio/logger": "9.18.0", + "@wdio/protocols": "9.16.2", + "@wdio/repl": "9.16.2", + "@wdio/types": "9.19.1", + "@wdio/utils": "9.19.1", + "archiver": "^7.0.1", + "aria-query": "^5.3.0", + "cheerio": "^1.0.0-rc.12", + "css-shorthand-properties": "^1.1.1", + "css-value": "^0.0.1", + "grapheme-splitter": "^1.0.4", + "htmlfy": "^0.8.1", + "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", + "lodash.clonedeep": "^4.5.0", + "lodash.zip": "^4.2.0", + "query-selector-shadow-dom": "^1.0.1", + "resq": "^1.11.0", + "rgb2hex": "0.2.5", + "serialize-error": "^12.0.0", + "urlpattern-polyfill": "^10.0.0", + "webdriver": "9.19.1" + }, + "engines": { + "node": ">=18.20.0" + }, + "peerDependencies": { + "puppeteer-core": ">=22.x || <=24.x" + }, + "peerDependenciesMeta": { + "puppeteer-core": { + "optional": true + } + } + }, "node_modules/@wdio/cli": { "version": "9.19.1", "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-9.19.1.tgz", @@ -4168,6 +4398,19 @@ "dev": true, "license": "MIT" }, + "node_modules/@wdio/cli/node_modules/@wdio/repl": { + "version": "9.16.2", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-9.16.2.tgz", + "integrity": "sha512-FLTF0VL6+o5BSTCO7yLSXocm3kUnu31zYwzdsz4n9s5YWt83sCtzGZlZpt7TaTzb3jVUfxuHNQDTb8UMkCu0lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, "node_modules/@wdio/cli/node_modules/@wdio/types": { "version": "9.19.1", "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.19.1.tgz", @@ -4207,6 +4450,16 @@ "node": ">=18.20.0" } }, + "node_modules/@wdio/cli/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/@wdio/cli/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -4366,6 +4619,20 @@ "node": ">=8" } }, + "node_modules/@wdio/cli/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@wdio/cli/node_modules/jest-diff": { "version": "30.0.5", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.0.5.tgz", @@ -4667,6 +4934,74 @@ "node": ">=14.0.0" } }, + "node_modules/@wdio/cli/node_modules/webdriver": { + "version": "9.19.1", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.19.1.tgz", + "integrity": "sha512-cvccIZ3QaUZxxrA81a3rqqgxKt6VzVrZupMc+eX9J40qfGrV3NtdLb/m4AA1PmeTPGN5O3/4KrzDpnVZM4WUnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0", + "@types/ws": "^8.5.3", + "@wdio/config": "9.19.1", + "@wdio/logger": "9.18.0", + "@wdio/protocols": "9.16.2", + "@wdio/types": "9.19.1", + "@wdio/utils": "9.19.1", + "deepmerge-ts": "^7.0.3", + "https-proxy-agent": "^7.0.6", + "undici": "^6.21.3", + "ws": "^8.8.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/cli/node_modules/webdriverio": { + "version": "9.19.1", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.19.1.tgz", + "integrity": "sha512-hpGgK6d9QNi3AaLFWIPQaEMqJhXF048XAIsV5i5mkL0kjghV1opcuhKgbbG+7pcn8JSpiq6mh7o3MDYtapw90w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.11.30", + "@types/sinonjs__fake-timers": "^8.1.5", + "@wdio/config": "9.19.1", + "@wdio/logger": "9.18.0", + "@wdio/protocols": "9.16.2", + "@wdio/repl": "9.16.2", + "@wdio/types": "9.19.1", + "@wdio/utils": "9.19.1", + "archiver": "^7.0.1", + "aria-query": "^5.3.0", + "cheerio": "^1.0.0-rc.12", + "css-shorthand-properties": "^1.1.1", + "css-value": "^0.0.1", + "grapheme-splitter": "^1.0.4", + "htmlfy": "^0.8.1", + "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", + "lodash.clonedeep": "^4.5.0", + "lodash.zip": "^4.2.0", + "query-selector-shadow-dom": "^1.0.1", + "resq": "^1.11.0", + "rgb2hex": "0.2.5", + "serialize-error": "^12.0.0", + "urlpattern-polyfill": "^10.0.0", + "webdriver": "9.19.1" + }, + "engines": { + "node": ">=18.20.0" + }, + "peerDependencies": { + "puppeteer-core": ">=22.x || <=24.x" + }, + "peerDependenciesMeta": { + "puppeteer-core": { + "optional": true + } + } + }, "node_modules/@wdio/cli/node_modules/yargs": { "version": "17.7.2", "dev": true, @@ -6735,11 +7070,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { @@ -6748,6 +7085,7 @@ }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.11.1", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.3", @@ -6758,10 +7096,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" + "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -6879,6 +7219,15 @@ "node": "^4.5.0 || >= 5.9" } }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.6.tgz", + "integrity": "sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/basic-auth": { "version": "2.0.1", "dev": true, @@ -7085,7 +7434,9 @@ "license": "ISC" }, "node_modules/browserslist": { - "version": "4.25.0", + "version": "4.26.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz", + "integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==", "funding": [ { "type": "opencollective", @@ -7102,9 +7453,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001718", - "electron-to-chromium": "^1.5.160", - "node-releases": "^2.0.19", + "baseline-browser-mapping": "^2.8.3", + "caniuse-lite": "^1.0.30001741", + "electron-to-chromium": "^1.5.218", + "node-releases": "^2.0.21", "update-browserslist-db": "^1.1.3" }, "bin": { @@ -7873,10 +8225,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.42.0", + "version": "3.45.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz", + "integrity": "sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==", "license": "MIT", "dependencies": { - "browserslist": "^4.24.4" + "browserslist": "^4.25.3" }, "funding": { "type": "opencollective", @@ -9045,7 +9399,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.161", + "version": "1.5.222", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.222.tgz", + "integrity": "sha512-gA7psSwSwQRE60CEoLz6JBCQPIxNeuzB2nL8vE03GK/OHxlvykbLyeiumQy1iH5C2f3YbRAZpGCMT12a/9ih9w==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -14454,6 +14810,16 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jiti": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.0.tgz", + "integrity": "sha512-VXe6RjJkBPj0ohtqaO8vSWP3ZhAKo66fKrFNCll4BTcwljPLz03pCbaNKfzGP5MbrCYcbJ7v0nOYYwUzTEIdXQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "license": "MIT" @@ -16364,7 +16730,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.19", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz", + "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==", "license": "MIT" }, "node_modules/node-request-interceptor": { @@ -17859,16 +18227,21 @@ "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.8", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -19421,9 +19794,9 @@ } }, "node_modules/tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dev": true, "license": "MIT", "dependencies": { @@ -20321,12 +20694,17 @@ } }, "node_modules/url": { - "version": "0.11.3", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", + "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", "dev": true, "license": "MIT", "dependencies": { "punycode": "^1.4.1", - "qs": "^6.11.2" + "qs": "^6.12.3" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/url-parse": { @@ -20931,20 +21309,20 @@ } }, "node_modules/webdriverio": { - "version": "9.19.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.19.1.tgz", - "integrity": "sha512-hpGgK6d9QNi3AaLFWIPQaEMqJhXF048XAIsV5i5mkL0kjghV1opcuhKgbbG+7pcn8JSpiq6mh7o3MDYtapw90w==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.20.0.tgz", + "integrity": "sha512-cqaXfahTzCFaQLlk++feZaze6tAsW8OSdaVRgmOGJRII1z2A4uh4YGHtusTpqOiZAST7OBPqycOwfh01G/Ktbg==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "^20.11.30", "@types/sinonjs__fake-timers": "^8.1.5", - "@wdio/config": "9.19.1", + "@wdio/config": "9.20.0", "@wdio/logger": "9.18.0", "@wdio/protocols": "9.16.2", "@wdio/repl": "9.16.2", - "@wdio/types": "9.19.1", - "@wdio/utils": "9.19.1", + "@wdio/types": "9.20.0", + "@wdio/utils": "9.20.0", "archiver": "^7.0.1", "aria-query": "^5.3.0", "cheerio": "^1.0.0-rc.12", @@ -20961,7 +21339,7 @@ "rgb2hex": "0.2.5", "serialize-error": "^12.0.0", "urlpattern-polyfill": "^10.0.0", - "webdriver": "9.19.1" + "webdriver": "9.20.0" }, "engines": { "node": ">=18.20.0" @@ -20976,18 +21354,19 @@ } }, "node_modules/webdriverio/node_modules/@wdio/config": { - "version": "9.19.1", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.19.1.tgz", - "integrity": "sha512-BeTB2paSjaij3cf1NXQzX9CZmdj5jz2/xdUhkJlCeGmGn1KjWu5BjMO+exuiy+zln7dOJjev8f0jlg8e8f1EbQ==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.20.0.tgz", + "integrity": "sha512-ggwd3EMsVj/LTcbYw2h+hma+/7fQ1cTXMuy9B5WTkLjDlOtbLjsqs9QLt4BLIo1cdsxvAw/UVpRVUuYy7rTmtQ==", "dev": true, "license": "MIT", "dependencies": { "@wdio/logger": "9.18.0", - "@wdio/types": "9.19.1", - "@wdio/utils": "9.19.1", + "@wdio/types": "9.20.0", + "@wdio/utils": "9.20.0", "deepmerge-ts": "^7.0.3", "glob": "^10.2.2", - "import-meta-resolve": "^4.0.0" + "import-meta-resolve": "^4.0.0", + "jiti": "^2.5.1" }, "engines": { "node": ">=18.20.0" @@ -21031,9 +21410,9 @@ } }, "node_modules/webdriverio/node_modules/@wdio/types": { - "version": "9.19.1", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.19.1.tgz", - "integrity": "sha512-Q1HVcXiWMHp3ze2NN1BvpsfEh/j6GtAeMHhHW4p2IWUfRZlZqTfiJ+95LmkwXOG2gw9yndT8NkJigAz8v7WVYQ==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.20.0.tgz", + "integrity": "sha512-zMmAtse2UMCSOW76mvK3OejauAdcFGuKopNRH7crI0gwKTZtvV89yXWRziz9cVXpFgfmJCjf9edxKFWdhuF5yw==", "dev": true, "license": "MIT", "dependencies": { @@ -21044,15 +21423,15 @@ } }, "node_modules/webdriverio/node_modules/@wdio/utils": { - "version": "9.19.1", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.19.1.tgz", - "integrity": "sha512-wWx5uPCgdZQxFIemAFVk/aa3JLwqrTsvEJsPlV3lCRpLeQ67V8aUPvvNAzE+RhX67qvelwwsvX8RrPdLDfnnYw==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.20.0.tgz", + "integrity": "sha512-T1ze005kncUTocYImSBQc/FAVcOwP/vOU4MDJFgzz/RTcps600qcKX98sVdWM5/ukXCVkjOufWteDHIbX5/tEA==", "dev": true, "license": "MIT", "dependencies": { "@puppeteer/browsers": "^2.2.0", "@wdio/logger": "9.18.0", - "@wdio/types": "9.19.1", + "@wdio/types": "9.20.0", "decamelize": "^6.0.0", "deepmerge-ts": "^7.0.3", "edgedriver": "^6.1.2", @@ -21080,9 +21459,9 @@ } }, "node_modules/webdriverio/node_modules/chalk": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz", - "integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "license": "MIT", "engines": { @@ -21107,19 +21486,19 @@ } }, "node_modules/webdriverio/node_modules/webdriver": { - "version": "9.19.1", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.19.1.tgz", - "integrity": "sha512-cvccIZ3QaUZxxrA81a3rqqgxKt6VzVrZupMc+eX9J40qfGrV3NtdLb/m4AA1PmeTPGN5O3/4KrzDpnVZM4WUnA==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.20.0.tgz", + "integrity": "sha512-Kk+AGV1xWLNHVpzUynQJDULMzbcO3IjXo3s0BzfC30OpGxhpaNmoazMQodhtv0Lp242Mb1VYXD89dCb4oAHc4w==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "^20.1.0", "@types/ws": "^8.5.3", - "@wdio/config": "9.19.1", + "@wdio/config": "9.20.0", "@wdio/logger": "9.18.0", "@wdio/protocols": "9.16.2", - "@wdio/types": "9.19.1", - "@wdio/utils": "9.19.1", + "@wdio/types": "9.20.0", + "@wdio/utils": "9.20.0", "deepmerge-ts": "^7.0.3", "https-proxy-agent": "^7.0.6", "undici": "^6.21.3", diff --git a/package.json b/package.json index 8997e8453..d02a7fa1c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openads.js", - "version": "10.11.0", + "version": "10.12.0", "oaVersion": "1.0.0", "description": "Header Bidding Management Library", "main": "dist/src/prebid.public.ts", @@ -58,7 +58,7 @@ "@babel/plugin-transform-runtime": "^7.27.4", "@babel/register": "^7.28.3", "@eslint/compat": "^1.3.2", - "@types/google-publisher-tag": "^1.20250811.0", + "@types/google-publisher-tag": "^1.20250811.1", "@wdio/browserstack-service": "^9.19.1", "@wdio/cli": "^9.19.1", "@wdio/concise-reporter": "^8.29.0", @@ -126,14 +126,14 @@ "through2": "^4.0.2", "typescript": "^5.8.2", "typescript-eslint": "^8.26.1", - "url": "^0.11.0", + "url": "^0.11.4", "url-parse": "^1.0.5", "video.js": "^7.21.7", "videojs-contrib-ads": "^6.9.0", "videojs-ima": "^2.4.0", "videojs-playlist": "^5.2.0", "webdriver": "^9.19.2", - "webdriverio": "^9.18.4", + "webdriverio": "^9.20.0", "webpack": "^5.101.3", "webpack-bundle-analyzer": "^4.5.0", "webpack-manifest-plugin": "^5.0.1", @@ -143,7 +143,7 @@ "dependencies": { "@babel/core": "^7.28.3", "@babel/plugin-transform-runtime": "^7.18.9", - "@babel/preset-env": "^7.27.2", + "@babel/preset-env": "^7.28.3", "@babel/preset-typescript": "^7.26.0", "@babel/runtime": "^7.28.3", "core-js": "^3.45.1", diff --git a/test/spec/modules/id5AnalyticsAdapter_spec.js b/test/spec/modules/id5AnalyticsAdapter_spec.js index 17b0ccb93..e213494ce 100644 --- a/test/spec/modules/id5AnalyticsAdapter_spec.js +++ b/test/spec/modules/id5AnalyticsAdapter_spec.js @@ -6,6 +6,7 @@ import { EVENTS } from '../../../src/constants.js'; import { generateUUID } from '../../../src/utils.js'; import {server} from '../../mocks/xhr.js'; import {getGlobal} from '../../../src/prebidGlobal.js'; +import {enrichEidsRule} from "../../../modules/tcfControl.ts"; const CONFIG_URL = 'https://api.id5-sync.com/analytics/12349/pbjs'; const INGEST_URL = 'https://test.me/ingest'; @@ -14,6 +15,8 @@ describe('ID5 analytics adapter', () => { let config; beforeEach(() => { + // to enforce tcfControl initialization when running in single test mode + expect(enrichEidsRule).to.exist config = { options: { partnerId: 12349, @@ -126,6 +129,27 @@ describe('ID5 analytics adapter', () => { expect(body2.payload).to.eql(auction); }); + it('does not repeat already sent events on new events', () => { + id5AnalyticsAdapter.enableAnalytics(config); + server.respond(); + events.emit(EVENTS.AUCTION_END, auction); + server.respond(); + events.emit(EVENTS.BID_WON, auction); + server.respond(); + + // Why 4? 1: config, 2: tcfEnforcement, 3: auctionEnd 4: bidWon + expect(server.requests).to.have.length(4); + + const body1 = JSON.parse(server.requests[1].requestBody); + expect(body1.event).to.equal('tcf2Enforcement'); + + const body2 = JSON.parse(server.requests[2].requestBody); + expect(body2.event).to.equal('auctionEnd'); + + const body3 = JSON.parse(server.requests[3].requestBody); + expect(body3.event).to.equal('bidWon'); + }) + it('filters unwanted IDs from the events it sends', () => { auction.adUnits[0].bids = [{ 'bidder': 'appnexus', @@ -453,5 +477,39 @@ describe('ID5 analytics adapter', () => { expect(body.payload.bidsReceived[0].bidderCode).to.equal('appnexus'); expect(body.payload.bidsReceived[1].bidderCode).to.equal('ix'); }); + + it('can replace cleanup rules from server side', () => { + auction.bidsReceived = [{ + 'meta': { + 'advertiserId': 4388779 + } + }] + auction.adUnits[0].bids = [{ + 'bidder': 'appnexus', + 'userId': { + 'id5id': { + 'uid': 'ID5-ZHMOQ99ulpk687Fd9xVwzxMsYtkQIJnI-qm3iWdtww!ID5*FSycZQy7v7zWXiKbEpPEWoB3_UiWdPGzh554ncYDvOkAAA3rajiR0yNrFAU7oDTu', + 'ext': { 'linkType': 1 } + } + } + }]; + server.respondWith('GET', CONFIG_URL, [200, + { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*' + }, + `{ "sampling": 1, "ingestUrl": "${INGEST_URL}", "replaceCleanupRules":true, "additionalCleanupRules": {"auctionEnd": [{"match":["bidsReceived", "*", "meta"],"apply":"erase"}]} }` + ]); + id5AnalyticsAdapter.enableAnalytics(config); + server.respond(); + events.emit(EVENTS.AUCTION_END, auction); + server.respond(); + + expect(server.requests).to.have.length(3); + const body = JSON.parse(server.requests[2].requestBody); + expect(body.event).to.equal('auctionEnd'); + expect(body.payload.bidsReceived[0].meta).to.equal(undefined); // new rule + expect(body.payload.adUnits[0].bids[0].userId.id5id.uid).to.equal(auction.adUnits[0].bids[0].userId.id5id.uid); // old, overridden rule + }); }); }); diff --git a/test/spec/modules/scope3RtdProvider_spec.js b/test/spec/modules/scope3RtdProvider_spec.js index f53a8205d..367d58238 100644 --- a/test/spec/modules/scope3RtdProvider_spec.js +++ b/test/spec/modules/scope3RtdProvider_spec.js @@ -1,3 +1,4 @@ +import {auctionManager} from 'src/auctionManager.js'; import { scope3SubModule } from 'modules/scope3RtdProvider.js'; import * as utils from 'src/utils.js'; import { server } from 'test/mocks/xhr.js'; @@ -242,10 +243,6 @@ describe('Scope3 RTD Module', function() { scope3SubModule.getBidRequestData(reqBidsConfigObj, callback, filteredConfig); expect(server.requests.length).to.be.at.least(1); - if (server.requests.length === 0) { - // Skip test if no request was made - return; - } const responseData = { aee_signals: { @@ -313,10 +310,6 @@ describe('Scope3 RTD Module', function() { scope3SubModule.getBidRequestData(reqBidsConfigObj, callback, config); expect(server.requests.length).to.be.at.least(1); - if (server.requests.length === 0) { - // Skip test if no request was made - return; - } const responseData = { aee_signals: { @@ -357,10 +350,6 @@ describe('Scope3 RTD Module', function() { scope3SubModule.getBidRequestData(reqBidsConfigObj, callback, cacheConfig); expect(server.requests.length).to.be.at.least(1); - if (server.requests.length === 0) { - // Skip test if no request was made - return; - } const responseData = { aee_signals: { @@ -497,4 +486,115 @@ describe('Scope3 RTD Module', function() { expect(result).to.be.true; }); }); + + describe('getTargetingData', function() { + let config; + let reqBidsConfigObj; + let callback; + + beforeEach(function() { + config = { + params: { + orgId: 'test-org-123', + endpoint: 'https://prebid.scope3.com/prebid', + timeout: 1000, + publisherTargeting: true, + advertiserTargeting: true, + cacheEnabled: true, // Need cache enabled for getTargetingData + includeKey: "axei", + excludeKey: "axex", + macroKey: "axem", + } + }; + + reqBidsConfigObj = { + ortb2Fragments: { + global: { + site: { + page: 'https://example1.com', + domain: 'example1.com', + ext: { + data: {} + } + }, + device: { + ua: 'test-user-agent-1' + } + }, + bidder: {} + }, + adUnits: [{ + code: 'test-ad-unit-nocache', + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bids: [ + { bidder: 'bidderA' }, + { bidder: 'bidderB' } + ], + ortb2Imp: { + ext: {} + } + }] + }; + + callback = sinon.spy(); + + // Initialize the module first + scope3SubModule.init(config); + }); + + afterEach(function() { + // Clean up after each test if needed + }); + + it('should get targeting items back', function() { + scope3SubModule.getBidRequestData(reqBidsConfigObj, callback, config); + + expect(server.requests.length).to.be.at.least(1); + + const responseData = { + aee_signals: { + include: ['x82s'], + exclude: ['c4x9'], + macro: 'ctx9h3v8s5', + bidders: { + 'bidderA': { + segments: ['seg1', 'seg2'], + deals: ['DEAL123'] + }, + 'bidderB': { + segments: ['seg3'], + deals: [] + } + } + } + }; + + server.requests[0].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify(responseData) + ); + + const getAuctionStub = sinon.stub(auctionManager.index, 'getAuction').returns({ + adUnits: reqBidsConfigObj.adUnits, + getFPD: () => { return reqBidsConfigObj.ortb2Fragments } + }); + + const targetingData = scope3SubModule.getTargetingData([ reqBidsConfigObj.adUnits[0].code ], config, {}, { adUnits: reqBidsConfigObj.adUnits }) + expect(targetingData['test-ad-unit-nocache']).to.be.an('object') + expect(targetingData['test-ad-unit-nocache']['axei']).to.be.an('array') + expect(targetingData['test-ad-unit-nocache']['axei'].length).to.equal(1) + expect(targetingData['test-ad-unit-nocache']['axei']).to.contain('x82s') + expect(targetingData['test-ad-unit-nocache']['axex']).to.be.an('array') + expect(targetingData['test-ad-unit-nocache']['axex'].length).to.equal(1) + expect(targetingData['test-ad-unit-nocache']['axex']).to.contain('c4x9') + expect(targetingData['test-ad-unit-nocache']['axem']).to.equal('ctx9h3v8s5') + + getAuctionStub.restore(); + }); + }); }); diff --git a/test/spec/modules/semantiqRtdProvider_spec.js b/test/spec/modules/semantiqRtdProvider_spec.js index 49abc6c23..8eef7a1fc 100644 --- a/test/spec/modules/semantiqRtdProvider_spec.js +++ b/test/spec/modules/semantiqRtdProvider_spec.js @@ -5,18 +5,18 @@ import * as utils from '../../../src/utils.js'; describe('semantiqRtdProvider', () => { let clock; - let getDataFromLocalStorageStub; + let getDataFromSessionStorage; let getWindowLocationStub; beforeEach(() => { clock = sinon.useFakeTimers(); - getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage').returns(null); + getDataFromSessionStorage = sinon.stub(storage, 'getDataFromSessionStorage').returns(null); getWindowLocationStub = sinon.stub(utils, 'getWindowLocation').returns(new URL('https://example.com/article')); }); afterEach(() => { clock.restore(); - getDataFromLocalStorageStub.restore(); + getDataFromSessionStorage.restore(); getWindowLocationStub.restore(); }); @@ -181,7 +181,7 @@ describe('semantiqRtdProvider', () => { }); it('gets keywords from the cache if the data is present in the storage', async () => { - getDataFromLocalStorageStub.returns(JSON.stringify({ url: 'https://example.com/article', keywords: { sentiment: 'negative', ctx_segment: ['C001', 'C002'] } })); + getDataFromSessionStorage.returns(JSON.stringify({ url: 'https://example.com/article', keywords: { sentiment: 'negative', ctx_segment: ['C001', 'C002'] } })); const reqBidsConfigObj = { adUnits: [{ bids: [{ bidder: 'appnexus' }] }], @@ -210,7 +210,7 @@ describe('semantiqRtdProvider', () => { }); it('requests keywords from the server if the URL of the page is different from the cached one', async () => { - getDataFromLocalStorageStub.returns(JSON.stringify({ url: 'https://example.com/article', keywords: { cached: 'true' } })); + getDataFromSessionStorage.returns(JSON.stringify({ url: 'https://example.com/article', keywords: { cached: 'true' } })); getWindowLocationStub.returns(new URL('https://example.com/another-article')); const reqBidsConfigObj = {