mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	support encryption for files, closes #60
This commit is contained in:
		| @@ -329,7 +329,8 @@ const noteEditor = (function() { | ||||
|         const url = new URL(window.location.href); | ||||
|         const host = url.protocol + "//" + url.hostname + ":" + url.port; | ||||
|  | ||||
|         const downloadUrl = "/api/attachments/download/" + getCurrentNoteId(); | ||||
|         const downloadUrl = "/api/attachments/download/" + getCurrentNoteId() | ||||
|             + "?protectedSessionId=" + encodeURIComponent(protected_session.getProtectedSessionId()); | ||||
|  | ||||
|         return host + downloadUrl; | ||||
|     } | ||||
|   | ||||
| @@ -6,6 +6,7 @@ const sql = require('../../services/sql'); | ||||
| const auth = require('../../services/auth'); | ||||
| const notes = require('../../services/notes'); | ||||
| const attributes = require('../../services/attributes'); | ||||
| const protected_session = require('../../services/protected_session'); | ||||
| const multer = require('multer')(); | ||||
| const wrap = require('express-promise-wrap').wrap; | ||||
|  | ||||
| @@ -44,9 +45,21 @@ router.post('/upload/:parentNoteId', auth.checkApiAuthOrElectron, multer.single( | ||||
| router.get('/download/:noteId', auth.checkApiAuthOrElectron, wrap(async (req, res, next) => { | ||||
|     const noteId = req.params.noteId; | ||||
|     const note = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]); | ||||
|     const protectedSessionId = req.query.protectedSessionId; | ||||
|  | ||||
|     if (!note) { | ||||
|         return res.status(404).send(`Note ${parentNoteId} doesn't exist.`); | ||||
|         return res.status(404).send(`Note ${noteId} doesn't exist.`); | ||||
|     } | ||||
|  | ||||
|     if (note.isProtected) { | ||||
|         const dataKey = protected_session.getDataKeyForProtectedSessionId(protectedSessionId); | ||||
|  | ||||
|         if (!dataKey) { | ||||
|             res.status(401).send("Protected session not available"); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         protected_session.decryptNote(dataKey, note); | ||||
|     } | ||||
|  | ||||
|     const attributeMap = await attributes.getNoteAttributeMap(noteId); | ||||
|   | ||||
| @@ -88,7 +88,7 @@ function noteTitleIv(iv) { | ||||
|     return "0" + iv; | ||||
| } | ||||
|  | ||||
| function noteTextIv(iv) { | ||||
| function noteContentIv(iv) { | ||||
|     return "1" + iv; | ||||
| } | ||||
|  | ||||
| @@ -97,5 +97,5 @@ module.exports = { | ||||
|     decrypt, | ||||
|     decryptString, | ||||
|     noteTitleIv, | ||||
|     noteTextIv | ||||
|     noteContentIv | ||||
| }; | ||||
| @@ -148,10 +148,14 @@ async function protectNoteHistory(noteId, dataKey, protect, sourceId) { | ||||
| async function saveNoteHistory(noteId, dataKey, sourceId, nowStr) { | ||||
|     const oldNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]); | ||||
|  | ||||
|     if (oldNote.type === 'file') { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (oldNote.isProtected) { | ||||
|         protected_session.decryptNote(dataKey, oldNote); | ||||
|  | ||||
|         note.isProtected = false; | ||||
|         oldNote.isProtected = false; | ||||
|     } | ||||
|  | ||||
|     const newNoteRevisionId = utils.newNoteRevisionId(); | ||||
| @@ -217,7 +221,21 @@ async function saveNoteImages(noteId, noteText, sourceId) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function loadFile(noteId, newNote, dataKey) { | ||||
|     const oldNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]); | ||||
|  | ||||
|     if (oldNote.isProtected) { | ||||
|         await protected_session.decryptNote(dataKey, oldNote); | ||||
|     } | ||||
|  | ||||
|     newNote.detail.content = oldNote.content; | ||||
| } | ||||
|  | ||||
| async function updateNote(noteId, newNote, dataKey, sourceId) { | ||||
|     if (newNote.detail.type === 'file') { | ||||
|         await loadFile(noteId, newNote, dataKey); | ||||
|     } | ||||
|  | ||||
|     if (newNote.detail.isProtected) { | ||||
|         await protected_session.encryptNote(dataKey, newNote.detail); | ||||
|     } | ||||
|   | ||||
| @@ -26,6 +26,10 @@ function getDataKey(obj) { | ||||
|  | ||||
|     const protectedSessionId = getProtectedSessionId(obj); | ||||
|  | ||||
|     return getDataKeyForProtectedSessionId(protectedSessionId); | ||||
| } | ||||
|  | ||||
| function getDataKeyForProtectedSessionId(protectedSessionId) { | ||||
|     if (protectedSessionId && session.protectedSessionId === protectedSessionId) { | ||||
|         return session.decryptedDataKey; | ||||
|     } | ||||
| @@ -52,7 +56,14 @@ function decryptNote(dataKey, note) { | ||||
|     } | ||||
|  | ||||
|     if (note.content) { | ||||
|         note.content = data_encryption.decryptString(dataKey, data_encryption.noteTextIv(note.noteId), note.content); | ||||
|         const contentIv = data_encryption.noteContentIv(note.noteId); | ||||
|  | ||||
|         if (note.type === 'file') { | ||||
|             note.content = data_encryption.decrypt(dataKey, contentIv, note.content); | ||||
|         } | ||||
|         else { | ||||
|             note.content = data_encryption.decryptString(dataKey, contentIv, note.content); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -76,7 +87,7 @@ function decryptNoteHistoryRow(dataKey, hist) { | ||||
|     } | ||||
|  | ||||
|     if (hist.content) { | ||||
|         hist.content = data_encryption.decryptString(dataKey, data_encryption.noteTextIv(hist.noteRevisionId), hist.content); | ||||
|         hist.content = data_encryption.decryptString(dataKey, data_encryption.noteContentIv(hist.noteRevisionId), hist.content); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -92,19 +103,20 @@ function encryptNote(dataKey, note) { | ||||
|     dataKey = getDataKey(dataKey); | ||||
|  | ||||
|     note.title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(note.noteId), note.title); | ||||
|     note.content = data_encryption.encrypt(dataKey, data_encryption.noteTextIv(note.noteId), note.content); | ||||
|     note.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(note.noteId), note.content); | ||||
| } | ||||
|  | ||||
| function encryptNoteHistoryRow(dataKey, history) { | ||||
|     dataKey = getDataKey(dataKey); | ||||
|  | ||||
|     history.title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(history.noteRevisionId), history.title); | ||||
|     history.content = data_encryption.encrypt(dataKey, data_encryption.noteTextIv(history.noteRevisionId), history.content); | ||||
|     history.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(history.noteRevisionId), history.content); | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|     setDataKey, | ||||
|     getDataKey, | ||||
|     getDataKeyForProtectedSessionId, | ||||
|     isProtectedSessionAvailable, | ||||
|     decryptNote, | ||||
|     decryptNotes, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user