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

View File

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

View File

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

View File

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

View File

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