Bug 177350 - CryptoKey in IndexedDB breaks db query
Summary: CryptoKey in IndexedDB breaks db query
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit Misc. (show other bugs)
Version: Other
Hardware: iPhone / iPad iOS 12
: P2 Blocker
Assignee: Nobody
URL: https://fiddle.jshell.net/sechel/qn7o...
Keywords: InRadar
Depends on:
Blocks: 133122 160306 165889
  Show dependency treegraph
 
Reported: 2017-09-22 02:30 PDT by Stefan Sechelmann
Modified: 2023-09-21 06:55 PDT (History)
7 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Sechelmann 2017-09-22 02:30:59 PDT
Storing CryptoKeys in IndexedDB does not work well. If we store a CryptoKey in IndexedDB we loose the ability to query by index:

>  QUnit.test('Native', async assert => {
>    const req = indexedDB.open(dbName, 1);
>    req.onupgradeneeded = function() {
>      const db = this.result;
>      const testStore = db.createObjectStore('test', { autoIncrement: false, keyPath: 'id' });
>      testStore.createIndex('id', 'id', { unique: true });
>      testStore.createIndex('IDB_class', 'IDB_class', { unique: false });
>    };  
>    await new Promise(r => req.onsuccess = r);
>    const db = req.result;
>    const testData = {id: 1, IDB_class: 'test_class', key}; // key is a CryptoKey
>    tx = db.transaction(['test'], 'readwrite');
>    store = tx.objectStore('test');
>    store.add(testData);
>    await new Promise(r => tx.oncomplete = r);
>    tx = db.transaction(['test'], 'readonly');
>    store = tx.objectStore('test');
>    const req1 = store.get(1);
>    await new Promise(r => req1.onsuccess = r);  
>    assert.propEqual(req1.result, testData, 'objects should be equivalent');
>    tx = db.transaction(['test'], 'readonly');
>    store = tx.objectStore('test');  
>    const index = store.index('IDB_class');
>    const req2 = index.get('test_class');
>    await new Promise(r => req2.onsuccess = r);
>    assert.propEqual(req2.result, testData, 'objects should be equivalent');
>    indexedDB.deleteDatabase(dbName);
>  });

You can test this using this Fiddle:
https://fiddle.jshell.net/sechel/qn7oesaf/

Expected behaviour: req1.result and req2.result should be property equivalent to testData.

Observed behaviour: Only req1.result is equivalent to testData, req2.result is undefined.
Comment 1 Stefan Sechelmann 2018-01-23 04:42:21 PST
Following up a discussion started in the IndexedDB 2.0 issue: https://bugs.webkit.org/show_bug.cgi?id=160306

> If you can give an example of a real world, in-production site where this
> works in other browsers and not WebKit-based ones that could help
> reprioritize.

You are right, its not high priority as one can create a workaround pretty easy. Just store all WebCrypto keys in a separate object store and resolve the corresponding "foreign keys" in the respective query transaction.

On the other hand this has an impact on performance. If there are many keys per object the subsequent resolution of CryptoKeys may be costly. Or is there an even more simple and more effective workaround that I am missing here?

We appreciate what has been accomplished with WebCrypto and IndexedDB in the last 12 months. Fixing this issue would just complete the otherwise nice picture.

Cheers
Stefan
Comment 2 Stefan Sechelmann 2018-02-20 07:20:21 PST
Then again, if one really tries to implement such a workaround further issues start to pop up: https://bugs.webkit.org/show_bug.cgi?id=182972
Comment 3 Stefan Sechelmann 2019-06-12 04:40:19 PDT
We have an App that uses WKWebView in the AppStore that is affected by this issue. I changed the architecture up in the meta data to reflect this. Here is a working demo of this issue: https://codepen.io/sechel/pen/VJYqgy
Comment 4 Radar WebKit Bug Importer 2021-03-03 13:53:20 PST
<rdar://problem/75002015>
Comment 5 Ahmad Saleem 2023-09-21 06:55:13 PDT
(In reply to Stefan Sechelmann from comment #3)
> We have an App that uses WKWebView in the AppStore that is affected by this
> issue. I changed the architecture up in the meta data to reflect this. Here
> is a working demo of this issue: https://codepen.io/sechel/pen/VJYqgy

We are still failing the test cases here on Safari Technology Preview 179.