mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	converted note revision protection to repository/entities
This commit is contained in:
		
							
								
								
									
										5
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -4418,11 +4418,6 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "express-promise-wrap": { | ||||
|       "version": "0.2.2", | ||||
|       "resolved": "https://registry.npmjs.org/express-promise-wrap/-/express-promise-wrap-0.2.2.tgz", | ||||
|       "integrity": "sha1-d9lx4UDbIPsnw3zMUwmSREyKBG0=" | ||||
|     }, | ||||
|     "express-session": { | ||||
|       "version": "1.15.6", | ||||
|       "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.6.tgz", | ||||
|   | ||||
| @@ -34,7 +34,6 @@ | ||||
|     "electron-in-page-search": "^1.2.4", | ||||
|     "electron-rebuild": "^1.7.3", | ||||
|     "express": "~4.16.3", | ||||
|     "express-promise-wrap": "^0.2.2", | ||||
|     "express-session": "^1.15.6", | ||||
|     "fs-extra": "^4.0.3", | ||||
|     "helmet": "^3.12.0", | ||||
|   | ||||
| @@ -10,6 +10,7 @@ const FileStore = require('session-file-store')(session); | ||||
| const os = require('os'); | ||||
| const sessionSecret = require('./services/session_secret'); | ||||
| const cls = require('./services/cls'); | ||||
| require('./entities/entity_constructor'); | ||||
|  | ||||
| const app = express(); | ||||
|  | ||||
|   | ||||
| @@ -5,14 +5,6 @@ const Entity = require('./entity'); | ||||
| class Branch extends Entity { | ||||
|     static get tableName() { return "branches"; } | ||||
|     static get primaryKeyName() { return "branchId"; } | ||||
|  | ||||
|     async getNote() { | ||||
|         return this.repository.getEntity("SELECT * FROM branches WHERE isDeleted = 0 AND noteId = ?", [this.noteId]); | ||||
|     } | ||||
|  | ||||
|     async getParentNote() { | ||||
|         return this.repository.getEntity("SELECT * FROM branches WHERE isDeleted = 0 AND parentNoteId = ?", [this.parentNoteId]); | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = Branch; | ||||
							
								
								
									
										33
									
								
								src/entities/entity_constructor.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/entities/entity_constructor.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| const Note = require('../entities/note'); | ||||
| const NoteRevision = require('../entities/note_revision'); | ||||
| const Branch = require('../entities/branch'); | ||||
| const Label = require('../entities/label'); | ||||
| const repository = require('../services/repository'); | ||||
|  | ||||
| function createEntityFromRow(row) { | ||||
|     let entity; | ||||
|  | ||||
|     if (row.labelId) { | ||||
|         entity = new Label(row); | ||||
|     } | ||||
|     else if (row.noteRevisionId) { | ||||
|         entity = new NoteRevision(row); | ||||
|     } | ||||
|     else if (row.branchId) { | ||||
|         entity = new Branch(row); | ||||
|     } | ||||
|     else if (row.noteId) { | ||||
|         entity = new Note(row); | ||||
|     } | ||||
|     else { | ||||
|         throw new Error('Unknown entity type for row: ' + JSON.stringify(row)); | ||||
|     } | ||||
|  | ||||
|     return entity; | ||||
| } | ||||
|  | ||||
| repository.setEntityConstructor(createEntityFromRow); | ||||
|  | ||||
| module.exports = { | ||||
|     createEntityFromRow | ||||
| }; | ||||
| @@ -1,13 +1,14 @@ | ||||
| "use strict"; | ||||
|  | ||||
| const Entity = require('./entity'); | ||||
| const repository = require('../services/repository'); | ||||
|  | ||||
| class Label extends Entity { | ||||
|     static get tableName() { return "labels"; } | ||||
|     static get primaryKeyName() { return "labelId"; } | ||||
|  | ||||
|     async getNote() { | ||||
|         return this.repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]); | ||||
|         return await repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -2,13 +2,14 @@ | ||||
|  | ||||
| const Entity = require('./entity'); | ||||
| const protected_session = require('../services/protected_session'); | ||||
| const repository = require('../services/repository'); | ||||
|  | ||||
| class Note extends Entity { | ||||
|     static get tableName() { return "notes"; } | ||||
|     static get primaryKeyName() { return "noteId"; } | ||||
|  | ||||
|     constructor(repository, row) { | ||||
|         super(repository, row); | ||||
|     constructor(row) { | ||||
|         super(row); | ||||
|  | ||||
|         if (this.isProtected) { | ||||
|             protected_session.decryptNote(this); | ||||
| @@ -49,7 +50,7 @@ class Note extends Entity { | ||||
|     } | ||||
|  | ||||
|     async getLabels() { | ||||
|         return this.repository.getEntities("SELECT * FROM labels WHERE noteId = ? AND isDeleted = 0", [this.noteId]); | ||||
|         return await repository.getEntities("SELECT * FROM labels WHERE noteId = ? AND isDeleted = 0", [this.noteId]); | ||||
|     } | ||||
|  | ||||
|     // WARNING: this doesn't take into account the possibility to have multi-valued labels! | ||||
| @@ -71,19 +72,19 @@ class Note extends Entity { | ||||
|  | ||||
|     // WARNING: this doesn't take into account the possibility to have multi-valued labels! | ||||
|     async getLabel(name) { | ||||
|         return this.repository.getEntity("SELECT * FROM labels WHERE noteId = ? AND name = ?", [this.noteId, name]); | ||||
|         return await repository.getEntity("SELECT * FROM labels WHERE noteId = ? AND name = ?", [this.noteId, name]); | ||||
|     } | ||||
|  | ||||
|     async getRevisions() { | ||||
|         return this.repository.getEntities("SELECT * FROM note_revisions WHERE noteId = ?", [this.noteId]); | ||||
|         return await repository.getEntities("SELECT * FROM note_revisions WHERE noteId = ?", [this.noteId]); | ||||
|     } | ||||
|  | ||||
|     async getTrees() { | ||||
|         return this.repository.getEntities("SELECT * FROM branches WHERE isDeleted = 0 AND noteId = ?", [this.noteId]); | ||||
|         return await repository.getEntities("SELECT * FROM branches WHERE isDeleted = 0 AND noteId = ?", [this.noteId]); | ||||
|     } | ||||
|  | ||||
|     async getChild(name) { | ||||
|         return this.repository.getEntity(` | ||||
|         return await repository.getEntity(` | ||||
|           SELECT notes.*  | ||||
|           FROM branches  | ||||
|             JOIN notes USING(noteId)  | ||||
| @@ -94,7 +95,7 @@ class Note extends Entity { | ||||
|     } | ||||
|  | ||||
|     async getChildren() { | ||||
|         return this.repository.getEntities(` | ||||
|         return await repository.getEntities(` | ||||
|           SELECT notes.*  | ||||
|           FROM branches  | ||||
|             JOIN notes USING(noteId)  | ||||
| @@ -105,7 +106,7 @@ class Note extends Entity { | ||||
|     } | ||||
|  | ||||
|     async getParents() { | ||||
|         return this.repository.getEntities(` | ||||
|         return await repository.getEntities(` | ||||
|           SELECT parent_notes.*  | ||||
|           FROM  | ||||
|             branches AS child_tree  | ||||
| @@ -116,7 +117,7 @@ class Note extends Entity { | ||||
|     } | ||||
|  | ||||
|     async getBranch() { | ||||
|         return this.repository.getEntities(` | ||||
|         return await repository.getEntities(` | ||||
|           SELECT branches.*  | ||||
|           FROM branches  | ||||
|             JOIN notes USING(noteId)  | ||||
|   | ||||
| @@ -1,13 +1,29 @@ | ||||
| "use strict"; | ||||
|  | ||||
| const Entity = require('./entity'); | ||||
| const protected_session = require('../services/protected_session'); | ||||
| const repository = require('../services/repository'); | ||||
|  | ||||
| class NoteRevision extends Entity { | ||||
|     static get tableName() { return "note_revisions"; } | ||||
|     static get primaryKeyName() { return "noteRevisionId"; } | ||||
|  | ||||
|     constructor(row) { | ||||
|         super(row); | ||||
|  | ||||
|         if (this.isProtected) { | ||||
|             protected_session.decryptNoteRevision(this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async getNote() { | ||||
|         return this.repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]); | ||||
|         return await repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]); | ||||
|     } | ||||
|  | ||||
|     beforeSaving() { | ||||
|         if (this.isProtected) { | ||||
|             protected_session.encryptNoteRevision(this); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,14 +1,9 @@ | ||||
| "use strict"; | ||||
|  | ||||
| const express = require('express'); | ||||
| const router = express.Router(); | ||||
| const sql = require('../../services/sql'); | ||||
| const auth = require('../../services/auth'); | ||||
| const labels = require('../../services/labels'); | ||||
| const notes = require('../../services/notes'); | ||||
| const wrap = require('express-promise-wrap').wrap; | ||||
| const tar = require('tar-stream'); | ||||
| const multer = require('multer')(); | ||||
| const stream = require('stream'); | ||||
| const path = require('path'); | ||||
|  | ||||
|   | ||||
| @@ -1,15 +1,12 @@ | ||||
| "use strict"; | ||||
|  | ||||
| const express = require('express'); | ||||
| const router = express.Router(); | ||||
| const auth = require('../../services/auth'); | ||||
| const sql = require('../../services/sql'); | ||||
| const notes = require('../../services/notes'); | ||||
| const utils = require('../../services/utils'); | ||||
| const protected_session = require('../../services/protected_session'); | ||||
| const tree = require('../../services/tree'); | ||||
| const sync_table = require('../../services/sync_table'); | ||||
| const wrap = require('express-promise-wrap').wrap; | ||||
| const repository = require('../../services/repository'); | ||||
|  | ||||
| async function getNote(req) { | ||||
|     const noteId = req.params.noteId; | ||||
| @@ -58,9 +55,10 @@ async function sortNotes(req) { | ||||
|  | ||||
| async function protectBranch(req) { | ||||
|     const noteId = req.params.noteId; | ||||
|     const isProtected = !!parseInt(req.params.isProtected); | ||||
|     const note = repository.getNote(noteId); | ||||
|     const protect = !!parseInt(req.params.isProtected); | ||||
|  | ||||
|     await notes.protectNoteRecursively(noteId, isProtected); | ||||
|     await notes.protectNoteRecursively(note, protect); | ||||
| } | ||||
|  | ||||
| async function setNoteTypeMime(req) { | ||||
|   | ||||
| @@ -1,14 +1,10 @@ | ||||
| "use strict"; | ||||
|  | ||||
| const express = require('express'); | ||||
| const router = express.Router(); | ||||
| const image = require('../../services/image'); | ||||
| const utils = require('../../services/utils'); | ||||
| const date_notes = require('../../services/date_notes'); | ||||
| const sql = require('../../services/sql'); | ||||
| const wrap = require('express-promise-wrap').wrap; | ||||
| const notes = require('../../services/notes'); | ||||
| const multer = require('multer')(); | ||||
| const password_encryption = require('../../services/password_encryption'); | ||||
| const options = require('../../services/options'); | ||||
| const sync_table = require('../../services/sync_table'); | ||||
|   | ||||
| @@ -4,6 +4,7 @@ const utils = require('./utils'); | ||||
| const sync_table = require('./sync_table'); | ||||
| const labels = require('./labels'); | ||||
| const protected_session = require('./protected_session'); | ||||
| const repository = require('./repository'); | ||||
|  | ||||
| async function createNewNote(parentNoteId, noteOpts) { | ||||
|     const noteId = utils.newNoteId(); | ||||
| @@ -117,15 +118,11 @@ async function createNote(parentNoteId, title, content = "", extraOptions = {}) | ||||
|     return noteId; | ||||
| } | ||||
|  | ||||
| async function protectNoteRecursively(noteId, protect) { | ||||
|     const note = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]); | ||||
|  | ||||
| async function protectNoteRecursively(note, protect) { | ||||
|     await protectNote(note, protect); | ||||
|  | ||||
|     const children = await sql.getColumn("SELECT noteId FROM branches WHERE parentNoteId = ? AND isDeleted = 0", [noteId]); | ||||
|  | ||||
|     for (const childNoteId of children) { | ||||
|         await protectNoteRecursively(childNoteId, protect); | ||||
|     for (const child of await note.getChildren()) { | ||||
|         await protectNoteRecursively(child, protect); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -133,47 +130,43 @@ async function protectNote(note, protect) { | ||||
|     let changed = false; | ||||
|  | ||||
|     if (protect && !note.isProtected) { | ||||
|         protected_session.encryptNote(note); | ||||
|  | ||||
|         note.isProtected = true; | ||||
|  | ||||
|         changed = true; | ||||
|     } | ||||
|     else if (!protect && note.isProtected) { | ||||
|         protected_session.decryptNote(note); | ||||
|  | ||||
|         note.isProtected = false; | ||||
|  | ||||
|         changed = true; | ||||
|     } | ||||
|  | ||||
|     if (changed) { | ||||
|         await sql.execute("UPDATE notes SET title = ?, content = ?, isProtected = ? WHERE noteId = ?", | ||||
|             [note.title, note.content, note.isProtected, note.noteId]); | ||||
|         await repository.updateEntity(note); | ||||
|  | ||||
|         await sync_table.addNoteSync(note.noteId); | ||||
|     } | ||||
|  | ||||
|     await protectNoteRevisions(note.noteId, protect); | ||||
|     await protectNoteRevisions(note, protect); | ||||
| } | ||||
|  | ||||
| async function protectNoteRevisions(noteId, protect) { | ||||
|     const revisionsToChange = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? AND isProtected != ?", [noteId, protect]); | ||||
|  | ||||
|     for (const revision of revisionsToChange) { | ||||
|         if (protect) { | ||||
|             protected_session.encryptNoteRevision(revision); | ||||
| async function protectNoteRevisions(note, protect) { | ||||
|     for (const revision of await note.getRevisions()) { | ||||
|         let changed = false; | ||||
|  | ||||
|         if (protect && !revision.isProtected) { | ||||
|             revision.isProtected = true; | ||||
|         } | ||||
|         else { | ||||
|             protected_session.decryptNoteRevision(revision); | ||||
|  | ||||
|             changed = true; | ||||
|         } | ||||
|         else if(!protect && revision.isProtected) { | ||||
|             revision.isProtected = false; | ||||
|  | ||||
|             changed = true; | ||||
|         } | ||||
|  | ||||
|         await sql.execute("UPDATE note_revisions SET title = ?, content = ?, isProtected = ? WHERE noteRevisionId = ?", | ||||
|             [revision.title, revision.content, revision.isProtected, revision.noteRevisionId]); | ||||
|         if (changed) { | ||||
|             await repository.updateEntity(revision); | ||||
|         } | ||||
|  | ||||
|         await sync_table.addNoteRevisionSync(revision.noteRevisionId); | ||||
|     } | ||||
| @@ -298,7 +291,7 @@ async function updateNote(noteId, newNote) { | ||||
|  | ||||
|         await saveNoteImages(noteId, newNote.content); | ||||
|  | ||||
|         await protectNoteRevisions(noteId, newNote.isProtected); | ||||
|         await protectNoteRevisions(await repository.getNote(noteId), newNote.isProtected); | ||||
|  | ||||
|         await sql.execute("UPDATE notes SET title = ?, content = ?, isProtected = ?, dateModified = ? WHERE noteId = ?", [ | ||||
|             newNote.title, | ||||
|   | ||||
| @@ -1,16 +1,18 @@ | ||||
| "use strict"; | ||||
|  | ||||
| const sql = require('./sql'); | ||||
| const Note = require('../entities/note'); | ||||
| const NoteRevision = require('../entities/note_revision'); | ||||
| const Branch = require('../entities/branch'); | ||||
| const Label = require('../entities/label'); | ||||
| const sync_table = require('../services/sync_table'); | ||||
|  | ||||
| let entityConstructor; | ||||
|  | ||||
| async function setEntityConstructor(constructor) { | ||||
|     entityConstructor = constructor; | ||||
| } | ||||
|  | ||||
| async function getEntities(query, params = []) { | ||||
|     const rows = await sql.getRows(query, params); | ||||
|  | ||||
|     return rows.map(row => this.createEntityFromRow(row)); | ||||
|     return rows.map(entityConstructor); | ||||
| } | ||||
|  | ||||
| async function getEntity(query, params = []) { | ||||
| @@ -20,33 +22,11 @@ async function getEntity(query, params = []) { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     return this.createEntityFromRow(row); | ||||
|     return entityConstructor(row); | ||||
| } | ||||
|  | ||||
| async function getNote(noteId) { | ||||
|     return await this.getEntity("SELECT * FROM notes WHERE noteId = ?", [noteId]); | ||||
| } | ||||
|  | ||||
| function createEntityFromRow(row) { | ||||
|     let entity; | ||||
|  | ||||
|     if (row.labelId) { | ||||
|         entity = new Label(row); | ||||
|     } | ||||
|     else if (row.noteRevisionId) { | ||||
|         entity = new NoteRevision(row); | ||||
|     } | ||||
|     else if (row.branchId) { | ||||
|         entity = new Branch(row); | ||||
|     } | ||||
|     else if (row.noteId) { | ||||
|         entity = new Note(row); | ||||
|     } | ||||
|     else { | ||||
|         throw new Error('Unknown entity type for row: ' + JSON.stringify(row)); | ||||
|     } | ||||
|  | ||||
|     return entity; | ||||
|     return await getEntity("SELECT * FROM notes WHERE noteId = ?", [noteId]); | ||||
| } | ||||
|  | ||||
| async function updateEntity(entity) { | ||||
| @@ -69,5 +49,6 @@ module.exports = { | ||||
|     getEntities, | ||||
|     getEntity, | ||||
|     getNote, | ||||
|     updateEntity | ||||
|     updateEntity, | ||||
|     setEntityConstructor | ||||
| }; | ||||
| @@ -41,7 +41,7 @@ function ScriptApi(startNote, currentNote) { | ||||
|     this.getInstanceName = () => config.General ? config.General.instanceName : null; | ||||
|  | ||||
|     this.getNoteById = async function(noteId) { | ||||
|         return repository.getNote(noteId); | ||||
|         return await repository.getNote(noteId); | ||||
|     }; | ||||
|  | ||||
|     this.getNotesWithLabel = async function (attrName, attrValue) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user