diff --git a/appinfo/routes.php b/appinfo/routes.php index fa05e3aa7..a954653bf 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -83,6 +83,20 @@ 'requirements' => ['id' => '\d+'], ], + ////////// A T T A C H M E N T S ////////// + + [ + 'name' => 'notes#getAttachment', + 'url' => '/notes/{noteid}/attachment', + 'verb' => 'GET', + 'requirements' => ['noteid' => '\d+'], + ], + [ + 'name' => 'notes#uploadFile', + 'url' => '/notes/{noteid}/attachment', + 'verb' => 'POST', + 'requirements' => ['noteid' => '\d+'], + ], ////////// S E T T I N G S ////////// ['name' => 'settings#set', 'url' => '/settings', 'verb' => 'PUT'], diff --git a/lib/Controller/NotesController.php b/lib/Controller/NotesController.php index 18a55823c..f90934c0a 100644 --- a/lib/Controller/NotesController.php +++ b/lib/Controller/NotesController.php @@ -9,6 +9,7 @@ use OCA\Notes\Service\SettingsService; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\FileDisplayResponse; use OCP\IRequest; use OCP\IConfig; use OCP\IL10N; @@ -296,4 +297,39 @@ public function destroy(int $id) : JSONResponse { return []; }); } + + /** + * With help from: https://github.com/nextcloud/cookbook + * @NoAdminRequired + * @NoCSRFRequired + * @return JSONResponse|FileDisplayResponse + */ + public function getAttachment(int $noteid, string $path) { + try { + $targetimage = $this->notesService->getAttachment( + $this->helper->getUID(), + $noteid, + $path + ); + $headers = ['Content-Type' => $targetimage->getMimetype(), 'Cache-Control' => 'public, max-age=604800']; + return new FileDisplayResponse($targetimage, Http::STATUS_OK, $headers); + } catch (\Exception $e) { + $this->helper->logException($e); + return $this->helper->createErrorResponse($e, Http::STATUS_NOT_FOUND); + } + } + + /** + * @NoAdminRequired + */ + public function uploadFile(int $noteid): JSONResponse { + $file = $this->request->getUploadedFile('file'); + return $this->helper->handleErrorResponse(function () use ($noteid, $file) { + return $this->notesService->createImage( + $this->helper->getUID(), + $noteid, + $file + ); + }); + } } diff --git a/lib/Service/NotesService.php b/lib/Service/NotesService.php index f73ff0749..9793dd181 100644 --- a/lib/Service/NotesService.php +++ b/lib/Service/NotesService.php @@ -7,6 +7,7 @@ use OCP\Files\File; use OCP\Files\FileInfo; use OCP\Files\Folder; +use OCP\Files\NotPermittedException; class NotesService { private $metaService; @@ -186,4 +187,60 @@ private static function getFileById(Folder $folder, int $id) : File { } return $file[0]; } + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @return \OCP\Files\File + */ + public function getAttachment(string $userId, int $noteid, string $path) : File { + $note = $this->get($userId, $noteid); + $notesFolder = $this->getNotesFolder($userId); + $path = str_replace('\\', '/', $path); // change windows style path + $p = explode('/', $note->getCategory()); + // process relative target path + foreach (explode('/', $path) as $f) { + if ($f == '..') { + array_pop($p); + } elseif ($f !== '') { + array_push($p, $f); + } + } + $targetNode = $notesFolder->get(implode('/', $p)); + assert($targetNode instanceof \OCP\Files\File); + return $targetNode; + } + + /** + * @param $userId + * @param $noteid + * @param $fileDataArray + * @throws NotPermittedException + * https://github.com/nextcloud/deck/blob/master/lib/Service/AttachmentService.php + */ + public function createImage(string $userId, int $noteid, $fileDataArray) { + $note = $this->get($userId, $noteid); + $notesFolder = $this->getNotesFolder($userId); + $parent = $this->noteUtil->getCategoryFolder($notesFolder, $note->getCategory()); + + // try to generate long id, if not available on system fall back to a shorter one + try { + $filename = bin2hex(random_bytes(16)); + } catch (\Exception $e) { + $filename = uniqid(); + } + $filename = $filename . '.' . explode('.', $fileDataArray['name'])[1]; + + // read uploaded file from disk + $fp = fopen($fileDataArray['tmp_name'], 'r'); + $content = fread($fp, $fileDataArray['size']); + fclose($fp); + + $result = []; + $result['filename'] = $filename; + $result['filepath'] = $parent->getPath() . '/' . $filename; + $result['wasUploaded'] = true; + + $this->noteUtil->getRoot()->newFile($parent->getPath() . '/' . $filename, $content); + } } diff --git a/src/components/EditorEasyMDE.vue b/src/components/EditorEasyMDE.vue index 17ef0f9ba..46b02b34b 100644 --- a/src/components/EditorEasyMDE.vue +++ b/src/components/EditorEasyMDE.vue @@ -6,6 +6,9 @@ diff --git a/src/components/EditorMarkdownIt.vue b/src/components/EditorMarkdownIt.vue index e3fd31a4e..fe9d0250d 100644 --- a/src/components/EditorMarkdownIt.vue +++ b/src/components/EditorMarkdownIt.vue @@ -5,6 +5,7 @@