mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
removed dataKey where it's not necessary anymore (use of CLS instead)
This commit is contained in:
parent
5d203b2278
commit
05676f3459
@ -11,7 +11,7 @@ class Note extends Entity {
|
|||||||
super(repository, row);
|
super(repository, row);
|
||||||
|
|
||||||
if (this.isProtected) {
|
if (this.isProtected) {
|
||||||
protected_session.decryptNote(this.dataKey, this);
|
protected_session.decryptNote(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isJson()) {
|
if (this.isJson()) {
|
||||||
@ -129,7 +129,7 @@ class Note extends Entity {
|
|||||||
this.content = JSON.stringify(this.jsonContent, null, '\t');
|
this.content = JSON.stringify(this.jsonContent, null, '\t');
|
||||||
|
|
||||||
if (this.isProtected) {
|
if (this.isProtected) {
|
||||||
protected_session.encryptNote(this.dataKey, this);
|
protected_session.encryptNote(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,21 +37,18 @@ async function uploadFile(req) {
|
|||||||
async function downloadFile(req, res) {
|
async function downloadFile(req, res) {
|
||||||
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 ${noteId} doesn't exist.`);
|
return res.status(404).send(`Note ${noteId} doesn't exist.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (note.isProtected) {
|
if (note.isProtected) {
|
||||||
const dataKey = protected_session.getDataKeyForProtectedSessionId(protectedSessionId);
|
if (!protected_session.isProtectedSessionAvailable()) {
|
||||||
|
|
||||||
if (!dataKey) {
|
|
||||||
res.status(401).send("Protected session not available");
|
res.status(401).send("Protected session not available");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected_session.decryptNote(dataKey, note);
|
protected_session.decryptNote(note);
|
||||||
}
|
}
|
||||||
|
|
||||||
const labelMap = await labels.getNoteLabelMap(noteId);
|
const labelMap = await labels.getNoteLabelMap(noteId);
|
||||||
|
@ -6,7 +6,7 @@ const protected_session = require('../../services/protected_session');
|
|||||||
async function getNoteRevisions(req) {
|
async function getNoteRevisions(req) {
|
||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
const revisions = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? order by dateModifiedTo desc", [noteId]);
|
const revisions = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? order by dateModifiedTo desc", [noteId]);
|
||||||
protected_session.decryptNoteRevisions(req, revisions);
|
protected_session.decryptNoteRevisions(revisions);
|
||||||
|
|
||||||
return revisions;
|
return revisions;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ async function getNote(req) {
|
|||||||
return [404, "Note " + noteId + " has not been found."];
|
return [404, "Note " + noteId + " has not been found."];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected_session.decryptNote(req, note);
|
protected_session.decryptNote(note);
|
||||||
|
|
||||||
if (note.type === 'file') {
|
if (note.type === 'file') {
|
||||||
// no need to transfer (potentially large) file payload for this request
|
// no need to transfer (potentially large) file payload for this request
|
||||||
@ -46,24 +46,21 @@ async function createNote(req) {
|
|||||||
async function updateNote(req) {
|
async function updateNote(req) {
|
||||||
const note = req.body;
|
const note = req.body;
|
||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
const dataKey = protected_session.getDataKey(req);
|
|
||||||
|
|
||||||
await notes.updateNote(noteId, note, dataKey);
|
await notes.updateNote(noteId, note);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sortNotes(req) {
|
async function sortNotes(req) {
|
||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
const dataKey = protected_session.getDataKey(req);
|
|
||||||
|
|
||||||
await tree.sortNotesAlphabetically(noteId, dataKey);
|
await tree.sortNotesAlphabetically(noteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function protectBranch(req) {
|
async function protectBranch(req) {
|
||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
const isProtected = !!parseInt(req.params.isProtected);
|
const isProtected = !!parseInt(req.params.isProtected);
|
||||||
const dataKey = protected_session.getDataKey(req);
|
|
||||||
|
|
||||||
await notes.protectNoteRecursively(noteId, dataKey, isProtected);
|
await notes.protectNoteRecursively(noteId, isProtected);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setNoteTypeMime(req) {
|
async function setNoteTypeMime(req) {
|
||||||
|
@ -45,7 +45,7 @@ async function getTree(req) {
|
|||||||
WHERE
|
WHERE
|
||||||
notes.isDeleted = 0`));
|
notes.isDeleted = 0`));
|
||||||
|
|
||||||
protected_session.decryptNotes(req, notes);
|
protected_session.decryptNotes(notes);
|
||||||
|
|
||||||
notes.forEach(note => {
|
notes.forEach(note => {
|
||||||
note.hideInAutocomplete = !!note.hideInAutocomplete;
|
note.hideInAutocomplete = !!note.hideInAutocomplete;
|
||||||
|
@ -38,6 +38,7 @@ const router = express.Router();
|
|||||||
const auth = require('../services/auth');
|
const auth = require('../services/auth');
|
||||||
const cls = require('../services/cls');
|
const cls = require('../services/cls');
|
||||||
const sql = require('../services/sql');
|
const sql = require('../services/sql');
|
||||||
|
const protectedSessionService = require('../services/protected_session');
|
||||||
|
|
||||||
function apiResultHandler(res, result) {
|
function apiResultHandler(res, result) {
|
||||||
// if it's an array and first element is integer then we consider this to be [statusCode, response] format
|
// if it's an array and first element is integer then we consider this to be [statusCode, response] format
|
||||||
@ -67,6 +68,7 @@ function route(method, path, middleware, routeHandler, resultHandler) {
|
|||||||
try {
|
try {
|
||||||
const result = await cls.init(async () => {
|
const result = await cls.init(async () => {
|
||||||
cls.namespace.set('sourceId', req.headers.source_id);
|
cls.namespace.set('sourceId', req.headers.source_id);
|
||||||
|
protectedSessionService.setProtectedSessionId(req);
|
||||||
|
|
||||||
return await sql.doInTransaction(async () => {
|
return await sql.doInTransaction(async () => {
|
||||||
return await routeHandler(req, res, next);
|
return await routeHandler(req, res, next);
|
||||||
|
@ -5,7 +5,7 @@ const sync_table = require('./sync_table');
|
|||||||
const labels = require('./labels');
|
const labels = require('./labels');
|
||||||
const protected_session = require('./protected_session');
|
const protected_session = require('./protected_session');
|
||||||
|
|
||||||
async function createNewNote(parentNoteId, noteOpts, dataKey) {
|
async function createNewNote(parentNoteId, noteOpts) {
|
||||||
const noteId = utils.newNoteId();
|
const noteId = utils.newNoteId();
|
||||||
const branchId = utils.newBranchId();
|
const branchId = utils.newBranchId();
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ async function createNewNote(parentNoteId, noteOpts, dataKey) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (note.isProtected) {
|
if (note.isProtected) {
|
||||||
protected_session.encryptNote(dataKey, note);
|
protected_session.encryptNote(note);
|
||||||
}
|
}
|
||||||
|
|
||||||
await sql.insert("notes", note);
|
await sql.insert("notes", note);
|
||||||
@ -106,7 +106,7 @@ async function createNote(parentNoteId, title, content = "", extraOptions = {})
|
|||||||
note.mime = "text/html";
|
note.mime = "text/html";
|
||||||
}
|
}
|
||||||
|
|
||||||
const {noteId} = await createNewNote(parentNoteId, note, extraOptions.dataKey);
|
const {noteId} = await createNewNote(parentNoteId, note);
|
||||||
|
|
||||||
if (extraOptions.labels) {
|
if (extraOptions.labels) {
|
||||||
for (const attrName in extraOptions.labels) {
|
for (const attrName in extraOptions.labels) {
|
||||||
@ -117,30 +117,30 @@ async function createNote(parentNoteId, title, content = "", extraOptions = {})
|
|||||||
return noteId;
|
return noteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function protectNoteRecursively(noteId, dataKey, protect) {
|
async function protectNoteRecursively(noteId, protect) {
|
||||||
const note = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
const note = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
||||||
|
|
||||||
await protectNote(note, dataKey, protect);
|
await protectNote(note, protect);
|
||||||
|
|
||||||
const children = await sql.getColumn("SELECT noteId FROM branches WHERE parentNoteId = ? AND isDeleted = 0", [noteId]);
|
const children = await sql.getColumn("SELECT noteId FROM branches WHERE parentNoteId = ? AND isDeleted = 0", [noteId]);
|
||||||
|
|
||||||
for (const childNoteId of children) {
|
for (const childNoteId of children) {
|
||||||
await protectNoteRecursively(childNoteId, dataKey, protect);
|
await protectNoteRecursively(childNoteId, protect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function protectNote(note, dataKey, protect) {
|
async function protectNote(note, protect) {
|
||||||
let changed = false;
|
let changed = false;
|
||||||
|
|
||||||
if (protect && !note.isProtected) {
|
if (protect && !note.isProtected) {
|
||||||
protected_session.encryptNote(dataKey, note);
|
protected_session.encryptNote(note);
|
||||||
|
|
||||||
note.isProtected = true;
|
note.isProtected = true;
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
else if (!protect && note.isProtected) {
|
else if (!protect && note.isProtected) {
|
||||||
protected_session.decryptNote(dataKey, note);
|
protected_session.decryptNote(note);
|
||||||
|
|
||||||
note.isProtected = false;
|
note.isProtected = false;
|
||||||
|
|
||||||
@ -154,20 +154,20 @@ async function protectNote(note, dataKey, protect) {
|
|||||||
await sync_table.addNoteSync(note.noteId);
|
await sync_table.addNoteSync(note.noteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
await protectNoteRevisions(note.noteId, dataKey, protect);
|
await protectNoteRevisions(note.noteId, protect);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function protectNoteRevisions(noteId, dataKey, protect) {
|
async function protectNoteRevisions(noteId, protect) {
|
||||||
const revisionsToChange = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? AND isProtected != ?", [noteId, protect]);
|
const revisionsToChange = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? AND isProtected != ?", [noteId, protect]);
|
||||||
|
|
||||||
for (const revision of revisionsToChange) {
|
for (const revision of revisionsToChange) {
|
||||||
if (protect) {
|
if (protect) {
|
||||||
protected_session.encryptNoteRevision(dataKey, revision);
|
protected_session.encryptNoteRevision(revision);
|
||||||
|
|
||||||
revision.isProtected = true;
|
revision.isProtected = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
protected_session.decryptNoteRevision(dataKey, revision);
|
protected_session.decryptNoteRevision(revision);
|
||||||
|
|
||||||
revision.isProtected = false;
|
revision.isProtected = false;
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ async function protectNoteRevisions(noteId, dataKey, protect) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveNoteRevision(noteId, dataKey, nowStr) {
|
async function saveNoteRevision(noteId, 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') {
|
if (oldNote.type === 'file') {
|
||||||
@ -187,7 +187,7 @@ async function saveNoteRevision(noteId, dataKey, nowStr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (oldNote.isProtected) {
|
if (oldNote.isProtected) {
|
||||||
protected_session.decryptNote(dataKey, oldNote);
|
protected_session.decryptNote(oldNote);
|
||||||
|
|
||||||
oldNote.isProtected = false;
|
oldNote.isProtected = false;
|
||||||
}
|
}
|
||||||
@ -255,23 +255,23 @@ async function saveNoteImages(noteId, noteText) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadFile(noteId, newNote, dataKey) {
|
async function loadFile(noteId, newNote) {
|
||||||
const oldNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
const oldNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
||||||
|
|
||||||
if (oldNote.isProtected) {
|
if (oldNote.isProtected) {
|
||||||
await protected_session.decryptNote(dataKey, oldNote);
|
await protected_session.decryptNote(oldNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
newNote.content = oldNote.content;
|
newNote.content = oldNote.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateNote(noteId, newNote, dataKey) {
|
async function updateNote(noteId, newNote) {
|
||||||
if (newNote.type === 'file') {
|
if (newNote.type === 'file') {
|
||||||
await loadFile(noteId, newNote, dataKey);
|
await loadFile(noteId, newNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newNote.isProtected) {
|
if (newNote.isProtected) {
|
||||||
await protected_session.encryptNote(dataKey, newNote);
|
await protected_session.encryptNote(newNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
const labelsMap = await labels.getNoteLabelMap(noteId);
|
const labelsMap = await labels.getNoteLabelMap(noteId);
|
||||||
@ -293,12 +293,12 @@ async function updateNote(noteId, newNote, dataKey) {
|
|||||||
&& !existingnoteRevisionId
|
&& !existingnoteRevisionId
|
||||||
&& msSinceDateCreated >= noteRevisionSnapshotTimeInterval * 1000) {
|
&& msSinceDateCreated >= noteRevisionSnapshotTimeInterval * 1000) {
|
||||||
|
|
||||||
await saveNoteRevision(noteId, dataKey, nowStr);
|
await saveNoteRevision(noteId, nowStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
await saveNoteImages(noteId, newNote.content);
|
await saveNoteImages(noteId, newNote.content);
|
||||||
|
|
||||||
await protectNoteRevisions(noteId, dataKey, newNote.isProtected);
|
await protectNoteRevisions(noteId, newNote.isProtected);
|
||||||
|
|
||||||
await sql.execute("UPDATE notes SET title = ?, content = ?, isProtected = ?, dateModified = ? WHERE noteId = ?", [
|
await sql.execute("UPDATE notes SET title = ?, content = ?, isProtected = ?, dateModified = ? WHERE noteId = ?", [
|
||||||
newNote.title,
|
newNote.title,
|
||||||
|
@ -2,50 +2,43 @@
|
|||||||
|
|
||||||
const utils = require('./utils');
|
const utils = require('./utils');
|
||||||
const data_encryption = require('./data_encryption');
|
const data_encryption = require('./data_encryption');
|
||||||
const session = {};
|
const dataKeyMap = {};
|
||||||
|
const cls = require('./cls');
|
||||||
|
|
||||||
function setDataKey(req, decryptedDataKey) {
|
function setDataKey(req, decryptedDataKey) {
|
||||||
session.decryptedDataKey = Array.from(decryptedDataKey); // can't store buffer in session
|
const protectedSessionId = utils.randomSecureToken(32);
|
||||||
session.protectedSessionId = utils.randomSecureToken(32);
|
|
||||||
|
|
||||||
return session.protectedSessionId;
|
dataKeyMap[protectedSessionId] = Array.from(decryptedDataKey); // can't store buffer in session
|
||||||
|
|
||||||
|
return protectedSessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProtectedSessionId(req) {
|
function setProtectedSessionId(req) {
|
||||||
return req.headers.protected_session_id;
|
cls.namespace.set('protectedSessionId', req.headers.protected_session_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function getProtectedSessionId() {
|
||||||
* @param obj - can be either array, in that case it's considered to be already dataKey and we just return it
|
return cls.namespace.get('protectedSessionId');
|
||||||
* if it's not a array, we consider it a request object and try to pull dataKey based on the session id header
|
}
|
||||||
*/
|
|
||||||
function getDataKey(obj) {
|
|
||||||
if (!obj || obj.constructor.name === 'Array') {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
const protectedSessionId = getProtectedSessionId(obj);
|
function getDataKey() {
|
||||||
|
const protectedSessionId = getProtectedSessionId();
|
||||||
|
|
||||||
return getDataKeyForProtectedSessionId(protectedSessionId);
|
return dataKeyMap[protectedSessionId];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDataKeyForProtectedSessionId(protectedSessionId) {
|
function getDataKeyForProtectedSessionId(protectedSessionId) {
|
||||||
if (protectedSessionId && session.protectedSessionId === protectedSessionId) {
|
return dataKeyMap[protectedSessionId];
|
||||||
return session.decryptedDataKey;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isProtectedSessionAvailable(req) {
|
function isProtectedSessionAvailable(req) {
|
||||||
const protectedSessionId = getProtectedSessionId(req);
|
const protectedSessionId = getProtectedSessionId(req);
|
||||||
|
|
||||||
return protectedSessionId && session.protectedSessionId === protectedSessionId;
|
return !!dataKeyMap[protectedSessionId];
|
||||||
}
|
}
|
||||||
|
|
||||||
function decryptNote(dataKey, note) {
|
function decryptNote(note) {
|
||||||
dataKey = getDataKey(dataKey);
|
const dataKey = getDataKey();
|
||||||
|
|
||||||
if (!note.isProtected) {
|
if (!note.isProtected) {
|
||||||
return;
|
return;
|
||||||
@ -67,16 +60,16 @@ function decryptNote(dataKey, note) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function decryptNotes(dataKey, notes) {
|
function decryptNotes(notes) {
|
||||||
dataKey = getDataKey(dataKey);
|
const dataKey = getDataKey();
|
||||||
|
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
decryptNote(dataKey, note);
|
decryptNote(note);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function decryptNoteRevision(dataKey, hist) {
|
function decryptNoteRevision(hist) {
|
||||||
dataKey = getDataKey(dataKey);
|
const dataKey = getDataKey();
|
||||||
|
|
||||||
if (!hist.isProtected) {
|
if (!hist.isProtected) {
|
||||||
return;
|
return;
|
||||||
@ -91,23 +84,21 @@ function decryptNoteRevision(dataKey, hist) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function decryptNoteRevisions(dataKey, noteRevisions) {
|
function decryptNoteRevisions(noteRevisions) {
|
||||||
dataKey = getDataKey(dataKey);
|
|
||||||
|
|
||||||
for (const revision of noteRevisions) {
|
for (const revision of noteRevisions) {
|
||||||
decryptNoteRevision(dataKey, revision);
|
decryptNoteRevision(revision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function encryptNote(dataKey, note) {
|
function encryptNote(note) {
|
||||||
dataKey = getDataKey(dataKey);
|
const dataKey = getDataKey();
|
||||||
|
|
||||||
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.noteContentIv(note.noteId), note.content);
|
note.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(note.noteId), note.content);
|
||||||
}
|
}
|
||||||
|
|
||||||
function encryptNoteRevision(dataKey, revision) {
|
function encryptNoteRevision(revision) {
|
||||||
dataKey = getDataKey(dataKey);
|
const dataKey = getDataKey();
|
||||||
|
|
||||||
revision.title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(revision.noteRevisionId), revision.title);
|
revision.title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(revision.noteRevisionId), revision.title);
|
||||||
revision.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(revision.noteRevisionId), revision.content);
|
revision.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(revision.noteRevisionId), revision.content);
|
||||||
@ -123,5 +114,6 @@ module.exports = {
|
|||||||
decryptNoteRevision,
|
decryptNoteRevision,
|
||||||
decryptNoteRevisions,
|
decryptNoteRevisions,
|
||||||
encryptNote,
|
encryptNote,
|
||||||
encryptNoteRevision
|
encryptNoteRevision,
|
||||||
|
setProtectedSessionId
|
||||||
};
|
};
|
@ -7,17 +7,9 @@ const Label = require('../entities/label');
|
|||||||
const sync_table = require('../services/sync_table');
|
const sync_table = require('../services/sync_table');
|
||||||
|
|
||||||
class Repository {
|
class Repository {
|
||||||
constructor(dataKey) {
|
|
||||||
this.dataKey = protected_session.getDataKey(dataKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getEntities(query, params = []) {
|
async getEntities(query, params = []) {
|
||||||
const rows = await sql.getRows(query, params);
|
const rows = await sql.getRows(query, params);
|
||||||
|
|
||||||
for (const row of rows) {
|
|
||||||
row.dataKey = this.dataKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rows.map(row => this.createEntityFromRow(row));
|
return rows.map(row => this.createEntityFromRow(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,8 +20,6 @@ class Repository {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
row.dataKey = this.dataKey;
|
|
||||||
|
|
||||||
return this.createEntityFromRow(row);
|
return this.createEntityFromRow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +56,6 @@ class Repository {
|
|||||||
|
|
||||||
const clone = Object.assign({}, entity);
|
const clone = Object.assign({}, entity);
|
||||||
|
|
||||||
delete clone.dataKey;
|
|
||||||
delete clone.jsonContent;
|
delete clone.jsonContent;
|
||||||
delete clone.repository;
|
delete clone.repository;
|
||||||
|
|
||||||
|
@ -2,17 +2,17 @@ const sql = require('./sql');
|
|||||||
const ScriptContext = require('./script_context');
|
const ScriptContext = require('./script_context');
|
||||||
const Repository = require('./repository');
|
const Repository = require('./repository');
|
||||||
|
|
||||||
async function executeNote(dataKey, note) {
|
async function executeNote(note) {
|
||||||
if (!note.isJavaScript()) {
|
if (!note.isJavaScript()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bundle = await getScriptBundle(note);
|
const bundle = await getScriptBundle(note);
|
||||||
|
|
||||||
await executeBundle(dataKey, bundle);
|
await executeBundle(bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function executeBundle(dataKey, bundle, startNote) {
|
async function executeBundle(bundle, startNote) {
|
||||||
if (!startNote) {
|
if (!startNote) {
|
||||||
// this is the default case, the only exception is when we want to preserve frontend startNote
|
// this is the default case, the only exception is when we want to preserve frontend startNote
|
||||||
startNote = bundle.note;
|
startNote = bundle.note;
|
||||||
@ -21,7 +21,7 @@ async function executeBundle(dataKey, bundle, startNote) {
|
|||||||
// last \r\n is necessary if script contains line comment on its last line
|
// last \r\n is necessary if script contains line comment on its last line
|
||||||
const script = "async function() {\r\n" + bundle.script + "\r\n}";
|
const script = "async function() {\r\n" + bundle.script + "\r\n}";
|
||||||
|
|
||||||
const ctx = new ScriptContext(dataKey, startNote, bundle.allNotes);
|
const ctx = new ScriptContext(startNote, bundle.allNotes);
|
||||||
|
|
||||||
if (await bundle.note.hasLabel('manual_transaction_handling')) {
|
if (await bundle.note.hasLabel('manual_transaction_handling')) {
|
||||||
return await execute(ctx, script, '');
|
return await execute(ctx, script, '');
|
||||||
@ -35,8 +35,8 @@ async function executeBundle(dataKey, bundle, startNote) {
|
|||||||
* This method preserves frontend startNode - that's why we start execution from currentNote and override
|
* This method preserves frontend startNode - that's why we start execution from currentNote and override
|
||||||
* bundle's startNote.
|
* bundle's startNote.
|
||||||
*/
|
*/
|
||||||
async function executeScript(dataKey, script, params, startNoteId, currentNoteId) {
|
async function executeScript(script, params, startNoteId, currentNoteId) {
|
||||||
const repository = new Repository(dataKey);
|
const repository = new Repository();
|
||||||
const startNote = await repository.getNote(startNoteId);
|
const startNote = await repository.getNote(startNoteId);
|
||||||
const currentNote = await repository.getNote(currentNoteId);
|
const currentNote = await repository.getNote(currentNoteId);
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ async function executeScript(dataKey, script, params, startNoteId, currentNoteId
|
|||||||
|
|
||||||
const bundle = await getScriptBundle(currentNote);
|
const bundle = await getScriptBundle(currentNote);
|
||||||
|
|
||||||
return await executeBundle(dataKey, bundle, startNote);
|
return await executeBundle(bundle, startNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function execute(ctx, script, paramsStr) {
|
async function execute(ctx, script, paramsStr) {
|
||||||
|
@ -9,12 +9,10 @@ const config = require('./config');
|
|||||||
const Repository = require('./repository');
|
const Repository = require('./repository');
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
function ScriptContext(dataKey, startNote, allNotes) {
|
function ScriptContext(startNote, allNotes) {
|
||||||
dataKey = protected_session.getDataKey(dataKey);
|
|
||||||
|
|
||||||
this.modules = {};
|
this.modules = {};
|
||||||
this.notes = utils.toObject(allNotes, note => [note.noteId, note]);
|
this.notes = utils.toObject(allNotes, note => [note.noteId, note]);
|
||||||
this.apis = utils.toObject(allNotes, note => [note.noteId, new ScriptApi(dataKey, startNote, note)]);
|
this.apis = utils.toObject(allNotes, note => [note.noteId, new ScriptApi(startNote, note)]);
|
||||||
this.require = moduleNoteIds => {
|
this.require = moduleNoteIds => {
|
||||||
return moduleName => {
|
return moduleName => {
|
||||||
const candidates = allNotes.filter(note => moduleNoteIds.includes(note.noteId));
|
const candidates = allNotes.filter(note => moduleNoteIds.includes(note.noteId));
|
||||||
@ -29,8 +27,8 @@ function ScriptContext(dataKey, startNote, allNotes) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function ScriptApi(dataKey, startNote, currentNote) {
|
function ScriptApi(startNote, currentNote) {
|
||||||
const repository = new Repository(dataKey);
|
const repository = new Repository();
|
||||||
this.startNote = startNote;
|
this.startNote = startNote;
|
||||||
this.currentNote = currentNote;
|
this.currentNote = currentNote;
|
||||||
|
|
||||||
@ -59,8 +57,6 @@ function ScriptApi(dataKey, startNote, currentNote) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.createNote = async function(parentNoteId, title, content = "", extraOptions = {}) {
|
this.createNote = async function(parentNoteId, title, content = "", extraOptions = {}) {
|
||||||
extraOptions.dataKey = dataKey;
|
|
||||||
|
|
||||||
return await notes.createNote(parentNoteId, title, content, extraOptions);
|
return await notes.createNote(parentNoteId, title, content, extraOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,13 +76,13 @@ async function loadSubTreeNoteIds(parentNoteId, subTreeNoteIds) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sortNotesAlphabetically(parentNoteId, req) {
|
async function sortNotesAlphabetically(parentNoteId) {
|
||||||
await sql.doInTransaction(async () => {
|
await sql.doInTransaction(async () => {
|
||||||
const notes = await sql.getRows(`SELECT branchId, noteId, title, isProtected
|
const notes = await sql.getRows(`SELECT branchId, noteId, title, isProtected
|
||||||
FROM notes JOIN branches USING(noteId)
|
FROM notes JOIN branches USING(noteId)
|
||||||
WHERE branches.isDeleted = 0 AND parentNoteId = ?`, [parentNoteId]);
|
WHERE branches.isDeleted = 0 AND parentNoteId = ?`, [parentNoteId]);
|
||||||
|
|
||||||
protected_session.decryptNotes(req, notes);
|
protected_session.decryptNotes(notes);
|
||||||
|
|
||||||
notes.sort((a, b) => a.title.toLowerCase() < b.title.toLowerCase() ? -1 : 1);
|
notes.sort((a, b) => a.title.toLowerCase() < b.title.toLowerCase() ? -1 : 1);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user