Skip to content

Commit 58fcbbf

Browse files
committed
Digital Credentials API: handle mediation requirement
https://bugs.webkit.org/show_bug.cgi?id=277322 rdar://133266859 Reviewed by Anne van Kesteren. Make sure mediation is alway required when getting digital credentials as required by the spec: w3c-fedid/digital-credentials#149 * LayoutTests/http/wpt/identity/identitycredentialscontainer-get-hidden.https.html: * LayoutTests/imported/w3c/web-platform-tests/digital-credentials/allow-attribute.https.html: * LayoutTests/imported/w3c/web-platform-tests/digital-credentials/dc-types.ts: * LayoutTests/imported/w3c/web-platform-tests/digital-credentials/default-permissions-policy.https.sub.html: * LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub.html: * LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html: * LayoutTests/imported/w3c/web-platform-tests/digital-credentials/identity-get.tentative.https-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/digital-credentials/identity-get.tentative.https.html: * LayoutTests/imported/w3c/web-platform-tests/digital-credentials/support/helper.js: (export.makeGetOptions): * LayoutTests/imported/w3c/web-platform-tests/permissions-policy/resources/digital-credentials-get.html: * LayoutTests/platform/ios/imported/w3c/web-platform-tests/digital-credentials/identity-get.tentative.https-expected.txt: * Source/WebCore/Modules/identity/IdentityCredentialsContainer.cpp: (WebCore::IdentityCredentialsContainer::get): Canonical link: https://commits.webkit.org/283148@main
1 parent 3a6f818 commit 58fcbbf

File tree

12 files changed

+50
-23
lines changed

12 files changed

+50
-23
lines changed

LayoutTests/http/wpt/identity/identitycredentialscontainer-get-hidden.https.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
digital: {
4141
providers: [],
4242
},
43+
mediation: "required",
4344
});
4445

4546
await promise_rejects_dom(t, "NotAllowedError", p);

LayoutTests/imported/w3c/web-platform-tests/digital-credentials/allow-attribute.https.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
// Results in TypeError when allowed, NotAllowedError when disallowed
106106
providers: [],
107107
},
108+
mediation: "required",
108109
};
109110
const { data } = await new Promise((resolve) => {
110111
window.addEventListener("message", resolve, {

LayoutTests/imported/w3c/web-platform-tests/digital-credentials/dc-types.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
export type ProviderType = "default" | "openid4vp";
2+
export type CredentialMediationRequirement =
3+
| "conditional"
4+
| "optional"
5+
| "required"
6+
| "silent";
27

38
/**
49
* @see https://wicg.github.io/digital-credentials/#dom-identityrequestprovider
@@ -26,12 +31,17 @@ export interface CredentialRequestOptions {
2631
* The digital credential request options.
2732
*/
2833
digital: DigitalCredentialRequestOptions;
34+
mediation: CredentialMediationRequirement;
2935
}
3036

3137
/**
3238
* The actions that can be performed on the API via the iframe.
3339
*/
34-
export type IframeActionType = "create" | "get" | "ping" | "preventSilentAccess" ;
40+
export type IframeActionType =
41+
| "create"
42+
| "get"
43+
| "ping"
44+
| "preventSilentAccess";
3545

3646
/**
3747
* If present, when the abort controller should be aborted
@@ -53,8 +63,8 @@ export interface EventData {
5363
*/
5464
options?: object;
5565
/**
56-
* If the API needs to blessed before the action is performed.
57-
*/
66+
* If the API needs to blessed before the action is performed.
67+
*/
5868
needsUserActivation?: boolean;
5969
}
6070

LayoutTests/imported/w3c/web-platform-tests/digital-credentials/default-permissions-policy.https.sub.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
<script src="/permissions-policy/resources/permissions-policy.js"></script>
88
<script src="/common/get-host-info.sub.js"></script>
99
<body></body>
10-
<script>
11-
"use strict";
10+
<script type="module">
11+
import { makeGetOptions } from "./support/helper.js";
1212
const { HTTPS_REMOTE_ORIGIN } = get_host_info();
1313
const same_origin_src =
1414
"/permissions-policy/resources/digital-credentials-get.html";
@@ -19,7 +19,7 @@
1919
await promise_rejects_js(
2020
test,
2121
TypeError,
22-
navigator.identity.get({ digital: { providers: [] } })
22+
navigator.identity.get(makeGetOptions([]))
2323
);
2424

2525
await test_feature_availability({

LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
<script src="/permissions-policy/resources/permissions-policy.js"></script>
88
<script src="/common/get-host-info.sub.js"></script>
99
<body></body>
10-
<script>
11-
"use strict";
10+
<script type="module">
11+
import { makeGetOptions } from "/digital-credentials/support/helper.js";
1212
const { HTTPS_REMOTE_ORIGIN } = get_host_info();
1313
const same_origin_src =
1414
"/permissions-policy/resources/digital-credentials-get.html";
@@ -19,7 +19,7 @@
1919
await promise_rejects_dom(
2020
test,
2121
"NotAllowedError",
22-
navigator.identity.get({ digital: { providers: [] } })
22+
navigator.identity.get(makeGetOptions([]))
2323
);
2424
}, "Permissions-Policy header digital-credentials-get=() disallows the top-level document.");
2525

LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
<script src="/permissions-policy/resources/permissions-policy.js"></script>
88
<script src="/common/get-host-info.sub.js"></script>
99
<body></body>
10-
<script>
11-
"use strict";
10+
<script type="module">
11+
import { makeGetOptions } from "./support/helper.js";
1212
const { HTTPS_REMOTE_ORIGIN } = get_host_info();
1313
const same_origin_src =
1414
"/permissions-policy/resources/digital-credentials-get.html";
@@ -19,7 +19,7 @@
1919
await promise_rejects_js(
2020
test,
2121
TypeError,
22-
navigator.identity.get({ digital: { providers: [] } })
22+
navigator.identity.get(makeGetOptions([]))
2323
);
2424
}, "Permissions-Policy header digital-credentials-get=(self) allows the top-level document.");
2525

LayoutTests/imported/w3c/web-platform-tests/digital-credentials/identity-get.tentative.https-expected.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ PASS navigator.identity.get() promise is rejected if called with an aborted sign
99
PASS navigator.identity.get() promise is rejected if called with an aborted signal in cross-origin iframe.
1010
FAIL navigator.identity.get() promise is rejected if abort controller is aborted after call to get(). promise_rejects_dom: function "function() { throw e }" threw object "NotSupportedError: Not implemented" that is not a DOMException AbortError: property "code" is equal to 9, expected 20
1111
FAIL navigator.identity.get() promise is rejected if abort controller is aborted after call to get() in cross-origin iframe. assert_equals: expected "AbortError" but got "NotAllowedError"
12+
PASS Mediation is required to get a DigitalCredential.
1213

LayoutTests/imported/w3c/web-platform-tests/digital-credentials/identity-get.tentative.https.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,4 +192,13 @@
192192
assert_equals(result.constructor, "DOMException");
193193
assert_equals(result.name, "AbortError");
194194
}, "navigator.identity.get() promise is rejected if abort controller is aborted after call to get() in cross-origin iframe.");
195+
196+
promise_test(async (t) => {
197+
/** @type sequence<CredentialMediationRequirement> */
198+
const disallowedMediations = [ "conditional", "optional", "silent"];
199+
for (const mediation of disallowedMediations) {
200+
const options = makeGetOptions("default", mediation);
201+
await promise_rejects_js(t, TypeError, navigator.identity.get(options));
202+
}
203+
}, "Mediation is required to get a DigitalCredential.");
195204
</script>

LayoutTests/imported/w3c/web-platform-tests/digital-credentials/support/helper.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,17 @@
99
*/
1010
/**
1111
* @param {ProviderType | ProviderType[]} [providersToUse=["default"]]
12+
* @param {CredentialMediationRequirement} [mediation="required"]
1213
* @returns {CredentialRequestOptions}
1314
*/
14-
export function makeGetOptions(providersToUse = ["default"]) {
15+
export function makeGetOptions(providersToUse = ["default"], mediation = "required") {
1516
if (typeof providersToUse === "string") {
1617
if (providersToUse === "default" || providersToUse === "openid4vp"){
1718
return makeGetOptions([providersToUse]);
1819
}
1920
}
2021
if (!Array.isArray(providersToUse) || !providersToUse?.length) {
21-
return { digital: { providers: providersToUse } };
22+
return { digital: { providers: providersToUse }, mediation };
2223
}
2324
const providers = [];
2425
for (const provider of providersToUse) {
@@ -31,10 +32,9 @@ export function makeGetOptions(providersToUse = ["default"]) {
3132
break;
3233
default:
3334
throw new Error(`Unknown provider type: ${provider}`);
34-
break;
3535
}
3636
}
37-
return { digital: { providers } };
37+
return { digital: { providers }, mediation };
3838
}
3939
/**
4040
*

LayoutTests/imported/w3c/web-platform-tests/permissions-policy/resources/digital-credentials-get.html

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
<meta charset="utf-8" />
33
<script src="/resources/testdriver.js"></script>
44
<script src="/resources/testdriver-vendor.js"></script>
5-
<body></body>
6-
<script>
5+
<script type="module">
6+
import { makeGetOptions } from "/digital-credentials/support/helper.js";
77
const type = "availability-result";
88
async function notify() {
99
if (!navigator.userActivation.isActive) {
1010
await test_driver.bless("user activation", null, window);
1111
}
1212
let enabled = undefined;
1313
try {
14-
await navigator.identity.get({ digital: { providers: [] } });
14+
await navigator.identity.get(makeGetOptions([]));
1515
} catch (e) {
1616
switch (e.name) {
1717
case "NotAllowedError":
@@ -27,7 +27,8 @@
2727
window.parent.postMessage({ type, enabled }, "*");
2828
}
2929
}
30+
window.onload = notify;
3031
</script>
31-
<body onload="notify()">
32+
<body>
3233
<h1>Digital Credentials iframe</h1>
3334
</body>

0 commit comments

Comments
 (0)