support encryption for files, closes #60

This commit is contained in:
azivner 2018-02-23 22:58:24 -05:00
parent 19308bbfbd
commit 3b4509d833
5 changed files with 53 additions and 9 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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
};

View File

@ -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);
}

View File

@ -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,