Page MenuHomePhorge

D7186.1765043680.diff
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

D7186.1765043680.diff

diff --git a/web/database/utils/constants.js b/web/database/utils/constants.js
--- a/web/database/utils/constants.js
+++ b/web/database/utils/constants.js
@@ -4,3 +4,5 @@
export const SQLITE_ENCRYPTION_KEY = 'encryptionKey';
export const CURRENT_USER_ID_KEY = 'current_user_id';
+
+export const DB_PERSIST_THROTTLE_WAIT_MS = 300;
diff --git a/web/database/worker/db-worker.js b/web/database/worker/db-worker.js
--- a/web/database/worker/db-worker.js
+++ b/web/database/worker/db-worker.js
@@ -1,6 +1,7 @@
// @flow
import localforage from 'localforage';
+import _throttle from 'lodash/throttle.js';
import initSqlJs, { type SqliteDatabase } from 'sql.js';
import type {
@@ -32,10 +33,15 @@
} from '../queries/storage-engine-queries.js';
import {
CURRENT_USER_ID_KEY,
+ DB_PERSIST_THROTTLE_WAIT_MS,
SQLITE_CONTENT,
SQLITE_ENCRYPTION_KEY,
} from '../utils/constants.js';
-import { generateDatabaseCryptoKey } from '../utils/worker-crypto-utils.js';
+import {
+ decryptDatabaseFile,
+ encryptDatabaseFile,
+ generateDatabaseCryptoKey,
+} from '../utils/worker-crypto-utils.js';
const localforageConfig: PartialConfig = {
driver: localforage.INDEXEDDB,
@@ -47,9 +53,26 @@
localforage.config(localforageConfig);
let sqliteDb: ?SqliteDatabase = null;
+let encryptionKey: ?CryptoKey = null;
async function initDatabase(sqljsFilePath: string, sqljsFilename: ?string) {
- const content = await localforage.getItem(SQLITE_CONTENT);
+ encryptionKey = await localforage.getItem(SQLITE_ENCRYPTION_KEY);
+ if (!encryptionKey) {
+ const cryptoKey = await generateDatabaseCryptoKey();
+ await localforage.setItem(SQLITE_ENCRYPTION_KEY, cryptoKey);
+ }
+
+ const encryptedContent = await localforage.getItem(SQLITE_CONTENT);
+
+ let dbContent = null;
+ try {
+ if (encryptionKey && encryptedContent) {
+ dbContent = await decryptDatabaseFile(encryptedContent, encryptionKey);
+ }
+ } catch (e) {
+ console.error('Error while decrypting content, clearing database content');
+ await localforage.removeItem(SQLITE_CONTENT);
+ }
const locateFile = defaultFilename => {
if (sqljsFilename) {
@@ -61,11 +84,15 @@
locateFile,
});
- if (content) {
- sqliteDb = new SQL.Database(new Uint8Array(content));
+ if (dbContent) {
+ sqliteDb = new SQL.Database(dbContent);
+ console.info(
+ 'Database exists and is properly encrypted, using persisted data',
+ );
} else {
sqliteDb = new SQL.Database();
setupSQLiteDB(sqliteDb);
+ console.info('Creating fresh database');
}
const dbVersion = getSQLiteDBVersion(sqliteDb);
@@ -104,6 +131,25 @@
};
}
+async function persist() {
+ if (!sqliteDb) {
+ throw new Error('Database not initialized');
+ }
+
+ if (!encryptionKey) {
+ encryptionKey = await localforage.getItem(SQLITE_ENCRYPTION_KEY);
+ }
+
+ const dbData = sqliteDb.export();
+ if (!encryptionKey) {
+ throw new Error('Encryption key is missing');
+ }
+ const encryptedData = await encryptDatabaseFile(dbData, encryptionKey);
+ await localforage.setItem(SQLITE_CONTENT, encryptedData);
+}
+
+const throttledPersist = _throttle(persist, DB_PERSIST_THROTTLE_WAIT_MS);
+
async function processAppRequest(
message: WorkerRequestMessage,
): Promise<?WorkerResponseMessage> {
@@ -157,19 +203,23 @@
if (draftStoreOperations) {
processDraftStoreOperations(draftStoreOperations);
}
+ throttledPersist();
return;
} else if (message.type === workerRequestMessageTypes.SET_CURRENT_USER_ID) {
setMetadata(sqliteDb, CURRENT_USER_ID_KEY, message.userID);
+ throttledPersist();
return;
} else if (
message.type === workerRequestMessageTypes.SET_PERSIST_STORAGE_ITEM
) {
setPersistStorageItem(sqliteDb, message.key, message.item);
+ throttledPersist();
return;
} else if (
message.type === workerRequestMessageTypes.REMOVE_PERSIST_STORAGE_ITEM
) {
removePersistStorageItem(sqliteDb, message.key);
+ throttledPersist();
return;
}

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 6, 5:54 PM (20 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5839925
Default Alt Text
D7186.1765043680.diff (3 KB)

Event Timeline