From eb209c179f2369e001af3889ae0270289d5ab4a9 Mon Sep 17 00:00:00 2001 From: Benjamin Klaus Date: Fri, 30 Jan 2026 11:25:38 +0100 Subject: [PATCH 1/4] #748 encrypt newly saved objects using username as salt --- src/js/service/data/encryptionService.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/js/service/data/encryptionService.js b/src/js/service/data/encryptionService.js index 9d8343c91..9b6ab2a85 100644 --- a/src/js/service/data/encryptionService.js +++ b/src/js/service/data/encryptionService.js @@ -43,9 +43,10 @@ encryptionService.encryptObject = function (object) { let jsonString = JSON.stringify(object); let shortJsonString = JSON.stringify(dataUtil.removeLongPropertyValues(object)); let shortVersionDifferent = jsonString !== shortJsonString; - encryptedObject.encryptedDataBase64 = encryptionService.encryptString(jsonString, _encryptionSalts[0]); + let salt = localStorageService.getAutologinOrActiveUser(); + encryptedObject.encryptedDataBase64 = encryptionService.encryptString(jsonString, salt); encryptedObject.encryptedDataBase64Short = shortVersionDifferent - ? encryptionService.encryptString(shortJsonString, _encryptionSalts[0]) + ? encryptionService.encryptString(shortJsonString, salt) : null; return encryptedObject; }; From 2cb80a9ebd91fc591a7b8a861a52f84d5bc0e13d Mon Sep 17 00:00:00 2001 From: Benjamin Klaus Date: Fri, 30 Jan 2026 11:26:32 +0100 Subject: [PATCH 2/4] #748 moving to new data model version 7 which uses username as salt for encryption --- src/js/service/data/convertServiceDb.js | 7 +++++++ src/js/util/constants.js | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/js/service/data/convertServiceDb.js b/src/js/service/data/convertServiceDb.js index b548fd654..80338831c 100644 --- a/src/js/service/data/convertServiceDb.js +++ b/src/js/service/data/convertServiceDb.js @@ -246,6 +246,13 @@ function getModelConversionFunctions(objectModelVersion) { object.modelVersion = modelUtil.getModelVersionString(); return object; }); + case 6: + filterFns.push(function (object, filterOptions) { + // fn from V6 to V7 + // now using username as encryption salt instead of metadata.id + object.modelVersion = modelUtil.getModelVersionString(); + return object; + }); } return filterFns; } diff --git a/src/js/util/constants.js b/src/js/util/constants.js index a6b0a18e8..9b6bc8e48 100644 --- a/src/js/util/constants.js +++ b/src/js/util/constants.js @@ -1,7 +1,7 @@ let constants = {}; constants.ELEMENT_EVENT_ID = 'ELEMENT_EVENT_ID'; -constants.MODEL_VERSION = '{"major": 6, "minor": 0, "patch": 0}'; +constants.MODEL_VERSION = '{"major": 7, "minor": 0, "patch": 0}'; constants.MODEL_VERSION_LOCAL = '{"major": 1, "minor": 0, "patch": 0}'; constants.MODEL_VERSION_CHANGED_TO_USERNAME_AS_SALT = 7; From a9d15259936b5e1cdc4fe7e38cca07a32f3607cf Mon Sep 17 00:00:00 2001 From: Benjamin Klaus Date: Fri, 30 Jan 2026 12:50:13 +0100 Subject: [PATCH 3/4] #748 adapted tests to reflect new encryption behaviour (username is salt) --- src/js/service/data/encryptionService.test.js | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/js/service/data/encryptionService.test.js b/src/js/service/data/encryptionService.test.js index f18bae72a..17856f8f2 100644 --- a/src/js/service/data/encryptionService.test.js +++ b/src/js/service/data/encryptionService.test.js @@ -1,6 +1,8 @@ import { encryptionService } from './encryptionService'; import { EncryptedObject } from '../../model/EncryptedObject'; import { dataUtil } from '../../util/dataUtil'; +import { localStorageService } from './localStorageService'; +import { constants } from '../../util/constants'; jest.mock('../../externals/sjcl'); jest.mock('../../model/EncryptedObject'); @@ -14,6 +16,7 @@ let MODEL_NAME = 'MODEL_NAME'; let DEFAULT_PASSWORD = 'DEFAULT_PASSWORD'; let DEFAULT_SALT = 'DEFAULT_SALT'; let DEFAULT_ENC_KEY = DEFAULT_SALT + DEFAULT_PASSWORD; +let NEW_ENC_KEY = localStorageService.getAutologinOrActiveUser() + DEFAULT_PASSWORD; test('encryptionService.encryptObject - Test 0', () => { let object = { data: 'testdata' }; @@ -29,7 +32,7 @@ test('encryptionService.encryptObject - Test 1', () => { encryptionService.setEncryptionProperties(DEFAULT_PASSWORD, DEFAULT_SALT); let result = encryptionService.encryptObject(object); expect(result instanceof EncryptedObject).toBeTruthy(); - expect(result.encryptedDataBase64).toEqual(DEFAULT_ENC_KEY + json); + expect(result.encryptedDataBase64).toEqual(NEW_ENC_KEY + json); expect(result.encryptedDataBase64Short).toEqual(null); }); @@ -45,7 +48,7 @@ test('encryptionService.encryptObject - Test 2', () => { id: ID, _id: ID, _rev: REV, - encryptedDataBase64: DEFAULT_ENC_KEY + JSON.stringify(object), + encryptedDataBase64: NEW_ENC_KEY + JSON.stringify(object), encryptedDataBase64Short: null }; encryptionService.setEncryptionProperties(DEFAULT_PASSWORD, DEFAULT_SALT); @@ -62,7 +65,7 @@ test('encryptionService.encryptObject - Test 3', () => { encryptionService.setEncryptionProperties(encryptionKey, DEFAULT_SALT); let result = encryptionService.encryptObject(object); expect(result instanceof EncryptedObject).toBeTruthy(); - expect(result.encryptedDataBase64).toEqual(DEFAULT_SALT + encryptionKey + json); + expect(result.encryptedDataBase64).toEqual(localStorageService.getAutologinOrActiveUser() + encryptionKey + json); expect(result.encryptedDataBase64Short).toEqual(null); }); @@ -80,7 +83,7 @@ test('encryptionService.encryptObject - Test 4', () => { id: ID, _id: ID, _rev: REV, - encryptedDataBase64: DEFAULT_SALT + encryptionKey + JSON.stringify(object), + encryptedDataBase64: localStorageService.getAutologinOrActiveUser() + encryptionKey + JSON.stringify(object), encryptedDataBase64Short: null }; encryptionService.setEncryptionProperties(encryptionKey, DEFAULT_SALT); @@ -109,8 +112,8 @@ test('encryptionService.encryptObject - shortening 1', () => { id: ID, _id: ID, _rev: REV, - encryptedDataBase64: DEFAULT_SALT + encryptionKey + JSON.stringify(object), - encryptedDataBase64Short: DEFAULT_SALT + encryptionKey + JSON.stringify(objectShortened) + encryptedDataBase64: localStorageService.getAutologinOrActiveUser() + encryptionKey + JSON.stringify(object), + encryptedDataBase64Short: localStorageService.getAutologinOrActiveUser() + encryptionKey + JSON.stringify(objectShortened) }; encryptionService.setEncryptionProperties(encryptionKey, DEFAULT_SALT); let result = encryptionService.encryptObject(object); @@ -120,16 +123,19 @@ test('encryptionService.encryptObject - shortening 1', () => { test('encryptionService.decryptObject - shortening', () => { //with password -> real encryption + EncryptedObject.prototype.modelVersion = '{"major": 7, "minor": 0, "patch": 0}'; // newly created instances should have this modelVersion let encryptionKey = 'mykey'; let object = { data: getLongData(501), modelName: MODEL_NAME, + modelVersion: constants.MODEL_VERSION, id: ID, _rev: REV }; let objectShortened = { data: dataUtil.getDefaultRemovedPlaceholder(), modelName: MODEL_NAME, + modelVersion: constants.MODEL_VERSION, id: ID, _rev: REV }; @@ -141,6 +147,7 @@ test('encryptionService.decryptObject - shortening', () => { test('encryptionService.decryptObject - shortening, no short version', () => { //with password -> real encryption + EncryptedObject.prototype.modelVersion = '{"major": 7, "minor": 0, "patch": 0}'; // newly created instances should have this modelVersion let encryptionKey = 'mykey'; let object = { data: getLongData(10), @@ -155,6 +162,7 @@ test('encryptionService.decryptObject - shortening, no short version', () => { test('encryptionService.encryptObject - shortening 2, below threshold', () => { //with password -> real encryption + EncryptedObject.prototype.modelVersion = '{"major": 7, "minor": 0, "patch": 0}'; // newly created instances should have this modelVersion let encryptionKey = 'mykey'; let object = { data: getLongData(500), @@ -167,7 +175,7 @@ test('encryptionService.encryptObject - shortening 2, below threshold', () => { id: ID, _id: ID, _rev: REV, - encryptedDataBase64: DEFAULT_SALT + encryptionKey + JSON.stringify(object), + encryptedDataBase64: localStorageService.getAutologinOrActiveUser() + encryptionKey + JSON.stringify(object), encryptedDataBase64Short: null }; encryptionService.setEncryptionProperties(encryptionKey, DEFAULT_SALT); From fb3c3c280f54fc8c521fc10c534117b27582f4f8 Mon Sep 17 00:00:00 2001 From: Benjamin Klaus Date: Fri, 30 Jan 2026 14:50:00 +0100 Subject: [PATCH 4/4] #748 added logs to check which versions are encrypted and decrypted --- src/js/service/data/encryptionService.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/js/service/data/encryptionService.js b/src/js/service/data/encryptionService.js index 9b6ab2a85..0d4d49efd 100644 --- a/src/js/service/data/encryptionService.js +++ b/src/js/service/data/encryptionService.js @@ -48,6 +48,7 @@ encryptionService.encryptObject = function (object) { encryptedObject.encryptedDataBase64Short = shortVersionDifferent ? encryptionService.encryptString(shortJsonString, salt) : null; + log.warn("encrypted data with version", encryptedObject.modelVersion); return encryptedObject; }; @@ -76,6 +77,7 @@ encryptionService.decryptObjects = function (encryptedObjects, options) { let decryptedString = null; let decryptedObject = null; let salts = _encryptionSalts; + log.warn("decrypt version", encryptedObject.modelVersion); if (modelUtil.getMajorVersion(encryptedObject) >= constants.MODEL_VERSION_CHANGED_TO_USERNAME_AS_SALT) { let username = localStorageService.getAutologinOrActiveUser(); salts = [username].concat(_encryptionSalts);