Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,22 @@ The helper APIs interpolate table and column names into SQL; use trusted identif

---

## Encryption

Database encryption is supported through [SQLite Encryption Extension](https://sqlite.org/see) (SEE).

As SEE is a paid product, you need to patch the files `react-native-nitro-sqlite/cpp/sqlite/sqlite3.c` and `react-native-nitro-sqlite/cpp/sqlite/sqlite3.h` after installation using `bun patch react-native-nitro-sqlite`. Replace them with the `sqlite.h` and `sqlite3-see-<algorithm>.c` files from the SEE sources.

In addition, the [pre-processor flag](#enable-compile-time-options) `SQLITE_ENABLE_SEE` needs to be specified.

You can then use encryption, by passing an encryption key when opening the database

```typescript
import {open} from 'react-native-nitro-sqlite'

const db = open({name: 'myDb.sqlite', encryptionKey: 'SUPER_SECURE_ENCRYPTION_KEY'})
```

# TypeORM

You can use this package as a TypeORM driver. Because of Metro and Node resolution, TypeORM’s `package.json` must be exposed and the driver aliased.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const std::string NITRO_SQLITE_EXCEPTION_PREFIX = "[NativeNitroSQLiteException]"
enum NitroSQLiteExceptionType {
UnknownError,
DatabaseCannotBeOpened,
EncryptionNotEnabled,
DatabaseCannotBeDecrypted,
DatabaseNotOpen,
UnableToAttachToDatabase,
SqlExecutionError,
Expand All @@ -20,6 +22,8 @@ enum NitroSQLiteExceptionType {
inline std::unordered_map<NitroSQLiteExceptionType, std::string> exceptionTypeStrings = {
{UnknownError, "UnknownError"},
{DatabaseCannotBeOpened, "DatabaseCannotBeOpened"},
{EncryptionNotEnabled, "EncryptionNotEnabled"},
{DatabaseCannotBeDecrypted, "DatabaseCannotBeDecrypted"},
{DatabaseNotOpen, "DatabaseNotOpen"},
{UnableToAttachToDatabase, "UnableToAttachToDatabase"},
{SqlExecutionError, "SqlExecutionError"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ const std::string getDocPath(const std::optional<std::string>& location) {
return tempDocPath;
}

void HybridNitroSQLite::open(const std::string& dbName, const std::optional<std::string>& location) {
void HybridNitroSQLite::open(const std::string& dbName, const std::optional<std::string>& location, const std::optional<std::string>& encryptionKey) {
const auto docPath = getDocPath(location);
sqliteOpenDb(dbName, docPath);
sqliteOpenDb(dbName, docPath, encryptionKey);
}

void HybridNitroSQLite::close(const std::string& dbName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class HybridNitroSQLite : public HybridNitroSQLiteSpec {

public:
// Methods
void open(const std::string& dbName, const std::optional<std::string>& location) override;
void open(const std::string& dbName, const std::optional<std::string>& location, const std::optional<std::string>& encryptionKey) override;

void close(const std::string& dbName) override;

Expand Down
16 changes: 14 additions & 2 deletions packages/react-native-nitro-sqlite/cpp/operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,21 @@ void sqliteOpenDb(const std::string& dbName, const std::string& docPath) {

if (exit != SQLITE_OK) {
throw NitroSQLiteException(NitroSQLiteExceptionType::DatabaseCannotBeOpened, sqlite3_errmsg(db));
} else {
dbMap[dbName] = db;
}

if (encryptionKey.has_value()) {
#ifdef SQLITE_ENABLE_SEE
exit = sqlite3_key_v2(db, "main", encryptionKey.value().c_str(), -1);

if (exit != SQLITE_OK) {
throw NitroSQLiteException(NitroSQLiteExceptionType::DatabaseCannotBeDecrypted, sqlite3_errmsg(db));
}
#else
throw NitroSQLiteException(NitroSQLiteExceptionType::EncryptionNotEnabled, "Enable encryption by specifying SQLITE_ENABLE_SEE pre-processor flag and replacing sqlite.h / sqlite.c.");
#endif
}

dbMap[dbName] = db;
}

void sqliteCloseDb(const std::string& dbName) {
Expand Down
6 changes: 5 additions & 1 deletion packages/react-native-nitro-sqlite/cpp/operations.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
#pragma once

#ifdef SQLITE_ENABLE_SEE
#define SQLITE_HAS_CODEC 1 // Enable SQLite encryption support
#endif

#include "hybridObjects/HybridNitroSQLiteQueryResult.hpp"
#include "types.hpp"

namespace margelo::rnnitrosqlite {

void sqliteOpenDb(const std::string& dbName, const std::string& docPath);
void sqliteOpenDb(const std::string& dbName, const std::string& docPath, const std::optional<std::string>& encryptionKey);

void sqliteCloseDb(const std::string& dbName);

Expand Down
6 changes: 5 additions & 1 deletion packages/react-native-nitro-sqlite/src/operations/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ export function open(
options: NitroSQLiteConnectionOptions,
): NitroSQLiteConnection {
try {
HybridNitroSQLite.open(options.name, options.location)
HybridNitroSQLite.open(
options.name,
options.location,
options.encryptionKey,
)
openDatabaseQueue(options.name)
} catch (error) {
throw NitroSQLiteError.fromError(error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface NitroSQLite
ios: 'c++'
android: 'c++'
}> {
open(dbName: string, location?: string): void
open(dbName: string, location?: string, encryptionKey?: string): void
close(dbName: string): void
drop(dbName: string, location?: string): void
attach(
Expand Down
1 change: 1 addition & 0 deletions packages/react-native-nitro-sqlite/src/typeORM.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const typeORMDriver = {
options: {
name: string
location?: string
encryptionKey?: string
},
ok: (db: TypeOrmNitroSQLiteConnection) => void,
fail: (msg: string) => void,
Expand Down
1 change: 1 addition & 0 deletions packages/react-native-nitro-sqlite/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { NitroSQLiteQueryResult } from './specs/NitroSQLiteQueryResult.nitr
export interface NitroSQLiteConnectionOptions {
name: string
location?: string
encryptionKey?: string
}

export interface NitroSQLiteConnection {
Expand Down