mark43 / dexie-encrypted Goto Github PK
View Code? Open in Web Editor NEWTransparent encryption for IndexedDB using Dexie
License: MIT License
Transparent encryption for IndexedDB using Dexie
License: MIT License
I don't know if this package is maintained or not but would like to submit a bug.
At least it could be helpful for future users of the package.
OR queries like this one are not working, and return an empty result set:
db.friends
.where("name")
.startsWith("kr")
.or("age")
.below(30)
Full example: https://codesandbox.io/s/dexie-encrypted-working-example-forked-75qwdj?file=/src/App.js
Click INSERT and the try out the get
buttons below. Check the console.
The last two buttons should return 2 records (one with name "kris" and one with age 24), but it returns zero records.
If I filter only by name or only by age I get 1 record, which is expected.
If I disable the encryption (db.js > ENABLE_ENCRYPTION
) and use dexie
without the dexie-encrypted
all queries work as expected.
When I try to call close
then open
Dexie method on the same db instance, reads are not decrypted.
My workaround is to re-create another instance of Dexie db after close
then open
it.
I wouldn't be forced to do it only because I encrypt my database with dexie-encrypted
.
With the new version of Dexie 3 out, does this library still work as is?
I see there hasn't been much activity here lately.
@dfahlander Any idea on this?
Thanks!
In my table I have saved contact object that has one of the properties named "icon" of type object.
I have it encrypted and Inoticed that icon was not updated properly on record update.
So I added that field into whitelist to see if that would fix it.
So before i update contact object looks like this:
{ etag: "" firstName: "" icon: { direct-uri: "https://domain/icon/1576169325909" etag: "1576169325909" uri: "https://domain/icon" } inTrash: 0 isFavorite: 0 ..... and so on }
after i update full contact with response from server it ends up like this even though "icon" is in whitelist
{ etag: "" firstName: "" icon: { direct-uri: "" etag: "" uri: "https://domain/icon" } inTrash: 0 isFavorite: 0 ..... and so on }
not sure what is going on but it seems that parts are still encrypted.
If I disable encryption update works perfectly ok. So it seems that something with nested objects does not work properly when updating?
BTW if I have "icon" object encrypted, when I update the contact with new data after updating icon on the server, data seems to be stale, when data is loaded from the database old "direct-uri" is decrypted.
So just to repeat, without "dexie-encrypted" update of the record works ok, when using "dexie-encrypted", "icon" object doesn't get updated properly, and even if I whitelist "icon" some of it's props are "emptied" on update
When I use Custom Encryption Method It gives me that error
Before using dexie-encrypted
I had code to update an indexed property value of an object stored with dexie.js.
This code looked like :
db.myTable.update(myObjectKey, { indexedProperty: newValue })
Cf. https://dexie.org/docs/Table/Table.update()
After adding dexie-encrypted
, this code stopped working and indexedProperty
was not updated.
As a workaround, I found that using put
method, it works well.
I would like update
method to work with dexie-encrypted
To help, I add a unit-test with update
method trying to update the age
property and results doesn't match :
- Expected
+ Received
Object {
- "age": 32,
+ "__encryptedData": Uint8Array [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 251,
+ 7,
+ 159,
+ 109,
+ 49,
+ 204,
+ 203,
+ 74,
+ 71,
+ 82,
+ 233,
+ 106,
+ 196,
+ 143,
+ 227,
+ 84,
+ 3,
+ 98,
+ 232,
+ 108,
+ 86,
+ 28,
+ 124,
+ 138,
+ 41,
+ 51,
+ 166,
+ 14,
+ 127,
+ 182,
+ 115,
+ 222,
+ 91,
+ 67,
+ 160,
+ 170,
+ 253,
+ 26,
+ 7,
+ 129,
+ 175,
+ 176,
+ 211,
+ 13,
+ 22,
+ 170,
+ 222,
+ 221,
+ 173,
+ 249,
+ 90,
+ 254,
+ 45,
+ 224,
+ 241,
+ 57,
+ 242,
+ 65,
+ 100,
+ 255,
+ 215,
+ 220,
+ 7,
+ 206,
+ 9,
+ 24,
+ 250,
+ 120,
+ 64,
+ 10,
+ 190,
+ 158,
+ 19,
+ 238,
+ 63,
+ 234,
+ 178,
+ 1,
+ 236,
+ 105,
+ 126,
+ 199,
+ 54,
+ 196,
+ 233,
+ 15,
+ 174,
+ 174,
+ 205,
+ 56,
+ 0,
+ 189,
+ 162,
+ 188,
+ 41,
+ 46,
+ 133,
+ 166,
+ 151,
+ 19,
+ 20,
+ 79,
+ 11,
+ 199,
+ 153,
+ 114,
+ 235,
+ 204,
+ 134,
+ 20,
+ 252,
+ 12,
+ 73,
+ 255,
+ 217,
+ 211,
+ 106,
+ 14,
+ 49,
+ 139,
+ 91,
+ 159,
+ 24,
+ 176,
+ 209,
+ 187,
+ 121,
+ 55,
+ 143,
+ ],
+ "age": 25,
"id": 1,
- "isFriendly": true,
- "name": "Camilla",
- "picture": "camilla.png",
- "street": "East 13:th Street",
+ "isFriendly": false,
+ "name": "",
+ "picture": "",
+ "street": "",
Hi,
Can you please provide a typescript example for this library?
Best regards,
Anuradha
Hi!
I'm trying to build dexie-encrypted locally but am failing to npm install the library. It fails with 401. I tried to remove the "repository" field as it seemed to try to authenticate towards https://github.com/mark43/, but still same problem.
What I'm trying to do is to try testing out the compatibility between dexie 4 and dexie-encrypted, as well as with dexie-cloud as I'd like to contribute to dexie-encrypted to make nescessary changes, so that's why I need to be able to build and run tests etc.
I'm using electron, dexie, and dexie-encrypted. After building the electron app I get the above error.
I'm importing like so:
import Dexie from "dexie";
import encrypt from "dexie-encrypted";
And my code is as follows:
encrypt(db, idbKey, {
certStore: encrypt.NON_INDEXED_FIELDS,
});
Is it something to do with the way I am importing dexie-encrypted? Any help would be appreciative
I've bumped Dexie to 3.0.0 then it stopped indexeddb encryption.
Does someone succeeded using dexie-encrypted with dexie 3 ?
My application code looks like this:
FriendApi.ts
import { Friend } from "./FriendList";
import Dexie from 'dexie';
import encrypt, { cryptoOptions } from 'dexie-encrypted';
const db = new Dexie("friendsDB4");
const binary_string = atob("pDA+nXDxXychsH/DQlBd/1b+4y0cjd1dsqRQwKiDD3U=");
const len = binary_string.length;
const cryptoKey = new Uint8Array(len);
for (var i = 0; i < len; i++) {
cryptoKey[i] = binary_string.charCodeAt(i);
}
encrypt(db, cryptoKey, {friends: cryptoOptions.NON_INDEXED_FIELDS});
db.version(1).stores({
friends: 'id, name'
});
export class FriendApi {
friends = db.table("friends") as Dexie.Table<Friend, number>;
listFriends (): Promise<Friend[]> {
return this.friends.orderBy("name").toArray();
}
upsertFriend(friend: Friend) {
return this.friends.put(friend);
}
removeFriend(id: number) {
return this.friends.delete(id);
}
}
export const friendApi = new FriendApi();
Now, if I add a friend, it works perfect, but if I edit the friend, it will alway get age: 0
. The field "age" is the only non-indexed field here.
Importing from a ESM module with Node v15.14.0 fails.
import { applyEncryptionMiddleware } from "dexie-encrypted";
Output:
node:internal/process/esm_loader:74
internalBinding('errors').triggerUncaughtException(
^
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/alex/xxx/node_modules/dexie/dist/modern/dexie.mjs
at new NodeError (node:internal/errors:329:5)
at Module.load (node:internal/modules/cjs/loader:970:11)
at Function.Module._load (node:internal/modules/cjs/loader:813:14)
at Module.require (node:internal/modules/cjs/loader:996:19)
at require (node:internal/modules/cjs/helpers:92:18)
at Object.<anonymous> (/home/alex/xxx/node_modules/dexie-encrypted/dist/applyMiddleware.js:5:41)
at Module._compile (node:internal/modules/cjs/loader:1092:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1121:10)
at Module.load (node:internal/modules/cjs/loader:972:32)
at Function.Module._load (node:internal/modules/cjs/loader:813:14) {
code: 'ERR_REQUIRE_ESM'
}
Strategies for storing keys
Password based
If you don't have a back end, or can't add this API to your back end, you may use the user's password or other information that is not stored locally. The simplest way to do this is to use the password or a hash of it. This has the disadvantage that you must reencrypt the full database if the user changes their password. An alternative is to generate a random key, then store it encrypted with the user's password. With this method when the user changes their password you only need to reencrypt their key, rather than the entire database.Back End
Using a back end lets you ensure that only a logged in user can have access to the data in your database, but it does mean that the user won't be able to access this data offline.
Is there any example of both of these strategies, or a library that handle this and play nice with dexie-encrypted plugin?
I had added encryption to db version 7. Till that all updates worked smoothly, as I incremented version after adding encryption. But after this I added one more store in schema with version 8 . but its failed on open & giving "An object store with the specified name already exists" error. Its work perfectly fine if I am removing encryption.
Does anything else I have to done while updating after Encrypted version?
It doesn't work with compound index (or blob non-indexed fields):
import Dexie from 'dexie'
import { applyEncryptionMiddleware, NON_INDEXED_FIELDS } from 'dexie-encrypted'
const db = new Dexie('testdb')
const enc = new TextEncoder()
const key = enc.encode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
applyEncryptionMiddleware(db, key, {
test: NON_INDEXED_FIELDS,
})
db.version(1)
.stores({
test: '[a+b]',
})
try {
await db.put({a: 123, b: 456, c: 789})
} catch(e) {
console.error(e)
}
oops this was a mistake, it is working.
I added support for ESM modules to better support moden build chains. Are you taking pull requests or new contributors for enhancements to the project. I haven't seen any activity for some time now. Plus there is some new Dexie changes that need a few tweaks. I would be happy to contribute to this project. Otherwise will need to branch. LMK...
Nick
Hi!
I've been testing out dexie-encrypted together with [email protected] and they work fine together except for the typings of applyEncryptionMiddleware()
. Would you be open to change package.json's devDependencies to dually accept "^3.0.0 || ^4.0.0-alpha.4"
instead of just ´"^3.0.0"`?
If you want, I'd gladly contribute to this update and fix the typings of applyEncryptionMiddleware()
but I'm currently having issues to build the project (see #40).
(There's some details on how make them work together in a dexie issue at dexie/Dexie.js#1604 (comment))
What would be the best strategy to have different records encrypted with different keys?
Is that possible? Or do I need to create separate db for each application user?
Thanks
Thank you for developing this nice add-on.
Could you please provide TypeScript type definitions as soon as possible?
Currently the package is not usable at all in our project. Tried to create a .d.ts but facing many issues on trying to get it to work.
There's a ticket posted to Dexie.js: dexie/Dexie.js#1621
Please let me know if I can do anything to troubleshoot it and fix it. I'm still having trouble with #40 to contribute to this library.
Is this library still maintained? If not, let me know how I can help to maintain it - it's becoming popular and vital for many dexie users.
Am trying to break my db code design into tow exports, but i never get values back.
import Dexie from 'dexie'
import encrypt, { cryptoOptions } from 'dexie-encrypted';
const dd = new Dexie('FriendsDB')
dd.version(1).stores({
friends: ' ++ ',
})
export var initDb = async ({string}) =>{
const binary_string = string;
const len = binary_string.length;
const cryptoKey = new Uint8Array(len);
for (var i = 0; i < len; i++) {
cryptoKey[i] = binary_string.charCodeAt(i);
}
encrypt(dd, cryptoKey, {
friends: cryptoOptions.NON_INDEXED_FIELDS,
});
}
export var db = dd
My aim is to init the db with string coming from server passed to the initDb method from my Vuex login action, then store data using db import, later on fetch data using db export again with vuex but i get the keys only without values.
Am i doing something wrong please advice.
I know it's shit browser but would it be possible to include ES5 compiled version as well. Still have to support it
Migrating from 1.2.2
encrypt(
this.db,k,{ audit: encrypt.NON_INDEXED_FIELDS});
}
To 2.0.0
applyEncryptionMiddleware(
this.db,k,{ audit: encrypt.NON_INDEXED_FIELDS}, {});
}
Error in Angular
Argument of type '{ audit: "NON_INDEXED_FIELDS"; }' is not assignable to parameter of type 'Partial<{ readonly name: never; readonly tables: never; readonly verno: never; readonly vip: never; readonly _allTables: never; readonly core: never; _createTrans
action: never; _dbSchema: never; ... 18 more ...; Collection: never; }>'.
Object literal may only specify known properties, and 'audit' does not exist in type 'Partial<{ readonly name: never; readonly tables: never; readonly verno: never; readonly vip: never; readonly _allTables: never; readonly core: never; _createTransaction: never; _dbSchema: never; ... 18 more ...; Collection: never
; }>'
I am following exact same procedure mentioned in docs, but still it is not allowing me to assign value
Hi! Thanks for this very interesting library. I've got the impression through issues over the years that this is really something that people need. And also really nice that it is designed to work with almost zero config.
However, when I was trying it out on both Dexie 2.x and 3.x I get the same error. I might be missing something. But the error I get is on line 160 where it expects a property db._encryptionSettings that is not defined. Tried to track it down but I couldn't find the place where it was supposed to be set.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.