diff options
-rw-r--r-- | appinfo/routes.php | 3 | ||||
-rw-r--r-- | lib/Controller/ImageController.php | 41 | ||||
-rw-r--r-- | lib/Listeners/NodeCopiedListener.php | 1 | ||||
-rw-r--r-- | lib/Service/ImageService.php | 80 | ||||
-rw-r--r-- | src/components/EditorWrapper.vue | 1 | ||||
-rw-r--r-- | src/components/MenuBar.vue | 10 | ||||
-rw-r--r-- | src/nodes/ImageView.vue | 25 | ||||
-rw-r--r-- | src/store.js | 8 |
8 files changed, 81 insertions, 88 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php index 471076d05..19931b74b 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -31,9 +31,6 @@ return [ ['name' => 'Image#insertImageLink', 'url' => '/image/link', 'verb' => 'POST'], ['name' => 'Image#uploadImage', 'url' => '/image/upload', 'verb' => 'POST'], ['name' => 'Image#getImage', 'url' => '/image', 'verb' => 'GET'], - ['name' => 'Image#insertImageLinkPublic', 'url' => '/public/image/link', 'verb' => 'POST'], - ['name' => 'Image#uploadImagePublic', 'url' => '/public/image/upload', 'verb' => 'POST'], - ['name' => 'Image#getImagePublic', 'url' => '/public/image', 'verb' => 'GET'], ['name' => 'Session#create', 'url' => '/session/create', 'verb' => 'PUT'], ['name' => 'Session#fetch', 'url' => '/session/fetch', 'verb' => 'POST'], diff --git a/lib/Controller/ImageController.php b/lib/Controller/ImageController.php index 8c18dd57e..3f50f0363 100644 --- a/lib/Controller/ImageController.php +++ b/lib/Controller/ImageController.php @@ -91,7 +91,7 @@ class ImageController extends Controller { */ public function insertImageFile(int $documentId, int $sessionId, string $sessionToken, string $imagePath): DataResponse { if (!$this->sessionService->isValidSession($documentId, $sessionId, $sessionToken)) { - return new DataResponse([], 500); + return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); } $session = $this->sessionService->getSession($documentId, $sessionId, $sessionToken); $userId = $session->getUserId(); @@ -122,7 +122,7 @@ class ImageController extends Controller { */ public function insertImageLink(string $link, int $documentId, int $sessionId, string $sessionToken, ?string $shareToken = null): DataResponse { if (!$this->sessionService->isValidSession($documentId, $sessionId, $sessionToken)) { - return new DataResponse([], 500); + return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); } try { @@ -156,7 +156,7 @@ class ImageController extends Controller { */ public function uploadImage(int $documentId, int $sessionId, string $sessionToken, ?string $shareToken = null): DataResponse { if (!$this->sessionService->isValidSession($documentId, $sessionId, $sessionToken)) { - return new DataResponse([], 500); + return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); } try { @@ -191,9 +191,13 @@ class ImageController extends Controller { /** * @NoAdminRequired * @NoCSRFRequired + * @PublicPage * * Serve the images in the editor - * @param int $textFileId + * @param int $documentId + * @param int $sessionId + * @param string $sessionToken + * @param string|null $shareToken * @param string $imageFileName * @return DataDisplayResponse * @throws \OCP\Files\InvalidPathException @@ -201,31 +205,16 @@ class ImageController extends Controller { * @throws \OCP\Files\NotPermittedException * @throws \OCP\Lock\LockedException */ - public function getImage(int $textFileId, string $imageFileName): DataDisplayResponse { - $imageFile = $this->imageService->getImage($textFileId, $imageFileName, $this->userId); - if ($imageFile !== null) { - return new DataDisplayResponse($imageFile->getContent(), Http::STATUS_OK, ['Content-Type' => $imageFile->getMimeType()]); - } else { + public function getImage(int $documentId, int $sessionId, string $sessionToken, ?string $shareToken = null, string $imageFileName): DataDisplayResponse { + if (!$this->sessionService->isValidSession($documentId, $sessionId, $sessionToken)) { return new DataDisplayResponse('', Http::STATUS_NOT_FOUND); } - } - /** - * @NoAdminRequired - * @NoCSRFRequired - * @PublicPage - * - * @param int $textFileId - * @param string $imageFileName - * @param string $shareToken - * @return DataDisplayResponse - * @throws \OCP\Files\InvalidPathException - * @throws \OCP\Files\NotFoundException - * @throws \OCP\Files\NotPermittedException - * @throws \OCP\Lock\LockedException - */ - public function getImagePublic(int $textFileId, string $imageFileName, string $shareToken): DataDisplayResponse { - $imageFile = $this->imageService->getImagePublic($textFileId, $imageFileName, $shareToken); + if ($shareToken) { + $imageFile = $this->imageService->getImagePublic($documentId, $imageFileName, $shareToken); + } else { + $imageFile = $this->imageService->getImage($documentId, $imageFileName, $this->userId); + } if ($imageFile !== null) { return new DataDisplayResponse($imageFile->getContent(), Http::STATUS_OK, ['Content-Type' => $imageFile->getMimeType()]); } else { diff --git a/lib/Listeners/NodeCopiedListener.php b/lib/Listeners/NodeCopiedListener.php index 26ed9ba1d..bb54c2ce7 100644 --- a/lib/Listeners/NodeCopiedListener.php +++ b/lib/Listeners/NodeCopiedListener.php @@ -42,7 +42,6 @@ class NodeCopiedListener implements IEventListener { if (!$event instanceof NodeCopiedEvent) { return; } - error_log('COPIED source ' . $event->getSource()->getId() . ' target '. $event->getTarget()->getId()); if ($event->getSource() instanceof File && $event->getSource()->getMimeType() === 'text/markdown' && $event->getTarget() instanceof File diff --git a/lib/Service/ImageService.php b/lib/Service/ImageService.php index 2a714ebbc..da4347074 100644 --- a/lib/Service/ImageService.php +++ b/lib/Service/ImageService.php @@ -85,7 +85,7 @@ class ImageService { /** * Get image content or preview from file id - * @param int $textFileId + * @param int $documentId * @param string $imageFileName * @param string $userId * @return File|\OCP\Files\Node|ISimpleFile|null @@ -93,14 +93,14 @@ class ImageService { * @throws \OCP\Files\InvalidPathException * @throws \OCP\Files\NotPermittedException */ - public function getImage(int $textFileId, string $imageFileName, string $userId) { - $textFile = $this->getTextFile($textFileId, $userId); + public function getImage(int $documentId, string $imageFileName, string $userId) { + $textFile = $this->getTextFile($documentId, $userId); return $textFile === null ? null : $this->getImagePreview($imageFileName, $textFile); } /** * Get image content or preview from file id in public context - * @param int $textFileId + * @param int $documentId * @param string $imageFileName * @param string $shareToken * @return File|\OCP\Files\Node|ISimpleFile|null @@ -108,8 +108,8 @@ class ImageService { * @throws \OCP\Files\InvalidPathException * @throws \OCP\Files\NotPermittedException */ - public function getImagePublic(int $textFileId, string $imageFileName, string $shareToken) { - $textFile = $this->getTextFilePublic($textFileId, $shareToken); + public function getImagePublic(int $documentId, string $imageFileName, string $shareToken) { + $textFile = $this->getTextFilePublic($documentId, $shareToken); return $textFile === null ? null : $this->getImagePreview($imageFileName, $textFile); } @@ -143,7 +143,7 @@ class ImageService { /** * Save an uploaded image in the attachment folder * - * @param int $textFileId + * @param int $documentId * @param string $newFileName * @param string $newFileContent * @param string $userId @@ -152,8 +152,8 @@ class ImageService { * @throws \OCP\Files\InvalidPathException * @throws \OCP\Files\NotPermittedException */ - public function uploadImage(int $textFileId, string $newFileName, string $newFileContent, string $userId): array { - $textFile = $this->getTextFile($textFileId, $userId); + public function uploadImage(int $documentId, string $newFileName, string $newFileContent, string $userId): array { + $textFile = $this->getTextFile($documentId, $userId); if (!$textFile->isUpdateable()) { throw new Exception('No write permissions'); } @@ -164,7 +164,7 @@ class ImageService { return [ 'name' => $fileName, 'id' => $savedFile->getId(), - 'textFileId' => $textFile->getId(), + 'documentId' => $textFile->getId(), ]; } else { return [ @@ -175,7 +175,7 @@ class ImageService { /** * Save an uploaded image in the attachment folder in a public context - * @param int|null $textFileId + * @param int|null $documentId * @param string $newFileName * @param string $newFileContent * @param string $shareToken @@ -184,11 +184,11 @@ class ImageService { * @throws \OCP\Files\InvalidPathException * @throws \OCP\Files\NotPermittedException */ - public function uploadImagePublic(?int $textFileId, string $newFileName, string $newFileContent, string $shareToken): array { + public function uploadImagePublic(?int $documentId, string $newFileName, string $newFileContent, string $shareToken): array { if (!$this->hasUpdatePermissions($shareToken)) { throw new Exception('No write permissions'); } - $textFile = $this->getTextFilePublic($textFileId, $shareToken); + $textFile = $this->getTextFilePublic($documentId, $shareToken); $saveDir = $this->getOrCreateAttachmentDirectoryForFile($textFile); if ($saveDir !== null) { $fileName = (string) time() . '-' . $newFileName; @@ -196,7 +196,7 @@ class ImageService { return [ 'name' => $fileName, 'id' => $savedFile->getId(), - 'textFileId' => $textFile->getId(), + 'documentId' => $textFile->getId(), ]; } else { return [ @@ -208,7 +208,7 @@ class ImageService { /** * Copy a file from a user's storage in the attachment folder * - * @param int $textFileId + * @param int $documentId * @param string $path * @param string $userId * @return array @@ -217,8 +217,8 @@ class ImageService { * @throws \OCP\Files\NotPermittedException * @throws \OCP\Lock\LockedException */ - public function insertImageFile(int $textFileId, string $path, string $userId): array { - $textFile = $this->getTextFile($textFileId, $userId); + public function insertImageFile(int $documentId, string $path, string $userId): array { + $textFile = $this->getTextFile($documentId, $userId); if (!$textFile->isUpdateable()) { throw new Exception('No write permissions'); } @@ -251,7 +251,7 @@ class ImageService { return [ 'name' => $fileName, 'id' => $targetFile->getId(), - 'textFileId' => $textFile->getId(), + 'documentId' => $textFile->getId(), ]; } return [ @@ -262,7 +262,7 @@ class ImageService { /** * Download and save an image from a link in the attachment folder * - * @param int $textFileId + * @param int $documentId * @param string $link * @param string $userId * @return array @@ -270,8 +270,8 @@ class ImageService { * @throws \OCP\Files\InvalidPathException * @throws \OCP\Files\NotPermittedException */ - public function insertImageLink(int $textFileId, string $link, string $userId): array { - $textFile = $this->getTextFile($textFileId, $userId); + public function insertImageLink(int $documentId, string $link, string $userId): array { + $textFile = $this->getTextFile($documentId, $userId); if (!$textFile->isUpdateable()) { throw new Exception('No write permissions'); } @@ -288,17 +288,17 @@ class ImageService { /** * Download and save an image from a link in the attachment folder in a public context * - * @param int|null $textFileId + * @param int|null $documentId * @param string $link * @param string $shareToken * @return array|string[] * @throws Exception */ - public function insertImageLinkPublic(?int $textFileId, string $link, string $shareToken): array { + public function insertImageLinkPublic(?int $documentId, string $link, string $shareToken): array { if (!$this->hasUpdatePermissions($shareToken)) { throw new Exception('No write permissions'); } - $textFile = $this->getTextFilePublic($textFileId, $shareToken); + $textFile = $this->getTextFilePublic($documentId, $shareToken); $saveDir = $this->getOrCreateAttachmentDirectoryForFile($textFile); if ($saveDir !== null) { return $this->downloadLink($saveDir, $link, $textFile); @@ -362,7 +362,7 @@ class ImageService { return [ 'name' => $fileName, 'id' => $savedFile->getId(), - 'textFileId' => $textFile->getId(), + 'documentId' => $textFile->getId(), ]; } else { $savedFile->delete(); @@ -474,14 +474,14 @@ class ImageService { /** * Get a user file from file ID * - * @param int $textFileId + * @param int $documentId * @param string $userId * @return File|null * @throws \OCP\Files\NotPermittedException */ - private function getTextFile(int $textFileId, string $userId): ?File { + private function getTextFile(int $documentId, string $userId): ?File { $userFolder = $this->rootFolder->getUserFolder($userId); - $textFile = $userFolder->getById($textFileId); + $textFile = $userFolder->getById($documentId); if (count($textFile) > 0 && $textFile[0] instanceof File) { return $textFile[0]; } @@ -491,12 +491,12 @@ class ImageService { /** * Get file from share token * - * @param int|null $textFileId + * @param int|null $documentId * @param string $shareToken * @return File|null * @throws NotFoundException */ - private function getTextFilePublic(?int $textFileId, string $shareToken): ?File { + private function getTextFilePublic(?int $documentId, string $shareToken): ?File { // is the file shared with this token? try { $share = $this->shareManager->getShareByToken($shareToken); @@ -507,10 +507,10 @@ class ImageService { if ($textFile instanceof File) { return $textFile; } - } elseif ($share->getNodeType() === 'folder' && $textFileId !== null) { + } elseif ($share->getNodeType() === 'folder' && $documentId !== null) { $folder = $share->getNode(); if ($folder instanceof Folder) { - $textFile = $folder->getById($textFileId); + $textFile = $folder->getById($documentId); if (count($textFile) > 0 && $textFile[0] instanceof File) { return $textFile[0]; } @@ -667,26 +667,12 @@ class ImageService { if ($sourceAttachmentDir !== null) { // create a new attachment dir next to the new file $targetAttachmentDir = $this->getOrCreateAttachmentDirectoryForFile($target); - $markdownContent = $source->getContent(); - // replace the text file ID in each attachment link in the markdown content - $markdownContent = preg_replace( - '/\!\[([^\[\]]+)\]\(text:\/\/image\?textFileId=' . $source->getId() . '&imageFileName=([^)&]+)\)/', - '![$1](text://image?textFileId=' . $target->getId() . '&imageFileName=$2)', - $markdownContent - ); // copy the attachment files foreach ($sourceAttachmentDir->getDirectoryListing() as $sourceAttachment) { if ($sourceAttachment instanceof File) { - $copied = $targetAttachmentDir->newFile($sourceAttachment->getName(), $sourceAttachment->getContent()); + $targetAttachmentDir->newFile($sourceAttachment->getName(), $sourceAttachment->getContent()); } } - try { - $target->putContent($markdownContent); - } catch (LockedException $e) { - $target->unlock(ILockingProvider::LOCK_SHARED); - $target->putContent($markdownContent); - $target->lock(ILockingProvider::LOCK_SHARED); - } } } } diff --git a/src/components/EditorWrapper.vue b/src/components/EditorWrapper.vue index a19e29b7e..5ba0b93c4 100644 --- a/src/components/EditorWrapper.vue +++ b/src/components/EditorWrapper.vue @@ -296,6 +296,7 @@ export default { this.document = document this.readOnly = document.readOnly localStorage.setItem('nick', this.currentSession.guestName) + this.$store.dispatch('setCurrentSession', this.currentSession) }) .on('change', ({ document, sessions }) => { if (this.document.baseVersionEtag !== '' && document.baseVersionEtag !== this.document.baseVersionEtag) { diff --git a/src/components/MenuBar.vue b/src/components/MenuBar.vue index 3e60aa40e..1f1a4b045 100644 --- a/src/components/MenuBar.vue +++ b/src/components/MenuBar.vue @@ -381,7 +381,7 @@ export default { event.target.value = '' this.syncService.uploadImage(image).then((response) => { - this.insertAttachmentImage(response.data?.name, response.data?.id, this.imageCommand, response.data?.textFileId) + this.insertAttachmentImage(response.data?.name, response.data?.id, this.imageCommand) }).catch((error) => { console.error(error) showError(error?.response?.data?.error) @@ -400,7 +400,7 @@ export default { this.$refs.imageActions[0].closeMenu() this.syncService.insertImageLink(this.imageLink).then((response) => { - this.insertAttachmentImage(response.data?.name, response.data?.id, command, response.data?.textFileId) + this.insertAttachmentImage(response.data?.name, response.data?.id, command) }).catch((error) => { console.error(error) showError(error?.response?.data?.error) @@ -414,7 +414,7 @@ export default { this.$refs.imageActions[0].closeMenu() this.syncService.insertImageFile(imagePath).then((response) => { - this.insertAttachmentImage(response.data?.name, response.data?.id, command, response.data?.textFileId) + this.insertAttachmentImage(response.data?.name, response.data?.id, command) }).catch((error) => { console.error(error) showError(error?.response?.data?.error) @@ -431,8 +431,8 @@ export default { this.onImagePathSubmit(file, command) }, false, [], true, undefined, this.imagePath) }, - insertAttachmentImage(name, fileId, command, textFileId) { - const src = 'text://image?textFileId=' + textFileId + '&imageFileName=' + encodeURIComponent(name) + insertAttachmentImage(name, fileId, command) { + const src = 'text://image?imageFileName=' + encodeURIComponent(name) command({ src, alt: name, diff --git a/src/nodes/ImageView.vue b/src/nodes/ImageView.vue index ce62fc7a1..cf0dd521e 100644 --- a/src/nodes/ImageView.vue +++ b/src/nodes/ImageView.vue @@ -61,6 +61,7 @@ import path from 'path' import { generateUrl, generateRemoteUrl } from '@nextcloud/router' import { getCurrentUser } from '@nextcloud/auth' +import store from './../mixins/store' const imageMimes = [ 'image/png', @@ -93,6 +94,9 @@ const getQueryVariable = (src, variable) => { export default { name: 'ImageView', + mixins: [ + store, + ], props: ['node', 'options', 'updateAttrs', 'view'], // eslint-disable-line data() { return { @@ -102,6 +106,9 @@ export default { } }, computed: { + currentSession() { + return this.$store.state.currentSession + }, davUrl() { if (getCurrentUser()) { const uid = getCurrentUser().uid @@ -118,20 +125,26 @@ export default { }, imageUrl() { if (this.src.startsWith('text://')) { + const documentId = this.currentSession?.documentId + const sessionId = this.currentSession?.id + const sessionToken = this.currentSession?.token const imageFileName = getQueryVariable(this.src, 'imageFileName') - const textFileId = getQueryVariable(this.src, 'textFileId') if (getCurrentUser()) { - return generateUrl('/apps/text/image?textFileId={textFileId}&imageFileName={imageFileName}', + return generateUrl('/apps/text/image?documentId={documentId}&sessionId={sessionId}&sessionToken={sessionToken}&imageFileName={imageFileName}', { - textFileId, + documentId, + sessionId, + sessionToken, imageFileName, }) } else { - return generateUrl('/apps/text/public/image?textFileId={textFileId}&imageFileName={imageFileName}&shareToken={token}', + return generateUrl('/apps/text/image?documentId={documentId}&sessionId={sessionId}&sessionToken={sessionToken}&imageFileName={imageFileName}&shareToken={shareToken}', { - textFileId, + documentId, + sessionId, + sessionToken, imageFileName, - token: this.token, + shareToken: this.token, }) } } diff --git a/src/store.js b/src/store.js index 53a8a22ac..46d24be27 100644 --- a/src/store.js +++ b/src/store.js @@ -31,17 +31,25 @@ Vue.use(Vuex) const store = new Vuex.Store({ state: { showAuthorAnnotations: persistentStorage.getItem('showAuthorAnnotations') === 'true', + currentSession: persistentStorage.getItem('currentSession'), }, mutations: { SET_SHOW_AUTHOR_ANNOTATIONS(state, value) { state.showAuthorAnnotations = value persistentStorage.setItem('showAuthorAnnotations', '' + value) }, + SET_CURRENT_SESSION(state, value) { + state.currentSession = value + persistentStorage.setItem('currentSession', value) + }, }, actions: { setShowAuthorAnnotations({ commit }, value) { store.commit('SET_SHOW_AUTHOR_ANNOTATIONS', value) }, + setCurrentSession({ commit }, value) { + store.commit('SET_CURRENT_SESSION', value) + }, }, }) |