tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 14e523cf736d0c165daa2bf4165515f224f99e3d
parent 6686939edd3e8e1e74bc6e89dddf1afe10046970
Author: Marcos Cáceres <caceres_m@apple.com>
Date:   Thu,  4 Dec 2025 07:10:04 +0000

Bug 2003206 [wpt-sync] Sync PR 56350 - Digital Credentials: add `signal` support to config property bag, a=testonly

- Add signal parameter to MakeGetOptionsConfig and MakeCreateOptionsConfig interfaces
- Update CredentialRequestOptions and CredentialCreationOptions to include optional signal
- Modify helper functions to accept and pass through abort signal
- Update test files to use new signal property in config objects
- Enables cleaner abort signal handling: makeGetOptions({protocol: 'x', signal})

wpt-commit: f57eba26d024a27e1dce2e656aad59c9e2b1f54b
wpt-type: dependency

Diffstat:
Mtesting/web-platform/tests/digital-credentials/create.tentative.https.html | 7+++----
Mtesting/web-platform/tests/digital-credentials/dc-types.ts | 10++++++++++
Mtesting/web-platform/tests/digital-credentials/get.tentative.https.html | 7+++----
Mtesting/web-platform/tests/digital-credentials/support/helper.js | 40+++++++++++++++++++++++++++-------------
Mtesting/web-platform/tests/digital-credentials/user-activation.https.html | 3+--
5 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/testing/web-platform/tests/digital-credentials/create.tentative.https.html b/testing/web-platform/tests/digital-credentials/create.tentative.https.html @@ -136,7 +136,7 @@ const abortController = new AbortController(); const { signal } = abortController; abortController.abort(); - for (const options of [{ signal }, { signal, ...makeCreateOptions({protocol: []}) }]) { + for (const options of [{ signal }, makeCreateOptions({protocol: [], signal})]) { await promise_rejects_dom( t, "AbortError", @@ -151,7 +151,7 @@ const abortController = new iframeWindow.AbortController(); const { signal } = abortController; abortController.abort(); - for (const options of [{ signal }, { signal, ...makeCreateOptions({protocol: []}) }]) { + for (const options of [{ signal }, makeCreateOptions({protocol: [], signal})]) { await test_driver.bless("user activation"); await promise_rejects_dom( t, @@ -182,8 +182,7 @@ promise_test(async (t) => { const abortController = new AbortController(); const { signal } = abortController; - const options = makeCreateOptions({protocol: "openid4vci"}); - options.signal = signal; + const options = makeCreateOptions({ protocol: "openid4vci", signal }); await test_driver.bless("user activation"); const promise = promise_rejects_dom( t, diff --git a/testing/web-platform/tests/digital-credentials/dc-types.ts b/testing/web-platform/tests/digital-credentials/dc-types.ts @@ -19,6 +19,10 @@ export interface MakeGetOptionsConfig { * Credential mediation requirement */ mediation?: CredentialMediationRequirement; + /** + * Optional AbortSignal for request cancellation + */ + signal?: AbortSignal; } /** @@ -33,6 +37,10 @@ export interface MakeCreateOptionsConfig { * Credential mediation requirement */ mediation?: CredentialMediationRequirement; + /** + * Optional AbortSignal for request cancellation + */ + signal?: AbortSignal; } /** @@ -59,6 +67,7 @@ export interface DigitalCredentialRequestOptions { export interface CredentialRequestOptions { digital: DigitalCredentialRequestOptions; mediation: CredentialMediationRequirement; + signal?: AbortSignal; } /** @@ -85,6 +94,7 @@ export interface DigitalCredentialCreationOptions { export interface CredentialCreationOptions { digital: DigitalCredentialCreationOptions; mediation: CredentialMediationRequirement; + signal?: AbortSignal; } /** diff --git a/testing/web-platform/tests/digital-credentials/get.tentative.https.html b/testing/web-platform/tests/digital-credentials/get.tentative.https.html @@ -160,7 +160,7 @@ const abortController = new AbortController(); const { signal } = abortController; abortController.abort(); - for (const options of [{ signal }, { signal, ...makeGetOptions({protocol: []}) }]) { + for (const options of [{ signal }, makeGetOptions({protocol: [], signal})]) { await promise_rejects_dom( t, "AbortError", @@ -175,7 +175,7 @@ const abortController = new iframeWindow.AbortController(); const { signal } = abortController; abortController.abort(); - for (const options of [{ signal }, { signal, ...makeGetOptions({protocol: []}) }]) { + for (const options of [{ signal }, makeGetOptions({protocol: [], signal})]) { await test_driver.bless("user activation"); await promise_rejects_dom( t, @@ -206,8 +206,7 @@ promise_test(async (t) => { const abortController = new AbortController(); const { signal } = abortController; - const options = makeGetOptions({protocol: "openid4vp-v1-unsigned"}); - options.signal = signal; + const options = makeGetOptions({protocol: "openid4vp-v1-unsigned", signal}); await test_driver.bless("user activation"); const promise = promise_rejects_dom( t, diff --git a/testing/web-platform/tests/digital-credentials/support/helper.js b/testing/web-platform/tests/digital-credentials/support/helper.js @@ -22,10 +22,11 @@ * @param {string[]} requestsInputArray - An array of request type strings. * @param {CredentialMediationRequirement} mediation - The mediation requirement. * @param {Record<string, () => any>} requestMapping - The specific mapping object for the operation type. - * @returns {{ digital: { requests: any[] }, mediation: CredentialMediationRequirement }} - The final options structure. + * @param {AbortSignal} [signal] - Optional abort signal. + * @returns {{ digital: { requests: any[] }, mediation: CredentialMediationRequirement, signal?: AbortSignal }} - The final options structure. * @throws {Error} If an unknown request type string is encountered within the array. */ -function _makeOptionsInternal(requestsInputArray, mediation, requestMapping) { +function _makeOptionsInternal(requestsInputArray, mediation, requestMapping, signal) { const requests = []; for (const request of requestsInputArray) { const factoryFunction = requestMapping[request]; @@ -36,7 +37,11 @@ function _makeOptionsInternal(requestsInputArray, mediation, requestMapping) { throw new Error(`Unknown request type within array: ${request}`); } } - return { digital: { requests }, mediation }; + const result = { digital: { requests }, mediation }; + if (signal !== undefined) { + result.signal = signal; + } + return result; } const allMappings = { @@ -59,10 +64,11 @@ const allMappings = { * @param {'get' | 'create'} type - The type of operation. * @param {string | string[]} protocol - Protocol(s) to use. * @param {CredentialMediationRequirement} mediation - Mediation requirement. - * @returns {{ digital: { requests: any[] }, mediation: CredentialMediationRequirement }} + * @param {AbortSignal} [signal] - Optional abort signal. + * @returns {{ digital: { requests: any[] }, mediation: CredentialMediationRequirement, signal?: AbortSignal }} * @throws {Error} If type is invalid internally, or input strings are invalid. */ -function _makeOptionsUnified(type, protocol, mediation) { +function _makeOptionsUnified(type, protocol, mediation, signal) { // 1. Get mapping (Type validation primarily happens via caller) const mapping = allMappings[type]; // Added safety check, though public functions should prevent this. @@ -74,7 +80,7 @@ function _makeOptionsUnified(type, protocol, mediation) { if (typeof protocol === 'string') { if (protocol in mapping) { // Valid single string: Pass as array to the core array helper - return _makeOptionsInternal([protocol], mediation, mapping); + return _makeOptionsInternal([protocol], mediation, mapping, signal); } else { // Invalid single string for this type throw new Error(`Unknown request type string '${protocol}' provided for operation type '${type}'`); @@ -85,14 +91,22 @@ function _makeOptionsUnified(type, protocol, mediation) { if (Array.isArray(protocol)) { if (protocol.length === 0) { // Handle empty array explicitly - return { digital: { requests: [] }, mediation }; + const result = { digital: { requests: [] }, mediation }; + if (signal !== undefined) { + result.signal = signal; + } + return result; } // Pass valid non-empty array to the core array helper - return _makeOptionsInternal(protocol, mediation, mapping); + return _makeOptionsInternal(protocol, mediation, mapping, signal); } // 4. Handle invalid input types (neither string nor array) - return { digital: { requests: [] }, mediation }; + const result = { digital: { requests: [] }, mediation }; + if (signal !== undefined) { + result.signal = signal; + } + return result; } /** @@ -102,8 +116,8 @@ function _makeOptionsUnified(type, protocol, mediation) { * @returns {CredentialRequestOptions} */ export function makeGetOptions(config = {}) { - const { protocol = "default", mediation = "required" } = config; - return _makeOptionsUnified('get', protocol, mediation); + const { protocol = "default", mediation = "required", signal } = config; + return _makeOptionsUnified('get', protocol, mediation, signal); } /** @@ -113,8 +127,8 @@ export function makeGetOptions(config = {}) { * @returns {CredentialCreationOptions} */ export function makeCreateOptions(config = {}) { - const { protocol = "default", mediation = "required" } = config; - return _makeOptionsUnified('create', protocol, mediation); + const { protocol = "default", mediation = "required", signal } = config; + return _makeOptionsUnified('create', protocol, mediation, signal); } /** diff --git a/testing/web-platform/tests/digital-credentials/user-activation.https.html b/testing/web-platform/tests/digital-credentials/user-activation.https.html @@ -25,8 +25,7 @@ promise_test(async (t) => { await test_driver.bless(); const abort = new AbortController(); - const options = makeGetOptions({protocol: "openid4vp-v1-unsigned"}); - options.signal = abort.signal; + const options = makeGetOptions({protocol: "openid4vp-v1-unsigned", signal: abort.signal}); assert_true( navigator.userActivation.isActive, "User activation should be active after test_driver.bless()."