mirror of
https://github.com/zadam/trilium.git
synced 2025-11-13 08:45:50 +01:00
Merge remote-tracking branch 'origin/master' into next
# Conflicts: # package-lock.json # src/public/app/services/note_content_renderer.js # src/public/stylesheets/style.css # src/routes/api/files.js # src/routes/routes.js
This commit is contained in:
@@ -107,7 +107,11 @@ function processContent(images, note, content) {
|
||||
const filename = path.basename(src);
|
||||
|
||||
if (!dataUrl || !dataUrl.startsWith("data:image")) {
|
||||
log.info("Image could not be recognized as data URL:", dataUrl.substr(0, Math.min(100, dataUrl.length)));
|
||||
const excerpt = dataUrl
|
||||
? dataUrl.substr(0, Math.min(100, dataUrl.length))
|
||||
: "null";
|
||||
|
||||
log.info("Image could not be recognized as data URL: " + excerpt);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -140,7 +144,7 @@ function processContent(images, note, content) {
|
||||
function openNote(req) {
|
||||
if (utils.isElectron()) {
|
||||
ws.sendMessageToAllClients({
|
||||
type: 'open-note',
|
||||
type: 'openNote',
|
||||
noteId: req.params.noteId
|
||||
});
|
||||
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
const protectedSessionService = require('../../services/protected_session');
|
||||
const repository = require('../../services/repository');
|
||||
const utils = require('../../services/utils');
|
||||
const log = require('../../services/log');
|
||||
const noteRevisionService = require('../../services/note_revisions');
|
||||
const tmp = require('tmp');
|
||||
const fs = require('fs');
|
||||
const { Readable } = require('stream');
|
||||
const chokidar = require('chokidar');
|
||||
const ws = require('../../services/ws');
|
||||
|
||||
function updateFile(req) {
|
||||
const {noteId} = req.params;
|
||||
@@ -120,6 +123,19 @@ function saveToTmpDir(req) {
|
||||
fs.writeSync(tmpObj.fd, note.getContent());
|
||||
fs.closeSync(tmpObj.fd);
|
||||
|
||||
log.info(`Saved temporary file for note ${noteId} into ${tmpObj.name}`);
|
||||
|
||||
if (utils.isElectron()) {
|
||||
chokidar.watch(tmpObj.name).on('change', (path, stats) => {
|
||||
ws.sendMessageToAllClients({
|
||||
type: 'openedFileUpdated',
|
||||
noteId: noteId,
|
||||
lastModifiedMs: stats.atimeMs,
|
||||
filePath: tmpObj.name
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
tmpFilePath: tmpObj.name
|
||||
};
|
||||
|
||||
@@ -7,6 +7,8 @@ const sql = require('../../services/sql');
|
||||
const utils = require('../../services/utils');
|
||||
const log = require('../../services/log');
|
||||
const TaskContext = require('../../services/task_context');
|
||||
const fs = require('fs');
|
||||
const noteRevisionService = require("../../services/note_revisions.js");
|
||||
|
||||
function getNote(req) {
|
||||
const noteId = req.params.noteId;
|
||||
@@ -80,7 +82,7 @@ function deleteNote(req) {
|
||||
function undeleteNote(req) {
|
||||
const note = repository.getNote(req.params.noteId);
|
||||
|
||||
const taskContext = TaskContext.getInstance(utils.randomString(10), 'undelete-notes');
|
||||
const taskContext = TaskContext.getInstance(utils.randomString(10), 'undeleteNotes');
|
||||
|
||||
noteService.undeleteNote(note, note.deleteId, taskContext);
|
||||
|
||||
@@ -109,7 +111,7 @@ function protectNote(req) {
|
||||
const protect = !!parseInt(req.params.isProtected);
|
||||
const includingSubTree = !!parseInt(req.query.subtree);
|
||||
|
||||
const taskContext = new TaskContext(utils.randomString(10), 'protect-notes', {protect});
|
||||
const taskContext = new TaskContext(utils.randomString(10), 'protectNotes', {protect});
|
||||
|
||||
noteService.protectNoteRecursively(note, protect, includingSubTree, taskContext);
|
||||
|
||||
@@ -273,6 +275,29 @@ function getDeleteNotesPreview(req) {
|
||||
};
|
||||
}
|
||||
|
||||
function uploadModifiedFile(req) {
|
||||
const noteId = req.params.noteId;
|
||||
const {filePath} = req.body;
|
||||
|
||||
const note = repository.getNote(noteId);
|
||||
|
||||
if (!note) {
|
||||
return [404, `Note ${noteId} has not been found`];
|
||||
}
|
||||
|
||||
log.info(`Updating note ${noteId} with content from ${filePath}`);
|
||||
|
||||
noteRevisionService.createNoteRevision(note);
|
||||
|
||||
const fileContent = fs.readFileSync(filePath);
|
||||
|
||||
if (!fileContent) {
|
||||
return [400, `File ${fileContent} is empty`];
|
||||
}
|
||||
|
||||
note.setContent(fileContent);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getNote,
|
||||
updateNote,
|
||||
@@ -286,5 +311,6 @@ module.exports = {
|
||||
changeTitle,
|
||||
duplicateSubtree,
|
||||
eraseDeletedNotesNow,
|
||||
getDeleteNotesPreview
|
||||
getDeleteNotesPreview,
|
||||
uploadModifiedFile
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
const utils = require('../services/utils');
|
||||
const optionService = require('../services/options');
|
||||
const myScryptService = require('../services/my_scrypt');
|
||||
const log = require('../services/log');
|
||||
|
||||
function loginPage(req, res) {
|
||||
res.render('login', { failedAuth: false });
|
||||
@@ -28,6 +29,9 @@ function login(req, res) {
|
||||
});
|
||||
}
|
||||
else {
|
||||
// note that logged IP address is usually meaningless since the traffic should come from a reverse proxy
|
||||
log.info(`WARNING: Wrong username / password from ${req.ip}, rejecting.`);
|
||||
|
||||
res.render('login', {'failedAuth': true});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +165,7 @@ function register(app) {
|
||||
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);
|
||||
apiRoute(POST, '/api/notes/:noteId/upload-modified-file', notesApiRoute.uploadModifiedFile);
|
||||
|
||||
apiRoute(GET, '/api/edited-notes/:date', noteRevisionsApiRoute.getEditedNotesOnDate);
|
||||
|
||||
@@ -177,14 +178,15 @@ function register(app) {
|
||||
route(PUT, '/api/notes/:noteId/file', [auth.checkApiAuthOrElectron, uploadMiddleware, csrfMiddleware],
|
||||
filesRoute.updateFile, apiResultHandler);
|
||||
|
||||
route(GET, '/api/notes/:noteId/open', [auth.checkApiAuthOrElectron],
|
||||
route(GET, '/api/notes/:noteId/open', [auth.checkApiAuthOrElectron], filesRoute.openFile);
|
||||
route(GET, '/api/notes/:noteId/open-partial', [auth.checkApiAuthOrElectron],
|
||||
createPartialContentHandler(filesRoute.fileContentProvider, {
|
||||
debug: (string, extra) => { console.log(string, extra); }
|
||||
}));
|
||||
route(GET, '/api/notes/:noteId/download', [auth.checkApiAuthOrElectron], filesRoute.downloadFile);
|
||||
// this "hacky" path is used for easier referencing of CSS resources
|
||||
route(GET, '/api/notes/download/:noteId', [auth.checkApiAuthOrElectron], filesRoute.downloadFile);
|
||||
apiRoute(POST, '/api/notes/:noteId/saveToTmpDir', filesRoute.saveToTmpDir);
|
||||
apiRoute(POST, '/api/notes/:noteId/save-to-tmp-dir', filesRoute.saveToTmpDir);
|
||||
|
||||
apiRoute(GET, '/api/notes/:noteId/attributes', attributesRoute.getEffectiveNoteAttributes);
|
||||
apiRoute(POST, '/api/notes/:noteId/attributes', attributesRoute.addNoteAttribute);
|
||||
|
||||
Reference in New Issue
Block a user