From 7ee4850fd73f6e6030afb55c13a1717566ad6a81 Mon Sep 17 00:00:00 2001 From: Mugi Khan Date: Thu, 12 Dec 2024 14:57:39 +0200 Subject: [PATCH] - Add README instructions - Pass encryptionKey to adapter and open factory - Cleanup --- packages/web/README.md | 48 +++++++++++++++++++ .../adapters/wa-sqlite/WASQLiteConnection.ts | 2 +- .../adapters/wa-sqlite/WASQLiteDBAdapter.ts | 4 +- .../adapters/wa-sqlite/WASQLiteOpenFactory.ts | 5 +- packages/web/src/db/adapters/web-sql-flags.ts | 12 +++++ 5 files changed, 66 insertions(+), 5 deletions(-) diff --git a/packages/web/README.md b/packages/web/README.md index 4d89f64d..951bc759 100644 --- a/packages/web/README.md +++ b/packages/web/README.md @@ -28,6 +28,54 @@ Install it in your app with: npm install @journeyapps/wa-sqlite ``` +### Encryption with Multiple Ciphers + +To enable encryption you need to specify an encryption key when instantiating the PowerSync database. + +> The PowerSync Web SDK uses the ChaCha20 cipher algorithm by [default](https://utelle.github.io/SQLite3MultipleCiphers/docs/ciphers/cipher_chacha20/). + +```typescript +export const db = new PowerSyncDatabase({ + // The schema you defined + schema: AppSchema, + database: { + // Filename for the SQLite database — it's important to only instantiate one instance per file. + dbFilename: 'powersync.db' + // Optional. Directory where the database file is located.' + // dbLocation: 'path/to/directory' + }, + // Encryption key for the database. + encryptionKey: 'your-encryption-key' +}); + +// If you are using a custom WASQLiteOpenFactory, you need specify the encryption key inside the factory construtor +export const db = new PowerSyncDatabase({ + schema: AppSchema, + database: new WASQLiteOpenFactory({ + dbFilename: 'examplsw1se112.db', + vfs: WASQLiteVFS.OPFSCoopSyncVFS, + // Encryption key for the database. + encryptionKey: 'your-encryption-key' + flags: { + enableMultiTabs: typeof SharedWorker !== 'undefined' + } + }) +}); +// If you are using a custom WASQLiteDBAdapter, you need specify the encryption key inside the factory construtor +export const db = new PowerSyncDatabase({ + schema: AppSchema, + database: new WASQLiteDBAdapter({ + dbFilename: 'examplsw1se112.db', + vfs: WASQLiteVFS.OPFSCoopSyncVFS, + // Encryption key for the database. + encryptionKey: 'your-encryption-key' + flags: { + enableMultiTabs: typeof SharedWorker !== 'undefined' + } + }) +}); +``` + ## Webpack See the [example Webpack config](https://github.com/powersync-ja/powersync-js/blob/main/demos/example-webpack/webpack.config.js) for details on polyfills and requirements. diff --git a/packages/web/src/db/adapters/wa-sqlite/WASQLiteConnection.ts b/packages/web/src/db/adapters/wa-sqlite/WASQLiteConnection.ts index a1cba8e8..4c8d3a95 100644 --- a/packages/web/src/db/adapters/wa-sqlite/WASQLiteConnection.ts +++ b/packages/web/src/db/adapters/wa-sqlite/WASQLiteConnection.ts @@ -178,7 +178,7 @@ export class WASqliteConnection } protected async executeEncryptionPragma(): Promise { - if (this.options.encryptionKey && this._dbP) { + if (this.options.encryptionKey) { await this.executeSingleStatement(`PRAGMA key = "${this.options.encryptionKey}"`); } return; diff --git a/packages/web/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts b/packages/web/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts index 8e8289f3..2c96a00f 100644 --- a/packages/web/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts +++ b/packages/web/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts @@ -52,7 +52,8 @@ export class WASQLiteDBAdapter extends LockedAsyncDatabaseAdapter { baseConnection: await remote({ ...options, temporaryStorage: temporaryStorage ?? TemporaryStorageOption.MEMORY, - flags: resolveWebPowerSyncFlags(options.flags) + flags: resolveWebPowerSyncFlags(options.flags), + encryptionKey: options.encryptionKey }) }); } @@ -64,6 +65,7 @@ export class WASQLiteDBAdapter extends LockedAsyncDatabaseAdapter { temporaryStorage, logger: options.logger, vfs: options.vfs, + encryptionKey: options.encryptionKey, worker: options.worker }); return openFactory.openConnection(); diff --git a/packages/web/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts b/packages/web/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts index 8638881a..f0feab0c 100644 --- a/packages/web/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +++ b/packages/web/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts @@ -10,12 +10,10 @@ import { WASqliteConnection, WASQLiteVFS } from './WASQLiteConnection'; export interface WASQLiteOpenFactoryOptions extends WebSQLOpenFactoryOptions { vfs?: WASQLiteVFS; - encryptionKey?: string; } export interface ResolvedWASQLiteOpenFactoryOptions extends ResolvedWebSQLOpenOptions { vfs: WASQLiteVFS; - encryptionKey?: string; } /** * Opens a SQLite connection using WA-SQLite. @@ -60,7 +58,8 @@ export class WASQLiteOpenFactory extends AbstractWebSQLOpenFactory { optionsDbWorker({ ...this.options, temporaryStorage, - flags: this.resolvedFlags + flags: this.resolvedFlags, + encryptionKey }) ) : openWorkerDatabasePort(this.options.dbFilename, enableMultiTabs, optionsDbWorker, this.waOptions.vfs); diff --git a/packages/web/src/db/adapters/web-sql-flags.ts b/packages/web/src/db/adapters/web-sql-flags.ts index abad37bc..f2036f0e 100644 --- a/packages/web/src/db/adapters/web-sql-flags.ts +++ b/packages/web/src/db/adapters/web-sql-flags.ts @@ -46,6 +46,12 @@ export interface ResolvedWebSQLOpenOptions extends SQLOpenOptions { * Setting this to `FILESYSTEM` can cause issues with larger queries or datasets. */ temporaryStorage: TemporaryStorageOption; + + /** + * Encryption key for the database. + * If set, the database will be encrypted using ChaCha20. + */ + encryptionKey?: string; } export enum TemporaryStorageOption { @@ -73,6 +79,12 @@ export interface WebSQLOpenFactoryOptions extends SQLOpenOptions { * Setting this to `FILESYSTEM` can cause issues with larger queries or datasets. */ temporaryStorage?: TemporaryStorageOption; + + /** + * Encryption key for the database. + * If set, the database will be encrypted using ChaCha20. + */ + encryptionKey?: string; } export function isServerSide() {