<!DOCTYPE html>
<title>Credentials in WebBundle subresource loading</title>
<link
rel="help"
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md#requests-mode-and-credentials-mode"
/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/test-helpers.js"></script>
<body>
<script>
// In this wpt, we test a request's credential mode, which controls
// whether UA sends a credential or not to fetch a bundle.
// If UA sends a credential, check-cookie-and-return-{cross-oriigin}-bundle.py
// returns a valid format webbundle. Then, a subresource fetch should be successful.
// Otherwise, a subresource fetch should be rejected.
setup(() => {
assert_true(HTMLScriptElement.supports("webbundle"));
});
document.cookie = "milk=1; path=/";
// Make sure to set a cookie for a cross-origin domain from where a cross
// origin bundle is served.
const setCookiePromise = fetch(
"https://{{domains[www1]}}:{{ports[https][0]}}/cookies/resources/set-cookie.py?name=milk&path=/web-bundle/resources/",
{
mode: "no-cors",
credentials: "include",
}
);
const same_origin_bundle = "../resources/check-cookie-and-return-bundle.py";
const cross_origin_bundle =
"https://{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/check-cookie-and-return-bundle.py?bundle=cross-origin";
const same_origin_bundle_subresource = "../resources/wbn/root.js";
const cross_origin_bundle_subresource =
"https://{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/simple-cross-origin.txt";
async function assertSubresourceCanBeFetched() {
const response = await fetch(same_origin_bundle_subresource);
const text = await response.text();
assert_equals(text, "export * from './submodule.js';\n");
}
async function assertCrossOriginSubresourceCanBeFetched() {
const response = await fetch(cross_origin_bundle_subresource);
const text = await response.text();
assert_equals(text, "hello from simple-cross-origin.txt");
}
function createScriptWebBundle(credentials) {
const options = {};
if (credentials) {
options.credentials = credentials;
}
return createWebBundleElement(
same_origin_bundle,
[same_origin_bundle_subresource],
options
);
}
function createScriptWebBundleCrossOrigin(credentials) {
const options = {};
if (credentials) {
options.credentials = credentials;
}
return createWebBundleElement(
cross_origin_bundle,
[cross_origin_bundle_subresource],
options
);
}
promise_test(async (t) => {
const script = createScriptWebBundle();
document.body.append(script);
t.add_cleanup(() => script.remove());
await assertSubresourceCanBeFetched();
}, "The default should send a credential to a same origin bundle");
promise_test(async (t) => {
const script = createScriptWebBundle("invalid");
document.body.append(script);
t.add_cleanup(() => script.remove());
await assertSubresourceCanBeFetched();
}, "An invalid value should send a credential to a same origin bundle");
promise_test(async (t) => {
const script = createScriptWebBundle("omit");
document.body.append(script);
t.add_cleanup(() => script.remove());
return promise_rejects_js(
t,
TypeError,
fetch(same_origin_bundle_subresource)
);
}, "'omit' should not send a credential to a same origin bundle");
promise_test(async (t) => {
const script = createScriptWebBundle("same-origin");
document.body.append(script);
t.add_cleanup(() => script.remove());
await assertSubresourceCanBeFetched();
}, "'same-origin' should send a credential to a same origin bundle");
promise_test(async (t) => {
const script = createScriptWebBundle("include");
document.body.append(script);
t.add_cleanup(() => script.remove());
await assertSubresourceCanBeFetched();
}, "'include' should send a credential to a same origin bundle");
promise_test(async (t) => {
await setCookiePromise;
const script = createScriptWebBundleCrossOrigin("omit");
document.body.append(script);
t.add_cleanup(() => script.remove());
return promise_rejects_js(
t,
TypeError,
fetch(cross_origin_bundle_subresource)
);
}, "'omit' should not send a credential to a cross origin bundle");
promise_test(async (t) => {
await setCookiePromise;
const script = createScriptWebBundleCrossOrigin("same-origin");
document.body.append(script);
t.add_cleanup(() => script.remove());
return promise_rejects_js(
t,
TypeError,
fetch(cross_origin_bundle_subresource)
);
}, "'same-origin' should not send a credential to a cross origin bundle");
promise_test(async (t) => {
await setCookiePromise;
const script = createScriptWebBundleCrossOrigin("include");
document.body.append(script);
t.add_cleanup(() => script.remove());
await assertCrossOriginSubresourceCanBeFetched();
}, "'include' should send a credential to a cross origin bundle");
promise_test(async (t) => {
const script = createScriptWebBundleCrossOrigin("invalid");
document.body.append(script);
t.add_cleanup(() => script.remove());
return promise_rejects_js(
t,
TypeError,
fetch(cross_origin_bundle_subresource)
);
}, "An invalid value should not send a credential to a cross origin bundle");
</script>
</body>