diff --git a/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml b/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml
index ae7ed066d..2f8739baa 100644
--- a/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml
+++ b/.idea/dataSources/a2c75661-f9e2-478f-a69f-6a9409e69997.xml
@@ -345,321 +345,333 @@ parentNoteId
1
""
-
+
+ 6
+ TEXT|0s
+ 1
+ '2018-05-08T23:41:15.225Z'
+
+
+ 7
+ TEXT|0s
+ 1
+ '2018-05-08T23:41:15.225Z'
+
+
1
noteContentId
1
-
+
noteId
1
-
+
noteContentId
1
sqlite_autoindex_note_contents_1
-
+
1
TEXT|0s
1
-
+
2
TEXT|0s
1
-
+
3
TEXT|0s
-
+
4
TEXT|0s
-
+
5
INT|0s
1
0
-
+
6
TEXT|0s
1
-
+
7
TEXT|0s
1
-
+
8
TEXT|0s
1
''
-
+
9
TEXT|0s
1
''
-
+
10
TEXT|0s
1
""
-
+
1
noteRevisionId
1
-
+
noteId
-
+
dateModifiedFrom
-
+
dateModifiedTo
-
+
noteRevisionId
1
sqlite_autoindex_note_revisions_1
-
+
1
TEXT|0s
1
-
+
2
TEXT|0s
1
"note"
-
+
3
INT|0s
1
0
-
+
4
TEXT|0s
1
'text'
-
+
5
TEXT|0s
1
'text/html'
-
+
6
TEXT|0s
1
""
-
+
7
INT|0s
1
0
-
+
8
TEXT|0s
1
-
+
9
TEXT|0s
1
-
+
1
noteId
1
-
+
noteId
1
sqlite_autoindex_notes_1
-
+
1
TEXT|0s
1
-
+
2
TEXT|0s
-
+
3
INT|0s
-
+
4
INTEGER|0s
1
0
-
+
5
TEXT|0s
1
""
-
+
6
TEXT|0s
1
'1970-01-01T00:00:00.000Z'
-
+
1
name
1
-
+
name
1
sqlite_autoindex_options_1
-
+
1
TEXT|0s
1
-
+
2
TEXT|0s
1
-
+
3
TEXT|0s
1
""
-
+
4
TEXT|0s
1
-
+
5
INT|0s
-
+
1
branchId
1
-
+
branchId
1
sqlite_autoindex_recent_notes_1
-
+
1
TEXT|0s
1
-
+
2
TEXT|0s
1
-
+
1
sourceId
1
-
+
sourceId
1
sqlite_autoindex_source_ids_1
-
+
1
text|0s
-
+
2
text|0s
-
+
3
text|0s
-
+
4
integer|0s
-
+
5
text|0s
-
+
1
-
+
2
-
+
1
INTEGER|0s
1
1
-
+
2
TEXT|0s
1
-
+
3
TEXT|0s
1
-
+
4
TEXT|0s
1
-
+
5
TEXT|0s
1
-
+
entityName
entityId
1
-
+
syncDate
-
+
id
1
diff --git a/src/entities/note.js b/src/entities/note.js
index 7d936ef22..23f7977f7 100644
--- a/src/entities/note.js
+++ b/src/entities/note.js
@@ -132,7 +132,7 @@ class Note extends Entity {
/** @returns {boolean} true if the note has string content (not binary) */
isStringNote() {
- return ["text", "code", "relation-map"].includes(this.type) || this.mime.startsWith('text/');
+ return ["text", "code", "relation-map", "search"].includes(this.type) || this.mime.startsWith('text/');
}
/** @returns {string} JS script environment - either "frontend" or "backend" */
diff --git a/src/public/javascripts/services/note_detail_search.js b/src/public/javascripts/services/note_detail_search.js
index d340005cd..ef7466664 100644
--- a/src/public/javascripts/services/note_detail_search.js
+++ b/src/public/javascripts/services/note_detail_search.js
@@ -6,15 +6,11 @@ const $searchString = $("#search-string");
const $component = $('#note-detail-search');
const $refreshButton = $('#note-detail-search-refresh-results-button');
-function getContent() {
- return JSON.stringify({
- searchString: $searchString.val()
- });
-}
-
function show() {
$component.show();
+ console.log(noteDetailService.getCurrentNote());
+
try {
const json = JSON.parse(noteDetailService.getCurrentNote().noteContent.content);
@@ -28,6 +24,12 @@ function show() {
$searchString.on('input', noteDetailService.noteChanged);
}
+function getContent() {
+ return JSON.stringify({
+ searchString: $searchString.val()
+ });
+}
+
$refreshButton.click(async () => {
await noteDetailService.saveNoteIfChanged();
diff --git a/src/public/javascripts/services/tree_builder.js b/src/public/javascripts/services/tree_builder.js
index a1a522be7..a7b196abf 100644
--- a/src/public/javascripts/services/tree_builder.js
+++ b/src/public/javascripts/services/tree_builder.js
@@ -126,7 +126,9 @@ async function prepareRealBranch(parentNote) {
async function prepareSearchBranch(note) {
const fullNote = await noteDetailService.loadNote(note.noteId);
- const results = (await server.get('search/' + encodeURIComponent(fullNote.jsonContent.searchString)))
+ const json = JSON.parse(fullNote.noteContent.content);
+
+ const results = (await server.get('search/' + encodeURIComponent(json.searchString)))
.filter(res => res.noteId !== note.noteId); // this is necessary because title of the search note is often the same as the search text which would match and create circle
// force to load all the notes at once instead of one by one
diff --git a/src/routes/api/search.js b/src/routes/api/search.js
index 7e536691d..2499b4254 100644
--- a/src/routes/api/search.js
+++ b/src/routes/api/search.js
@@ -1,6 +1,7 @@
"use strict";
const sql = require('../../services/sql');
+const utils = require('../../services/utils');
const noteService = require('../../services/notes');
const noteCacheService = require('../../services/note_cache');
const parseFilters = require('../../services/parse_filters');
@@ -55,15 +56,18 @@ async function getFullTextResults(searchText) {
const tokenSql = ["1=1"];
for (const token of tokens) {
- // FIXME: escape token!
- tokenSql.push(`(title LIKE '%${token}%' OR content LIKE '%${token}%')`);
+ const safeToken = utils.sanitizeSql(token);
+
+ tokenSql.push(`(title LIKE '%${safeToken}%' OR content LIKE '%${safeToken}%')`);
}
const noteIds = await sql.getColumn(`
SELECT DISTINCT noteId
- FROM notes
+ FROM
+ notes
+ JOIN note_contents USING(noteId)
WHERE isDeleted = 0
- AND isProtected = 0
+ AND notes.isProtected = 0
AND type IN ('text', 'code')
AND ${tokenSql.join(' AND ')}`);