tor-browser

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

commit 79716282846e7660c6df31d363c63a8834e34db8
parent 0dc5cac8584c2b5648d0e57b1876eeffe8257f39
Author: Marcos Cáceres <caceres_m@apple.com>
Date:   Thu,  4 Dec 2025 16:55:00 +0000

Bug 2003205 [wpt PR 56349] - Digital Credentials: Refactor makeGetOptions/makeCreateOptions to use property bag, a=testonly

Automatic update from web-platform-tests
Refactor makeGetOptions/makeCreateOptions to use property bag (#56349)

- Convert function signatures from positional parameters to property bag objects
- Add MakeGetOptionsConfig and MakeCreateOptionsConfig interfaces
- Update all test files to use new {protocol: ...} syntax
- Maintain backward compatibility: makeGetOptions() still defaults to 'default' protocol
--

wpt-commits: e57f6118fbcc894871f8a1bacb429bf09eb24e44
wpt-pr: 56349

Diffstat:
Mtesting/web-platform/tests/digital-credentials/create.disabled-by-permissions-policy.https.sub.html | 2+-
Mtesting/web-platform/tests/digital-credentials/create.tentative.https.html | 12++++++------
Mtesting/web-platform/tests/digital-credentials/dc-types.ts | 28++++++++++++++++++++++++++++
Mtesting/web-platform/tests/digital-credentials/default-permissions-policy.https.sub.html | 4++--
Mtesting/web-platform/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html | 4++--
Mtesting/web-platform/tests/digital-credentials/get.disabled-by-permissions-policy.https.sub.html | 2+-
Mtesting/web-platform/tests/digital-credentials/get.tentative.https.html | 12++++++------
Mtesting/web-platform/tests/digital-credentials/non-fully-active.https.html | 2+-
Mtesting/web-platform/tests/digital-credentials/support/helper.js | 62++++++++++++++++++++++++++++++--------------------------------
Mtesting/web-platform/tests/digital-credentials/user-activation.https.html | 8++++----
10 files changed, 81 insertions(+), 55 deletions(-)

diff --git a/testing/web-platform/tests/digital-credentials/create.disabled-by-permissions-policy.https.sub.html b/testing/web-platform/tests/digital-credentials/create.disabled-by-permissions-policy.https.sub.html @@ -19,7 +19,7 @@ await promise_rejects_dom( test, "NotAllowedError", - navigator.credentials.create(makeCreateOptions([])) + navigator.credentials.create(makeCreateOptions({protocol: []})) ); }, "Permissions-Policy header digital-credentials-create=() disallows the top-level document."); 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([]) }]) { + for (const options of [{ signal }, { signal, ...makeCreateOptions({protocol: []}) }]) { 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([]) }]) { + for (const options of [{ signal }, { signal, ...makeCreateOptions({protocol: []}) }]) { await test_driver.bless("user activation"); await promise_rejects_dom( t, @@ -168,7 +168,7 @@ promise_test(async (t) => { iframeCrossOrigin.focus(); - for (const options of [undefined, {}, makeCreateOptions([])]) { + for (const options of [undefined, {}, makeCreateOptions({protocol: []})]) { const result = await sendMessage(iframeCrossOrigin, { abort: "before", action: "create", @@ -182,7 +182,7 @@ promise_test(async (t) => { const abortController = new AbortController(); const { signal } = abortController; - const options = makeCreateOptions("openid4vci"); + const options = makeCreateOptions({protocol: "openid4vci"}); options.signal = signal; await test_driver.bless("user activation"); const promise = promise_rejects_dom( @@ -201,7 +201,7 @@ abort: "after", action: "create", needsActivation: true, - options: makeCreateOptions("openid4vci"), + options: makeCreateOptions({protocol: "openid4vci"}), }); assert_equals(result.constructor, "DOMException"); assert_equals(result.name, "AbortError"); @@ -237,7 +237,7 @@ ]; for (const badValue of throwingValues) { - const options = makeCreateOptions("openid4vci"); + const options = makeCreateOptions({protocol: "openid4vci"}); options.digital.requests[0].data = badValue; await promise_rejects_js( diff --git a/testing/web-platform/tests/digital-credentials/dc-types.ts b/testing/web-platform/tests/digital-credentials/dc-types.ts @@ -8,6 +8,34 @@ export type CredentialMediationRequirement = | "silent"; /** + * Configuration for makeGetOptions function + */ +export interface MakeGetOptionsConfig { + /** + * Protocol(s) to use for the request + */ + protocol?: GetProtocol | GetProtocol[]; + /** + * Credential mediation requirement + */ + mediation?: CredentialMediationRequirement; +} + +/** + * Configuration for makeCreateOptions function + */ +export interface MakeCreateOptionsConfig { + /** + * Protocol(s) to use for the request + */ + protocol?: CreateProtocol | CreateProtocol[]; + /** + * Credential mediation requirement + */ + mediation?: CredentialMediationRequirement; +} + +/** * @see https://w3c-fedid.github.io/digital-credentials/#the-digitalcredentialgetrequest-dictionary */ export interface DigitalCredentialGetRequest { diff --git a/testing/web-platform/tests/digital-credentials/default-permissions-policy.https.sub.html b/testing/web-platform/tests/digital-credentials/default-permissions-policy.https.sub.html @@ -23,7 +23,7 @@ await promise_rejects_js( test, TypeError, - navigator.credentials.get(makeGetOptions([])) + navigator.credentials.get(makeGetOptions({protocol: []})) ); await test_feature_availability({ @@ -49,7 +49,7 @@ await promise_rejects_js( test, TypeError, - navigator.credentials.create(makeCreateOptions([])) + navigator.credentials.create(makeCreateOptions({protocol: []})) ); await test_feature_availability({ diff --git a/testing/web-platform/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html b/testing/web-platform/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html @@ -24,7 +24,7 @@ await promise_rejects_js( test, TypeError, - navigator.credentials.get(makeGetOptions([])) + navigator.credentials.get(makeGetOptions({protocol: []})) ); }, "Permissions-Policy header digital-credentials-get=(self) allows the top-level document."); @@ -67,7 +67,7 @@ await promise_rejects_js( test, TypeError, - navigator.credentials.create(makeCreateOptions([])) + navigator.credentials.create(makeCreateOptions({protocol: []})) ); }, "Permissions-Policy header digital-credentials-create=(self) allows the top-level document."); diff --git a/testing/web-platform/tests/digital-credentials/get.disabled-by-permissions-policy.https.sub.html b/testing/web-platform/tests/digital-credentials/get.disabled-by-permissions-policy.https.sub.html @@ -19,7 +19,7 @@ await promise_rejects_dom( test, "NotAllowedError", - navigator.credentials.get(makeGetOptions([])) + navigator.credentials.get(makeGetOptions({protocol: []})) ); }, "Permissions-Policy header digital-credentials-get=() disallows the top-level document."); 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([]) }]) { + for (const options of [{ signal }, { signal, ...makeGetOptions({protocol: []}) }]) { 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([]) }]) { + for (const options of [{ signal }, { signal, ...makeGetOptions({protocol: []}) }]) { await test_driver.bless("user activation"); await promise_rejects_dom( t, @@ -192,7 +192,7 @@ promise_test(async (t) => { iframeCrossOrigin.focus(); - for (const options of [undefined, {}, makeGetOptions([])]) { + for (const options of [undefined, {}, makeGetOptions({protocol: []})]) { const result = await sendMessage(iframeCrossOrigin, { abort: "before", action: "get", @@ -206,7 +206,7 @@ promise_test(async (t) => { const abortController = new AbortController(); const { signal } = abortController; - const options = makeGetOptions("openid4vp-v1-unsigned"); + const options = makeGetOptions({protocol: "openid4vp-v1-unsigned"}); options.signal = signal; await test_driver.bless("user activation"); const promise = promise_rejects_dom( @@ -225,7 +225,7 @@ abort: "after", action: "get", needsActivation: true, - options: makeGetOptions("openid4vp-v1-signed"), + options: makeGetOptions({protocol: "openid4vp-v1-signed"}), }); assert_equals(result.constructor, "DOMException"); assert_equals(result.name, "AbortError"); @@ -254,7 +254,7 @@ promise_test(async t => { ]; for (const badValue of throwingValues) { - const options = makeGetOptions("openid4vp-v1-multisigned"); + const options = makeGetOptions({protocol: "openid4vp-v1-multisigned"}); options.digital.requests[0].data = badValue; await promise_rejects_js( diff --git a/testing/web-platform/tests/digital-credentials/non-fully-active.https.html b/testing/web-platform/tests/digital-credentials/non-fully-active.https.html @@ -71,7 +71,7 @@ let iframe = await createIframe(); const DOMExceptionCtor = iframe.contentWindow.DOMException; let stolenNavigator = iframe.contentWindow.navigator; - const request = makeGetOptions("openid4vp-v1-unsigned"); + const request = makeGetOptions({ protocol: "openid4vp-v1-unsigned" }); await test_driver.bless("User activation", null, iframe.contentWindow); await iframe.focus(); const p = promise_rejects_dom( diff --git a/testing/web-platform/tests/digital-credentials/support/helper.js b/testing/web-platform/tests/digital-credentials/support/helper.js @@ -10,6 +10,9 @@ * @typedef {import('../dc-types').CredentialCreationOptions} CredentialCreationOptions * @typedef {import('../dc-types').DigitalCredentialCreationOptions} DigitalCredentialCreationOptions * @typedef {import('../dc-types').SendMessageData} SendMessageData + * @typedef {import('../dc-types').MakeGetOptionsConfig} MakeGetOptionsConfig + * @typedef {import('../dc-types').MakeCreateOptionsConfig} MakeCreateOptionsConfig + * @typedef {import('../dc-types').CredentialMediationRequirement} CredentialMediationRequirement */ /** @@ -17,9 +20,9 @@ * Assumes requestsInputArray is a non-empty array of strings. * @private * @param {string[]} requestsInputArray - An array of request type strings. - * @param {string} mediation - The mediation requirement. - * @param {object} requestMapping - The specific mapping object for the operation type. - * @returns {{ digital: { requests: any[] }, mediation: string }} - The final options structure. + * @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. * @throws {Error} If an unknown request type string is encountered within the array. */ function _makeOptionsInternal(requestsInputArray, mediation, requestMapping) { @@ -54,12 +57,12 @@ const allMappings = { * Routes calls from specific public functions. * @private * @param {'get' | 'create'} type - The type of operation. - * @param {string | string[]} [requestsToUse] - Raw input for request types from public function. - * @param {string} mediation - Mediation requirement (default handled by public function). - * @returns {{ digital: { requests: any[] }, mediation: string }} + * @param {string | string[]} protocol - Protocol(s) to use. + * @param {CredentialMediationRequirement} mediation - Mediation requirement. + * @returns {{ digital: { requests: any[] }, mediation: CredentialMediationRequirement }} * @throws {Error} If type is invalid internally, or input strings are invalid. */ -function _makeOptionsUnified(type, requestsToUse, mediation) { +function _makeOptionsUnified(type, protocol, mediation) { // 1. Get mapping (Type validation primarily happens via caller) const mapping = allMappings[type]; // Added safety check, though public functions should prevent this. @@ -67,56 +70,51 @@ function _makeOptionsUnified(type, requestsToUse, mediation) { throw new Error(`Internal error: Invalid options type specified: ${type}`); } - // 2. Handle default for requestsToUse - const actualRequestsToUse = requestsToUse === undefined ? ["default"] : requestsToUse; - - // 3. Handle single string input - if (typeof actualRequestsToUse === 'string') { - if (mapping[actualRequestsToUse]) { + // 2. Handle single string input + if (typeof protocol === 'string') { + if (protocol in mapping) { // Valid single string: Pass as array to the core array helper - return _makeOptionsInternal([actualRequestsToUse], mediation, mapping); + return _makeOptionsInternal([protocol], mediation, mapping); } else { // Invalid single string for this type - throw new Error(`Unknown request type string '${actualRequestsToUse}' provided for operation type '${type}'`); + throw new Error(`Unknown request type string '${protocol}' provided for operation type '${type}'`); } } - // 4. Handle array input - if (Array.isArray(actualRequestsToUse)) { - if (actualRequestsToUse.length === 0) { + // 3. Handle array input + if (Array.isArray(protocol)) { + if (protocol.length === 0) { // Handle empty array explicitly return { digital: { requests: [] }, mediation }; } // Pass valid non-empty array to the core array helper - return _makeOptionsInternal(actualRequestsToUse, mediation, mapping); + return _makeOptionsInternal(protocol, mediation, mapping); } - // 5. Handle invalid input types (neither string nor array) + // 4. Handle invalid input types (neither string nor array) return { digital: { requests: [] }, mediation }; } /** * Creates options for getting credentials. * @export - * @param {string | string[]} [requestsToUse] - Request types ('default', 'openid4vp-v1-unsigned', 'openid4vp-v1-signed', 'openid4vp-v1-multisigned', or an array). Defaults to ['default']. - * @param {string} [mediation="required"] - Credential mediation requirement ("required", "optional", "silent"). - * @returns {{ digital: { requests: any[] }, mediation: string }} + * @param {MakeGetOptionsConfig} [config={}] - Configuration options + * @returns {CredentialRequestOptions} */ -export function makeGetOptions(requestsToUse, mediation = "required") { - // Pass type 'get', the user's input, and the final mediation value - return _makeOptionsUnified('get', requestsToUse, mediation); +export function makeGetOptions(config = {}) { + const { protocol = "default", mediation = "required" } = config; + return _makeOptionsUnified('get', protocol, mediation); } /** * Creates options for creating credentials. * @export - * @param {string | string[]} [requestsToUse] - Request types ('default', 'openid4vci', or an array). Defaults to ['default']. - * @param {string} [mediation="required"] - Credential mediation requirement ("required", "optional", "silent"). - * @returns {{ digital: { requests: any[] }, mediation: string }} // Adjust inner array type if known + * @param {MakeCreateOptionsConfig} [config={}] - Configuration options + * @returns {CredentialCreationOptions} */ -export function makeCreateOptions(requestsToUse, mediation = "required") { - // Pass type 'create', the user's input, and the final mediation value - return _makeOptionsUnified('create', requestsToUse, mediation); +export function makeCreateOptions(config = {}) { + const { protocol = "default", mediation = "required" } = config; + return _makeOptionsUnified('create', protocol, mediation); } /** diff --git a/testing/web-platform/tests/digital-credentials/user-activation.https.html b/testing/web-platform/tests/digital-credentials/user-activation.https.html @@ -14,7 +14,7 @@ navigator.userActivation.isActive, "User activation should not be active" ); - const options = makeGetOptions("openid4vp-v1-unsigned"); + const options = makeGetOptions({protocol: "openid4vp-v1-unsigned"}); await promise_rejects_dom( t, "NotAllowedError", @@ -25,7 +25,7 @@ promise_test(async (t) => { await test_driver.bless(); const abort = new AbortController(); - const options = makeGetOptions("openid4vp-v1-unsigned"); + const options = makeGetOptions({protocol: "openid4vp-v1-unsigned"}); options.signal = abort.signal; assert_true( navigator.userActivation.isActive, @@ -46,7 +46,7 @@ navigator.userActivation.isActive, "User activation should not be active" ); - const options = makeCreateOptions([]); + const options = makeCreateOptions({protocol: []}); await promise_rejects_dom( t, "NotAllowedError", @@ -60,7 +60,7 @@ navigator.userActivation.isActive, "User activation should be active after test_driver.bless()." ); - const options = makeCreateOptions([]); + const options = makeCreateOptions({protocol: []}); await promise_rejects_js(t, TypeError, navigator.credentials.create(options)); assert_false( navigator.userActivation.isActive,