2017-11-14 21:54:12 -05:00
|
|
|
"use strict";
|
|
|
|
|
2017-11-09 23:25:23 -05:00
|
|
|
const utils = require('./utils');
|
2018-04-01 21:27:46 -04:00
|
|
|
const dataEncryptionService = require('./data_encryption');
|
2018-03-31 08:53:52 -04:00
|
|
|
const cls = require('./cls');
|
2017-11-09 23:25:23 -05:00
|
|
|
|
2018-04-01 21:27:46 -04:00
|
|
|
const dataKeyMap = {};
|
|
|
|
|
2018-04-20 00:12:01 -04:00
|
|
|
function setDataKey(decryptedDataKey) {
|
2018-03-31 08:53:52 -04:00
|
|
|
const protectedSessionId = utils.randomSecureToken(32);
|
2017-11-09 23:25:23 -05:00
|
|
|
|
2018-03-31 08:53:52 -04:00
|
|
|
dataKeyMap[protectedSessionId] = Array.from(decryptedDataKey); // can't store buffer in session
|
|
|
|
|
|
|
|
return protectedSessionId;
|
2017-11-09 23:25:23 -05:00
|
|
|
}
|
|
|
|
|
2018-03-31 08:53:52 -04:00
|
|
|
function setProtectedSessionId(req) {
|
2019-03-31 12:49:42 +02:00
|
|
|
cls.namespace.set('protectedSessionId', req.cookies.protectedSessionId);
|
2017-11-14 21:54:12 -05:00
|
|
|
}
|
|
|
|
|
2018-03-31 08:53:52 -04:00
|
|
|
function getProtectedSessionId() {
|
|
|
|
return cls.namespace.get('protectedSessionId');
|
|
|
|
}
|
2018-01-24 22:13:41 -05:00
|
|
|
|
2018-03-31 08:53:52 -04:00
|
|
|
function getDataKey() {
|
|
|
|
const protectedSessionId = getProtectedSessionId();
|
2017-11-10 22:55:19 -05:00
|
|
|
|
2018-03-31 08:53:52 -04:00
|
|
|
return dataKeyMap[protectedSessionId];
|
2018-02-23 22:58:24 -05:00
|
|
|
}
|
|
|
|
|
2018-04-20 00:12:01 -04:00
|
|
|
function isProtectedSessionAvailable() {
|
|
|
|
const protectedSessionId = getProtectedSessionId();
|
2017-11-14 21:54:12 -05:00
|
|
|
|
2018-03-31 08:53:52 -04:00
|
|
|
return !!dataKeyMap[protectedSessionId];
|
2017-11-14 21:54:12 -05:00
|
|
|
}
|
|
|
|
|
2018-04-20 00:12:01 -04:00
|
|
|
function decryptNoteTitle(noteId, encryptedTitle) {
|
|
|
|
const dataKey = getDataKey();
|
|
|
|
|
2018-08-27 21:58:02 +02:00
|
|
|
try {
|
2019-01-11 23:04:51 +01:00
|
|
|
return dataEncryptionService.decryptString(dataKey, encryptedTitle);
|
2018-08-27 21:58:02 +02:00
|
|
|
}
|
|
|
|
catch (e) {
|
|
|
|
e.message = `Cannot decrypt note title for noteId=${noteId}: ` + e.message;
|
|
|
|
throw e;
|
|
|
|
}
|
2018-04-20 00:12:01 -04:00
|
|
|
}
|
|
|
|
|
2018-03-31 08:53:52 -04:00
|
|
|
function decryptNote(note) {
|
2018-01-28 19:30:14 -05:00
|
|
|
if (!note.isProtected) {
|
2018-01-24 22:13:41 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-02-06 20:19:25 +01:00
|
|
|
if (note.title) {
|
2019-02-07 22:16:40 +01:00
|
|
|
note.title = decryptNoteTitle(note.noteId, note.title);
|
2019-02-06 20:19:25 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-26 22:24:04 +01:00
|
|
|
function decryptNoteContent(note) {
|
2018-08-27 21:58:02 +02:00
|
|
|
try {
|
2019-03-26 22:24:04 +01:00
|
|
|
if (note.content != null) {
|
2019-05-04 16:05:28 +02:00
|
|
|
note.content = dataEncryptionService.decrypt(getDataKey(), note.content);
|
2019-03-07 22:00:23 +01:00
|
|
|
}
|
2018-01-24 22:13:41 -05:00
|
|
|
}
|
2018-08-27 21:58:02 +02:00
|
|
|
catch (e) {
|
2019-03-26 22:24:04 +01:00
|
|
|
e.message = `Cannot decrypt content for noteId=${note.noteId}: ` + e.message;
|
2018-08-27 21:58:02 +02:00
|
|
|
throw e;
|
|
|
|
}
|
2018-01-24 22:13:41 -05:00
|
|
|
}
|
|
|
|
|
2018-03-31 08:53:52 -04:00
|
|
|
function decryptNotes(notes) {
|
2018-01-24 22:13:41 -05:00
|
|
|
for (const note of notes) {
|
2018-03-31 08:53:52 -04:00
|
|
|
decryptNote(note);
|
2018-01-24 22:13:41 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-31 08:53:52 -04:00
|
|
|
function decryptNoteRevision(hist) {
|
|
|
|
const dataKey = getDataKey();
|
2018-01-24 22:13:41 -05:00
|
|
|
|
2018-01-28 19:30:14 -05:00
|
|
|
if (!hist.isProtected) {
|
2018-01-24 22:13:41 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-30 19:24:53 +01:00
|
|
|
try {
|
|
|
|
if (hist.title) {
|
2019-03-31 22:54:38 +02:00
|
|
|
hist.title = dataEncryptionService.decryptString(dataKey, hist.title.toString());
|
2019-03-30 19:24:53 +01:00
|
|
|
}
|
2018-01-24 22:13:41 -05:00
|
|
|
|
2019-03-30 19:24:53 +01:00
|
|
|
if (hist.content) {
|
2019-03-31 22:54:38 +02:00
|
|
|
hist.content = dataEncryptionService.decryptString(dataKey, hist.content.toString());
|
2019-03-30 19:24:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (e) {
|
2019-03-31 22:23:50 +02:00
|
|
|
throw new Error(`Decryption failed for note ${hist.noteId}, revision ${hist.noteRevisionId}: ` + e.message + " " + e.stack);
|
2018-01-24 22:13:41 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-31 08:53:52 -04:00
|
|
|
function encryptNote(note) {
|
2019-02-06 20:19:25 +01:00
|
|
|
note.title = dataEncryptionService.encrypt(getDataKey(), note.title);
|
|
|
|
}
|
2018-01-24 22:13:41 -05:00
|
|
|
|
2019-03-26 22:24:04 +01:00
|
|
|
function encryptNoteContent(note) {
|
|
|
|
note.content = dataEncryptionService.encrypt(getDataKey(), note.content);
|
2018-01-24 22:13:41 -05:00
|
|
|
}
|
|
|
|
|
2018-03-31 08:53:52 -04:00
|
|
|
function encryptNoteRevision(revision) {
|
|
|
|
const dataKey = getDataKey();
|
2018-01-24 22:13:41 -05:00
|
|
|
|
2019-01-11 23:04:51 +01:00
|
|
|
revision.title = dataEncryptionService.encrypt(dataKey, revision.title);
|
|
|
|
revision.content = dataEncryptionService.encrypt(dataKey, revision.content);
|
2018-01-24 22:13:41 -05:00
|
|
|
}
|
|
|
|
|
2017-11-09 23:25:23 -05:00
|
|
|
module.exports = {
|
|
|
|
setDataKey,
|
2017-11-14 21:54:12 -05:00
|
|
|
getDataKey,
|
2018-01-24 22:13:41 -05:00
|
|
|
isProtectedSessionAvailable,
|
2018-04-20 00:12:01 -04:00
|
|
|
decryptNoteTitle,
|
2018-01-24 22:13:41 -05:00
|
|
|
decryptNote,
|
2019-02-06 20:19:25 +01:00
|
|
|
decryptNoteContent,
|
2018-01-24 22:13:41 -05:00
|
|
|
decryptNotes,
|
2018-03-25 20:52:38 -04:00
|
|
|
decryptNoteRevision,
|
2018-01-24 22:13:41 -05:00
|
|
|
encryptNote,
|
2019-02-06 20:19:25 +01:00
|
|
|
encryptNoteContent,
|
2018-03-31 08:53:52 -04:00
|
|
|
encryptNoteRevision,
|
|
|
|
setProtectedSessionId
|
2017-11-09 23:25:23 -05:00
|
|
|
};
|