| 
									
										
										
										
											2022-05-09 16:38:23 +02:00
										 |  |  | const express = require('express'); | 
					
						
							|  |  |  | const path = require('path'); | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  | const safeCompare = require('safe-compare'); | 
					
						
							| 
									
										
										
										
											2022-05-09 16:38:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-17 14:44:59 +02:00
										 |  |  | const shaca = require("./shaca/shaca"); | 
					
						
							|  |  |  | const shacaLoader = require("./shaca/shaca_loader"); | 
					
						
							| 
									
										
										
										
											2021-10-19 22:48:38 +02:00
										 |  |  | const shareRoot = require("./share_root"); | 
					
						
							| 
									
										
										
										
											2022-01-10 17:09:20 +01:00
										 |  |  | const contentRenderer = require("./content_renderer"); | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:54 +02:00
										 |  |  | const assetPath = require("../services/asset_path"); | 
					
						
							| 
									
										
										
										
											2022-12-25 11:58:24 +01:00
										 |  |  | const appPath = require("../services/app_path"); | 
					
						
							| 
									
										
										
										
											2021-10-19 22:48:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-23 20:54:48 +01:00
										 |  |  | function getSharedSubTreeRoot(note) { | 
					
						
							| 
									
										
										
										
											2021-10-19 22:48:38 +02:00
										 |  |  |     if (note.noteId === shareRoot.SHARE_ROOT_NOTE_ID) { | 
					
						
							| 
									
										
										
										
											2021-12-23 20:54:48 +01:00
										 |  |  |         // share root itself is not shared
 | 
					
						
							| 
									
										
										
										
											2021-10-19 22:48:38 +02:00
										 |  |  |         return null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-23 20:54:48 +01:00
										 |  |  |     // every path leads to share root, but which one to choose?
 | 
					
						
							| 
									
										
										
										
											2023-06-30 11:18:34 +02:00
										 |  |  |     // for the sake of simplicity, URLs are not note paths
 | 
					
						
							| 
									
										
										
										
											2021-10-19 22:48:38 +02:00
										 |  |  |     const parentNote = note.getParentNotes()[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (parentNote.noteId === shareRoot.SHARE_ROOT_NOTE_ID) { | 
					
						
							|  |  |  |         return note; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-23 20:54:48 +01:00
										 |  |  |     return getSharedSubTreeRoot(parentNote); | 
					
						
							| 
									
										
										
										
											2021-10-19 22:48:38 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2021-10-17 14:44:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 23:17:47 +01:00
										 |  |  | function addNoIndexHeader(note, res) { | 
					
						
							| 
									
										
										
										
											2023-06-29 00:14:12 +02:00
										 |  |  |     if (note.isLabelTruthy('shareDisallowRobotIndexing')) { | 
					
						
							| 
									
										
										
										
											2022-03-22 23:17:47 +01:00
										 |  |  |         res.setHeader('X-Robots-Tag', 'noindex'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 19:56:09 +02:00
										 |  |  | function requestCredentials(res) { | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |     res.setHeader('WWW-Authenticate', 'Basic realm="User Visible Realm", charset="UTF-8"') | 
					
						
							|  |  |  |         .sendStatus(401); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-05 23:05:05 +02:00
										 |  |  | /** @returns {SAttachment|boolean} */ | 
					
						
							|  |  |  | function checkAttachmentAccess(attachmentId, req, res) { | 
					
						
							|  |  |  |     const attachment = shaca.getAttachment(attachmentId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!attachment) { | 
					
						
							|  |  |  |         res.status(404) | 
					
						
							|  |  |  |             .json({ message: `Attachment '${attachmentId}' not found.` }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const note = checkNoteAccess(attachment.parentId, req, res); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-30 11:18:34 +02:00
										 |  |  |     // truthy note means the user has access, and we can return the attachment
 | 
					
						
							| 
									
										
										
										
											2023-06-05 23:05:05 +02:00
										 |  |  |     return note ? attachment : false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-11 22:55:50 +02:00
										 |  |  | /** @returns {SNote|boolean} */ | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  | function checkNoteAccess(noteId, req, res) { | 
					
						
							|  |  |  |     const note = shaca.getNote(noteId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!note) { | 
					
						
							| 
									
										
										
										
											2022-12-19 21:39:12 +01:00
										 |  |  |         res.status(404) | 
					
						
							| 
									
										
										
										
											2023-06-05 23:05:05 +02:00
										 |  |  |             .json({ message: `Note '${noteId}' not found.` }); | 
					
						
							| 
									
										
										
										
											2022-12-19 21:39:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-21 16:11:00 +01:00
										 |  |  |     if (noteId === '_share' && !shaca.shareIndexEnabled) { | 
					
						
							| 
									
										
										
										
											2022-12-19 21:39:12 +01:00
										 |  |  |         res.status(403) | 
					
						
							|  |  |  |             .json({ message: `Accessing share index is forbidden.` }); | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const credentials = note.getCredentials(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (credentials.length === 0) { | 
					
						
							|  |  |  |         return note; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const header = req.header("Authorization"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!header?.startsWith("Basic ")) { | 
					
						
							| 
									
										
										
										
											2022-08-01 19:56:09 +02:00
										 |  |  |         requestCredentials(res); | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const base64Str = header.substring("Basic ".length); | 
					
						
							|  |  |  |     const buffer = Buffer.from(base64Str, 'base64'); | 
					
						
							|  |  |  |     const authString = buffer.toString('utf-8'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const credentialLabel of credentials) { | 
					
						
							|  |  |  |         if (safeCompare(authString, credentialLabel.value)) { | 
					
						
							|  |  |  |             return note; // success;
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-17 14:44:59 +02:00
										 |  |  | function register(router) { | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |     function renderNote(note, req, res) { | 
					
						
							| 
									
										
										
										
											2022-03-22 23:17:47 +01:00
										 |  |  |         if (!note) { | 
					
						
							| 
									
										
										
										
											2021-12-22 09:10:38 +01:00
										 |  |  |             res.status(404).render("share/404"); | 
					
						
							| 
									
										
										
										
											2022-03-22 23:17:47 +01:00
										 |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |         if (!checkNoteAccess(note.noteId, req, res)) { | 
					
						
							| 
									
										
										
										
											2022-08-01 19:56:09 +02:00
										 |  |  |             requestCredentials(res); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 23:17:47 +01:00
										 |  |  |         addNoIndexHeader(note, res); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-29 00:14:12 +02:00
										 |  |  |         if (note.isLabelTruthy('shareRaw')) { | 
					
						
							| 
									
										
										
										
											2022-07-01 00:01:29 +02:00
										 |  |  |             res.setHeader('Content-Type', note.mime) | 
					
						
							|  |  |  |                 .send(note.getContent()); | 
					
						
							| 
									
										
										
										
											2022-03-22 23:17:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2021-10-17 14:44:59 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-03-22 23:17:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const {header, content, isEmpty} = contentRenderer.getContent(note); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const subRoot = getSharedSubTreeRoot(note); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         res.render("share/page", { | 
					
						
							|  |  |  |             note, | 
					
						
							|  |  |  |             header, | 
					
						
							|  |  |  |             content, | 
					
						
							|  |  |  |             isEmpty, | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:54 +02:00
										 |  |  |             subRoot, | 
					
						
							| 
									
										
										
										
											2022-12-25 11:58:24 +01:00
										 |  |  |             assetPath, | 
					
						
							|  |  |  |             appPath | 
					
						
							| 
									
										
										
										
											2022-03-22 23:17:47 +01:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2022-01-17 23:13:56 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-11 09:06:30 +02:00
										 |  |  |     router.use('/share/canvas_share.js', express.static(path.join(__dirname, 'canvas_share.js'))); | 
					
						
							| 
									
										
										
										
											2022-05-09 16:38:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-30 09:05:12 +01:00
										 |  |  |     router.get('/share/', (req, res, next) => { | 
					
						
							|  |  |  |         if (req.path.substr(-1) !== '/') { | 
					
						
							|  |  |  |             res.redirect('../share/'); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-17 23:13:56 +01:00
										 |  |  |         shacaLoader.ensureLoad(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |         renderNote(shaca.shareRootNote, req, res); | 
					
						
							| 
									
										
										
										
											2022-01-17 23:13:56 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     router.get('/share/:shareId', (req, res, next) => { | 
					
						
							|  |  |  |         shacaLoader.ensureLoad(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-01 23:16:47 +02:00
										 |  |  |         const {shareId} = req.params; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-17 23:13:56 +01:00
										 |  |  |         const note = shaca.aliasToNote[shareId] || shaca.notes[shareId]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |         renderNote(note, req, res); | 
					
						
							| 
									
										
										
										
											2021-10-17 14:44:59 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-10-19 22:48:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-01 13:23:09 +01:00
										 |  |  |     router.get('/share/api/notes/:noteId', (req, res, next) => { | 
					
						
							| 
									
										
										
										
											2022-05-01 23:16:47 +02:00
										 |  |  |         shacaLoader.ensureLoad(); | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |         let note; | 
					
						
							| 
									
										
										
										
											2022-05-01 23:16:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |         if (!(note = checkNoteAccess(req.params.noteId, req, res))) { | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2021-10-19 22:48:38 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 23:17:47 +01:00
										 |  |  |         addNoIndexHeader(note, res); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-05 23:05:05 +02:00
										 |  |  |         res.json(note.getPojo()); | 
					
						
							| 
									
										
										
										
											2021-10-19 22:48:38 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-12-06 22:53:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-22 09:36:38 +01:00
										 |  |  |     router.get('/share/api/notes/:noteId/download', (req, res, next) => { | 
					
						
							| 
									
										
										
										
											2022-05-01 23:16:47 +02:00
										 |  |  |         shacaLoader.ensureLoad(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |         let note; | 
					
						
							| 
									
										
										
										
											2021-12-06 22:53:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |         if (!(note = checkNoteAccess(req.params.noteId, req, res))) { | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2021-12-06 22:53:17 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 23:17:47 +01:00
										 |  |  |         addNoIndexHeader(note, res); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-06 22:53:17 +01:00
										 |  |  |         const utils = require("../services/utils"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const filename = utils.formatDownloadTitle(note.title, note.type, note.mime); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         res.setHeader('Content-Disposition', utils.getContentDisposition(filename)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); | 
					
						
							|  |  |  |         res.setHeader('Content-Type', note.mime); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         res.send(note.getContent()); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-12-27 20:48:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-05 23:17:23 +02:00
										 |  |  |     // :filename is not used by trilium, but instead used for "save as" to assign a human-readable filename
 | 
					
						
							| 
									
										
										
										
											2022-01-01 13:23:09 +01:00
										 |  |  |     router.get('/share/api/images/:noteId/:filename', (req, res, next) => { | 
					
						
							| 
									
										
										
										
											2022-05-01 23:16:47 +02:00
										 |  |  |         shacaLoader.ensureLoad(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |         let image; | 
					
						
							| 
									
										
										
										
											2022-01-01 13:23:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |         if (!(image = checkNoteAccess(req.params.noteId, req, res))) { | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2022-01-01 13:23:09 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (!["image", "canvas"].includes(image.type)) { | 
					
						
							| 
									
										
										
										
											2022-12-19 21:39:12 +01:00
										 |  |  |             return res.status(400) | 
					
						
							|  |  |  |                 .json({ message: "Requested note is not a shareable image" }); | 
					
						
							| 
									
										
										
										
											2022-05-10 13:43:05 +02:00
										 |  |  |         } else if (image.type === "canvas") { | 
					
						
							| 
									
										
										
										
											2022-04-11 21:38:05 +02:00
										 |  |  |             /** | 
					
						
							| 
									
										
										
										
											2022-07-01 00:01:29 +02:00
										 |  |  |              * special "image" type. the canvas is actually type application/json | 
					
						
							| 
									
										
										
										
											2022-05-03 22:06:24 +02:00
										 |  |  |              * to avoid bitrot and enable usage as referenced image the svg is included. | 
					
						
							| 
									
										
										
										
											2022-04-11 21:38:05 +02:00
										 |  |  |              */ | 
					
						
							|  |  |  |             const content = image.getContent(); | 
					
						
							|  |  |  |             try { | 
					
						
							| 
									
										
										
										
											2022-05-03 22:06:24 +02:00
										 |  |  |                 const data = JSON.parse(content); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 const svg = data.svg || '<svg />'; | 
					
						
							| 
									
										
										
										
											2022-05-03 21:56:52 +02:00
										 |  |  |                 addNoIndexHeader(image, res); | 
					
						
							| 
									
										
											  
											
												missing path2d support for freedawings, remove node-side rendering, allow async getContent()
 * ## Excalidraw and SVG
 * 2022-04-16 - @thfrei
 *
 * Known issues:
 *  - excalidraw-to-svg (node.js) does not render any hand drawn (freedraw) paths. There is an issue with
 *    Path2D object not present in node-canvas library used by jsdom. (See Trilium PR for samples and other issues
 *    in respective library. Link will be added later). Related links:
 *     - https://github.com/Automattic/node-canvas/pull/2013
 *     - https://github.com/google/canvas-5-polyfill
 *     - https://github.com/Automattic/node-canvas/issues/1116
 *     - https://www.npmjs.com/package/path2d-polyfill
 *  - excalidraw-to-svg (node.js) takes quite some time to load an image (1-2s)
 *  - excalidraw-utils (browser) does render freedraw, however NOT freedraw with background
 *
 * Due to this issues, we opt to use **only excalidraw in the frontend**. Upon saving, we will also get the SVG
 * output from the live excalidraw instance. We will save this **SVG side by side the native excalidraw format
 * in the trilium note**.
 *
 * Pro: we will combat bit-rot. Showing the SVG will be very fast, since it is already rendered.
 * Con: The note will get bigger (maybe +30%?), we will generate more bandwith.
 *      (However, using trilium desktop instance, does not care too much about bandwidth. Size increase is probably
 *       acceptable, as a trade off.)
											
										 
											2022-04-19 00:21:20 +02:00
										 |  |  |                 res.set('Content-Type', "image/svg+xml"); | 
					
						
							|  |  |  |                 res.set("Cache-Control", "no-cache, no-store, must-revalidate"); | 
					
						
							|  |  |  |                 res.send(svg); | 
					
						
							| 
									
										
										
										
											2022-12-19 21:39:12 +01:00
										 |  |  |             } catch (err) { | 
					
						
							|  |  |  |                 res.status(500) | 
					
						
							|  |  |  |                     .json({ message: "There was an error parsing excalidraw to svg." }); | 
					
						
							| 
									
										
										
										
											2022-04-11 21:38:05 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             // normal image
 | 
					
						
							|  |  |  |             res.set('Content-Type', image.mime); | 
					
						
							| 
									
										
										
										
											2022-05-03 21:56:52 +02:00
										 |  |  |             addNoIndexHeader(image, res); | 
					
						
							| 
									
										
										
										
											2022-04-11 21:38:05 +02:00
										 |  |  |             res.send(image.getContent()); | 
					
						
							| 
									
										
										
										
											2022-01-01 13:23:09 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-05 23:05:05 +02:00
										 |  |  |     // :filename is not used by trilium, but instead used for "save as" to assign a human-readable filename
 | 
					
						
							|  |  |  |     router.get('/share/api/attachments/:attachmentId/image/:filename', (req, res, next) => { | 
					
						
							|  |  |  |         shacaLoader.ensureLoad(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let attachment; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!(attachment = checkAttachmentAccess(req.params.attachmentId, req, res))) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (attachment.role === "image") { | 
					
						
							|  |  |  |             res.set('Content-Type', attachment.mime); | 
					
						
							|  |  |  |             addNoIndexHeader(attachment.note, res); | 
					
						
							|  |  |  |             res.send(attachment.getContent()); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             return res.status(400) | 
					
						
							|  |  |  |                 .json({ message: "Requested attachment is not a shareable image" }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 00:16:32 +02:00
										 |  |  |     router.get('/share/api/attachments/:attachmentId/download', (req, res, next) => { | 
					
						
							|  |  |  |         shacaLoader.ensureLoad(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let attachment; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!(attachment = checkAttachmentAccess(req.params.attachmentId, req, res))) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         addNoIndexHeader(attachment.note, res); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const utils = require("../services/utils"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const filename = utils.formatDownloadTitle(attachment.title, null, attachment.mime); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         res.setHeader('Content-Disposition', utils.getContentDisposition(filename)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); | 
					
						
							|  |  |  |         res.setHeader('Content-Type', attachment.mime); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         res.send(attachment.getContent()); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-01 13:23:09 +01:00
										 |  |  |     // used for PDF viewing
 | 
					
						
							| 
									
										
										
										
											2021-12-24 21:36:31 +00:00
										 |  |  |     router.get('/share/api/notes/:noteId/view', (req, res, next) => { | 
					
						
							| 
									
										
										
										
											2022-05-01 23:16:47 +02:00
										 |  |  |         shacaLoader.ensureLoad(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |         let note; | 
					
						
							| 
									
										
										
										
											2021-12-24 21:36:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 21:45:32 +02:00
										 |  |  |         if (!(note = checkNoteAccess(req.params.noteId, req, res))) { | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2021-12-24 21:36:31 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 23:17:47 +01:00
										 |  |  |         addNoIndexHeader(note, res); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-24 21:36:31 +00:00
										 |  |  |         res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); | 
					
						
							|  |  |  |         res.setHeader('Content-Type', note.mime); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         res.send(note.getContent()); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-10-17 14:44:59 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = { | 
					
						
							|  |  |  |     register | 
					
						
							|  |  |  | } |