Skip to content

Commit 8d3b513

Browse files
committed
Add new param to openSync, encryptionKey, which enables encryption
1 parent cb9ff4e commit 8d3b513

File tree

11 files changed

+116
-96
lines changed

11 files changed

+116
-96
lines changed

cpp/DBHostObject.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ void DBHostObject::auto_register_update_hook() {
140140
// | |___| (_) | | | \__ \ |_| | | |_| | (__| || (_) | |
141141
// \_____\___/|_| |_|___/\__|_| \__,_|\___|\__\___/|_|
142142
#ifdef OP_SQLITE_USE_LIBSQL
143+
// Remote connection constructor
143144
DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &url,
144145
std::string &auth_token,
145146
std::shared_ptr<react::CallInvoker> invoker)
@@ -150,15 +151,19 @@ DBHostObject::DBHostObject(jsi::Runtime &rt, std::string &url,
150151
create_jsi_functions();
151152
}
152153

154+
// Sync connection constructor
153155
DBHostObject::DBHostObject(jsi::Runtime &rt,
154156
std::shared_ptr<react::CallInvoker> invoker,
155157
std::string &db_name, std::string &path,
156158
std::string &url, std::string &auth_token,
157-
int sync_interval, bool offline)
159+
int sync_interval, bool offline,
160+
std::string &encryption_key)
158161
: db_name(db_name), invoker(std::move(invoker)), rt(rt) {
162+
159163
_thread_pool = std::make_shared<ThreadPool>();
164+
160165
db = opsqlite_libsql_open_sync(db_name, path, url, auth_token,
161-
sync_interval, offline);
166+
sync_interval, offline, encryption_key);
162167

163168
create_jsi_functions();
164169
}

cpp/DBHostObject.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ class JSI_EXPORT DBHostObject : public jsi::HostObject {
5454
// Constructor for a local database with remote sync
5555
DBHostObject(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> invoker,
5656
std::string &db_name, std::string &path, std::string &url,
57-
std::string &auth_token, int sync_interval, bool offline);
57+
std::string &auth_token, int sync_interval, bool offline,
58+
std::string &encryption_key);
5859
#endif
5960

6061
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;

cpp/bindings.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,15 @@ void install(jsi::Runtime &rt,
112112
#ifdef OP_SQLITE_USE_LIBSQL
113113
auto open_remote = HOST_STATIC_FN("openRemote") {
114114
jsi::Object options = args[0].asObject(rt);
115+
115116
std::string url = options.getProperty(rt, "url").asString(rt).utf8(rt);
117+
116118
std::string auth_token =
117119
options.getProperty(rt, "authToken").asString(rt).utf8(rt);
118-
119-
std::shared_ptr<DBHostObject> db =
120-
std::make_shared<DBHostObject>(rt, url, auth_token, invoker);
120+
121+
std::shared_ptr<DBHostObject> db = std::make_shared<DBHostObject>(
122+
rt, url, auth_token, invoker);
123+
121124
return jsi::Object::createFromHostObject(rt, db);
122125
});
123126

@@ -141,6 +144,12 @@ void install(jsi::Runtime &rt,
141144
offline = options.getProperty(rt, "libsqlOffline").asBool();
142145
}
143146

147+
std::string encryption_key;
148+
if (options.hasProperty(rt, "encryptionKey")) {
149+
encryption_key =
150+
options.getProperty(rt, "encryptionKey").asString(rt).utf8(rt);
151+
}
152+
144153
std::string location;
145154
if (options.hasProperty(rt, "location")) {
146155
location =
@@ -157,7 +166,7 @@ void install(jsi::Runtime &rt,
157166
}
158167

159168
std::shared_ptr<DBHostObject> db = std::make_shared<DBHostObject>(
160-
rt, invoker, name, path, url, auth_token, sync_interval, offline);
169+
rt, invoker, name, path, url, auth_token, sync_interval, offline, encryption_key);
161170
return jsi::Object::createFromHostObject(rt, db);
162171
});
163172
#endif

cpp/libsql/bridge.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ DB opsqlite_libsql_open_sync(std::string const &name,
4040
std::string const &base_path,
4141
std::string const &url,
4242
std::string const &auth_token, int sync_interval,
43-
bool offline) {
43+
bool offline, std::string const &encryption_key) {
4444
std::string path = opsqlite_get_db_path(name, base_path);
4545

4646
int status;
@@ -52,7 +52,7 @@ DB opsqlite_libsql_open_sync(std::string const &name,
5252
.primary_url = url.c_str(),
5353
.auth_token = auth_token.c_str(),
5454
.read_your_writes = '1',
55-
.encryption_key = nullptr,
55+
.encryption_key = encryption_key.c_str(),
5656
.sync_interval = sync_interval,
5757
.with_webpki = '1',
5858
.offline = offline};

cpp/libsql/bridge.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ DB opsqlite_libsql_open_remote(std::string const &url,
4141
DB opsqlite_libsql_open_sync(std::string const &name, std::string const &path,
4242
std::string const &url,
4343
std::string const &auth_token, int sync_interval,
44-
bool offline);
44+
bool offline, std::string const &encryption_key);
4545

4646
void opsqlite_libsql_close(DB &db);
4747

docs/docs/Libsql/start.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,12 @@ const remoteDb = openSync({
3939
url: 'url',
4040
authToken: 'token',
4141
syncInterval: 1, // Optional, in seconds
42+
encryptionKey: 'my encryption key', // Optional, will encrypt the database on device. Will add overhead to your queries
4243
});
4344
```
4445

46+
Be careful when setting an encryption key as you need to keep your key secure. [Read more about React Native security](https://ospfranco.com/react-native-security-guide/).
47+
4548
## Sync Database
4649

4750
You can force a sync to your remote database by calling the `sync()` method. This is only available for `libsql` databases:

example/ios/Podfile.lock

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,75 +1958,75 @@ SPEC CHECKSUMS:
19581958
GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4
19591959
glog: 08b301085f15bcbb6ff8632a8ebaf239aae04e6a
19601960
hermes-engine: 314be5250afa5692b57b4dd1705959e1973a8ebe
1961-
op-sqlite: 3542bd9b1f45190426e95ee3873b09349be96335
1961+
op-sqlite: d58de9322037133d8da81961b1cb49fc799e2e46
19621962
RCT-Folly: e78785aa9ba2ed998ea4151e314036f6c49e6d82
19631963
RCTDeprecation: 83ffb90c23ee5cea353bd32008a7bca100908f8c
19641964
RCTRequired: eb7c0aba998009f47a540bec9e9d69a54f68136e
19651965
RCTTypeSafety: 659ae318c09de0477fd27bbc9e140071c7ea5c93
19661966
React: c2d3aa44c49bb34e4dfd49d3ee92da5ebacc1c1c
19671967
React-callinvoker: 1bdfb7549b5af266d85757193b5069f60659ef9d
1968-
React-Core: 10597593fdbae06f0089881e025a172e51d4a769
1969-
React-CoreModules: 6907b255529dd46895cf687daa67b24484a612c2
1970-
React-cxxreact: a9f5b8180d6955bc3f6a3fcd657c4d9b4d95c1f6
1968+
React-Core: 7150cf9b6a5af063b37003062689f1691e79c020
1969+
React-CoreModules: 15a85e6665d61678942da6ae485b351f4c699049
1970+
React-cxxreact: 74f9de59259ac951923f5726aa14f0398f167af9
19711971
React-debug: e74e76912b91e08d580c481c34881899ccf63da9
1972-
React-defaultsnativemodule: 11f6ee2cf69bf3af9d0f28a6253def33d21b5266
1973-
React-domnativemodule: f940bbc4fa9e134190acbf3a4a9f95621b5a8f51
1974-
React-Fabric: 6f5c357bf3a42ff11f8844ad3fc7a1eb04f4b9de
1975-
React-FabricComponents: 10e0c0209822ac9e69412913a8af1ca33573379b
1976-
React-FabricImage: f582e764072dfa4715ae8c42979a5bace9cbcc12
1972+
React-defaultsnativemodule: 628285212bbd65417d40ad6a9f8781830fda6c98
1973+
React-domnativemodule: 185d9808198405c176784aaf33403d713bd24fb7
1974+
React-Fabric: c814804affbe1952e16149ddd20256e1bccae67e
1975+
React-FabricComponents: 81ef47d596966121784afec9924f9562a29b1691
1976+
React-FabricImage: f14f371d678aa557101def954ac3ba27e48948ff
19771977
React-featureflags: d5facceff8f8f6de430e0acecf4979a9a0839ba9
1978-
React-featureflagsnativemodule: a7dd141f1ef4b7c1331af0035689fbc742a49ff4
1979-
React-graphics: 36ae3407172c1c77cea29265d2b12b90aaef6aa0
1980-
React-hermes: 9116d4e6d07abeb519a2852672de087f44da8f12
1981-
React-idlecallbacksnativemodule: ae7f5ffc6cf2d2058b007b78248e5b08172ad5c3
1982-
React-ImageManager: 9daee0dc99ad6a001d4b9e691fbf37107e2b7b54
1983-
React-jserrorhandler: 1e6211581071edaf4ecd5303147328120c73f4dc
1984-
React-jsi: 753ba30c902f3a41fa7f956aca8eea3317a44ee6
1985-
React-jsiexecutor: 47520714aa7d9589c51c0f3713dfbfca4895d4f9
1986-
React-jsinspector: cfd27107f6d6f1076a57d88c932401251560fe5f
1987-
React-jsinspectortracing: 76a7d791f3c0c09a0d2bf6f46dfb0e79a4fcc0ac
1988-
React-jsitooling: 995e826570dd58f802251490486ebd3244a037ab
1989-
React-jsitracing: 094ae3d8c123cea67b50211c945b7c0443d3e97b
1990-
React-logger: 8edfcedc100544791cd82692ca5a574240a16219
1991-
React-Mapbuffer: c3f4b608e4a59dd2f6a416ef4d47a14400194468
1992-
React-microtasksnativemodule: 054f34e9b82f02bd40f09cebd4083828b5b2beb6
1993-
react-native-http-bridge-refurbished: 1bd13b32a8e62abe61bab809c26e2dcf21256ed7
1994-
react-native-restart: 0bc732f4461709022a742bb29bcccf6bbc5b4863
1995-
React-NativeModulesApple: 2c4377e139522c3d73f5df582e4f051a838ff25e
1978+
React-featureflagsnativemodule: 96f0ab285382d95c90f663e02526a5ceefa95a11
1979+
React-graphics: 1a66ee0a3f093b125b853f6370296fadcaf6f233
1980+
React-hermes: 8b86e5f54a65ecb69cdf22b3a00a11562eda82d2
1981+
React-idlecallbacksnativemodule: 5c25ab145c602264d00cb26a397ab52e0efa031c
1982+
React-ImageManager: 15e34bd5ef1ac4a18e96660817ef70a7f99ee8c2
1983+
React-jserrorhandler: 02cdf2cd45350108be1ffd2b164578936dbbdff7
1984+
React-jsi: 6af1987cfbb1b6621664fdbf6c7b62bd4d38c923
1985+
React-jsiexecutor: 51f372998e0303585cb0317232b938d694663cbd
1986+
React-jsinspector: 3539ad976d073bfaa8a7d2fa9bef35e70e55033e
1987+
React-jsinspectortracing: e8dbacaf67c201f23052ca1c2bae2f7b84dec443
1988+
React-jsitooling: 95a34f41e3c249d42181de13b4f8d854f178ca9f
1989+
React-jsitracing: 25b029cf5cad488252d46da19dd8c4c134fd5fe4
1990+
React-logger: 368570a253f00879a1e4fea24ed4047e72e7bbf3
1991+
React-Mapbuffer: c04fcda1c6281fc0a6824c7dcc1633dd217ac1ec
1992+
React-microtasksnativemodule: ca2804a25fdcefffa0aa942aa23ab53b99614a34
1993+
react-native-http-bridge-refurbished: e2e45508ec1573999ace69a0b880eee8f0e5bab2
1994+
react-native-restart: 7595693413fe3ca15893702f2c8306c62a708162
1995+
React-NativeModulesApple: 452b86b29fae99ed0a4015dca3ad9cd222f88abf
19961996
React-oscompat: ef5df1c734f19b8003e149317d041b8ce1f7d29c
1997-
React-perflogger: 9a151e0b4c933c9205fd648c246506a83f31395d
1998-
React-performancetimeline: 5b0dfc0acba29ea0269ddb34cd6dd59d3b8a1c66
1997+
React-perflogger: 6fd2f6811533e9c19a61e855c3033eecbf4ad2a0
1998+
React-performancetimeline: abf31259d794c9274b3ea19c5016186925eec6c4
19991999
React-RCTActionSheet: a499b0d6d9793886b67ba3e16046a3fef2cdbbc3
2000-
React-RCTAnimation: cc64adc259aabc3354b73065e2231d796dfce576
2001-
React-RCTAppDelegate: 9d523da768f1c9e84c5f3b7e3624d097dfb0e16b
2002-
React-RCTBlob: e727f53eeefded7e6432eb76bd22b57bc880e5d1
2003-
React-RCTFabric: 58590aa4fdb4ad546c06a7449b486cf6844e991f
2004-
React-RCTFBReactNativeSpec: 9064c63d99e467a3893e328ba3612745c3c3a338
2005-
React-RCTImage: 7159cbdbb18a09d97ba1a611416eced75b3ccb29
2006-
React-RCTLinking: 46293afdb859bccc63e1d3dedc6901a3c04ef360
2007-
React-RCTNetwork: 4a6cd18f5bcd0363657789c64043123a896b1170
2008-
React-RCTRuntime: 5ab904fd749aa52f267ef771d265612582a17880
2009-
React-RCTSettings: 61e361dc85136d1cb0e148b7541993d2ee950ea7
2010-
React-RCTText: abd1e196c3167175e6baef18199c6d9d8ac54b4e
2011-
React-RCTVibration: 490e0dcb01a3fe4a0dfb7bc51ad5856d8b84f343
2000+
React-RCTAnimation: 2595dcb10a82216a511b54742f8c28d793852ac6
2001+
React-RCTAppDelegate: f03604b70f57c9469a84a159d8abecf793a5bcff
2002+
React-RCTBlob: e00f9b4e2f151938f4d9864cf33ebf24ac03328a
2003+
React-RCTFabric: 3945d116fd271598db262d4e6ed5691d431ed9e8
2004+
React-RCTFBReactNativeSpec: 0f4d4f0da938101f2ca9d5333a8f46e527ad2819
2005+
React-RCTImage: dac5e9f8ec476aefe6e60ee640ebc1dfaf1a4dbe
2006+
React-RCTLinking: 494b785a40d952a1dfbe712f43214376e5f0e408
2007+
React-RCTNetwork: b3d7c30cd21793e268db107dd0980cb61b3c1c44
2008+
React-RCTRuntime: a8ff419d437228e7b8a793b14f9d711e1cbb82af
2009+
React-RCTSettings: a060c7e381a3896104761b8eed7e284d95e37df3
2010+
React-RCTText: 4f272b72dbb61f390d8c8274528f9fdbff983806
2011+
React-RCTVibration: 0e5326220719aca12473d703aa46693e3b4ce67a
20122012
React-rendererconsistency: 351fdbc5c1fe4da24243d939094a80f0e149c7a1
2013-
React-renderercss: 3438814bee838ae7840a633ab085ac81699fd5cf
2014-
React-rendererdebug: 0ac2b9419ad6f88444f066d4b476180af311fb1e
2013+
React-renderercss: d333f2ada83969591100d91ec6b23ca2e17e1507
2014+
React-rendererdebug: 039e5949b72ba63c703de020701e3fd152434c61
20152015
React-rncore: 57ed480649bb678d8bdc386d20fee8bf2b0c307c
2016-
React-RuntimeApple: 8b7a9788f31548298ba1990620fe06b40de65ad7
2017-
React-RuntimeCore: e03d96fbd57ce69fd9bca8c925942194a5126dbc
2016+
React-RuntimeApple: 344a5e1105256000afabaa8df12c3e4cab880340
2017+
React-RuntimeCore: 0e48fb5e5160acc0334c7a723a42d42cef4b58b6
20182018
React-runtimeexecutor: d60846710facedd1edb70c08b738119b3ee2c6c2
2019-
React-RuntimeHermes: aab794755d9f6efd249b61f3af4417296904e3ba
2020-
React-runtimescheduler: c3cd124fa5db7c37f601ee49ca0d97019acd8788
2019+
React-RuntimeHermes: 064286a03871d932c99738e0f8ef854962ab4b99
2020+
React-runtimescheduler: e917ab17ae08c204af1ebf8f669b7e411b0220c8
20212021
React-timing: a90f4654cbda9c628614f9bee68967f1768bd6a5
2022-
React-utils: a612d50555b6f0f90c74b7d79954019ad47f5de6
2023-
ReactAppDependencyProvider: 04d5eb15eb46be6720e17a4a7fa92940a776e584
2024-
ReactCodegen: c63eda03ba1d94353fb97b031fc84f75a0d125ba
2025-
ReactCommon: 76d2dc87136d0a667678668b86f0fca0c16fdeb0
2026-
RNShare: a9f1a356b3f46e5395d9885687c296b116699176
2022+
React-utils: 51c4e71608b8133fecc9a15801d244ae7bdf3758
2023+
ReactAppDependencyProvider: d5dcc564f129632276bd3184e60f053fcd574d6b
2024+
ReactCodegen: fda99a79c866370190e162083a35602fdc314e5d
2025+
ReactCommon: 4d0da92a5eb8da86c08e3ec34bd23ab439fb2461
2026+
RNShare: a21b3cdcf22b8aa699cd54aaec8ae1c1ca709559
20272027
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
20282028
Yoga: c758bfb934100bb4bf9cbaccb52557cee35e8bdf
20292029

20302030
PODFILE CHECKSUM: 74b5ec2885cdfc97dce635b4ac32258ec9fa3179
20312031

2032-
COCOAPODS: 1.15.2
2032+
COCOAPODS: 1.16.2

example/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"node": ">=18"
6464
},
6565
"op-sqlite": {
66-
"libsql": false,
66+
"libsql": true,
6767
"sqlcipher": false,
6868
"iosSqlite": false,
6969
"fts5": true,

example/src/App.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {getDylibPath, open} from '@op-engineering/op-sqlite';
1+
import {getDylibPath, isLibsql, open} from '@op-engineering/op-sqlite';
22
import clsx from 'clsx';
33
import {useEffect, useState} from 'react';
44
import {
@@ -208,6 +208,11 @@ export default function App() {
208208
ms
209209
</Text>
210210
)}
211+
<View className="p-2">
212+
<Text className="text-white">
213+
is libsql: {isLibsql() ? 'YES' : 'NO'}
214+
</Text>
215+
</View>
211216
<Text
212217
className={clsx('font-bold flex-1 text-white p-2 mt-4', {
213218
'bg-green-500': allTestsPassed,

example/src/tests/queries.spec.ts

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -38,37 +38,33 @@ export function queriesTests() {
3838
db = null;
3939
}
4040
});
41-
// if (isLibsql()) {
42-
// itOnly('Remote open a turso database', async () => {
43-
// const remoteDb = openRemote({
44-
// url: 'libsql://foo-ospfranco.turso.io',
45-
// authToken:
46-
// 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJhIjoicnciLCJpYXQiOjE3MTY5NTc5OTUsImlkIjoiZmJkNzZmMjYtZTliYy00MGJiLTlmYmYtMDczZjFmMjdjOGY4In0.U3cAWBOvcdiqoPN3MB81sco7x8CGOjjtZ1ZEf30uo2iPcAmOuJzcnAznmDlZ6SpQd4qzuJxE4mAIoRlOkpzgBQ',
47-
// });
48-
49-
// console.log('Running select 1');
50-
// const res = await remoteDb.execute('SELECT 1');
51-
// console.log('after select 1;');
52-
53-
// expect(res.rowsAffected).to.equal(0);
54-
// });
55-
56-
// // it('Open a libsql database replicated to turso', async () => {
57-
// // const remoteDb = openSync({
58-
// // url: 'libsql://foo-ospfranco.turso.io',
59-
// // authToken:
60-
// // 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJhIjoicnciLCJpYXQiOjE3MTY5NTc5OTUsImlkIjoiZmJkNzZmMjYtZTliYy00MGJiLTlmYmYtMDczZjFmMjdjOGY4In0.U3cAWBOvcdiqoPN3MB81sco7x8CGOjjtZ1ZEf30uo2iPcAmOuJzcnAznmDlZ6SpQd4qzuJxE4mAIoRlOkpzgBQ',
61-
// // name: 'my replica',
62-
// // syncInterval: 1000,
63-
// // });
64-
65-
// // const res = await remoteDb.execute('SELECT 1');
66-
67-
// // remoteDb.sync();
68-
69-
// // expect(res.rowsAffected).to.equal(0);
70-
// // });
71-
// }
41+
42+
if (isLibsql()) {
43+
// itOnly('Remote open a turso database', async () => {
44+
// const remoteDb = openRemote({
45+
// url: 'libsql://foo-ospfranco.turso.io',
46+
// authToken:
47+
// 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJhIjoicnciLCJpYXQiOjE3MTY5NTc5OTUsImlkIjoiZmJkNzZmMjYtZTliYy00MGJiLTlmYmYtMDczZjFmMjdjOGY4In0.U3cAWBOvcdiqoPN3MB81sco7x8CGOjjtZ1ZEf30uo2iPcAmOuJzcnAznmDlZ6SpQd4qzuJxE4mAIoRlOkpzgBQ',
48+
// });
49+
// console.log('Running select 1');
50+
// const res = await remoteDb.execute('SELECT 1');
51+
// console.log('after select 1;');
52+
// expect(res.rowsAffected).to.equal(0);
53+
// });
54+
// it('Open a libsql database replicated to turso', async () => {
55+
// const remoteDb = openSync({
56+
// url: 'libsql://foo-ospfranco.turso.io',
57+
// authToken:
58+
// 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJhIjoicnciLCJpYXQiOjE3MTY5NTc5OTUsImlkIjoiZmJkNzZmMjYtZTliYy00MGJiLTlmYmYtMDczZjFmMjdjOGY4In0.U3cAWBOvcdiqoPN3MB81sco7x8CGOjjtZ1ZEf30uo2iPcAmOuJzcnAznmDlZ6SpQd4qzuJxE4mAIoRlOkpzgBQ',
59+
// name: 'my replica',
60+
// libsqlSyncInterval: 1000,
61+
// encryptionKey: 'blah',
62+
// });
63+
// const res = await remoteDb.execute('SELECT 1');
64+
// remoteDb.sync();
65+
// expect(res.rowsAffected).to.equal(0);
66+
// });
67+
}
7268

7369
it('Can create multiple connections to same db', async () => {
7470
const db2 = open({

0 commit comments

Comments
 (0)