diff --git a/CHANGELOG.md b/CHANGELOG.md
index eb4d974f8..9a24f47e7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [15.2.1] - 2025-11-08
+
+### Fixed
+
+- chore: Simplify routes
+
## [15.2.0] - 2025-09-03
### New
diff --git a/Makefile b/Makefile
index 4401e8de1..3e3ef75c6 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ source_dir=$(build_dir)/source
sign_dir=$(build_dir)/sign
package_name=$(app_name)
cert_dir=$(HOME)/.nextcloud/certificates
-version+=15.2.0
+version+=15.2.1
all: dev-setup build-js-production composer-no-dev
diff --git a/appinfo/info.xml b/appinfo/info.xml
index 47bc51d3a..d26793961 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -23,7 +23,7 @@ Requirements:
- mbstring: *
- when using MySQL, use at least v8.0
]]>
- 15.2.0
+ 15.2.1
agpl
Marcel Klehr
Arthur Schiwon
diff --git a/lib/Controller/BookmarkController.php b/lib/Controller/BookmarkController.php
index 47fed16bf..40f2558b9 100644
--- a/lib/Controller/BookmarkController.php
+++ b/lib/Controller/BookmarkController.php
@@ -238,7 +238,9 @@ private function toExternalFolderId(int $internal): int {
*/
public function getSingleBookmark($id): JSONResponse {
if (!Authorizer::hasPermission(Authorizer::PERM_READ, $this->authorizer->getPermissionsForBookmark((int)$id, $this->request))) {
- return new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
}
try {
/**
@@ -246,7 +248,9 @@ public function getSingleBookmark($id): JSONResponse {
*/
$bm = $this->bookmarkMapper->find((int)$id);
} catch (DoesNotExistException $e) {
- return new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
} catch (MultipleObjectsReturnedException $e) {
return new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
}
@@ -370,7 +374,9 @@ public function getBookmarks(
if ($folder !== null) {
if (!Authorizer::hasPermission(Authorizer::PERM_READ, $this->authorizer->getPermissionsForFolder($folder, $this->request))) {
- return new DataResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
+ $res = new DataResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
+ $res->throttle();
+ return $res;
}
try {
/** @var Folder $folderEntity */
@@ -380,7 +386,9 @@ public function getBookmarks(
// to theirs
$userId = $folderEntity->getUserId();
} catch (DoesNotExistException|MultipleObjectsReturnedException $e) {
- return new DataResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
+ $res = new DataResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
+ $res->throttle();
+ return $res;
}
$params->setFolder($this->toInternalFolderId($folder));
$params->setRecursive($recursive);
@@ -431,7 +439,9 @@ public function newBookmark($url = '', $title = null, $description = null, $tags
$permissions &= $this->authorizer->getPermissionsForFolder($folder, $this->request);
}
if (!Authorizer::hasPermission(Authorizer::PERM_WRITE, $permissions) || $this->authorizer->getUserId() === null) {
- return new JSONResponse(['status' => 'error', 'data' => ['Could not add bookmark']], Http::STATUS_BAD_REQUEST);
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Could not add bookmark']], Http::STATUS_BAD_REQUEST);
+ $res->throttle();
+ return $res;
}
try {
@@ -474,7 +484,9 @@ public function newBookmark($url = '', $title = null, $description = null, $tags
*/
public function editBookmark($id = null, $url = null, $title = null, $description = null, $tags = null, $folders = null, $target = null): JSONResponse {
if (!Authorizer::hasPermission(Authorizer::PERM_EDIT, $this->authorizer->getPermissionsForBookmark($id, $this->request))) {
- return new JSONResponse(['status' => 'error', 'data' => ['Could not edit bookmark']], Http::STATUS_NOT_FOUND);
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Could not edit bookmark']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
}
try {
@@ -522,13 +534,17 @@ public function editBookmark($id = null, $url = null, $title = null, $descriptio
*/
public function deleteBookmark($id): JSONResponse {
if (!Authorizer::hasPermission(Authorizer::PERM_EDIT, $this->authorizer->getPermissionsForBookmark($id, $this->request))) {
- return new JSONResponse(['status' => 'success']);
+ $res = new JSONResponse(['status' => 'success']);
+ $res->throttle();
+ return $res;
}
try {
$this->bookmarkMapper->find($id);
} catch (DoesNotExistException|MultipleObjectsReturnedException) {
- return new JSONResponse(['status' => 'success']);
+ $res = new JSONResponse(['status' => 'success']);
+ $res->throttle();
+ return $res;
}
try {
@@ -550,6 +566,7 @@ public function deleteBookmark($id): JSONResponse {
*
* @NoAdminRequired
* @NoCSRFRequired
+ * @BruteForceProtection
*
* @PublicPage
*/
@@ -561,13 +578,17 @@ public function clickBookmark($url = ''): JSONResponse {
try {
$bookmark = $this->bookmarks->findByUrl($this->authorizer->getUserId(), $url);
} catch (DoesNotExistException $e) {
- return new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
+ $res->throttle();
+ return $res;
} catch (UrlParseError $e) {
return new JSONResponse(['status' => 'error', 'data' => ['Failed to parse URL']], Http::STATUS_BAD_REQUEST);
}
if ($bookmark->getUserId() !== $this->authorizer->getUserId()) {
- return new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
+ $res->throttle();
+ return $res;
}
try {
@@ -591,7 +612,7 @@ public function clickBookmark($url = ''): JSONResponse {
* @NoCSRFRequired
*
* @PublicPage
- * @BruteForceProtection(action=bookmarks#getBookmarkImage)
+ * @BruteForceProtection
* @return DataDisplayResponse|NotFoundResponse|RedirectResponse
*/
public function getBookmarkImage($id) {
@@ -617,7 +638,7 @@ public function getBookmarkImage($id) {
*
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#getBookmarkFavicon)
+ * @BruteForceProtection
* @PublicPage
* @return DataDisplayResponse|NotFoundResponse|DataResponse
*/
@@ -670,7 +691,7 @@ public function doImageResponse(?IImage $image) {
*
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#importBookmark)
+ * @BruteForceProtection
* @PublicPage
*/
public function importBookmark($folder = null): JSONResponse {
@@ -712,7 +733,9 @@ public function importBookmark($folder = null): JSONResponse {
$res->throttle();
return $res;
} catch (DoesNotExistException $e) {
- return new JSONResponse(['status' => 'error', 'data' => ['Folder not found']], Http::STATUS_BAD_REQUEST);
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Folder not found']], Http::STATUS_BAD_REQUEST);
+ $res->throttle();
+ return $res;
} catch (MultipleObjectsReturnedException $e) {
return new JSONResponse(['status' => 'error', 'data' => ['Multiple objects found']], Http::STATUS_INTERNAL_SERVER_ERROR);
} catch (HtmlParseError $e) {
@@ -739,7 +762,7 @@ public function importBookmark($folder = null): JSONResponse {
* @return ExportResponse|JSONResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#exportBookmark)
+ * @BruteForceProtection
* @PublicPage
*/
public function exportBookmark() {
@@ -769,7 +792,7 @@ public function exportBookmark() {
* @return JSONResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#countBookmarks)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -794,7 +817,7 @@ public function countBookmarks(int $folder): JSONResponse {
* @return JSONResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#countUnavailable)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -817,7 +840,7 @@ public function countUnavailable(): JSONResponse {
* @return JSONResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#countArchived)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -836,7 +859,7 @@ public function countArchived(): JSONResponse {
* @return JSONResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#countDuplicated)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -855,7 +878,7 @@ public function countDuplicated(): JSONResponse {
* @return JSONResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#acquireLock)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -883,7 +906,7 @@ public function acquireLock(): JSONResponse {
* @return JSONResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#releaseLock)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -911,7 +934,7 @@ public function releaseLock(): JSONResponse {
* @return Http\DataResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#getDeletedBookmarks)
+ * @BruteForceProtection
* @PublicPage
*/
public function getDeletedBookmarks(): DataResponse {
@@ -933,7 +956,7 @@ public function getDeletedBookmarks(): DataResponse {
/**
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#countAllClicks)
+ * @BruteForceProtection
* @return DataResponse
*/
public function countAllClicks(): DataResponse {
@@ -954,7 +977,7 @@ public function countAllClicks(): DataResponse {
/**
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#countWithClicks)
+ * @BruteForceProtection
* @return DataResponse
*/
public function countWithClicks(): DataResponse {
diff --git a/lib/Controller/FoldersController.php b/lib/Controller/FoldersController.php
index d0e0e96d8..024f835b0 100644
--- a/lib/Controller/FoldersController.php
+++ b/lib/Controller/FoldersController.php
@@ -154,7 +154,7 @@ private function _returnFolderAsArray($folder): array {
*
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#addFolder)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -165,8 +165,13 @@ public function addFolder(string $title = '', int $parent_folder = -1): JSONResp
return $res;
}
try {
- $parent_folder = $this->toInternalFolderId($parent_folder);
- $folder = $this->folders->create($title, $parent_folder);
+ $parent = $this->toInternalFolderId($parent_folder);
+ if ($parent === null) {
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Could not find parent folder']], Http::STATUS_BAD_REQUEST);
+ $res->throttle();
+ return $res;
+ }
+ $folder = $this->folders->create($title, $parent);
} catch (MultipleObjectsReturnedException $e) {
return new JSONResponse(['status' => 'error', 'data' => ['Multiple parent folders found']], Http::STATUS_INTERNAL_SERVER_ERROR);
} catch (UnsupportedOperation $e) {
@@ -186,7 +191,7 @@ public function addFolder(string $title = '', int $parent_folder = -1): JSONResp
*
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#addFolder)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -197,6 +202,11 @@ public function getFolder($folderId): JSONResponse {
return $res;
}
$folderId = $this->toInternalFolderId($folderId);
+ if ($folderId === null) {
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Could not find folder']], Http::STATUS_BAD_REQUEST);
+ $res->throttle();
+ return $res;
+ }
try {
$folder = $this->folders->findSharedFolderOrFolder($this->authorizer->getUserId(), $folderId);
return new JSONResponse(['status' => 'success', 'item' => $this->_returnFolderAsArray($folder)]);
@@ -216,7 +226,7 @@ public function getFolder($folderId): JSONResponse {
*
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#addToFolder)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -228,6 +238,11 @@ public function addToFolder($folderId, $bookmarkId): JSONResponse {
return $res;
}
$folderId = $this->toInternalFolderId($folderId);
+ if ($folderId === null) {
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
+ }
try {
$this->bookmarks->addToFolder($folderId, $bookmarkId);
} catch (UnsupportedOperation $e) {
@@ -254,7 +269,7 @@ public function addToFolder($folderId, $bookmarkId): JSONResponse {
*
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#removeFromFolder)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -267,6 +282,11 @@ public function removeFromFolder($folderId, $bookmarkId, bool $hardDelete = fals
}
try {
$folderId = $this->toInternalFolderId($folderId);
+ if ($folderId === null) {
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
+ $res->throttle();
+ return $res;
+ }
$this->bookmarks->removeFromFolder($folderId, $bookmarkId, $hardDelete);
} catch (DoesNotExistException $e) {
return new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
@@ -301,6 +321,11 @@ public function undeleteFromFolder(int $folderId, int $bookmarkId): JSONResponse
}
try {
$folderId = $this->toInternalFolderId($folderId);
+ if ($folderId === null) {
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
+ }
$this->bookmarks->undeleteInFolder($folderId, $bookmarkId);
return new JSONResponse(['status' => 'success']);
} catch (DoesNotExistException $e) {
@@ -335,7 +360,9 @@ public function deleteFolder(int $folderId, bool $hardDelete = false): JSONRespo
$folderId = $this->toInternalFolderId($folderId);
if ($folderId === null) {
- return new JSONResponse(['status' => 'success']);
+ $res = new JSONResponse(['status' => 'success']);
+ $res->throttle();
+ return $res;
}
try {
$this->folders->deleteSharedFolderOrFolder($this->authorizer->getUserId(), $folderId, $hardDelete);
@@ -355,7 +382,7 @@ public function deleteFolder(int $folderId, bool $hardDelete = false): JSONRespo
*
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#undeleteFolder)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -367,6 +394,11 @@ public function undeleteFolder(int $folderId): JSONResponse {
}
$folderId = $this->toInternalFolderId($folderId);
+ if ($folderId === null) {
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Could not find folder']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
+ }
try {
$this->folders->undelete($this->authorizer->getUserId(), $folderId);
return new JSONResponse(['status' => 'success']);
@@ -389,7 +421,7 @@ public function undeleteFolder(int $folderId): JSONResponse {
*
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#editFolder)
+ * @BruteForceProtection
* @PupblicPage
* @throws UnauthenticatedError
*/
@@ -401,6 +433,11 @@ public function editFolder(int $folderId, ?string $title = null, ?int $parent_fo
}
if ($parent_folder !== null) {
$parent_folder = $this->toInternalFolderId($parent_folder);
+ if ($parent_folder === null) {
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
+ }
}
try {
$folder = $this->folders->updateSharedFolderOrFolder($this->authorizer->getUserId(), $folderId, $title, $parent_folder);
@@ -423,7 +460,7 @@ public function editFolder(int $folderId, ?string $title = null, ?int $parent_fo
*
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=hashFolder)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -438,6 +475,11 @@ public function hashFolder(int $folderId, array $fields = ['title', 'url'], stri
}
try {
$folderId = $this->toInternalFolderId($folderId);
+ if ($folderId === null) {
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Could not find folder']], Http::STATUS_BAD_REQUEST);
+ $res->throttle();
+ return $res;
+ }
$hash = $this->hashManager->hashFolder($this->authorizer->getUserId(), $folderId, $fields, $hashFn);
$res = new JSONResponse(['status' => 'success', 'data' => $hash]);
$res->addHeader('Cache-Control', 'no-cache, must-revalidate');
@@ -473,7 +515,9 @@ public function getFolderChildren(int $folderId, int $layers = 0): JSONResponse
}
$folderId = $this->toInternalFolderId($folderId);
if ($folderId === null) {
- return new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
}
$children = $this->treeMapper->getChildren($folderId, $layers);
$res = new JSONResponse(['status' => 'success', 'data' => $children]);
@@ -489,7 +533,7 @@ public function getFolderChildren(int $folderId, int $layers = 0): JSONResponse
*
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#getFolderChildrenOrder)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -501,7 +545,9 @@ public function getFolderChildrenOrder(int $folderId, int $layers = 0): JSONResp
}
$folderId = $this->toInternalFolderId($folderId);
if ($folderId === null) {
- return new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
}
try {
$children = $this->treeMapper->getChildrenOrder($folderId, $layers);
@@ -533,7 +579,9 @@ public function setFolderChildrenOrder(int $folderId, array $data = []): JSONRes
}
$folderId = $this->toInternalFolderId($folderId);
if ($folderId === null) {
- return new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
}
try {
$this->treeMapper->setChildrenOrder($folderId, $data);
@@ -549,7 +597,7 @@ public function setFolderChildrenOrder(int $folderId, array $data = []): JSONRes
*
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#getFolders)
+ * @BruteForceProtection
* @PublicPage
* @return JSONResponse
* @throws UnauthenticatedError
@@ -562,7 +610,9 @@ public function getFolders(int $root = -1, int $layers = -1): JSONResponse {
}
$internalRoot = $this->toInternalFolderId($root);
if ($internalRoot === null) {
- return new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
}
$folders = $this->treeMapper->getSubFolders($internalRoot, $layers, $root === -1 ? false : null);
if ($root === -1) {
@@ -581,7 +631,7 @@ public function getFolders(int $root = -1, int $layers = -1): JSONResponse {
* @return Http\DataResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#getFolderPublicToken)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -594,7 +644,9 @@ public function getFolderPublicToken(int $folderId): DataResponse {
try {
$publicFolder = $this->publicFolderMapper->findByFolder($folderId);
} catch (DoesNotExistException $e) {
- return new Http\DataResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res = new Http\DataResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
} catch (MultipleObjectsReturnedException $e) {
return new Http\DataResponse(['status' => 'error', 'data' => ['Internal error']], Http::STATUS_INTERNAL_SERVER_ERROR);
}
@@ -606,7 +658,7 @@ public function getFolderPublicToken(int $folderId): DataResponse {
* @return Http\DataResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#createFolderPublicToken)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -622,7 +674,9 @@ public function createFolderPublicToken(int $folderId): DataResponse {
} catch (MultipleObjectsReturnedException $e) {
return new DataResponse(['status' => 'error', 'data' => ['Multiple objects returned']], Http::STATUS_INTERNAL_SERVER_ERROR);
} catch (DoesNotExistException $e) {
- return new DataResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
+ $res = new DataResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND);
+ $res->throttle();
+ return $res;
} catch (UnsupportedOperation $e) {
return new DataResponse(['status' => 'error', 'data' => ['Unsupported operation']], Http::STATUS_BAD_REQUEST);
}
@@ -633,7 +687,7 @@ public function createFolderPublicToken(int $folderId): DataResponse {
* @return Http\DataResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#deleteFolderPublicToken)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -647,7 +701,9 @@ public function deleteFolderPublicToken(int $folderId): DataResponse {
$this->folders->deleteFolderPublicToken($folderId);
return new Http\DataResponse(['status' => 'success']);
} catch (DoesNotExistException $e) {
- return new DataResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
+ $res = new DataResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST);
+ $res->throttle();
+ return $res;
} catch (MultipleObjectsReturnedException|Exception $e) {
return new Http\DataResponse(['status' => 'error', 'data' => ['Internal error']], Http::STATUS_BAD_REQUEST);
}
@@ -658,7 +714,7 @@ public function deleteFolderPublicToken(int $folderId): DataResponse {
* @return Http\DataResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#getShare)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -684,7 +740,7 @@ public function getShare($shareId): DataResponse {
* @return Http\DataResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#findSharedFolders))
+ * @BruteForceProtection)
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -712,7 +768,7 @@ public function findSharedFolders(): DataResponse {
* @return Http\DataResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#findShares)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -739,7 +795,7 @@ public function findShares(): DataResponse {
* @return Http\DataResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#getShares)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -787,7 +843,7 @@ public function getShares(int $folderId): DataResponse {
* @return Http\DataResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#createShare)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -803,7 +859,9 @@ public function createShare(int $folderId, string $participant, int $type, bool
$share = $this->folders->createShare($folderId, $participant, $type, $canWrite, $canShare);
return new Http\DataResponse(['status' => 'success', 'item' => $share->toArray()]);
} catch (DoesNotExistException $e) {
- return new Http\DataResponse(['status' => 'error', 'data' => ['Could not find folder']], Http::STATUS_BAD_REQUEST);
+ $res = new Http\DataResponse(['status' => 'error', 'data' => ['Could not find folder']], Http::STATUS_BAD_REQUEST);
+ $res->throttle();
+ return $res;
} catch (MultipleObjectsReturnedException $e) {
return new Http\DataResponse(['status' => 'error', 'data' => ['Multiple objects returned']], Http::STATUS_INTERNAL_SERVER_ERROR);
} catch (UnsupportedOperation $e) {
@@ -818,7 +876,7 @@ public function createShare(int $folderId, string $participant, int $type, bool
* @return Http\DataResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#editShare)
+ * @BruteForceProtection
* @PublicPage
*/
public function editShare(int $shareId, bool $canWrite = false, bool $canShare = false): Http\DataResponse {
@@ -855,7 +913,7 @@ public function editShare(int $shareId, bool $canWrite = false, bool $canShare =
* @return Http\DataResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#deleteShare)
+ * @BruteForceProtection
* @PublicPage
* @throws UnauthenticatedError
*/
@@ -863,7 +921,9 @@ public function deleteShare(int $shareId): DataResponse {
try {
$share = $this->shareMapper->find($shareId);
} catch (DoesNotExistException $e) {
- return new Http\DataResponse(['status' => 'success']);
+ $res = new Http\DataResponse(['status' => 'success']);
+ $res->throttle();
+ return $res;
} catch (MultipleObjectsReturnedException $e) {
return new Http\DataResponse(['status' => 'error', 'data' => ['Internal error']], Http::STATUS_INTERNAL_SERVER_ERROR);
}
@@ -885,7 +945,7 @@ public function deleteShare(int $shareId): DataResponse {
* @return Http\DataResponse
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=bookmarks#getDeletedFolders)
+ * @BruteForceProtection
* @PublicPage
*/
public function getDeletedFolders(): DataResponse {
diff --git a/lib/Controller/WebViewController.php b/lib/Controller/WebViewController.php
index e693a1199..fe6ac1184 100644
--- a/lib/Controller/WebViewController.php
+++ b/lib/Controller/WebViewController.php
@@ -99,7 +99,7 @@ public function index(): AugmentedTemplateResponse {
*
* @NoAdminRequired
* @NoCSRFRequired
- * @BruteForceProtection(action=link)
+ * @BruteForceProtection
* @PublicPage
*/
public function link(string $token) {
diff --git a/lib/Service/Authorizer.php b/lib/Service/Authorizer.php
index 315ddea60..a9f3b5a2e 100644
--- a/lib/Service/Authorizer.php
+++ b/lib/Service/Authorizer.php
@@ -74,10 +74,14 @@ public function setCredentials(IRequest $request): void {
if (strtolower($type) === 'bearer') {
$userFromTicket = $this->checkTicket($credentials);
if ($userFromTicket !== null) {
- $this->userSession->setUser($this->userManager->get($userFromTicket));
$this->setUserId($userFromTicket);
return;
}
+ try {
+ $this->publicMapper->find($credentials);
+ } catch (DoesNotExistException|MultipleObjectsReturnedException $e) {
+ throw new UnauthenticatedError();
+ }
$this->setToken($credentials);
}
}
@@ -330,7 +334,12 @@ public function generateTicket(string $userId): string {
public function checkTicket(string $ticket): ?string {
try {
- $data = json_decode($this->crypto->decrypt($ticket), true);
+ $json = $this->crypto->decrypt($ticket);
+ } catch (\Exception $e) {
+ return null;
+ }
+ try {
+ $data = json_decode($json, true);
} catch (\Exception $e) {
return null;
}
diff --git a/package.json b/package.json
index af0f73246..56b2e1d86 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "bookmarks",
- "version": "15.2.0",
+ "version": "15.2.1",
"main": "js/index.js",
"scripts": {
"build": "webpack --node-env production --progress --config webpack.js",