Skip to content

Commit 701cdba

Browse files
committed
Encryption
1 parent 1dc7d76 commit 701cdba

3 files changed

Lines changed: 36 additions & 13 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ edition = "2021"
1010
crate-type = ["cdylib"]
1111

1212
[dependencies]
13-
libsql = { version = "0.9.10" }
13+
libsql = { version = "0.9.10", features = ["encryption"] }
1414
napi = { version = "2", default-features = false, features = ["napi6", "tokio_rt", "async"] }
1515
napi-derive = "2"
1616
once_cell = "1.18.0"

index.d.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ export interface Options {
99
authToken?: string
1010
syncUrl?: string
1111
syncPeriod?: number
12+
encryptionCipher?: string
13+
encryptionKey?: string
1214
}
1315
export declare function databaseSyncSync(db: Database): SyncResult
1416
export declare function databasePrepareSync(db: Database, sql: string): Statement
@@ -34,11 +36,6 @@ export declare class Database {
3436
get memory(): boolean
3537
inTransaction(): boolean
3638
prepare(sql: string): Promise<Statement>
37-
backup(): void
38-
serialize(): void
39-
function(): void
40-
aggregate(): void
41-
table(): void
4239
authorizer(rulesObj: object): void
4340
loadExtension(path: string, entryPoint?: string | undefined | null): void
4441
maxWriteReplicationIndex(): number

src/lib.rs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ extern crate napi_derive;
1010
use napi::bindgen_prelude::{Array, FromNapiValue, ToNapiValue};
1111
use napi::{Env, JsUnknown, Result, ValueType};
1212
use once_cell::sync::OnceCell;
13+
use std::str::FromStr;
1314
use std::sync::atomic::{AtomicBool, Ordering};
1415
use std::sync::Arc;
1516
use std::time::Duration;
@@ -167,6 +168,8 @@ pub struct Options {
167168
pub authToken: Option<String>,
168169
pub syncUrl: Option<String>,
169170
pub syncPeriod: Option<f64>,
171+
pub encryptionCipher: Option<String>,
172+
pub encryptionKey: Option<String>,
170173
}
171174

172175
/// Database connection.
@@ -191,23 +194,45 @@ impl Database {
191194
ensure_logger();
192195
let rt = runtime()?;
193196
let remote = is_remote_path(&path);
194-
195197
let db = if remote {
196198
let auth_token = opts
197199
.as_ref()
198200
.and_then(|o| o.authToken.as_ref())
199201
.cloned()
200202
.unwrap_or_default();
201-
202203
let builder = libsql::Builder::new_remote(path.clone(), auth_token);
203204
rt.block_on(builder.build()).map_err(Error::from)?
204205
} else if let Some(options) = &opts {
205206
if let Some(sync_url) = &options.syncUrl {
206207
let auth_token = options.authToken.as_ref().cloned().unwrap_or_default();
207208

209+
let encryption_cipher: String = opts
210+
.as_ref()
211+
.and_then(|o| o.encryptionCipher.as_ref())
212+
.cloned()
213+
.unwrap_or("aes256cbc".to_string());
214+
let cipher = libsql::Cipher::from_str(&encryption_cipher).map_err(|_| {
215+
throw_sqlite_error(
216+
"Invalid encryption cipher".to_string(),
217+
"SQLITE_INVALID_ENCRYPTION_CIPHER".to_string(),
218+
0,
219+
)
220+
})?;
221+
let encryption_key = opts
222+
.as_ref()
223+
.and_then(|o| o.encryptionKey.as_ref())
224+
.cloned()
225+
.unwrap_or("".to_string());
226+
208227
let mut builder =
209228
libsql::Builder::new_remote_replica(path.clone(), sync_url.clone(), auth_token);
210229

230+
if encryption_key.len() > 0 {
231+
let encryption_config =
232+
libsql::EncryptionConfig::new(cipher, encryption_key.into());
233+
builder = builder.encryption_config(encryption_config);
234+
}
235+
211236
if let Some(period) = options.syncPeriod {
212237
if period > 0.0 {
213238
builder = builder.sync_interval(std::time::Duration::from_secs_f64(period));
@@ -349,22 +374,23 @@ impl Database {
349374

350375
rt.block_on(async move {
351376
let conn = conn.lock().await;
352-
377+
353378
// Enable extension loading
354379
conn.load_extension_enable().map_err(Error::from)?;
355-
380+
356381
// Load the extension
357382
if let Err(err) = conn.load_extension(&path, entry_point.as_deref()) {
358383
// Disable extension loading on error
359384
let _ = conn.load_extension_disable();
360385
return Err(Error::from(err));
361386
}
362-
387+
363388
// Disable extension loading after successful load
364389
conn.load_extension_disable().map_err(Error::from)?;
365-
390+
366391
Ok(())
367-
}).map_err(|e| napi::Error::from(e))
392+
})
393+
.map_err(|e| napi::Error::from(e))
368394
}
369395

370396
#[napi]

0 commit comments

Comments
 (0)