Notes/src/routes/api/note_revisions.js

198 lines
5.9 KiB
JavaScript
Raw Normal View History

2017-10-21 21:10:33 -04:00
"use strict";
2021-06-29 22:15:57 +02:00
const beccaService = require('../../becca/becca_service');
2020-05-07 23:34:13 +02:00
const noteRevisionService = require('../../services/note_revisions');
2019-11-09 08:53:13 +01:00
const utils = require('../../services/utils');
const sql = require('../../services/sql');
const cls = require('../../services/cls');
2019-11-09 08:53:13 +01:00
const path = require('path');
2021-06-29 22:15:57 +02:00
const becca = require("../../becca/becca");
2023-05-05 16:37:39 +02:00
const blobService = require("../../services/blob.js");
function getNoteRevisionBlob(req) {
2023-05-05 22:21:51 +02:00
const preview = req.query.preview === 'true';
2023-05-05 16:37:39 +02:00
2023-05-05 22:21:51 +02:00
return blobService.getBlobPojo('note_revisions', req.params.noteRevisionId, { preview });
2023-05-05 16:37:39 +02:00
}
2020-06-20 12:31:38 +02:00
function getNoteRevisions(req) {
2021-05-02 19:59:16 +02:00
return becca.getNoteRevisionsFromQuery(`
SELECT note_revisions.*,
2023-03-16 11:02:07 +01:00
LENGTH(blobs.content) AS contentLength
FROM note_revisions
2023-03-16 11:02:07 +01:00
JOIN blobs ON note_revisions.blobId = blobs.blobId
2020-12-16 14:36:24 +01:00
WHERE noteId = ?
2019-11-09 15:21:14 +01:00
ORDER BY utcDateCreated DESC`, [req.params.noteId]);
}
2020-06-20 12:31:38 +02:00
function getNoteRevision(req) {
const noteRevision = becca.getNoteRevision(req.params.noteRevisionId);
2019-11-09 13:01:05 +01:00
if (noteRevision.type === 'file') {
2023-05-05 16:37:39 +02:00
if (noteRevision.hasStringContent()) {
noteRevision.content = noteRevision.getContent().substr(0, 10000);
2019-11-09 13:01:05 +01:00
}
}
else {
2020-06-20 12:31:38 +02:00
noteRevision.content = noteRevision.getContent();
2019-11-01 20:00:56 +01:00
2019-11-09 08:53:13 +01:00
if (noteRevision.content && noteRevision.type === 'image') {
noteRevision.content = noteRevision.content.toString('base64');
}
2019-11-08 23:09:57 +01:00
}
2019-11-01 20:00:56 +01:00
return noteRevision;
}
2019-11-09 08:53:13 +01:00
/**
* @param {BNoteRevision} noteRevision
2023-01-05 23:38:41 +01:00
* @returns {string}
2019-11-09 08:53:13 +01:00
*/
function getRevisionFilename(noteRevision) {
let filename = utils.formatDownloadTitle(noteRevision.title, noteRevision.type, noteRevision.mime);
2019-11-09 08:53:13 +01:00
const extension = path.extname(filename);
const date = noteRevision.dateCreated
.substr(0, 19)
.replace(' ', '_')
.replace(/[^0-9_]/g, '');
if (extension) {
filename = `${filename.substr(0, filename.length - extension.length)}-${date}${extension}`;
2019-11-09 08:53:13 +01:00
}
else {
filename += `-${date}`;
2019-11-09 08:53:13 +01:00
}
return filename;
}
2020-06-20 12:31:38 +02:00
function downloadNoteRevision(req, res) {
const noteRevision = becca.getNoteRevision(req.params.noteRevisionId);
2019-11-09 08:53:13 +01:00
2023-04-14 16:49:06 +02:00
if (!noteRevision.isContentAvailable()) {
return res.setHeader("Content-Type", "text/plain")
.status(401)
.send("Protected session not available");
2019-11-09 08:53:13 +01:00
}
const filename = getRevisionFilename(noteRevision);
res.setHeader('Content-Disposition', utils.getContentDisposition(filename));
res.setHeader('Content-Type', noteRevision.mime);
2020-06-20 12:31:38 +02:00
res.send(noteRevision.getContent());
2019-11-09 08:53:13 +01:00
}
2020-06-20 12:31:38 +02:00
function eraseAllNoteRevisions(req) {
2020-12-16 15:01:20 +01:00
const noteRevisionIdsToErase = sql.getColumn('SELECT noteRevisionId FROM note_revisions WHERE noteId = ?',
2019-11-09 15:21:14 +01:00
[req.params.noteId]);
2020-12-16 14:36:24 +01:00
noteRevisionService.eraseNoteRevisions(noteRevisionIdsToErase);
2019-11-09 15:21:14 +01:00
}
2020-06-20 12:31:38 +02:00
function eraseNoteRevision(req) {
2020-12-16 14:36:24 +01:00
noteRevisionService.eraseNoteRevisions([req.params.noteRevisionId]);
2019-11-09 15:21:14 +01:00
}
2020-06-20 12:31:38 +02:00
function restoreNoteRevision(req) {
const noteRevision = becca.getNoteRevision(req.params.noteRevisionId);
2020-05-07 23:34:13 +02:00
2020-12-16 15:01:20 +01:00
if (noteRevision) {
2020-06-20 12:31:38 +02:00
const note = noteRevision.getNote();
2020-05-07 23:34:13 +02:00
2023-04-19 22:47:33 +02:00
sql.transactional(() => {
note.saveNoteRevision();
2020-05-07 23:34:13 +02:00
2023-04-19 22:47:33 +02:00
for (const oldNoteAttachment of note.getAttachments()) {
oldNoteAttachment.markAsDeleted();
}
let revisionContent = noteRevision.getContent();
for (const revisionAttachment of noteRevision.getAttachments()) {
const noteAttachment = revisionAttachment.copy();
noteAttachment.parentId = note.noteId;
noteAttachment.setContent(revisionAttachment.getContent(), { forceSave: true });
// content is rewritten to point to the restored revision attachments
revisionContent = revisionContent.replaceAll(`attachments/${revisionAttachment.attachmentId}`, `attachments/${noteAttachment.attachmentId}`);
}
note.title = noteRevision.title;
note.setContent(revisionContent, { forceSave: true });
});
2020-05-07 23:34:13 +02:00
}
}
2020-06-20 12:31:38 +02:00
function getEditedNotesOnDate(req) {
2021-05-02 19:59:16 +02:00
const noteIds = sql.getColumn(`
2019-12-01 14:30:59 +01:00
SELECT notes.*
FROM notes
WHERE noteId IN (
SELECT noteId FROM notes
WHERE notes.dateCreated LIKE :date
OR notes.dateModified LIKE :date
2019-12-01 14:30:59 +01:00
UNION ALL
SELECT noteId FROM note_revisions
WHERE note_revisions.dateLastEdited LIKE :date
2019-12-01 14:30:59 +01:00
)
ORDER BY isDeleted
LIMIT 50`, {date: `${req.params.date}%`});
2019-09-07 10:11:59 +02:00
let notes = becca.getNotes(noteIds, true);
// Narrow down the results if a note is hoisted, similar to "Jump to note".
const hoistedNoteId = cls.getHoistedNoteId();
2022-11-03 21:40:42 +01:00
if (hoistedNoteId !== 'root') {
notes = notes.filter(note => note.hasAncestor(hoistedNoteId));
}
2023-05-26 14:54:13 +08:00
return notes.map(note => {
2023-04-16 11:28:24 +02:00
const notePath = note.isDeleted ? null : getNotePathData(note);
2019-09-07 10:11:59 +02:00
2023-05-26 14:54:13 +08:00
const notePojo = note.getPojo();
notePojo.notePath = notePath ? notePath.notePath : null;
2023-05-26 14:36:21 +08:00
2023-05-26 14:54:13 +08:00
return notePojo;
});
2019-09-07 10:11:59 +02:00
}
2023-04-16 11:28:24 +02:00
function getNotePathData(note) {
const retPath = note.getBestNotePath();
if (retPath) {
const noteTitle = beccaService.getNoteTitleForPath(retPath);
let branchId;
if (note.isRoot()) {
branchId = 'none_root';
}
else {
const parentNote = note.parents[0];
branchId = becca.getBranchFromChildAndParent(note.noteId, parentNote.noteId).branchId;
}
return {
noteId: note.noteId,
branchId: branchId,
title: noteTitle,
notePath: retPath,
path: retPath.join('/')
};
}
}
module.exports = {
2023-05-05 16:37:39 +02:00
getNoteRevisionBlob,
2019-09-07 10:11:59 +02:00
getNoteRevisions,
2019-11-01 19:21:48 +01:00
getNoteRevision,
2019-11-09 08:53:13 +01:00
downloadNoteRevision,
2019-11-09 15:21:14 +01:00
getEditedNotesOnDate,
eraseAllNoteRevisions,
2020-05-07 23:34:13 +02:00
eraseNoteRevision,
restoreNoteRevision
};