mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 09:58:32 +02:00
support encryption for files, closes #60
This commit is contained in:
parent
19308bbfbd
commit
3b4509d833
@ -329,7 +329,8 @@ const noteEditor = (function() {
|
|||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
const host = url.protocol + "//" + url.hostname + ":" + url.port;
|
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;
|
return host + downloadUrl;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ const sql = require('../../services/sql');
|
|||||||
const auth = require('../../services/auth');
|
const auth = require('../../services/auth');
|
||||||
const notes = require('../../services/notes');
|
const notes = require('../../services/notes');
|
||||||
const attributes = require('../../services/attributes');
|
const attributes = require('../../services/attributes');
|
||||||
|
const protected_session = require('../../services/protected_session');
|
||||||
const multer = require('multer')();
|
const multer = require('multer')();
|
||||||
const wrap = require('express-promise-wrap').wrap;
|
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) => {
|
router.get('/download/:noteId', auth.checkApiAuthOrElectron, wrap(async (req, res, next) => {
|
||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
const note = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
const note = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
||||||
|
const protectedSessionId = req.query.protectedSessionId;
|
||||||
|
|
||||||
if (!note) {
|
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);
|
const attributeMap = await attributes.getNoteAttributeMap(noteId);
|
||||||
|
@ -88,7 +88,7 @@ function noteTitleIv(iv) {
|
|||||||
return "0" + iv;
|
return "0" + iv;
|
||||||
}
|
}
|
||||||
|
|
||||||
function noteTextIv(iv) {
|
function noteContentIv(iv) {
|
||||||
return "1" + iv;
|
return "1" + iv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,5 +97,5 @@ module.exports = {
|
|||||||
decrypt,
|
decrypt,
|
||||||
decryptString,
|
decryptString,
|
||||||
noteTitleIv,
|
noteTitleIv,
|
||||||
noteTextIv
|
noteContentIv
|
||||||
};
|
};
|
@ -148,10 +148,14 @@ async function protectNoteHistory(noteId, dataKey, protect, sourceId) {
|
|||||||
async function saveNoteHistory(noteId, dataKey, sourceId, nowStr) {
|
async function saveNoteHistory(noteId, dataKey, sourceId, nowStr) {
|
||||||
const oldNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
const oldNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
||||||
|
|
||||||
|
if (oldNote.type === 'file') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (oldNote.isProtected) {
|
if (oldNote.isProtected) {
|
||||||
protected_session.decryptNote(dataKey, oldNote);
|
protected_session.decryptNote(dataKey, oldNote);
|
||||||
|
|
||||||
note.isProtected = false;
|
oldNote.isProtected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newNoteRevisionId = utils.newNoteRevisionId();
|
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) {
|
async function updateNote(noteId, newNote, dataKey, sourceId) {
|
||||||
|
if (newNote.detail.type === 'file') {
|
||||||
|
await loadFile(noteId, newNote, dataKey);
|
||||||
|
}
|
||||||
|
|
||||||
if (newNote.detail.isProtected) {
|
if (newNote.detail.isProtected) {
|
||||||
await protected_session.encryptNote(dataKey, newNote.detail);
|
await protected_session.encryptNote(dataKey, newNote.detail);
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,10 @@ function getDataKey(obj) {
|
|||||||
|
|
||||||
const protectedSessionId = getProtectedSessionId(obj);
|
const protectedSessionId = getProtectedSessionId(obj);
|
||||||
|
|
||||||
|
return getDataKeyForProtectedSessionId(protectedSessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDataKeyForProtectedSessionId(protectedSessionId) {
|
||||||
if (protectedSessionId && session.protectedSessionId === protectedSessionId) {
|
if (protectedSessionId && session.protectedSessionId === protectedSessionId) {
|
||||||
return session.decryptedDataKey;
|
return session.decryptedDataKey;
|
||||||
}
|
}
|
||||||
@ -52,7 +56,14 @@ function decryptNote(dataKey, note) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (note.content) {
|
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) {
|
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);
|
dataKey = getDataKey(dataKey);
|
||||||
|
|
||||||
note.title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(note.noteId), note.title);
|
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) {
|
function encryptNoteHistoryRow(dataKey, history) {
|
||||||
dataKey = getDataKey(dataKey);
|
dataKey = getDataKey(dataKey);
|
||||||
|
|
||||||
history.title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(history.noteRevisionId), history.title);
|
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 = {
|
module.exports = {
|
||||||
setDataKey,
|
setDataKey,
|
||||||
getDataKey,
|
getDataKey,
|
||||||
|
getDataKeyForProtectedSessionId,
|
||||||
isProtectedSessionAvailable,
|
isProtectedSessionAvailable,
|
||||||
decryptNote,
|
decryptNote,
|
||||||
decryptNotes,
|
decryptNotes,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user