Skip to content

Commit 8da9e21

Browse files
Release build 11.29.0 [ci release]
1 parent 87df3ed commit 8da9e21

File tree

12 files changed

+385
-268
lines changed

12 files changed

+385
-268
lines changed

CHANGELOG.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
- Add timeout to enumerateDevices call (#1982)
2+
- build(deps-dev): bump the eslint group across 1 directory with 2 updates (#1980)
3+
- build(deps-dev): bump web-ext from 8.9.0 to 8.10.0 (#1978)
4+
- build(deps): bump esbuild from 0.25.9 to 0.25.10 (#1976)
5+
- build(deps-dev): bump wait-on from 8.0.5 to 9.0.1 (#1975)

build/android/adsjsContentScope.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4662,6 +4662,16 @@
46624662
});
46634663
return deviceInfo;
46644664
}
4665+
/**
4666+
* Helper to wrap a promise with timeout
4667+
* @param {Promise} promise - Promise to wrap
4668+
* @param {number} timeoutMs - Timeout in milliseconds
4669+
* @returns {Promise} Promise that rejects on timeout
4670+
*/
4671+
withTimeout(promise, timeoutMs) {
4672+
const timeout = new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Request timeout")), timeoutMs));
4673+
return Promise.race([promise, timeout]);
4674+
}
46654675
/**
46664676
* Fixes device enumeration to handle permission prompts gracefully
46674677
*/
@@ -4677,8 +4687,12 @@
46774687
* @returns {Promise<MediaDeviceInfo[]>}
46784688
*/
46794689
apply: async (target, thisArg, args) => {
4690+
const settings = this.getFeatureSetting("enumerateDevices") || {};
4691+
const timeoutEnabled = settings.timeoutEnabled !== false;
4692+
const timeoutMs = settings.timeoutMs ?? 2e3;
46804693
try {
4681-
const response = await this.messaging.request(MSG_DEVICE_ENUMERATION, {});
4694+
const messagingPromise = this.messaging.request(MSG_DEVICE_ENUMERATION, {});
4695+
const response = timeoutEnabled ? await this.withTimeout(messagingPromise, timeoutMs) : await messagingPromise;
46824696
if (response.willPrompt) {
46834697
const devices = [];
46844698
if (response.videoInput) {

build/android/contentScope.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7402,6 +7402,16 @@
74027402
});
74037403
return deviceInfo;
74047404
}
7405+
/**
7406+
* Helper to wrap a promise with timeout
7407+
* @param {Promise} promise - Promise to wrap
7408+
* @param {number} timeoutMs - Timeout in milliseconds
7409+
* @returns {Promise} Promise that rejects on timeout
7410+
*/
7411+
withTimeout(promise, timeoutMs) {
7412+
const timeout = new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Request timeout")), timeoutMs));
7413+
return Promise.race([promise, timeout]);
7414+
}
74057415
/**
74067416
* Fixes device enumeration to handle permission prompts gracefully
74077417
*/
@@ -7417,8 +7427,12 @@
74177427
* @returns {Promise<MediaDeviceInfo[]>}
74187428
*/
74197429
apply: async (target, thisArg, args) => {
7430+
const settings = this.getFeatureSetting("enumerateDevices") || {};
7431+
const timeoutEnabled = settings.timeoutEnabled !== false;
7432+
const timeoutMs = settings.timeoutMs ?? 2e3;
74207433
try {
7421-
const response = await this.messaging.request(MSG_DEVICE_ENUMERATION, {});
7434+
const messagingPromise = this.messaging.request(MSG_DEVICE_ENUMERATION, {});
7435+
const response = timeoutEnabled ? await this.withTimeout(messagingPromise, timeoutMs) : await messagingPromise;
74227436
if (response.willPrompt) {
74237437
const devices = [];
74247438
if (response.videoInput) {

build/apple/contentScope.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5418,6 +5418,16 @@
54185418
});
54195419
return deviceInfo;
54205420
}
5421+
/**
5422+
* Helper to wrap a promise with timeout
5423+
* @param {Promise} promise - Promise to wrap
5424+
* @param {number} timeoutMs - Timeout in milliseconds
5425+
* @returns {Promise} Promise that rejects on timeout
5426+
*/
5427+
withTimeout(promise, timeoutMs) {
5428+
const timeout = new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Request timeout")), timeoutMs));
5429+
return Promise.race([promise, timeout]);
5430+
}
54215431
/**
54225432
* Fixes device enumeration to handle permission prompts gracefully
54235433
*/
@@ -5433,8 +5443,12 @@
54335443
* @returns {Promise<MediaDeviceInfo[]>}
54345444
*/
54355445
apply: async (target, thisArg, args) => {
5446+
const settings = this.getFeatureSetting("enumerateDevices") || {};
5447+
const timeoutEnabled = settings.timeoutEnabled !== false;
5448+
const timeoutMs = settings.timeoutMs ?? 2e3;
54365449
try {
5437-
const response = await this.messaging.request(MSG_DEVICE_ENUMERATION, {});
5450+
const messagingPromise = this.messaging.request(MSG_DEVICE_ENUMERATION, {});
5451+
const response = timeoutEnabled ? await this.withTimeout(messagingPromise, timeoutMs) : await messagingPromise;
54385452
if (response.willPrompt) {
54395453
const devices = [];
54405454
if (response.videoInput) {

build/integration/contentScope.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16725,6 +16725,16 @@ ${truncatedWarning}
1672516725
});
1672616726
return deviceInfo;
1672716727
}
16728+
/**
16729+
* Helper to wrap a promise with timeout
16730+
* @param {Promise} promise - Promise to wrap
16731+
* @param {number} timeoutMs - Timeout in milliseconds
16732+
* @returns {Promise} Promise that rejects on timeout
16733+
*/
16734+
withTimeout(promise, timeoutMs) {
16735+
const timeout = new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Request timeout")), timeoutMs));
16736+
return Promise.race([promise, timeout]);
16737+
}
1672816738
/**
1672916739
* Fixes device enumeration to handle permission prompts gracefully
1673016740
*/
@@ -16740,8 +16750,12 @@ ${truncatedWarning}
1674016750
* @returns {Promise<MediaDeviceInfo[]>}
1674116751
*/
1674216752
apply: async (target, thisArg, args) => {
16753+
const settings = this.getFeatureSetting("enumerateDevices") || {};
16754+
const timeoutEnabled = settings.timeoutEnabled !== false;
16755+
const timeoutMs = settings.timeoutMs ?? 2e3;
1674316756
try {
16744-
const response = await this.messaging.request(MSG_DEVICE_ENUMERATION, {});
16757+
const messagingPromise = this.messaging.request(MSG_DEVICE_ENUMERATION, {});
16758+
const response = timeoutEnabled ? await this.withTimeout(messagingPromise, timeoutMs) : await messagingPromise;
1674516759
if (response.willPrompt) {
1674616760
const devices = [];
1674716761
if (response.videoInput) {

build/windows/contentScope.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15495,6 +15495,16 @@
1549515495
});
1549615496
return deviceInfo;
1549715497
}
15498+
/**
15499+
* Helper to wrap a promise with timeout
15500+
* @param {Promise} promise - Promise to wrap
15501+
* @param {number} timeoutMs - Timeout in milliseconds
15502+
* @returns {Promise} Promise that rejects on timeout
15503+
*/
15504+
withTimeout(promise, timeoutMs) {
15505+
const timeout = new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Request timeout")), timeoutMs));
15506+
return Promise.race([promise, timeout]);
15507+
}
1549815508
/**
1549915509
* Fixes device enumeration to handle permission prompts gracefully
1550015510
*/
@@ -15510,8 +15520,12 @@
1551015520
* @returns {Promise<MediaDeviceInfo[]>}
1551115521
*/
1551215522
apply: async (target, thisArg, args) => {
15523+
const settings = this.getFeatureSetting("enumerateDevices") || {};
15524+
const timeoutEnabled = settings.timeoutEnabled !== false;
15525+
const timeoutMs = settings.timeoutMs ?? 2e3;
1551315526
try {
15514-
const response = await this.messaging.request(MSG_DEVICE_ENUMERATION, {});
15527+
const messagingPromise = this.messaging.request(MSG_DEVICE_ENUMERATION, {});
15528+
const response = timeoutEnabled ? await this.withTimeout(messagingPromise, timeoutMs) : await messagingPromise;
1551515529
if (response.willPrompt) {
1551615530
const devices = [];
1551715531
if (response.videoInput) {

injected/integration-test/extension/contentScope.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16725,6 +16725,16 @@ ${truncatedWarning}
1672516725
});
1672616726
return deviceInfo;
1672716727
}
16728+
/**
16729+
* Helper to wrap a promise with timeout
16730+
* @param {Promise} promise - Promise to wrap
16731+
* @param {number} timeoutMs - Timeout in milliseconds
16732+
* @returns {Promise} Promise that rejects on timeout
16733+
*/
16734+
withTimeout(promise, timeoutMs) {
16735+
const timeout = new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Request timeout")), timeoutMs));
16736+
return Promise.race([promise, timeout]);
16737+
}
1672816738
/**
1672916739
* Fixes device enumeration to handle permission prompts gracefully
1673016740
*/
@@ -16740,8 +16750,12 @@ ${truncatedWarning}
1674016750
* @returns {Promise<MediaDeviceInfo[]>}
1674116751
*/
1674216752
apply: async (target, thisArg, args) => {
16753+
const settings = this.getFeatureSetting("enumerateDevices") || {};
16754+
const timeoutEnabled = settings.timeoutEnabled !== false;
16755+
const timeoutMs = settings.timeoutMs ?? 2e3;
1674316756
try {
16744-
const response = await this.messaging.request(MSG_DEVICE_ENUMERATION, {});
16757+
const messagingPromise = this.messaging.request(MSG_DEVICE_ENUMERATION, {});
16758+
const response = timeoutEnabled ? await this.withTimeout(messagingPromise, timeoutMs) : await messagingPromise;
1674516759
if (response.willPrompt) {
1674616760
const devices = [];
1674716761
if (response.videoInput) {

injected/integration-test/test-pages/build/contentScope.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16725,6 +16725,16 @@ ${truncatedWarning}
1672516725
});
1672616726
return deviceInfo;
1672716727
}
16728+
/**
16729+
* Helper to wrap a promise with timeout
16730+
* @param {Promise} promise - Promise to wrap
16731+
* @param {number} timeoutMs - Timeout in milliseconds
16732+
* @returns {Promise} Promise that rejects on timeout
16733+
*/
16734+
withTimeout(promise, timeoutMs) {
16735+
const timeout = new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Request timeout")), timeoutMs));
16736+
return Promise.race([promise, timeout]);
16737+
}
1672816738
/**
1672916739
* Fixes device enumeration to handle permission prompts gracefully
1673016740
*/
@@ -16740,8 +16750,12 @@ ${truncatedWarning}
1674016750
* @returns {Promise<MediaDeviceInfo[]>}
1674116751
*/
1674216752
apply: async (target, thisArg, args) => {
16753+
const settings = this.getFeatureSetting("enumerateDevices") || {};
16754+
const timeoutEnabled = settings.timeoutEnabled !== false;
16755+
const timeoutMs = settings.timeoutMs ?? 2e3;
1674316756
try {
16744-
const response = await this.messaging.request(MSG_DEVICE_ENUMERATION, {});
16757+
const messagingPromise = this.messaging.request(MSG_DEVICE_ENUMERATION, {});
16758+
const response = timeoutEnabled ? await this.withTimeout(messagingPromise, timeoutMs) : await messagingPromise;
1674516759
if (response.willPrompt) {
1674616760
const devices = [];
1674716761
if (response.videoInput) {

injected/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"seedrandom": "^3.0.5",
3232
"sjcl": "^1.0.8",
3333
"@duckduckgo/privacy-configuration": "github:duckduckgo/privacy-configuration#1752154773643",
34-
"esbuild": "^0.25.9",
34+
"esbuild": "^0.25.10",
3535
"urlpattern-polyfill": "^10.1.0"
3636
},
3737
"devDependencies": {
@@ -40,9 +40,9 @@
4040
"@types/chrome": "^0.1.1",
4141
"@types/jasmine": "^5.1.9",
4242
"@types/node": "^24.1.0",
43-
"@typescript-eslint/eslint-plugin": "^8.42.0",
43+
"@typescript-eslint/eslint-plugin": "^8.44.1",
4444
"fast-check": "^4.2.0",
4545
"jasmine": "^5.10.0",
46-
"web-ext": "^8.9.0"
46+
"web-ext": "^8.10.0"
4747
}
4848
}

injected/src/features/web-compat.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,17 @@ export class WebCompat extends ContentFeature {
867867
return deviceInfo;
868868
}
869869

870+
/**
871+
* Helper to wrap a promise with timeout
872+
* @param {Promise} promise - Promise to wrap
873+
* @param {number} timeoutMs - Timeout in milliseconds
874+
* @returns {Promise} Promise that rejects on timeout
875+
*/
876+
withTimeout(promise, timeoutMs) {
877+
const timeout = new Promise((_resolve, reject) => setTimeout(() => reject(new Error('Request timeout')), timeoutMs));
878+
return Promise.race([promise, timeout]);
879+
}
880+
870881
/**
871882
* Fixes device enumeration to handle permission prompts gracefully
872883
*/
@@ -883,10 +894,13 @@ export class WebCompat extends ContentFeature {
883894
* @returns {Promise<MediaDeviceInfo[]>}
884895
*/
885896
apply: async (target, thisArg, args) => {
897+
const settings = this.getFeatureSetting('enumerateDevices') || {};
898+
const timeoutEnabled = settings.timeoutEnabled !== false;
899+
const timeoutMs = settings.timeoutMs ?? 2000;
900+
886901
try {
887-
// Request device enumeration information from native
888-
/** @type {{willPrompt: boolean, videoInput: boolean, audioInput: boolean, audioOutput: boolean}} */
889-
const response = await this.messaging.request(MSG_DEVICE_ENUMERATION, {});
902+
const messagingPromise = this.messaging.request(MSG_DEVICE_ENUMERATION, {});
903+
const response = timeoutEnabled ? await this.withTimeout(messagingPromise, timeoutMs) : await messagingPromise;
890904

891905
// Check if native indicates that prompts would be required
892906
if (response.willPrompt) {
@@ -913,7 +927,7 @@ export class WebCompat extends ContentFeature {
913927
return DDGReflect.apply(target, thisArg, args);
914928
}
915929
} catch (err) {
916-
// If the native request fails, fall back to the original implementation
930+
// If the native request fails or times out, fall back to the original implementation
917931
return DDGReflect.apply(target, thisArg, args);
918932
}
919933
},

0 commit comments

Comments
 (0)