mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	Compare commits
	
		
			21 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 6afc299efb | ||
|  | 369274ead7 | ||
|  | 04e6431c09 | ||
|  | e89057a771 | ||
|  | 4f27254e64 | ||
|  | 577dc95ab8 | ||
|  | a266d6a3d5 | ||
|  | 749b6cb57e | ||
|  | b0b2951ff6 | ||
|  | 1f3d73b9fd | ||
|  | bdfd760b9d | ||
|  | 7133e60267 | ||
|  | fc4edf4aa7 | ||
|  | eaf93a70cd | ||
|  | b093569ec5 | ||
|  | 4633c68a0c | ||
|  | 33571e0ef3 | ||
|  | 31876d2cf9 | ||
|  | 81c6043cb6 | ||
|  | 1982d054ef | ||
|  | e56979c482 | 
| @@ -1,5 +1,5 @@ | ||||
| [General] | ||||
| # Instance name can be used to distinguish between different instances | ||||
| # Instance name can be used to distinguish between different instances using backend api.getInstanceName() | ||||
| instanceName= | ||||
|  | ||||
| # set to true to allow using Trilium without authentication (makes sense for server build only, desktop build doesn't need password) | ||||
|   | ||||
							
								
								
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "trilium", | ||||
|   "version": "0.45.5", | ||||
|   "version": "0.45.6", | ||||
|   "lockfileVersion": 1, | ||||
|   "requires": true, | ||||
|   "dependencies": { | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   "name": "trilium", | ||||
|   "productName": "Trilium Notes", | ||||
|   "description": "Trilium Notes", | ||||
|   "version": "0.45.6", | ||||
|   "version": "0.45.8", | ||||
|   "license": "AGPL-3.0-only", | ||||
|   "main": "electron.js", | ||||
|   "bin": { | ||||
|   | ||||
| @@ -51,6 +51,12 @@ const TPL = ` | ||||
|         <label for="erase-notes-after-time-in-seconds">Erase notes after X seconds</label> | ||||
|         <input class="form-control" id="erase-notes-after-time-in-seconds" type="number" min="0"> | ||||
|     </div> | ||||
|      | ||||
|     <p>You can also trigger erasing manually:</p> | ||||
|      | ||||
|     <button id="erase-deleted-notes-now-button" class="btn">Erase deleted notes now</button> | ||||
|      | ||||
|     <br/><br/> | ||||
| </div> | ||||
|  | ||||
| <div> | ||||
| @@ -117,6 +123,13 @@ export default class ProtectedSessionOptions { | ||||
|             return false; | ||||
|         }); | ||||
|  | ||||
|         this.$eraseDeletedNotesButton = $("#erase-deleted-notes-now-button"); | ||||
|         this.$eraseDeletedNotesButton.on('click', () => { | ||||
|             server.post('notes/erase-deleted-notes-now').then(() => { | ||||
|                 toastService.showMessage("Deleted notes have been erased."); | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         this.$protectedSessionTimeout = $("#protected-session-timeout-in-seconds"); | ||||
|  | ||||
|         this.$protectedSessionTimeout.on('change', () => { | ||||
|   | ||||
| @@ -75,15 +75,17 @@ class NoteShort { | ||||
|         this.parentToBranch[parentNoteId] = branchId; | ||||
|     } | ||||
|  | ||||
|     addChild(childNoteId, branchId) { | ||||
|     addChild(childNoteId, branchId, sort = true) { | ||||
|         if (!this.children.includes(childNoteId)) { | ||||
|             this.children.push(childNoteId); | ||||
|         } | ||||
|  | ||||
|         this.childToBranch[childNoteId] = branchId; | ||||
|  | ||||
|         if (sort) { | ||||
|             this.sortChildren(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     sortChildren() { | ||||
|         const branchIdPos = {}; | ||||
|   | ||||
| @@ -8,8 +8,8 @@ async function syncNow() { | ||||
|         toastService.showMessage("Sync finished successfully."); | ||||
|     } | ||||
|     else { | ||||
|         if (result.message.length > 100) { | ||||
|             result.message = result.message.substr(0, 100); | ||||
|         if (result.message.length > 200) { | ||||
|             result.message = result.message.substr(0, 200) + "..."; | ||||
|         } | ||||
|  | ||||
|         toastService.showError("Sync failed: " + result.message); | ||||
|   | ||||
| @@ -87,6 +87,8 @@ class TreeCache { | ||||
|         const branchRows = resp.branches; | ||||
|         const attributeRows = resp.attributes; | ||||
|  | ||||
|         const noteIdsToSort = new Set(); | ||||
|  | ||||
|         for (const noteRow of noteRows) { | ||||
|             const {noteId} = noteRow; | ||||
|  | ||||
| @@ -153,7 +155,9 @@ class TreeCache { | ||||
|             const parentNote = this.notes[branch.parentNoteId]; | ||||
|  | ||||
|             if (parentNote) { | ||||
|                 parentNote.addChild(branch.noteId, branch.branchId); | ||||
|                 parentNote.addChild(branch.noteId, branch.branchId, false); | ||||
|  | ||||
|                 noteIdsToSort.add(parentNote.noteId); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -178,6 +182,11 @@ class TreeCache { | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // sort all of them at once, this avoids repeated sorts (#1480) | ||||
|         for (const noteId of noteIdsToSort) { | ||||
|             this.notes[noteId].sortChildren(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async reloadNotes(noteIds) { | ||||
|   | ||||
| @@ -248,13 +248,22 @@ export default class NoteDetailWidget extends TabAwareWidget { | ||||
|  | ||||
|         this.$widget.find('.note-detail-printable:visible').printThis({ | ||||
|             header: $("<h2>").text(this.note && this.note.title).prop('outerHTML'), | ||||
|             footer: "<script>document.body.className += ' ck-content printed-content';</script>", | ||||
|             footer: ` | ||||
| <script src="libraries/katex/katex.min.js"></script> | ||||
| <script src="libraries/katex/auto-render.min.js"></script> | ||||
| <script> | ||||
|     document.body.className += ' ck-content printed-content'; | ||||
|      | ||||
|     renderMathInElement(document.body, {}); | ||||
| </script> | ||||
| `, | ||||
|             importCSS: false, | ||||
|             loadCSS: [ | ||||
|                 "libraries/codemirror/codemirror.css", | ||||
|                 "libraries/ckeditor/ckeditor-content.css", | ||||
|                 "libraries/ckeditor/ckeditor-content.css", | ||||
|                 "libraries/bootstrap/css/bootstrap.min.css", | ||||
|                 "libraries/katex/katex.min.css", | ||||
|                 "stylesheets/print.css", | ||||
|                 "stylesheets/relation_map.css", | ||||
|                 "stylesheets/themes.css" | ||||
|   | ||||
| @@ -38,7 +38,7 @@ const TPL = ` | ||||
|         cursor: text !important; | ||||
|     } | ||||
|      | ||||
|     .note-detail-editable-text *:first-child { | ||||
|     .note-detail-editable-text *:not(figure):first-child { | ||||
|         margin-top: 0 !important; | ||||
|     } | ||||
|      | ||||
|   | ||||
| @@ -23,11 +23,7 @@ function exportBranch(req, res) { | ||||
|  | ||||
|     try { | ||||
|         if (type === 'subtree' && (format === 'html' || format === 'markdown')) { | ||||
|             const start = Date.now(); | ||||
|  | ||||
|             zipExportService.exportToZip(taskContext, branch, format, res); | ||||
|  | ||||
|             console.log("Export took", Date.now() - start, "ms"); | ||||
|         } | ||||
|         else if (type === 'single') { | ||||
|             singleExportService.exportSingleNote(taskContext, branch, format, res); | ||||
|   | ||||
| @@ -193,6 +193,10 @@ function duplicateSubtree(req) { | ||||
|     return noteService.duplicateSubtree(noteId, parentNoteId); | ||||
| } | ||||
|  | ||||
| function eraseDeletedNotesNow() { | ||||
|     noteService.eraseDeletedNotesNow(); | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|     getNote, | ||||
|     updateNote, | ||||
| @@ -204,5 +208,6 @@ module.exports = { | ||||
|     setNoteTypeMime, | ||||
|     getRelationMap, | ||||
|     changeTitle, | ||||
|     duplicateSubtree | ||||
|     duplicateSubtree, | ||||
|     eraseDeletedNotesNow | ||||
| }; | ||||
|   | ||||
| @@ -38,6 +38,8 @@ function saveSyncSeed(req) { | ||||
|         }] | ||||
|     } | ||||
|  | ||||
|     log.info("Saved sync seed."); | ||||
|  | ||||
|     sqlInit.createDatabaseForSync(options); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -57,7 +57,7 @@ function getTree(req) { | ||||
|     const noteIds = sql.getColumn(` | ||||
|         WITH RECURSIVE | ||||
|             treeWithDescendants(noteId, isExpanded) AS ( | ||||
|                 SELECT noteId, 1 FROM branches WHERE parentNoteId = ? AND isDeleted = 0 | ||||
|                 SELECT noteId, isExpanded FROM branches WHERE parentNoteId = ? AND isDeleted = 0 | ||||
|                 UNION | ||||
|                 SELECT branches.noteId, branches.isExpanded FROM branches | ||||
|                   JOIN treeWithDescendants ON branches.parentNoteId = treeWithDescendants.noteId | ||||
|   | ||||
| @@ -153,6 +153,7 @@ function register(app) { | ||||
|     route(GET, '/api/notes/:noteId/revisions/:noteRevisionId/download', [auth.checkApiAuthOrElectron], noteRevisionsApiRoute.downloadNoteRevision); | ||||
|     apiRoute(PUT, '/api/notes/:noteId/restore-revision/:noteRevisionId', noteRevisionsApiRoute.restoreNoteRevision); | ||||
|     apiRoute(POST, '/api/notes/relation-map', notesApiRoute.getRelationMap); | ||||
|     apiRoute(POST, '/api/notes/erase-deleted-notes-now', notesApiRoute.eraseDeletedNotesNow); | ||||
|     apiRoute(PUT, '/api/notes/:noteId/change-title', notesApiRoute.changeTitle); | ||||
|     apiRoute(POST, '/api/notes/:noteId/duplicate/:parentNoteId', notesApiRoute.duplicateSubtree); | ||||
|  | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| module.exports = { buildDate:"2020-12-04T22:08:24+01:00", buildRevision: "b7b1324dd0b2af6abc8cd5b98f620ca227582d4d" }; | ||||
| module.exports = { buildDate:"2021-01-11T22:29:31+01:00", buildRevision: "369274ead75947a68bf7bbb5ab1e784e81521030" }; | ||||
|   | ||||
| @@ -650,7 +650,7 @@ class ConsistencyChecks { | ||||
|         // root branch should always be expanded | ||||
|         sql.execute("UPDATE branches SET isExpanded = 1 WHERE branchId = 'root'"); | ||||
|  | ||||
|         if (this.unrecoveredConsistencyErrors) { | ||||
|         if (!this.unrecoveredConsistencyErrors) { | ||||
|             // we run this only if basic checks passed since this assumes basic data consistency | ||||
|  | ||||
|             this.checkTreeCycles(); | ||||
|   | ||||
| @@ -52,6 +52,10 @@ function encrypt(key, plainText, ivLength = 13) { | ||||
| } | ||||
|  | ||||
| function decrypt(key, cipherText, ivLength = 13) { | ||||
|     if (cipherText === null) { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     if (!key) { | ||||
|         return "[protected]"; | ||||
|     } | ||||
| @@ -93,6 +97,10 @@ function decrypt(key, cipherText, ivLength = 13) { | ||||
| function decryptString(dataKey, cipherText) { | ||||
|     const buffer = decrypt(dataKey, cipherText); | ||||
|  | ||||
|     if (buffer === null) { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     const str = buffer.toString('utf-8'); | ||||
|  | ||||
|     if (str === 'false') { | ||||
|   | ||||
| @@ -143,7 +143,7 @@ function exportToZip(taskContext, branch, format, res) { | ||||
|         const available = !note.isProtected || protectedSessionService.isProtectedSessionAvailable(); | ||||
|  | ||||
|         // if it's a leaf then we'll export it even if it's empty | ||||
|         if (available && ((note.getContent()).length > 0 || childBranches.length === 0)) { | ||||
|         if (available && (note.getContent().length > 0 || childBranches.length === 0)) { | ||||
|             meta.dataFileName = getDataFileName(note, baseFileName, existingFileNames); | ||||
|         } | ||||
|  | ||||
| @@ -234,7 +234,7 @@ function exportToZip(taskContext, branch, format, res) { | ||||
|     <link rel="stylesheet" href="${cssUrl}"> | ||||
|     <base target="_parent"> | ||||
| </head> | ||||
| <body> | ||||
| <body class="ck-content"> | ||||
|   <h1>${utils.escapeHtml(title)}</h1> | ||||
| ${content} | ||||
| </body> | ||||
| @@ -433,14 +433,13 @@ ${content} | ||||
|     } | ||||
|  | ||||
|     const note = branch.getNote(); | ||||
|     const zipFileName = (branch.prefix ? (branch.prefix + " - ") : "") + note.title + ".zip"; | ||||
|     const zipFileName = (branch.prefix ? `${branch.prefix} - ` : "") + note.title + ".zip"; | ||||
|  | ||||
|     res.setHeader('Content-Disposition', utils.getContentDisposition(zipFileName)); | ||||
|     res.setHeader('Content-Type', 'application/zip'); | ||||
|  | ||||
|     zipFile.end(); | ||||
|  | ||||
|     zipFile.outputStream.pipe(res); | ||||
|     zipFile.end(); | ||||
|  | ||||
|     taskContext.taskSucceeded(); | ||||
| } | ||||
|   | ||||
| @@ -70,6 +70,10 @@ eventService.subscribe(eventService.ENTITY_CREATED, ({ entityName, entity }) => | ||||
|                 if (templateNoteContent) { | ||||
|                     note.setContent(templateNoteContent); | ||||
|                 } | ||||
|  | ||||
|                 note.type = templateNote.type; | ||||
|                 note.mime = templateNote.mime; | ||||
|                 note.save(); | ||||
|             } | ||||
|  | ||||
|             noteService.duplicateSubtreeWithoutRoot(templateNote.noteId, note.noteId); | ||||
| @@ -90,10 +94,10 @@ eventService.subscribe(eventService.CHILD_NOTE_CREATED, ({ parentNote, childNote | ||||
| function processInverseRelations(entityName, entity, handler) { | ||||
|     if (entityName === 'attributes' && entity.type === 'relation') { | ||||
|         const note = entity.getNote(); | ||||
|         const attributes = (note.getOwnedAttributes(entity.name)).filter(relation => relation.type === 'relation-definition'); | ||||
|         const relDefinitions = note.getLabels('relation:' + entity.name); | ||||
|  | ||||
|         for (const attribute of attributes) { | ||||
|             const definition = attribute.value; | ||||
|         for (const relDefinition of relDefinitions) { | ||||
|             const definition = relDefinition.getDefinition(); | ||||
|  | ||||
|             if (definition.inverseRelation && definition.inverseRelation.trim()) { | ||||
|                 const targetNote = entity.getTargetNote(); | ||||
|   | ||||
| @@ -338,7 +338,7 @@ class Note { | ||||
|  | ||||
|     decrypt() { | ||||
|         if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) { | ||||
|             this.title = protectedSessionService.decryptString(note.title); | ||||
|             this.title = protectedSessionService.decryptString(this.title); | ||||
|  | ||||
|             this.isDecrypted = true; | ||||
|         } | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| const NoteRevision = require('../entities/note_revision'); | ||||
| const dateUtils = require('../services/date_utils'); | ||||
| const log = require('../services/log'); | ||||
|  | ||||
| /** | ||||
|  * @param {Note} note | ||||
| @@ -9,6 +10,7 @@ const dateUtils = require('../services/date_utils'); | ||||
| function protectNoteRevisions(note) { | ||||
|     for (const revision of note.getRevisions()) { | ||||
|         if (note.isProtected !== revision.isProtected) { | ||||
|             try { | ||||
|                 const content = revision.getContent(); | ||||
|  | ||||
|                 revision.isProtected = note.isProtected; | ||||
| @@ -18,6 +20,12 @@ function protectNoteRevisions(note) { | ||||
|  | ||||
|                 revision.save(); | ||||
|             } | ||||
|             catch (e) { | ||||
|                 log.error("Could not un/protect note revision ID = " + revision.noteRevisionId); | ||||
|  | ||||
|                 throw e; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -185,6 +185,7 @@ function protectNoteRecursively(note, protect, includingSubTree, taskContext) { | ||||
| } | ||||
|  | ||||
| function protectNote(note, protect) { | ||||
|     try { | ||||
|         if (protect !== note.isProtected) { | ||||
|             const content = note.getContent(); | ||||
|  | ||||
| @@ -197,6 +198,12 @@ function protectNote(note, protect) { | ||||
|         } | ||||
|  | ||||
|         noteRevisionService.protectNoteRevisions(note); | ||||
|     } | ||||
|     catch (e) { | ||||
|         log.error("Could not un/protect note ID = " + note.noteId); | ||||
|  | ||||
|         throw e; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function findImageLinks(content, foundLinks) { | ||||
| @@ -668,8 +675,10 @@ function scanForLinks(note) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| function eraseDeletedNotes() { | ||||
|     const eraseNotesAfterTimeInSeconds = optionService.getOptionInt('eraseNotesAfterTimeInSeconds'); | ||||
| function eraseDeletedNotes(eraseNotesAfterTimeInSeconds = null) { | ||||
|     if (eraseNotesAfterTimeInSeconds === null) { | ||||
|         eraseNotesAfterTimeInSeconds = optionService.getOptionInt('eraseNotesAfterTimeInSeconds'); | ||||
|     } | ||||
|  | ||||
|     const cutoffDate = new Date(Date.now() - eraseNotesAfterTimeInSeconds * 1000); | ||||
|  | ||||
| @@ -719,6 +728,10 @@ function eraseDeletedNotes() { | ||||
|     log.info(`Erased notes: ${JSON.stringify(noteIdsToErase)}`); | ||||
| } | ||||
|  | ||||
| function eraseDeletedNotesNow() { | ||||
|     eraseDeletedNotes(0); | ||||
| } | ||||
|  | ||||
| // do a replace in str - all keys should be replaced by the corresponding values | ||||
| function replaceByMap(str, mapObj) { | ||||
|     const re = new RegExp(Object.keys(mapObj).join("|"),"g"); | ||||
| @@ -825,9 +838,9 @@ function getNoteIdMapping(origNote) { | ||||
|  | ||||
| sqlInit.dbReady.then(() => { | ||||
|     // first cleanup kickoff 5 minutes after startup | ||||
|     setTimeout(cls.wrap(eraseDeletedNotes), 5 * 60 * 1000); | ||||
|     setTimeout(cls.wrap(() => eraseDeletedNotes()), 5 * 60 * 1000); | ||||
|  | ||||
|     setInterval(cls.wrap(eraseDeletedNotes), 4 * 3600 * 1000); | ||||
|     setInterval(cls.wrap(() => eraseDeletedNotes()), 4 * 3600 * 1000); | ||||
| }); | ||||
|  | ||||
| module.exports = { | ||||
| @@ -841,5 +854,6 @@ module.exports = { | ||||
|     duplicateSubtree, | ||||
|     duplicateSubtreeWithoutRoot, | ||||
|     getUndeletedParentBranches, | ||||
|     triggerNoteTitleChanged | ||||
|     triggerNoteTitleChanged, | ||||
|     eraseDeletedNotesNow | ||||
| }; | ||||
|   | ||||
| @@ -31,10 +31,7 @@ function initNotSyncedOptions(initialized, startNotePath = 'root', opts = {}) { | ||||
|     optionService.createOption('openTabs', JSON.stringify([ | ||||
|         { | ||||
|             notePath: startNotePath, | ||||
|             active: true, | ||||
|             sidebar: { | ||||
|                 widgets: [] | ||||
|             } | ||||
|             active: true | ||||
|         } | ||||
|     ]), false); | ||||
|  | ||||
| @@ -103,6 +100,15 @@ function initStartupOptions() { | ||||
|             log.info(`Created missing option "${name}" with default value "${value}"`); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (process.env.TRILIUM_START_NOTE_ID) { | ||||
|         optionService.setOption('openTabs', JSON.stringify([ | ||||
|             { | ||||
|                 notePath: process.env.TRILIUM_START_NOTE_ID, | ||||
|                 active: true | ||||
|             } | ||||
|         ])); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function getKeyboardDefaultOptions() { | ||||
|   | ||||
| @@ -43,10 +43,18 @@ function decryptNotes(notes) { | ||||
| } | ||||
|  | ||||
| function encrypt(plainText) { | ||||
|     if (plainText === null) { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     return dataEncryptionService.encrypt(getDataKey(), plainText); | ||||
| } | ||||
|  | ||||
| function decrypt(cipherText) { | ||||
|     if (cipherText === null) { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     return dataEncryptionService.decrypt(getDataKey(), cipherText); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -32,26 +32,29 @@ class NoteContentProtectedFulltextExp extends Expression { | ||||
|                 FROM notes JOIN note_contents USING (noteId)  | ||||
|                 WHERE type IN ('text', 'code') AND isDeleted = 0 AND isProtected = 1`)) { | ||||
|  | ||||
|             if (!inputNoteSet.hasNoteId(noteId) || !(noteId in noteCache.notes)) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             try { | ||||
|                 content = protectedSessionService.decryptString(content); | ||||
|             } | ||||
|             catch (e) { | ||||
|                 log.info('Cannot decrypt content of note', noteId); | ||||
|                 log.info(`Cannot decrypt content of note ${noteId}`); | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             content = content.toLowerCase(); | ||||
|  | ||||
|             if (type === 'text' && mime === 'text/html') { | ||||
|                 if (content.length < 20000) { // striptags is slow for very large notes | ||||
|                     content = striptags(content); | ||||
|                 } | ||||
|  | ||||
|                 content = content.replace(/ /g, ' '); | ||||
|             } | ||||
|  | ||||
|             if (this.tokens.find(token => !content.includes(token))) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (inputNoteSet.hasNoteId(noteId) && noteId in noteCache.notes) { | ||||
|             if (!this.tokens.find(token => !content.includes(token))) { | ||||
|                 resultNoteSet.add(noteCache.notes[noteId]); | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -26,18 +26,21 @@ class NoteContentUnprotectedFulltextExp extends Expression { | ||||
|                 FROM notes JOIN note_contents USING (noteId)  | ||||
|                 WHERE type IN ('text', 'code') AND isDeleted = 0 AND isProtected = 0`)) { | ||||
|  | ||||
|             content = content.toString().toLowerCase(); | ||||
|  | ||||
|             if (type === 'text' && mime === 'text/html') { | ||||
|                 content = striptags(content); | ||||
|                 content = content.replace(/ /g, ' '); | ||||
|             } | ||||
|  | ||||
|             if (this.tokens.find(token => !content.includes(token))) { | ||||
|             if (!inputNoteSet.hasNoteId(noteId) || !(noteId in noteCache.notes)) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (inputNoteSet.hasNoteId(noteId) && noteId in noteCache.notes) { | ||||
|             content = content.toString().toLowerCase(); | ||||
|  | ||||
|             if (type === 'text' && mime === 'text/html') { | ||||
|                 if (content.length < 20000) { // striptags is slow for very large notes | ||||
|                     content = striptags(content); | ||||
|                 } | ||||
|  | ||||
|                 content = content.replace(/ /g, ' '); | ||||
|             } | ||||
|  | ||||
|             if (!this.tokens.find(token => !content.includes(token))) { | ||||
|                 resultNoteSet.add(noteCache.notes[noteId]); | ||||
|             } | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user