diff --git a/Dockerfile b/Dockerfile index fe88bfb02..84db0939b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,4 +39,4 @@ RUN adduser -s /bin/false node; exit 0 EXPOSE 8080 CMD [ "./start-docker.sh" ] -HEALTHCHECK --start-period=10s CMD node docker_healthcheck.js +HEALTHCHECK --start-period=10s CMD exec su-exec node node docker_healthcheck.js diff --git a/README.md b/README.md index dc451dbc9..d2806af64 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,19 @@ # Trilium Notes -[English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) +[![Join the chat at https://gitter.im/trilium-notes/Lobby](https://badges.gitter.im/trilium-notes/Lobby.svg)](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [English](https://github.com/zadam/trilium/blob/master/README.md) | [Chinese](https://github.com/zadam/trilium/blob/master/README-ZH_CN.md) | [Russian](https://github.com/zadam/trilium/blob/master/README.ru.md) -[![Join the chat at https://gitter.im/trilium-notes/Lobby](https://badges.gitter.im/trilium-notes/Lobby.svg)](https://gitter.im/trilium-notes/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Trilium Notes is a hierarchical note taking application with focus on building large personal knowledge bases. See [screenshots](https://github.com/zadam/trilium/wiki/Screenshot-tour) for quick overview: -![](https://raw.githubusercontent.com/wiki/zadam/trilium/images/screenshot.png) +Trilium Screenshot Ukraine is currently defending itself from Russian aggression, please consider [donating to Ukrainian Army or humanitarian charities](https://standforukraine.com/). -drawing +

+ drawing + Trilium Notes supports Ukraine! +

-Trilium Notes supports Ukraine! - -## Features +## 🎁 Features * Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://github.com/zadam/trilium/wiki/Cloning-notes)) * Rich WYSIWYG note editing including e.g. tables, images and [math](https://github.com/zadam/trilium/wiki/Text-notes#math-support) with markdown [autoformat](https://github.com/zadam/trilium/wiki/Text-notes#autoformat) @@ -37,7 +37,7 @@ Ukraine is currently defending itself from Russian aggression, please consider [ Check out [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party themes, scripts, plugins and more. -## Builds +## 🏗 Builds Trilium is provided as either desktop application (Linux and Windows) or web application hosted on your server (Linux). Mac OS desktop build is available, but it is [unsupported](https://github.com/zadam/trilium/wiki/FAQ#mac-os-support). @@ -49,13 +49,13 @@ Trilium is also provided as a Flatpak: [](https://flathub.org/apps/details/com.github.zadam.trilium) -## Documentation +## 📝 Documentation [See wiki for complete list of documentation pages.](https://github.com/zadam/trilium/wiki/) You can also read [Patterns of personal knowledge base](https://github.com/zadam/trilium/wiki/Patterns-of-personal-knowledge-base) to get some inspiration on how you might use Trilium. -## Contribute +## 💻 Contribute Use a browser based dev environment @@ -67,17 +67,17 @@ npm install npm run start-server ``` -## Shoutouts +## 📢 Shoutouts * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - best WYSIWYG editor on the market, very interactive and listening team * [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. Trilium Notes would not be the same without it. * [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages * [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://github.com/zadam/trilium/wiki/Relation-map) and [link maps](https://github.com/zadam/trilium/wiki/Link-map) -## Donating +## 🤝 Support -You can donate using GitHub Sponsors, [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). +You can support Trilum using GitHub Sponsors, [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). -## License +## 🔑 License This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. diff --git a/docker_healthcheck.js b/docker_healthcheck.js index eeceea584..2602cd706 100755 --- a/docker_healthcheck.js +++ b/docker_healthcheck.js @@ -1,5 +1,8 @@ const http = require("http"); -const config = require("./src/services/config"); +const ini = require("ini"); +const fs = require("fs"); +const dataDir = require("./src/services/data_dir"); +const config = ini.parse(fs.readFileSync(dataDir.CONFIG_INI_PATH, 'utf-8')); if (config.https) { // built-in TLS (terminated by trilium) is not supported yet, PRs are welcome @@ -10,18 +13,31 @@ if (config.https) { const port = require('./src/services/port'); const host = require('./src/services/host'); -const url = `http://${host}:${port}/api/health-check`; + const options = { timeout: 2000 }; -const request = http.request(url, options, res => { + +const callback = res => { console.log(`STATUS: ${res.statusCode}`); if (res.statusCode === 200) { process.exit(0); } else { process.exit(1); } -}); +}; + +let request; + +if (port !== 0) { // TCP socket. + const url = `http://${host}:${port}/api/health-check`; + request = http.request(url, options, callback); +} else { // Unix socket. + options.socketPath = host; + options.path = '/api/health-check'; + request = http.request(options, callback); +} + request.on("error", err => { console.log("ERROR"); process.exit(1); }); -request.end(); \ No newline at end of file +request.end(); diff --git a/src/becca/entities/bnote.js b/src/becca/entities/bnote.js index d0698601f..2187dc41e 100644 --- a/src/becca/entities/bnote.js +++ b/src/becca/entities/bnote.js @@ -1376,7 +1376,7 @@ class BNote extends AbstractBeccaEntity { /** * @param parentNoteId - * @returns {{success: boolean, message: string}} + * @returns {{success: boolean, message: string, branchId: string, notePath: string}} */ cloneTo(parentNoteId) { const cloningService = require("../../services/cloning"); diff --git a/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js b/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js index 19263fdf4..e434c20a6 100644 --- a/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js +++ b/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js @@ -44,7 +44,7 @@ export default class InheritedAttributesWidget extends NoteContextAwareWidget { getTitle() { return { show: !this.note.isLaunchBarConfig(), - title: "Inherited attributes", + title: "Inherited Attributes", icon: "bx bx-list-plus" }; } diff --git a/src/public/app/widgets/ribbon_widgets/owned_attribute_list.js b/src/public/app/widgets/ribbon_widgets/owned_attribute_list.js index 836d39a98..343cf8ff4 100644 --- a/src/public/app/widgets/ribbon_widgets/owned_attribute_list.js +++ b/src/public/app/widgets/ribbon_widgets/owned_attribute_list.js @@ -48,7 +48,7 @@ export default class OwnedAttributeListWidget extends NoteContextAwareWidget { getTitle() { return { show: !this.note.isLaunchBarConfig(), - title: "Owned attributes", + title: "Owned Attributes", icon: "bx bx-list-check" }; } diff --git a/src/public/app/widgets/sql_table_schemas.js b/src/public/app/widgets/sql_table_schemas.js index 8a986fe04..5764636b5 100644 --- a/src/public/app/widgets/sql_table_schemas.js +++ b/src/public/app/widgets/sql_table_schemas.js @@ -6,8 +6,9 @@ const TPL = ` - + Tables: `; diff --git a/src/public/app/widgets/type_widgets/editable_code.js b/src/public/app/widgets/type_widgets/editable_code.js index 144f1392d..abb55b36b 100644 --- a/src/public/app/widgets/type_widgets/editable_code.js +++ b/src/public/app/widgets/type_widgets/editable_code.js @@ -77,12 +77,15 @@ export default class EditableCodeTypeWidget extends TypeWidget { this.codeEditor.setValue(noteComplement.content || ""); this.codeEditor.clearHistory(); - const info = CodeMirror.findModeByMIME(note.mime); - - if (info) { - this.codeEditor.setOption("mode", info.mime); - CodeMirror.autoLoadMode(this.codeEditor, info.mode); + let info = CodeMirror.findModeByMIME(note.mime); + if (!info) { + // Switch back to plain text if CodeMirror does not have a mode for whatever MIME type we're editing. + // To avoid inheriting a mode from a previously open code note. + info = CodeMirror.findModeByMIME("text/plain"); } + + this.codeEditor.setOption("mode", info.mime); + CodeMirror.autoLoadMode(this.codeEditor, info.mode); }); this.show(); diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index bfa6a3a22..90970b2c0 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -783,7 +783,7 @@ body { ::-webkit-scrollbar-thumb { border-radius: 3px; border: 1px solid var(--scrollbar-border-color); - background-color: var(--main-background-color); + background-color: var(--active-item-background-color); } ::-webkit-scrollbar-corner { diff --git a/src/services/html_sanitizer.js b/src/services/html_sanitizer.js index 32b275d17..4693ee1df 100644 --- a/src/services/html_sanitizer.js +++ b/src/services/html_sanitizer.js @@ -45,7 +45,12 @@ function sanitize(dirtyHtml) { 'table': [ 'class' ], 'en-media': [ 'hash' ] }, - allowedSchemes: ['http', 'https', 'ftp', 'mailto', 'data', 'evernote'], + allowedSchemes: [ + 'http', 'https', 'ftp', 'ftps', 'mailto', 'data', 'evernote', 'file', 'facetime', 'irc', 'gemini', 'git', + 'gopher', 'imap', 'irc', 'irc6', 'jabber', 'jar', 'lastfm', 'ldap', 'ldaps', 'magnet', 'message', + 'mumble', 'nfs', 'onenote', 'pop', 'rmi', 's3', 'sftp', 'skype', 'sms', 'spotify', 'steam', 'svn', 'udp', + 'view-source', 'vnc', 'ws', 'wss', 'xmpp', 'jdbc', 'slack' + ], transformTags, }); } diff --git a/src/services/keyboard_actions.js b/src/services/keyboard_actions.js index d665692a9..063bcdbda 100644 --- a/src/services/keyboard_actions.js +++ b/src/services/keyboard_actions.js @@ -14,13 +14,13 @@ const DEFAULT_KEYBOARD_ACTIONS = [ { actionName: "backInNoteHistory", // Mac has a different history navigation shortcuts - https://github.com/zadam/trilium/issues/376 - defaultShortcuts: isMac ? ["Meta+Left"] : ["Alt+Left"], + defaultShortcuts: isMac ? ["CommandOrControl+Left"] : ["Alt+Left"], scope: "window" }, { actionName: "forwardInNoteHistory", // Mac has a different history navigation shortcuts - https://github.com/zadam/trilium/issues/376 - defaultShortcuts: isMac ? ["Meta+Right"] : ["Alt+Right"], + defaultShortcuts: isMac ? ["CommandOrControl+Right"] : ["Alt+Right"], scope: "window" }, { diff --git a/src/services/port.js b/src/services/port.js index 559385644..c57f22a5d 100644 --- a/src/services/port.js +++ b/src/services/port.js @@ -6,8 +6,8 @@ const dataDir = require('./data_dir'); function parseAndValidate(portStr, source) { const portNum = parseInt(portStr); - if (!portNum || portNum < 0 || portNum >= 65536) { - console.log(`FATAL ERROR: Invalid port value "${portStr}" from ${source}, should be a number between 0 and 65536.`); + if (isNaN(portNum) || portNum < 0 || portNum >= 65536) { + console.log(`FATAL ERROR: Invalid port value "${portStr}" from ${source}, should be an integer between 0 and 65536.`); process.exit(-1); } diff --git a/src/services/search/services/search.js b/src/services/search/services/search.js index 06362b28c..80b49f3bb 100644 --- a/src/services/search/services/search.js +++ b/src/services/search/services/search.js @@ -331,6 +331,11 @@ function highlightSearchResults(searchResults, highlightedTokens) { } for (const token of highlightedTokens) { + if (!token) { + // Avoid empty tokens, which might cause an infinite loop. + continue; + } + for (const result of searchResults) { // Reset token const tokenRegex = new RegExp(utils.escapeRegExp(token), "gi"); diff --git a/src/www b/src/www index 778197e37..136feabf3 100644 --- a/src/www +++ b/src/www @@ -100,9 +100,14 @@ async function startTrilium() { */ httpServer.keepAliveTimeout = 120000 * 5; - httpServer.listen(port, host); + const listenOnTcp = port !== 0; + if (listenOnTcp) { + httpServer.listen(port, host); // TCP socket. + } else { + httpServer.listen(host); // Unix socket. + } httpServer.on('error', error => { - if (error.syscall !== 'listen') { + if (!listenOnTcp || error.syscall !== 'listen') { throw error; } @@ -124,7 +129,13 @@ async function startTrilium() { } ) - httpServer.on('listening', () => log.info(`Listening on port ${httpServer.address().port}`)); + httpServer.on('listening', () => { + if (listenOnTcp) { + log.info(`Listening on port ${port}`) + } else { + log.info(`Listening on unix socket ${host}`) + } + }); ws.init(httpServer, sessionParser);