3 <script src=
"/resources/testdriver.js"></script>
4 <script src=
"/resources/testdriver-vendor.js"></script>
5 <script src=
"/storage-access-api/helpers.js"></script>
8 test_driver
.set_test_context(window
.top
);
9 const type
= (new URLSearchParams(window
.location
.search
)).get("type");
10 const id
= (new URLSearchParams(window
.location
.search
)).get("id");
11 let message
= "HasAccess for " + type
;
12 // Step 6 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
14 await
MaybeSetStorageAccess("*", "*", "blocked");
15 await test_driver
.set_permission({ name
: 'storage-access' }, 'granted');
18 let couldRequestStorageAccessForNone
= true;
20 await document
.requestStorageAccess({});
22 couldRequestStorageAccessForNone
= false;
24 if (couldRequestStorageAccessForNone
) {
25 message
= "Requesting access for {} should fail."
27 let couldRequestStorageAccessForAllFalse
= true;
29 await document
.requestStorageAccess({all
:false});
31 couldRequestStorageAccessForAllFalse
= false;
33 if (couldRequestStorageAccessForAllFalse
) {
34 message
= "Requesting access for {all:false} should fail."
36 let hasUnpartitionedCookieAccess
= await document
.hasUnpartitionedCookieAccess();
37 if (hasUnpartitionedCookieAccess
) {
38 message
= "First-party cookies should not be readable if not requested.";
43 let hasUnpartitionedCookieAccess
= await document
.hasUnpartitionedCookieAccess();
44 if (hasUnpartitionedCookieAccess
|| document
.cookie
.includes("test="+id
)) {
45 message
= "First-party cookies should not be readable before handle is loaded.";
47 await document
.requestStorageAccess({cookies
: true});
48 hasUnpartitionedCookieAccess
= await document
.hasUnpartitionedCookieAccess();
49 if (!hasUnpartitionedCookieAccess
|| !document
.cookie
.includes("test="+id
)) {
50 message
= "First-party cookies should be readable if cookies were requested.";
54 case "sessionStorage": {
55 const handle
= await document
.requestStorageAccess({sessionStorage
: true});
56 let hasUnpartitionedCookieAccess
= await document
.hasUnpartitionedCookieAccess();
57 if (hasUnpartitionedCookieAccess
) {
58 message
= "First-party cookies should not be readable if not requested.";
60 if (id
!= handle
.sessionStorage
.getItem("test")) {
61 message
= "No first-party Session Storage access";
63 if (!!window
.sessionStorage
.getItem("test")) {
64 message
= "Handle should not override window Session Storage";
66 window
.onstorage
= (e
) => {
67 if (e
.key
== "window_event") {
68 if (e
.newValue
!= id
) {
69 handle
.sessionStorage
.setItem("handle_event", "wrong data " + e
.newValue
);
70 } else if (e
.storageArea
!= handle
.sessionStorage
) {
71 handle
.sessionStorage
.setItem("handle_event", "storage area mismatch");
73 handle
.sessionStorage
.setItem("handle_event", id
);
79 case "localStorage": {
80 const handle
= await document
.requestStorageAccess({localStorage
: true});
81 let hasUnpartitionedCookieAccess
= await document
.hasUnpartitionedCookieAccess();
82 if (hasUnpartitionedCookieAccess
) {
83 message
= "First-party cookies should not be readable if not requested.";
85 if (id
!= handle
.localStorage
.getItem("test")) {
86 message
= "No first-party Local Storage access";
88 if (!!window
.localStorage
.getItem("test")) {
89 message
= "Handle should not override window Local Storage";
91 window
.onstorage
= (e
) => {
92 if (e
.key
== "window_event") {
93 if (e
.newValue
!= id
) {
94 handle
.localStorage
.setItem("handle_event", "wrong data " + e
.newValue
);
95 } else if (e
.storageArea
!= handle
.localStorage
) {
96 handle
.localStorage
.setItem("handle_event", "storage area mismatch");
98 handle
.localStorage
.setItem("handle_event", id
);
105 const handle
= await document
.requestStorageAccess({indexedDB
: true});
106 let hasUnpartitionedCookieAccess
= await document
.hasUnpartitionedCookieAccess();
107 if (hasUnpartitionedCookieAccess
) {
108 message
= "First-party cookies should not be readable if not requested.";
110 const handle_dbs
= await handle
.indexedDB
.databases();
111 if (handle_dbs
.length
!= 1 || handle_dbs
[0].name
!= id
) {
112 message
= "No first-party IndexedDB access";
114 const local_dbs
= await window
.indexedDB
.databases();
115 if (local_dbs
.length
!= 0) {
116 message
= "Handle should not override window IndexedDB";
118 await handle
.indexedDB
.deleteDatabase(id
);
122 const handle
= await document
.requestStorageAccess({locks
: true});
123 let hasUnpartitionedCookieAccess
= await document
.hasUnpartitionedCookieAccess();
124 if (hasUnpartitionedCookieAccess
) {
125 message
= "First-party cookies should not be readable if not requested.";
127 const handle_state
= await handle
.locks
.query();
128 if (handle_state
.held
.length
!= 1 || handle_state
.held
[0].name
!= id
) {
129 message
= "No first-party Web Lock access";
131 const local_state
= await window
.navigator
.locks
.query();
132 if (local_state
.held
.length
!= 0) {
133 message
= "Handle should not override window Web Locks";
135 await handle
.locks
.request(id
, {steal
: true}, async () => {});
139 const handle
= await document
.requestStorageAccess({caches
: true});
140 let hasUnpartitionedCookieAccess
= await document
.hasUnpartitionedCookieAccess();
141 if (hasUnpartitionedCookieAccess
) {
142 message
= "First-party cookies should not be readable if not requested.";
144 const handle_has
= await handle
.caches
.has(id
);
146 message
= "No first-party Cache Storage access";
148 const local_has
= await window
.caches
.has(id
);
150 message
= "Handle should not override window Cache Storage";
152 await handle
.caches
.delete(id
);
155 case "getDirectory": {
156 const handle
= await document
.requestStorageAccess({getDirectory
: true});
157 let hasUnpartitionedCookieAccess
= await document
.hasUnpartitionedCookieAccess();
158 if (hasUnpartitionedCookieAccess
) {
159 message
= "First-party cookies should not be readable if not requested.";
161 const handle_root
= await handle
.getDirectory();
162 let handle_has
= await handle_root
.getFileHandle(id
).then(() => true, () => false);
164 message
= "No first-party Origin Private File System access";
166 const local_root
= await window
.navigator
.storage
.getDirectory();
167 let local_has
= await local_root
.getFileHandle(id
).then(() => true, () => false);
169 message
= "Handle should not override window Origin Private File System";
171 await handle_root
.removeEntry(id
);
175 const handle
= await document
.requestStorageAccess({estimate
: true});
176 let hasUnpartitionedCookieAccess
= await document
.hasUnpartitionedCookieAccess();
177 if (hasUnpartitionedCookieAccess
) {
178 message
= "First-party cookies should not be readable if not requested.";
180 const handle_estimate
= await handle
.estimate();
181 if (handle_estimate
.usage
<= 0) {
182 message
= "No first-party quota access";
184 const local_estimate
= await window
.navigator
.storage
.estimate();
185 if (local_estimate
> 0) {
186 message
= "Handle should not override window quota";
190 case "blobStorage": {
191 const handle
= await document
.requestStorageAccess({createObjectURL
: true, revokeObjectURL
: true});
192 let hasUnpartitionedCookieAccess
= await document
.hasUnpartitionedCookieAccess();
193 if (hasUnpartitionedCookieAccess
) {
194 message
= "First-party cookies should not be readable if not requested.";
196 let blob
= await
fetch(atob(id
)).then(
197 (response
) => response
.text(),
199 if (blob
!= "TEST") {
200 message
= "Blob storage should be readable in this context";
202 URL
.revokeObjectURL(atob(id
));
203 blob
= await
fetch(atob(id
)).then(
204 (response
) => response
.text(),
206 if (blob
!= "TEST") {
207 message
= "Handle should not override window blob storage";
209 handle
.revokeObjectURL(atob(id
));
210 blob
= await
fetch(atob(id
)).then(
211 (response
) => response
.text(),
214 message
= "No first-party blob access";
216 const url
= handle
.createObjectURL(new Blob(["TEST2"]));
217 blob
= await
fetch(url
).then(
218 (response
) => response
.text(),
220 if (blob
!= "TEST2") {
221 message
= "A blob url created via the handle should be readable";
223 handle
.revokeObjectURL(url
);
224 blob
= await
fetch(url
).then(
225 (response
) => response
.text(),
228 message
= "A blob url removed via the handle should be cleared";
232 case "BroadcastChannel": {
233 const handle
= await document
.requestStorageAccess({BroadcastChannel
: true});
234 let hasUnpartitionedCookieAccess
= await document
.hasUnpartitionedCookieAccess();
235 if (hasUnpartitionedCookieAccess
) {
236 message
= "First-party cookies should not be readable if not requested.";
238 const handle_channel
= handle
.BroadcastChannel(id
);
239 handle_channel
.postMessage("Same-origin handle access");
240 handle_channel
.close();
241 const local_channel
= new BroadcastChannel(id
);
242 local_channel
.postMessage("Same-origin local access");
243 local_channel
.close();
246 case "SharedWorker": {
247 const local_shared_worker
= new SharedWorker("/storage-access-api/resources/shared-worker-relay.js", id
);
248 local_shared_worker
.port
.start();
249 local_shared_worker
.port
.postMessage("Same-origin local access");
250 const handle
= await document
.requestStorageAccess({SharedWorker
: true});
251 let couldRequestAllCookies
= true;
253 handle
.SharedWorker("/storage-access-api/resources/shared-worker-relay.js", {name
: id
, sameSiteCookies
: 'all'});
255 couldRequestAllCookies
= false;
257 if (couldRequestAllCookies
) {
258 message
= "Shared Workers in a third-party context should not be able to request SameSite cookies.";
260 handle
.SharedWorker("/storage-access-api/resources/shared-worker-cookies.py", id
).port
.start();
261 const handle_shared_worker
= handle
.SharedWorker("/storage-access-api/resources/shared-worker-relay.js", {name
: id
, sameSiteCookies
: 'none'});
262 handle_shared_worker
.port
.start();
263 handle_shared_worker
.port
.postMessage("Same-origin handle access");
267 message
= "Unexpected type " + type
;
272 message
= "Unable to load handle in same-origin context for " + type
;
274 // Step 7 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
275 await
MaybeSetStorageAccess("*", "*", "allowed");
276 await test_driver
.set_permission({ name
: 'storage-access' }, 'prompt');
277 window
.top
.postMessage(message
, "*");