mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	removed dataKey where it's not necessary anymore (use of CLS instead)
This commit is contained in:
		| @@ -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); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user