mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	per-browser source id so we support having notecase opened in multiple tabs/windows
This commit is contained in:
		| @@ -1,9 +1,5 @@ | |||||||
| "use strict"; | "use strict"; | ||||||
|  |  | ||||||
| const glob = { |  | ||||||
|     activeDialog: null |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| // hot keys are active also inside inputs and content editables | // hot keys are active also inside inputs and content editables | ||||||
| jQuery.hotkeys.options.filterInputAcceptingElements = true; | jQuery.hotkeys.options.filterInputAcceptingElements = true; | ||||||
| jQuery.hotkeys.options.filterContentEditable = true; | jQuery.hotkeys.options.filterContentEditable = true; | ||||||
|   | |||||||
| @@ -19,23 +19,27 @@ const messaging = (function() { | |||||||
|     function messageHandler(event) { |     function messageHandler(event) { | ||||||
|         const message = JSON.parse(event.data); |         const message = JSON.parse(event.data); | ||||||
|  |  | ||||||
|  |         if (message.data.length > 0) { | ||||||
|  |             console.log(message); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (message.type === 'sync') { |         if (message.type === 'sync') { | ||||||
|             lastPingTs = new Date().getTime(); |             lastPingTs = new Date().getTime(); | ||||||
|             const data = message.data; |             const syncData = message.data.filter(sync => sync.source_id !== glob.sourceId); | ||||||
|  |  | ||||||
|             if (data.notes_tree) { |             if (syncData.some(sync => sync.entity_name === 'notes_tree')) { | ||||||
|                 console.log("Reloading tree because of background changes"); |                 console.log("Reloading tree because of background changes"); | ||||||
|  |  | ||||||
|                 noteTree.reload(); |                 noteTree.reload(); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (data.notes && data.notes.includes(noteEditor.getCurrentNoteId())) { |             if (syncData.some(sync => sync.entity_name === 'notes' && sync.entity_id === noteEditor.getCurrentNoteId())) { | ||||||
|                 showMessage('Reloading note because background change'); |                 showMessage('Reloading note because background change'); | ||||||
|  |  | ||||||
|                 noteEditor.reload(); |                 noteEditor.reload(); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (data.recent_notes) { |             if (syncData.some(sync => sync.entity_name === 'recent_notes')) { | ||||||
|                 console.log("Reloading recent notes because of background changes"); |                 console.log("Reloading recent notes because of background changes"); | ||||||
|  |  | ||||||
|                 recentNotes.reload(); |                 recentNotes.reload(); | ||||||
|   | |||||||
| @@ -8,7 +8,8 @@ const server = (function() { | |||||||
|         catch(e) {} |         catch(e) {} | ||||||
|  |  | ||||||
|         return { |         return { | ||||||
|             'x-protected-session-id': protectedSessionId |             protected_session_id: protectedSessionId, | ||||||
|  |             source_id: glob.sourceId | ||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -25,10 +25,12 @@ router.get('/:noteId', auth.checkApiAuth, async (req, res, next) => { | |||||||
| }); | }); | ||||||
|  |  | ||||||
| router.put('', auth.checkApiAuth, async (req, res, next) => { | router.put('', auth.checkApiAuth, async (req, res, next) => { | ||||||
|  |     const sourceId = req.headers.source_id; | ||||||
|  |  | ||||||
|     await sql.doInTransaction(async () => { |     await sql.doInTransaction(async () => { | ||||||
|         await sql.replace("notes_history", req.body); |         await sql.replace("notes_history", req.body); | ||||||
|  |  | ||||||
|         await sync_table.addNoteHistorySync(req.body.note_history_id); |         await sync_table.addNoteHistorySync(req.body.note_history_id, sourceId); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     res.send(); |     res.send(); | ||||||
|   | |||||||
| @@ -35,10 +35,11 @@ router.get('/:noteId', auth.checkApiAuth, async (req, res, next) => { | |||||||
| }); | }); | ||||||
|  |  | ||||||
| router.post('/:parentNoteId/children', async (req, res, next) => { | router.post('/:parentNoteId/children', async (req, res, next) => { | ||||||
|  |     const sourceId = req.headers.source_id; | ||||||
|     const parentNoteId = req.params.parentNoteId; |     const parentNoteId = req.params.parentNoteId; | ||||||
|     const note = req.body; |     const note = req.body; | ||||||
|  |  | ||||||
|     const { noteId, noteTreeId } = await notes.createNewNote(parentNoteId, note); |     const { noteId, noteTreeId } = await notes.createNewNote(parentNoteId, note, sourceId); | ||||||
|  |  | ||||||
|     res.send({ |     res.send({ | ||||||
|         'note_id': noteId, |         'note_id': noteId, | ||||||
| @@ -58,7 +59,7 @@ router.put('/:noteId', async (req, res, next) => { | |||||||
|  |  | ||||||
| router.delete('/:noteTreeId', async (req, res, next) => { | router.delete('/:noteTreeId', async (req, res, next) => { | ||||||
|     await sql.doInTransaction(async () => { |     await sql.doInTransaction(async () => { | ||||||
|         await notes.deleteNote(req.params.noteTreeId); |         await notes.deleteNote(req.params.noteTreeId, req.headers.source_id); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     res.send({}); |     res.send({}); | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ const sync_table = require('../../services/sync_table'); | |||||||
| router.put('/:noteTreeId/move-to/:parentNoteId', auth.checkApiAuth, async (req, res, next) => { | router.put('/:noteTreeId/move-to/:parentNoteId', auth.checkApiAuth, async (req, res, next) => { | ||||||
|     const noteTreeId = req.params.noteTreeId; |     const noteTreeId = req.params.noteTreeId; | ||||||
|     const parentNoteId = req.params.parentNoteId; |     const parentNoteId = req.params.parentNoteId; | ||||||
|  |     const sourceId = req.headers.source_id; | ||||||
|  |  | ||||||
|     const maxNotePos = await sql.getSingleValue('SELECT MAX(note_pos) FROM notes_tree WHERE note_pid = ? AND is_deleted = 0', [parentNoteId]); |     const maxNotePos = await sql.getSingleValue('SELECT MAX(note_pos) FROM notes_tree WHERE note_pid = ? AND is_deleted = 0', [parentNoteId]); | ||||||
|     const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1; |     const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1; | ||||||
| @@ -20,7 +21,7 @@ router.put('/:noteTreeId/move-to/:parentNoteId', auth.checkApiAuth, async (req, | |||||||
|         await sql.execute("UPDATE notes_tree SET note_pid = ?, note_pos = ?, date_modified = ? WHERE note_tree_id = ?", |         await sql.execute("UPDATE notes_tree SET note_pid = ?, note_pos = ?, date_modified = ? WHERE note_tree_id = ?", | ||||||
|             [parentNoteId, newNotePos, now, noteTreeId]); |             [parentNoteId, newNotePos, now, noteTreeId]); | ||||||
|  |  | ||||||
|         await sync_table.addNoteTreeSync(noteTreeId); |         await sync_table.addNoteTreeSync(noteTreeId, sourceId); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     res.send({}); |     res.send({}); | ||||||
| @@ -29,6 +30,7 @@ router.put('/:noteTreeId/move-to/:parentNoteId', auth.checkApiAuth, async (req, | |||||||
| router.put('/:noteTreeId/move-before/:beforeNoteTreeId', async (req, res, next) => { | router.put('/:noteTreeId/move-before/:beforeNoteTreeId', async (req, res, next) => { | ||||||
|     const noteTreeId = req.params.noteTreeId; |     const noteTreeId = req.params.noteTreeId; | ||||||
|     const beforeNoteTreeId = req.params.beforeNoteTreeId; |     const beforeNoteTreeId = req.params.beforeNoteTreeId; | ||||||
|  |     const sourceId = req.headers.source_id; | ||||||
|  |  | ||||||
|     const beforeNote = await sql.getSingleResult("SELECT * FROM notes_tree WHERE note_tree_id = ?", [beforeNoteTreeId]); |     const beforeNote = await sql.getSingleResult("SELECT * FROM notes_tree WHERE note_tree_id = ?", [beforeNoteTreeId]); | ||||||
|  |  | ||||||
| @@ -38,14 +40,14 @@ router.put('/:noteTreeId/move-before/:beforeNoteTreeId', async (req, res, next) | |||||||
|             await sql.execute("UPDATE notes_tree SET note_pos = note_pos + 1 WHERE note_pid = ? AND note_pos >= ? AND is_deleted = 0", |             await sql.execute("UPDATE notes_tree SET note_pos = note_pos + 1 WHERE note_pid = ? AND note_pos >= ? AND is_deleted = 0", | ||||||
|                 [beforeNote.note_pid, beforeNote.note_pos]); |                 [beforeNote.note_pid, beforeNote.note_pos]); | ||||||
|  |  | ||||||
|             await sync_table.addNoteReorderingSync(beforeNote.note_pid); |             await sync_table.addNoteReorderingSync(beforeNote.note_pid, sourceId); | ||||||
|  |  | ||||||
|             const now = utils.nowDate(); |             const now = utils.nowDate(); | ||||||
|  |  | ||||||
|             await sql.execute("UPDATE notes_tree SET note_pid = ?, note_pos = ?, date_modified = ? WHERE note_tree_id = ?", |             await sql.execute("UPDATE notes_tree SET note_pid = ?, note_pos = ?, date_modified = ? WHERE note_tree_id = ?", | ||||||
|                 [beforeNote.note_pid, beforeNote.note_pos, now, noteTreeId]); |                 [beforeNote.note_pid, beforeNote.note_pos, now, noteTreeId]); | ||||||
|  |  | ||||||
|             await sync_table.addNoteTreeSync(noteTreeId); |             await sync_table.addNoteTreeSync(noteTreeId, sourceId); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         res.send({}); |         res.send({}); | ||||||
| @@ -58,6 +60,7 @@ router.put('/:noteTreeId/move-before/:beforeNoteTreeId', async (req, res, next) | |||||||
| router.put('/:noteTreeId/move-after/:afterNoteTreeId', async (req, res, next) => { | router.put('/:noteTreeId/move-after/:afterNoteTreeId', async (req, res, next) => { | ||||||
|     const noteTreeId = req.params.noteTreeId; |     const noteTreeId = req.params.noteTreeId; | ||||||
|     const afterNoteTreeId = req.params.afterNoteTreeId; |     const afterNoteTreeId = req.params.afterNoteTreeId; | ||||||
|  |     const sourceId = req.headers.source_id; | ||||||
|  |  | ||||||
|     const afterNote = await sql.getSingleResult("SELECT * FROM notes_tree WHERE note_tree_id = ?", [afterNoteTreeId]); |     const afterNote = await sql.getSingleResult("SELECT * FROM notes_tree WHERE note_tree_id = ?", [afterNoteTreeId]); | ||||||
|  |  | ||||||
| @@ -67,12 +70,12 @@ router.put('/:noteTreeId/move-after/:afterNoteTreeId', async (req, res, next) => | |||||||
|             await sql.execute("UPDATE notes_tree SET note_pos = note_pos + 1 WHERE note_pid = ? AND note_pos > ? AND is_deleted = 0", |             await sql.execute("UPDATE notes_tree SET note_pos = note_pos + 1 WHERE note_pid = ? AND note_pos > ? AND is_deleted = 0", | ||||||
|                 [afterNote.note_pid, afterNote.note_pos]); |                 [afterNote.note_pid, afterNote.note_pos]); | ||||||
|  |  | ||||||
|             await sync_table.addNoteReorderingSync(afterNote.note_pid); |             await sync_table.addNoteReorderingSync(afterNote.note_pid, sourceId); | ||||||
|  |  | ||||||
|             await sql.execute("UPDATE notes_tree SET note_pid = ?, note_pos = ?, date_modified = ? WHERE note_tree_id = ?", |             await sql.execute("UPDATE notes_tree SET note_pid = ?, note_pos = ?, date_modified = ? WHERE note_tree_id = ?", | ||||||
|                 [afterNote.note_pid, afterNote.note_pos + 1, utils.nowDate(), noteTreeId]); |                 [afterNote.note_pid, afterNote.note_pos + 1, utils.nowDate(), noteTreeId]); | ||||||
|  |  | ||||||
|             await sync_table.addNoteTreeSync(noteTreeId); |             await sync_table.addNoteTreeSync(noteTreeId, sourceId); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         res.send({}); |         res.send({}); | ||||||
| @@ -85,6 +88,7 @@ router.put('/:noteTreeId/move-after/:afterNoteTreeId', async (req, res, next) => | |||||||
| router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, async (req, res, next) => { | router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, async (req, res, next) => { | ||||||
|     const parentNoteId = req.params.parentNoteId; |     const parentNoteId = req.params.parentNoteId; | ||||||
|     const childNoteId = req.params.childNoteId; |     const childNoteId = req.params.childNoteId; | ||||||
|  |     const sourceId = req.headers.source_id; | ||||||
|  |  | ||||||
|     const existing = await sql.getSingleValue('SELECT * FROM notes_tree WHERE note_id = ? AND note_pid = ?', [childNoteId, parentNoteId]); |     const existing = await sql.getSingleValue('SELECT * FROM notes_tree WHERE note_id = ? AND note_pid = ?', [childNoteId, parentNoteId]); | ||||||
|  |  | ||||||
| @@ -118,7 +122,7 @@ router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, async (req | |||||||
|  |  | ||||||
|         await sql.replace("notes_tree", noteTree); |         await sql.replace("notes_tree", noteTree); | ||||||
|  |  | ||||||
|         await sync_table.addNoteTreeSync(noteTree.note_tree_id); |         await sync_table.addNoteTreeSync(noteTree.note_tree_id, sourceId); | ||||||
|  |  | ||||||
|         res.send({ |         res.send({ | ||||||
|             success: true |             success: true | ||||||
| @@ -129,6 +133,7 @@ router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, async (req | |||||||
| router.put('/:noteId/clone-after/:afterNoteTreeId', async (req, res, next) => { | router.put('/:noteId/clone-after/:afterNoteTreeId', async (req, res, next) => { | ||||||
|     const noteId = req.params.noteId; |     const noteId = req.params.noteId; | ||||||
|     const afterNoteTreeId = req.params.afterNoteTreeId; |     const afterNoteTreeId = req.params.afterNoteTreeId; | ||||||
|  |     const sourceId = req.headers.source_id; | ||||||
|  |  | ||||||
|     const afterNote = await sql.getSingleResult("SELECT * FROM notes_tree WHERE note_tree_id = ?", [afterNoteTreeId]); |     const afterNote = await sql.getSingleResult("SELECT * FROM notes_tree WHERE note_tree_id = ?", [afterNoteTreeId]); | ||||||
|  |  | ||||||
| @@ -157,7 +162,7 @@ router.put('/:noteId/clone-after/:afterNoteTreeId', async (req, res, next) => { | |||||||
|         await sql.execute("UPDATE notes_tree SET note_pos = note_pos + 1 WHERE note_pid = ? AND note_pos > ? AND is_deleted = 0", |         await sql.execute("UPDATE notes_tree SET note_pos = note_pos + 1 WHERE note_pid = ? AND note_pos > ? AND is_deleted = 0", | ||||||
|             [afterNote.note_pid, afterNote.note_pos]); |             [afterNote.note_pid, afterNote.note_pos]); | ||||||
|  |  | ||||||
|         await sync_table.addNoteReorderingSync(afterNote.note_pid); |         await sync_table.addNoteReorderingSync(afterNote.note_pid, sourceId); | ||||||
|  |  | ||||||
|         const noteTree = { |         const noteTree = { | ||||||
|             note_tree_id: utils.newNoteTreeId(), |             note_tree_id: utils.newNoteTreeId(), | ||||||
| @@ -171,7 +176,7 @@ router.put('/:noteId/clone-after/:afterNoteTreeId', async (req, res, next) => { | |||||||
|  |  | ||||||
|         await sql.replace("notes_tree", noteTree); |         await sql.replace("notes_tree", noteTree); | ||||||
|  |  | ||||||
|         await sync_table.addNoteTreeSync(noteTree.note_tree_id); |         await sync_table.addNoteTreeSync(noteTree.note_tree_id, sourceId); | ||||||
|  |  | ||||||
|         res.send({ |         res.send({ | ||||||
|             success: true |             success: true | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ router.get('', auth.checkApiAuth, async (req, res, next) => { | |||||||
| router.put('/:noteTreeId/:notePath', auth.checkApiAuth, async (req, res, next) => { | router.put('/:noteTreeId/:notePath', auth.checkApiAuth, async (req, res, next) => { | ||||||
|     const noteTreeId = req.params.noteTreeId; |     const noteTreeId = req.params.noteTreeId; | ||||||
|     const notePath = req.params.notePath; |     const notePath = req.params.notePath; | ||||||
|  |     const sourceId = req.headers.source_id; | ||||||
|  |  | ||||||
|     await sql.doInTransaction(async () => { |     await sql.doInTransaction(async () => { | ||||||
|         await sql.replace('recent_notes', { |         await sql.replace('recent_notes', { | ||||||
| @@ -24,9 +25,9 @@ router.put('/:noteTreeId/:notePath', auth.checkApiAuth, async (req, res, next) = | |||||||
|             is_deleted: 0 |             is_deleted: 0 | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         await sync_table.addRecentNoteSync(noteTreeId); |         await sync_table.addRecentNoteSync(noteTreeId, sourceId); | ||||||
|  |  | ||||||
|         await options.setOption('start_note_path', notePath); |         await options.setOption('start_note_path', notePath, sourceId); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     res.send(await getRecentNotes()); |     res.send(await getRecentNotes()); | ||||||
|   | |||||||
| @@ -25,12 +25,13 @@ router.get('/', auth.checkApiAuth, async (req, res, next) => { | |||||||
|  |  | ||||||
| router.post('/', async (req, res, next) => { | router.post('/', async (req, res, next) => { | ||||||
|     const body = req.body; |     const body = req.body; | ||||||
|  |     const sourceId = req.headers.source_id; | ||||||
|  |  | ||||||
|     if (ALLOWED_OPTIONS.includes(body['name'])) { |     if (ALLOWED_OPTIONS.includes(body['name'])) { | ||||||
|         const optionName = await options.getOption(body['name']); |         const optionName = await options.getOption(body['name']); | ||||||
|  |  | ||||||
|         await sql.doInTransaction(async () => { |         await sql.doInTransaction(async () => { | ||||||
|             await options.setOption(body['name'], body['value']); |             await options.setOption(body['name'], body['value'], sourceId); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         res.send({}); |         res.send({}); | ||||||
|   | |||||||
| @@ -39,9 +39,10 @@ router.put('/:noteId/protect-sub-tree/:isProtected', auth.checkApiAuth, async (r | |||||||
|     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); |     const dataKey = protected_session.getDataKey(req); | ||||||
|  |     const sourceId = req.headers.source_id; | ||||||
|  |  | ||||||
|     await sql.doInTransaction(async () => { |     await sql.doInTransaction(async () => { | ||||||
|         await notes.protectNoteRecursively(noteId, dataKey, isProtected); |         await notes.protectNoteRecursively(noteId, dataKey, isProtected, sourceId); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     res.send({}); |     res.send({}); | ||||||
| @@ -49,12 +50,13 @@ router.put('/:noteId/protect-sub-tree/:isProtected', auth.checkApiAuth, async (r | |||||||
|  |  | ||||||
| router.put('/:noteTreeId/set-prefix', auth.checkApiAuth, async (req, res, next) => { | router.put('/:noteTreeId/set-prefix', auth.checkApiAuth, async (req, res, next) => { | ||||||
|     const noteTreeId = req.params.noteTreeId; |     const noteTreeId = req.params.noteTreeId; | ||||||
|  |     const sourceId = req.headers.source_id; | ||||||
|     const prefix = utils.isEmptyOrWhitespace(req.body.prefix) ? null : req.body.prefix; |     const prefix = utils.isEmptyOrWhitespace(req.body.prefix) ? null : req.body.prefix; | ||||||
|  |  | ||||||
|     await sql.doInTransaction(async () => { |     await sql.doInTransaction(async () => { | ||||||
|         await sql.execute("UPDATE notes_tree SET prefix = ?, date_modified = ? WHERE note_tree_id = ?", [prefix, utils.nowDate(), noteTreeId]); |         await sql.execute("UPDATE notes_tree SET prefix = ?, date_modified = ? WHERE note_tree_id = ?", [prefix, utils.nowDate(), noteTreeId]); | ||||||
|  |  | ||||||
|         await sync_table.addNoteTreeSync(noteTreeId); |         await sync_table.addNoteTreeSync(noteTreeId, sourceId); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     res.send({}); |     res.send({}); | ||||||
|   | |||||||
| @@ -3,10 +3,12 @@ | |||||||
| const express = require('express'); | const express = require('express'); | ||||||
| const router = express.Router(); | const router = express.Router(); | ||||||
| const auth = require('../services/auth'); | const auth = require('../services/auth'); | ||||||
| const utils = require('../services/utils'); | const source_id = require('../services/source_id'); | ||||||
|  |  | ||||||
| router.get('', auth.checkAuth, async (req, res, next) => { | router.get('', auth.checkAuth, async (req, res, next) => { | ||||||
|     res.render('index', {}); |     res.render('index', { | ||||||
|  |         sourceId: await source_id.generateSourceId() | ||||||
|  |     }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| module.exports = router; | module.exports = router; | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ const notes = require('./notes'); | |||||||
| const data_encryption = require('./data_encryption'); | const data_encryption = require('./data_encryption'); | ||||||
| const sync_table = require('./sync_table'); | const sync_table = require('./sync_table'); | ||||||
|  |  | ||||||
| async function createNewNote(parentNoteId, note) { | async function createNewNote(parentNoteId, note, sourceId) { | ||||||
|     const noteId = utils.newNoteId(); |     const noteId = utils.newNoteId(); | ||||||
|     const noteTreeId = utils.newNoteTreeId(); |     const noteTreeId = utils.newNoteTreeId(); | ||||||
|  |  | ||||||
| @@ -25,7 +25,7 @@ async function createNewNote(parentNoteId, note) { | |||||||
|             await sql.execute('UPDATE notes_tree SET note_pos = note_pos + 1, date_modified = ? WHERE note_pid = ? AND note_pos > ? AND is_deleted = 0', |             await sql.execute('UPDATE notes_tree SET note_pos = note_pos + 1, date_modified = ? WHERE note_pid = ? AND note_pos > ? AND is_deleted = 0', | ||||||
|                 [utils.nowDate(), parentNoteId, afterNote.note_pos]); |                 [utils.nowDate(), parentNoteId, afterNote.note_pos]); | ||||||
|  |  | ||||||
|             await sync_table.addNoteReorderingSync(parentNoteId); |             await sync_table.addNoteReorderingSync(parentNoteId, sourceId); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             throw new Error('Unknown target: ' + note.target); |             throw new Error('Unknown target: ' + note.target); | ||||||
| @@ -42,7 +42,7 @@ async function createNewNote(parentNoteId, note) { | |||||||
|             is_protected: note.is_protected |             is_protected: note.is_protected | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         await sync_table.addNoteSync(noteId); |         await sync_table.addNoteSync(noteId, sourceId); | ||||||
|  |  | ||||||
|         await sql.insert("notes_tree", { |         await sql.insert("notes_tree", { | ||||||
|             note_tree_id: noteTreeId, |             note_tree_id: noteTreeId, | ||||||
| @@ -54,7 +54,7 @@ async function createNewNote(parentNoteId, note) { | |||||||
|             is_deleted: 0 |             is_deleted: 0 | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         await sync_table.addNoteTreeSync(noteTreeId); |         await sync_table.addNoteTreeSync(noteTreeId, sourceId); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     return { |     return { | ||||||
| @@ -68,15 +68,15 @@ async function encryptNote(note, ctx) { | |||||||
|     note.detail.note_text = data_encryption.encrypt(ctx.getDataKey(), data_encryption.noteTextIv(note.detail.note_id), note.detail.note_text); |     note.detail.note_text = data_encryption.encrypt(ctx.getDataKey(), data_encryption.noteTextIv(note.detail.note_id), note.detail.note_text); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function protectNoteRecursively(noteId, dataKey, protect) { | async function protectNoteRecursively(noteId, dataKey, protect, sourceId) { | ||||||
|     const note = await sql.getSingleResult("SELECT * FROM notes WHERE note_id = ?", [noteId]); |     const note = await sql.getSingleResult("SELECT * FROM notes WHERE note_id = ?", [noteId]); | ||||||
|  |  | ||||||
|     await protectNote(note, dataKey, protect); |     await protectNote(note, dataKey, protect, sourceId); | ||||||
|  |  | ||||||
|     const children = await sql.getFlattenedResults("SELECT note_id FROM notes_tree WHERE note_pid = ?", [noteId]); |     const children = await sql.getFlattenedResults("SELECT note_id FROM notes_tree WHERE note_pid = ?", [noteId]); | ||||||
|  |  | ||||||
|     for (const childNoteId of children) { |     for (const childNoteId of children) { | ||||||
|         await protectNoteRecursively(childNoteId, dataKey, protect); |         await protectNoteRecursively(childNoteId, dataKey, protect, sourceId); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -86,7 +86,7 @@ function decryptNote(note, dataKey) { | |||||||
|     note.is_protected = false; |     note.is_protected = false; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function protectNote(note, dataKey, protect) { | async function protectNote(note, dataKey, protect, sourceId) { | ||||||
|     let changed = false; |     let changed = false; | ||||||
|  |  | ||||||
|     if (protect && !note.is_protected) { |     if (protect && !note.is_protected) { | ||||||
| @@ -108,13 +108,13 @@ async function protectNote(note, dataKey, protect) { | |||||||
|         await sql.execute("UPDATE notes SET note_title = ?, note_text = ?, is_protected = ? WHERE note_id = ?", |         await sql.execute("UPDATE notes SET note_title = ?, note_text = ?, is_protected = ? WHERE note_id = ?", | ||||||
|             [note.note_title, note.note_text, note.is_protected, note.note_id]); |             [note.note_title, note.note_text, note.is_protected, note.note_id]); | ||||||
|  |  | ||||||
|         await sync_table.addNoteSync(note.note_id); |         await sync_table.addNoteSync(note.note_id, sourceId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     await protectNoteHistory(note.note_id, dataKey, protect); |     await protectNoteHistory(note.note_id, dataKey, protect, sourceId); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function protectNoteHistory(noteId, dataKey, protect) { | async function protectNoteHistory(noteId, dataKey, protect, sourceId) { | ||||||
|     const historyToChange = await sql.getResults("SELECT * FROM notes_history WHERE note_id = ? AND is_protected != ?", [noteId, protect]); |     const historyToChange = await sql.getResults("SELECT * FROM notes_history WHERE note_id = ? AND is_protected != ?", [noteId, protect]); | ||||||
|  |  | ||||||
|     for (const history of historyToChange) { |     for (const history of historyToChange) { | ||||||
| @@ -132,7 +132,7 @@ async function protectNoteHistory(noteId, dataKey, protect) { | |||||||
|         await sql.execute("UPDATE notes_history SET note_title = ?, note_text = ?, is_protected = ? WHERE note_history_id = ?", |         await sql.execute("UPDATE notes_history SET note_title = ?, note_text = ?, is_protected = ? WHERE note_history_id = ?", | ||||||
|             [history.note_title, history.note_text, history.is_protected, history.note_history_id]); |             [history.note_title, history.note_text, history.is_protected, history.note_history_id]); | ||||||
|  |  | ||||||
|         await sync_table.addNoteHistorySync(history.note_history_id); |         await sync_table.addNoteHistorySync(history.note_history_id, sourceId); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -174,7 +174,7 @@ async function updateNote(noteId, newNote, ctx) { | |||||||
|                 date_modified_to: nowStr |                 date_modified_to: nowStr | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
|             await sync_table.addNoteHistorySync(newNoteHistoryId); |             await sync_table.addNoteHistorySync(newNoteHistoryId, ctx.sourceId); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         await protectNoteHistory(noteId, ctx.getDataKeyOrNull(), newNote.detail.is_protected); |         await protectNoteHistory(noteId, ctx.getDataKeyOrNull(), newNote.detail.is_protected); | ||||||
| @@ -186,15 +186,15 @@ async function updateNote(noteId, newNote, ctx) { | |||||||
|             nowStr, |             nowStr, | ||||||
|             noteId]); |             noteId]); | ||||||
|  |  | ||||||
|         await sync_table.addNoteSync(noteId); |         await sync_table.addNoteSync(noteId, ctx.sourceId); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function deleteNote(noteTreeId) { | async function deleteNote(noteTreeId, sourceId) { | ||||||
|     const now = utils.nowDate(); |     const now = utils.nowDate(); | ||||||
|  |  | ||||||
|     await sql.execute("UPDATE notes_tree SET is_deleted = 1, date_modified = ? WHERE note_tree_id = ?", [now, noteTreeId]); |     await sql.execute("UPDATE notes_tree SET is_deleted = 1, date_modified = ? WHERE note_tree_id = ?", [now, noteTreeId]); | ||||||
|     await sync_table.addNoteTreeSync(noteTreeId); |     await sync_table.addNoteTreeSync(noteTreeId, sourceId); | ||||||
|  |  | ||||||
|     const noteId = await sql.getSingleValue("SELECT note_id FROM notes_tree WHERE note_tree_id = ?", [noteTreeId]); |     const noteId = await sql.getSingleValue("SELECT note_id FROM notes_tree WHERE note_tree_id = ?", [noteTreeId]); | ||||||
|  |  | ||||||
| @@ -202,12 +202,12 @@ async function deleteNote(noteTreeId) { | |||||||
|  |  | ||||||
|     if (!notDeletedNoteTreesCount) { |     if (!notDeletedNoteTreesCount) { | ||||||
|         await sql.execute("UPDATE notes SET is_deleted = 1, date_modified = ? WHERE note_id = ?", [now, noteId]); |         await sql.execute("UPDATE notes SET is_deleted = 1, date_modified = ? WHERE note_id = ?", [now, noteId]); | ||||||
|         await sync_table.addNoteSync(noteId); |         await sync_table.addNoteSync(noteId, sourceId); | ||||||
|  |  | ||||||
|         const children = await sql.getResults("SELECT note_tree_id FROM notes_tree WHERE note_pid = ? AND is_deleted = 0", [noteId]); |         const children = await sql.getResults("SELECT note_tree_id FROM notes_tree WHERE note_pid = ? AND is_deleted = 0", [noteId]); | ||||||
|  |  | ||||||
|         for (const child of children) { |         for (const child of children) { | ||||||
|             await deleteNote(child.note_tree_id); |             await deleteNote(child.note_tree_id, sourceId); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,9 +16,9 @@ async function getOption(optName) { | |||||||
|     return row['opt_value']; |     return row['opt_value']; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function setOption(optName, optValue) { | async function setOption(optName, optValue, sourceId) { | ||||||
|     if (SYNCED_OPTIONS.includes(optName)) { |     if (SYNCED_OPTIONS.includes(optName)) { | ||||||
|         await sync_table.addOptionsSync(optName); |         await sync_table.addOptionsSync(optName, sourceId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     await sql.replace("options", { |     await sql.replace("options", { | ||||||
|   | |||||||
| @@ -1,5 +1,4 @@ | |||||||
| const sql = require('./sql'); | const sql = require('./sql'); | ||||||
| const source_id = require('./source_id'); |  | ||||||
| const utils = require('./utils'); | const utils = require('./utils'); | ||||||
| const messaging = require('./messaging'); | const messaging = require('./messaging'); | ||||||
| const options = require('./options'); | const options = require('./options'); | ||||||
| @@ -9,24 +8,10 @@ let startTime = utils.nowDate(); | |||||||
| let sentSyncId = []; | let sentSyncId = []; | ||||||
|  |  | ||||||
| async function sendPing() { | async function sendPing() { | ||||||
|     const syncs = await sql.getResults("SELECT * FROM sync WHERE sync_date >= ? AND source_id != ?", [startTime, source_id.currentSourceId]); |     const syncs = await sql.getResults("SELECT * FROM sync WHERE sync_date >= ?", [startTime]); | ||||||
|     startTime = utils.nowDate(); |     startTime = utils.nowDate(); | ||||||
|  |  | ||||||
|     const data = {}; |     const syncData = syncs.filter(sync => !sentSyncId.includes(sync.id)); | ||||||
|     const syncIds = []; |  | ||||||
|  |  | ||||||
|     for (const sync of syncs) { |  | ||||||
|         if (sentSyncId.includes(sync.id)) { |  | ||||||
|             continue; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (!data[sync.entity_name]) { |  | ||||||
|             data[sync.entity_name] = []; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         data[sync.entity_name].push(sync.entity_id); |  | ||||||
|         syncIds.push(sync.id); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const lastSyncedPush = await options.getOption('last_synced_push'); |     const lastSyncedPush = await options.getOption('last_synced_push'); | ||||||
|  |  | ||||||
| @@ -34,12 +19,12 @@ async function sendPing() { | |||||||
|  |  | ||||||
|     messaging.sendMessage({ |     messaging.sendMessage({ | ||||||
|         type: 'sync', |         type: 'sync', | ||||||
|         data: data, |         data: syncData, | ||||||
|         changesToPushCount: sync_setup.isSyncSetup ? changesToPushCount : 0 |         changesToPushCount: sync_setup.isSyncSetup ? changesToPushCount : 0 | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     for (const syncId of syncIds) { |     for (const sync of syncData) { | ||||||
|         sentSyncId.push(syncId); |         sentSyncId.push(sync.id); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ function setDataKey(req, decryptedDataKey) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function getProtectedSessionId(req) { | function getProtectedSessionId(req) { | ||||||
|     return req.headers['x-protected-session-id']; |     return req.headers.protected_session_id; | ||||||
| } | } | ||||||
|  |  | ||||||
| function getDataKey(req) { | function getDataKey(req) { | ||||||
|   | |||||||
| @@ -3,6 +3,8 @@ | |||||||
| const protected_session = require('./protected_session'); | const protected_session = require('./protected_session'); | ||||||
|  |  | ||||||
| module.exports = function(req) { | module.exports = function(req) { | ||||||
|  |     const sourceId = req.headers.source_id; | ||||||
|  |  | ||||||
|     function isProtectedSessionAvailable() { |     function isProtectedSessionAvailable() { | ||||||
|         return protected_session.isProtectedSessionAvailable(req); |         return protected_session.isProtectedSessionAvailable(req); | ||||||
|     } |     } | ||||||
| @@ -24,6 +26,7 @@ module.exports = function(req) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     return { |     return { | ||||||
|  |         sourceId, | ||||||
|         isProtectedSessionAvailable, |         isProtectedSessionAvailable, | ||||||
|         getDataKey, |         getDataKey, | ||||||
|         getDataKeyOrNull |         getDataKeyOrNull | ||||||
|   | |||||||
| @@ -2,31 +2,39 @@ const utils = require('./utils'); | |||||||
| const log = require('./log'); | const log = require('./log'); | ||||||
| const sql = require('./sql'); | const sql = require('./sql'); | ||||||
|  |  | ||||||
| const currentSourceId = utils.randomString(12); | async function generateSourceId() { | ||||||
|  |     const sourceId = utils.randomString(12); | ||||||
|  |  | ||||||
| log.info("Using sourceId=" + currentSourceId); |     log.info("Generated sourceId=" + sourceId); | ||||||
|  |  | ||||||
|  |     await sql.doInTransaction(async () => { | ||||||
|  |         await sql.insert("source_ids", { | ||||||
|  |             source_id: sourceId, | ||||||
|  |             date_created: utils.nowDate() | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     await refreshSourceIds(); | ||||||
|  |  | ||||||
|  |     return sourceId; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function refreshSourceIds() { | ||||||
|  |     allSourceIds = await sql.getFlattenedResults("SELECT source_id FROM source_ids ORDER BY date_created DESC"); | ||||||
|  | } | ||||||
|  |  | ||||||
| let allSourceIds = []; | let allSourceIds = []; | ||||||
|  |  | ||||||
| sql.dbReady.then(async () => { | sql.dbReady.then(refreshSourceIds); | ||||||
|     try { |  | ||||||
|         await sql.doInTransaction(async () => { |  | ||||||
|             await sql.insert("source_ids", { |  | ||||||
|                 source_id: currentSourceId, |  | ||||||
|                 date_created: utils.nowDate() |  | ||||||
|             }); |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         allSourceIds = await sql.getFlattenedResults("SELECT source_id FROM source_ids ORDER BY date_created DESC"); |  | ||||||
|     } |  | ||||||
|     catch (e) {} |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| function isLocalSourceId(srcId) { | function isLocalSourceId(srcId) { | ||||||
|     return allSourceIds.includes(srcId); |     return allSourceIds.includes(srcId); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | const currentSourceId = generateSourceId(); | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|  |     generateSourceId, | ||||||
|     currentSourceId, |     currentSourceId, | ||||||
|     isLocalSourceId |     isLocalSourceId | ||||||
| }; | }; | ||||||
| @@ -291,6 +291,10 @@ | |||||||
|  |  | ||||||
|     <script type="text/javascript"> |     <script type="text/javascript"> | ||||||
|       const baseApiUrl = 'api/'; |       const baseApiUrl = 'api/'; | ||||||
|  |       const glob = { | ||||||
|  |           activeDialog: null, | ||||||
|  |           sourceId: '<%= sourceId %>' | ||||||
|  |       }; | ||||||
|     </script> |     </script> | ||||||
|  |  | ||||||
|     <!-- Required for correct loading of scripts in Electron --> |     <!-- Required for correct loading of scripts in Electron --> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user