diff --git a/src/entities/note.js b/src/entities/note.js index 4e61631ab..da4640379 100644 --- a/src/entities/note.js +++ b/src/entities/note.js @@ -47,7 +47,18 @@ class Note extends Entity { if (this.isProtected && this.noteId) { this.isContentAvailable = protectedSessionService.isProtectedSessionAvailable(); - protectedSessionService.decryptNote(this); + if (this.isContentAvailable) { + protectedSessionService.decryptNote(this); + } + else { + // saving ciphertexts in case we do want to update protected note outside of protected session + // (which is allowed) + this.titleCipherText = this.title; + this.contentCipherText = this.content; + + this.title = "[protected]"; + this.content = ""; + } } this.setContent(this.content); @@ -629,12 +640,21 @@ class Note extends Entity { // cannot be static! updatePojo(pojo) { if (pojo.isProtected) { - protectedSessionService.encryptNote(pojo); + if (this.isContentAvailable) { + protectedSessionService.encryptNote(pojo); + } + else { + // updating protected note outside of protected session means we will keep original ciphertexts + pojo.title = pojo.titleCipherText; + pojo.content = pojo.contentCipherText; + } } delete pojo.jsonContent; delete pojo.isContentAvailable; delete pojo.__attributeCache; + delete pojo.titleCipherText; + delete pojo.contentCipherText; } } diff --git a/src/services/data_encryption.js b/src/services/data_encryption.js index 42a77488a..dd899f077 100644 --- a/src/services/data_encryption.js +++ b/src/services/data_encryption.js @@ -26,11 +26,8 @@ function pad(data) { data = Buffer.concat([data, Buffer.from(zeros)]); } - else { - data = Buffer.from(data); - } - return data; + return Buffer.from(data); } function encrypt(key, plainText, ivLength = 13) { diff --git a/src/services/notes.js b/src/services/notes.js index aefa7d96e..7cebb2dee 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -359,18 +359,8 @@ async function deleteNote(branch) { const notDeletedBranches = await note.getBranches(); if (notDeletedBranches.length === 0) { - // maybe a bit counter-intuitively, protected notes can be deleted also outside of protected session - // this is because protected notes offer only confidentiality which makes some things simpler - e.g. deletion UI - // to allow this, we just set the isDeleted flag, otherwise saving would fail because of attempt to encrypt - // content with non-existent protected session key - // we don't reset content here, that's postponed and done later to give the user a chance to correct a mistake - await sql.execute("UPDATE notes SET isDeleted = 1 WHERE noteId = ?", [note.noteId]); - // need to manually trigger sync since it's not taken care of by note save - await syncTableService.addNoteSync(note.noteId); - - for (const noteRevision of await note.getRevisions()) { - await noteRevision.save(); - } + note.isDeleted = true; + await note.save(); for (const childBranch of await note.getChildBranches()) { await deleteNote(childBranch); diff --git a/src/services/password_encryption.js b/src/services/password_encryption.js index 903bf9e62..74002ac2d 100644 --- a/src/services/password_encryption.js +++ b/src/services/password_encryption.js @@ -14,7 +14,7 @@ async function verifyPassword(password) { async function setDataKey(password, plainTextDataKey) { const passwordDerivedKey = await myScryptService.getPasswordDerivedKey(password); - const newEncryptedDataKey = dataEncryptionService.encrypt(passwordDerivedKey, Buffer.from(plainTextDataKey)); + const newEncryptedDataKey = dataEncryptionService.encrypt(passwordDerivedKey, plainTextDataKey, 16); await optionService.setOption('encryptedDataKey', newEncryptedDataKey); } diff --git a/src/views/setup.ejs b/src/views/setup.ejs index 04ec6c748..e6447d9ba 100644 --- a/src/views/setup.ejs +++ b/src/views/setup.ejs @@ -7,7 +7,7 @@
-
+