diff --git a/main.js b/main.js index 546cf92..fe93751 100644 --- a/main.js +++ b/main.js @@ -98,6 +98,15 @@ var themes = lineheight: "24px", accentcolor: "#5AA7CE" }, + "White monkey": + { + bgcolor: "white", + fontfamily: "'Inconsolata', 'Consolas', monospace", + fontsize: "18px", + fontcolor: "black", + lineheight: "150%", + accentcolor: "#5AA7CE" + }, Mariana: { bgcolor: "rgb(48,56,65)", @@ -207,6 +216,12 @@ var commands = [ hint: "Restore note", action: restore }, +{ + shortcut: "ctrl+h", + hint: "Insert markdown header", + action: insertheader, + allowunsaved: true +}, { shortcut: "F1", hint: "Show help", @@ -495,6 +510,11 @@ function formatsize(size) return size.toFixed(2) + " " + unit; } +function pospercent() +{ + return md.value.length > 0 ?(100 * md.selectionStart / md.value.length).toFixed(2) : 100; +} + function showinfo() { var tags = gettags(currentnote); @@ -503,7 +523,7 @@ function showinfo() "vault: " + currentvault, "saved: " + saved, "title: " + currentnote.title, - "cursor position: " + md.selectionStart + " (" + (100 * md.selectionStart / md.value.length).toFixed(2) + "%)", + "cursor position: " + md.selectionStart + " (" + pospercent() + "%)", (tags ? "tags: " + tags : ""), "spell check: " + (md.spellcheck ? "en" : "dis") + "abled", "notes count: " + localdata.length, @@ -1130,7 +1150,7 @@ function loadsettings() applystyle(); - if (settings.titlebydefault) + if (settings.titlebydefault && title.hidden) { toggletitle(); } @@ -2096,6 +2116,17 @@ function restore() } } +function insertheader() +{ + if (preview.hidden && !md.value.startsWith("---\n")) + { + var headers = "---\ndate: " + (new Date).toISOString().substring(0, 10) + "\ntags: \n---\n\n"; + md.value = headers + md.value; + setpos(27); + } + resize(); +} + function splitshortcut(s) { var r = {}; @@ -2210,14 +2241,23 @@ function ontitlechange() datachanged(); setwindowtitle(); - toggletitle(); + + if (!settings.titlebydefault) + { + toggletitle(); + } +} + +function simplifystring(str) +{ + return str.toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, ""); } function applyfilter() { [...filteredlist.children].forEach(div => { - div.hidden = div.textContent.toLowerCase().indexOf(filter.value.toLowerCase()) < 0; + div.hidden = simplifystring(div.textContent).indexOf(simplifystring(filter.value)) < 0; }); fileindex = 0; diff --git a/tools/nodeclient/app.js b/tools/nodeclient/app.js index c4312ba..54287c6 100644 --- a/tools/nodeclient/app.js +++ b/tools/nodeclient/app.js @@ -1,6 +1,7 @@ const axios = require("axios"); const readline = require("readline"); const fs = require("fs"); +const openpgp = require("openpgp"); var cp = require("child_process"); var rl = readline.createInterface({ @@ -9,14 +10,43 @@ var rl = readline.createInterface({ }); var settings = JSON.parse(fs.readFileSync("settings.json", { encoding: "utf8", flag: "r" })); +var pgpkey = fs.readFileSync("key.acs", { encoding: "utf8", flag: "r" }); var filter = process.argv.length > 2 ? process.argv[2] : ""; var intervalid = null; var notes = null; +function simplifystring(str) +{ + return str.toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, ""); +} + +async function decrypt(str) +{ + var key = pgpkey.split("-----END PGP PUBLIC KEY BLOCK-----")[1]; + var privateKey = await openpgp.readKey({ armoredKey: key }); + var decrypted = await openpgp.decrypt({ + message: await openpgp.readMessage({ armoredMessage: str }), + decryptionKeys: privateKey }); + const chunks = []; + for await (const chunk of decrypted.data) { + chunks.push(chunk); + } + return chunks.join(''); +} + +async function encrypt(str) +{ + var key = pgpkey.split("-----BEGIN PGP PRIVATE KEY BLOCK-----")[0]; + var publicKey = await openpgp.readKey({ armoredKey: key }); + return await openpgp.encrypt({ + message: await openpgp.createMessage({ text: str }), + encryptionKeys: publicKey }); +} + function filteredlist() { return notes - .filter(n => n.title.toLowerCase().includes(filter.toLowerCase())); + .filter(n => simplifystring(n.title).includes(simplifystring(filter))); } axios.post(`${settings.url}/handler.php`, @@ -30,27 +60,27 @@ axios.post(`${settings.url}/handler.php`, "Content-type": "application/x-www-form-urlencoded" } }) -.then(res => +.then(async function(res) { - notes = res.data; + notes = JSON.parse(await decrypt(res.data)); filteredlist() .every( (note, i) => { console.log(`[${i}] ${note.title}`) - return i < settings.maxcount; + return Boolean(filter) || i < settings.maxcountifnofilter; }); // todo: open if only one match. quit if no match rl.prompt(); - rl.on("line", (line) => + rl.on("line", async function (line) { var note = filteredlist()[line]; // todo: use title instead? To put in data folder? fs.writeFileSync("note.md", note.content); - cp.exec(`${settings.command} note.md`, function (err, stdout, stderr) + cp.exec(`${settings.command} note.md`, async function (err, stdout, stderr) { clearInterval(intervalid); var newcontent = fs.readFileSync("note.md", { encoding: "utf8", flag: "r" }); @@ -62,11 +92,12 @@ axios.post(`${settings.url}/handler.php`, notes.unshift(note); console.log("sending data file to server..."); + var encrypted = await encrypt(JSON.stringify(notes)); axios.post(`${settings.url}/handler.php`, { action: "push", password: settings.password, - data: JSON.stringify(notes) + data: encrypted }, { headers: @@ -83,7 +114,7 @@ axios.post(`${settings.url}/handler.php`, } }) - intervalid = setInterval(function() + intervalid = setInterval(async function() { //todo: refactor "save" var newcontent = fs.readFileSync("note.md", { encoding: "utf8", flag: "r" }); @@ -95,11 +126,12 @@ axios.post(`${settings.url}/handler.php`, notes.unshift(note); console.log("sending data file to server..."); + var encrypted = await encrypt(JSON.stringify(notes)); axios.post(`${settings.url}/handler.php`, { action: "push", password: settings.password, - data: JSON.stringify(notes) + data: encrypted }, { headers: diff --git a/tools/nodeclient/settings.json b/tools/nodeclient/settingssample.json similarity index 76% rename from tools/nodeclient/settings.json rename to tools/nodeclient/settingssample.json index fa4fd04..227734b 100644 --- a/tools/nodeclient/settings.json +++ b/tools/nodeclient/settingssample.json @@ -1,6 +1,6 @@ { "password": "", "url": "http://localhost:8000", - "maxcount": 50, + "maxcountifnofilter": 10, "command": "sublime_text.exe -w" }