Merge pull request #2510 from brian-superlist/fix-opfs-issue

Bugfix: Only remove available implementations entries if they're available
This commit is contained in:
Simon Binder 2023-07-06 22:19:18 +02:00 committed by GitHub
commit 77fc624322
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 14 deletions

View File

@ -108,10 +108,22 @@ Unfortunately, there's no way (that I'm aware of) to add these headers onto `flu
Drift will fall back to a (slightly slower) implementation in that case (see [storages](#storages)),
but we recommend researching and enabling these headers in production if possible.
Note that Safari 16 has an [unfortunate bug](https://bugs.webkit.org/show_bug.cgi?id=245346)
{% block "blocks/alert" title="Downsides of COOP and COEP" color="danger" %}
While these headers are required for the origin-private FileSystem Access API
and bring a security benefit, there are some known problems:
- These headers are incompatible with some other packages opening popups,
such as the ones used for [Google Auth](https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid?hl=en#cross_origin_opener_policy).
- Safari 16 has an [unfortunate bug](https://bugs.webkit.org/show_bug.cgi?id=245346)
preventing dedicated workers to be loaded from cache with these headers. However, shared and service workers
are unaffected by this.
Please carefully test your app with these headers to evaluate whether you might
be affected by these limitations.
If the headers break your app, you should not enable them - drift will fall back
to another (potentially slower) implementation in that case.
{% endblock %}
### Setup in Dart
From a perspective of the Dart code used, drift on the web is similar to drift on other platforms.

View File

@ -93,11 +93,19 @@ class WasmDatabaseOpener {
// format to avoid data loss (e.g. after a browser update that enables a
// otherwise preferred storage implementation). In the future, we might want
// to consider migrating between storage implementations as well.
if (_existsInIndexedDb) {
if (_existsInIndexedDb &&
(availableImplementations
.contains(WasmStorageImplementation.sharedIndexedDb) ||
availableImplementations
.contains(WasmStorageImplementation.unsafeIndexedDb))) {
availableImplementations.removeWhere((element) =>
element != WasmStorageImplementation.sharedIndexedDb &&
element != WasmStorageImplementation.unsafeIndexedDb);
} else if (_existsInOpfs) {
} else if (_existsInOpfs &&
(availableImplementations
.contains(WasmStorageImplementation.opfsShared) ||
availableImplementations
.contains(WasmStorageImplementation.opfsLocks))) {
availableImplementations.removeWhere((element) =>
element != WasmStorageImplementation.opfsShared &&
element != WasmStorageImplementation.opfsLocks);

View File

@ -20,8 +20,6 @@ class TestAssetServer {
final BuildDaemonClient buildRunner;
late final HttpServer server;
bool addCoopAndCoepHeaders = true;
TestAssetServer(this.buildRunner);
Future<void> close() async {
@ -69,9 +67,16 @@ class TestAssetServer {
final proxy = proxyHandler('http://localhost:$assetServerPort/web/');
server.server = await serve(
(request) async {
final pathSegments = request.url.pathSegments;
if (pathSegments.isNotEmpty && pathSegments[0] == 'no-coep') {
// Serve stuff under /no-coep like the regular website, but without
// adding the security headers.
return await proxy(request.change(path: 'no-coep'));
} else {
final response = await proxy(request);
if (server.addCoopAndCoepHeaders) {
if (!request.url.path.startsWith('/no-coep')) {
return response.change(headers: {
// Needed for shared array buffers to work
'Cross-Origin-Opener-Policy': 'same-origin',
@ -80,6 +85,7 @@ class TestAssetServer {
}
return response;
}
},
'localhost',
8080,

View File

@ -176,6 +176,22 @@ void main() {
expect(await driver.amountOfRows, 1);
},
);
if (!browser.supports(WasmStorageImplementation.opfsShared)) {
test('uses indexeddb after OPFS becomes unavailable', () async {
// This browser only supports OPFS with the right headers. If they
// are ever removed, data is lost (nothing we could do about that),
// but drift should continue to work.
await driver.openDatabase(WasmStorageImplementation.opfsLocks);
await driver.insertIntoDatabase();
expect(await driver.amountOfRows, 1);
await Future.delayed(const Duration(seconds: 2));
await driver.driver.get('http://localhost:8080/no-coep');
await driver.openDatabase();
expect(await driver.amountOfRows, isZero);
});
}
}
});
}