aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/l10n/et_EE.js10
-rw-r--r--lib/l10n/et_EE.json10
-rw-r--r--lib/l10n/lv.js12
-rw-r--r--lib/l10n/lv.json12
-rw-r--r--lib/private/AppConfig.php8
-rw-r--r--lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php2
-rw-r--r--lib/private/Security/Bruteforce/Throttler.php29
-rw-r--r--lib/private/Setup.php2
-rw-r--r--lib/private/Share20/DefaultShareProvider.php42
-rw-r--r--lib/private/Share20/Manager.php13
-rw-r--r--lib/public/Share/IShareProviderSupportsAllSharesInFolder.php24
13 files changed, 125 insertions, 41 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 177abfefe8e..b1c6c453b0a 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -780,6 +780,7 @@ return array(
'OCP\\Share\\IShareHelper' => $baseDir . '/lib/public/Share/IShareHelper.php',
'OCP\\Share\\IShareProvider' => $baseDir . '/lib/public/Share/IShareProvider.php',
'OCP\\Share\\IShareProviderSupportsAccept' => $baseDir . '/lib/public/Share/IShareProviderSupportsAccept.php',
+ 'OCP\\Share\\IShareProviderSupportsAllSharesInFolder' => $baseDir . '/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php',
'OCP\\Share\\IShareProviderWithNotification' => $baseDir . '/lib/public/Share/IShareProviderWithNotification.php',
'OCP\\Share_Backend' => $baseDir . '/lib/public/Share_Backend.php',
'OCP\\Share_Backend_Collection' => $baseDir . '/lib/public/Share_Backend_Collection.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index ddccd0692ca..6eecb2da4b5 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -821,6 +821,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Share\\IShareHelper' => __DIR__ . '/../../..' . '/lib/public/Share/IShareHelper.php',
'OCP\\Share\\IShareProvider' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProvider.php',
'OCP\\Share\\IShareProviderSupportsAccept' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProviderSupportsAccept.php',
+ 'OCP\\Share\\IShareProviderSupportsAllSharesInFolder' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php',
'OCP\\Share\\IShareProviderWithNotification' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProviderWithNotification.php',
'OCP\\Share_Backend' => __DIR__ . '/../../..' . '/lib/public/Share_Backend.php',
'OCP\\Share_Backend_Collection' => __DIR__ . '/../../..' . '/lib/public/Share_Backend_Collection.php',
diff --git a/lib/l10n/et_EE.js b/lib/l10n/et_EE.js
index d882e0ee79e..d0ff1a1e511 100644
--- a/lib/l10n/et_EE.js
+++ b/lib/l10n/et_EE.js
@@ -279,6 +279,7 @@ OC.L10N.register(
"Ensure there is a file called \"%1$s\" in the root of the data directory. It should have the content: \"%2$s\"" : "Palun taga, et andmete juurkaustas leidub fail „%1$s“, mille sisuks on „%2$s“",
"Action \"%s\" not supported or implemented." : "„%s“ tegevus pole toetatud või implementeeritud.",
"Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Päringu lõpetamiseks on puudu järgmised parameetrid; „%s“",
+ "ID \"%1$s\" already used by cloud federation provider \"%2$s\"" : "„%1$s“ tunnus on juba kasutusel liitpilve serveris „%2$s“",
"Cloud Federation Provider with ID: \"%s\" does not exist." : "Liitpilve teenusepakkujat tunnusega „%s“ pole olemas.",
"Could not obtain lock type %d on \"%s\"." : "Ei suutnud hankida %d tüüpi lukustust asukohas „%s“.",
"Storage unauthorized. %s" : "Andmeruum on autoriseerimata. %s",
@@ -286,6 +287,12 @@ OC.L10N.register(
"Storage connection error. %s" : "Viga andmeruumi ühenduse loomisel. %s",
"Storage is temporarily not available" : "Salvestusruum pole ajutiselt kättesaadav",
"Storage connection timeout. %s" : "Aegumine andmeruumi ühenduse loomisel. %s",
+ "Transcribe audio" : "Kirjuta heli üles",
+ "Transcribe the things said in an audio" : "Kirjuta üles helifailis kuuldav jutt",
+ "Audio input" : "Helisisend",
+ "The audio to transcribe" : "Üleskirjutatav helifail",
+ "Transcription" : "Üleskirjutus",
+ "The transcribed text" : "Üleskirjutatud tekst",
"Generate image" : "Piltide loomine",
"Generate an image from a text prompt" : "Loo tekstisisendist pilt",
"Prompt" : "Sisendvorm",
@@ -299,6 +306,9 @@ OC.L10N.register(
"Write transcript that you want the assistant to generate speech from" : "Kirjuta üles see, mille alusel tahad Abilisel lasta koostada kõne",
"Output speech" : "Kõneväljund",
"The generated speech" : "Koostatud kõne",
+ "Chat" : "Vestle",
+ "Chat with the assistant" : "Vestle Abilisega",
+ "System prompt" : "Süsteemi viip",
"Generate a headline" : "Alapealkirja loomine",
"Generates a possible headline for a text." : "Võimaldab luua teksti põhjal kokkuvõtliku alapealkirja.",
"Original text" : "Lähtetekst",
diff --git a/lib/l10n/et_EE.json b/lib/l10n/et_EE.json
index 295c4b77855..f42e00f28f1 100644
--- a/lib/l10n/et_EE.json
+++ b/lib/l10n/et_EE.json
@@ -277,6 +277,7 @@
"Ensure there is a file called \"%1$s\" in the root of the data directory. It should have the content: \"%2$s\"" : "Palun taga, et andmete juurkaustas leidub fail „%1$s“, mille sisuks on „%2$s“",
"Action \"%s\" not supported or implemented." : "„%s“ tegevus pole toetatud või implementeeritud.",
"Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Päringu lõpetamiseks on puudu järgmised parameetrid; „%s“",
+ "ID \"%1$s\" already used by cloud federation provider \"%2$s\"" : "„%1$s“ tunnus on juba kasutusel liitpilve serveris „%2$s“",
"Cloud Federation Provider with ID: \"%s\" does not exist." : "Liitpilve teenusepakkujat tunnusega „%s“ pole olemas.",
"Could not obtain lock type %d on \"%s\"." : "Ei suutnud hankida %d tüüpi lukustust asukohas „%s“.",
"Storage unauthorized. %s" : "Andmeruum on autoriseerimata. %s",
@@ -284,6 +285,12 @@
"Storage connection error. %s" : "Viga andmeruumi ühenduse loomisel. %s",
"Storage is temporarily not available" : "Salvestusruum pole ajutiselt kättesaadav",
"Storage connection timeout. %s" : "Aegumine andmeruumi ühenduse loomisel. %s",
+ "Transcribe audio" : "Kirjuta heli üles",
+ "Transcribe the things said in an audio" : "Kirjuta üles helifailis kuuldav jutt",
+ "Audio input" : "Helisisend",
+ "The audio to transcribe" : "Üleskirjutatav helifail",
+ "Transcription" : "Üleskirjutus",
+ "The transcribed text" : "Üleskirjutatud tekst",
"Generate image" : "Piltide loomine",
"Generate an image from a text prompt" : "Loo tekstisisendist pilt",
"Prompt" : "Sisendvorm",
@@ -297,6 +304,9 @@
"Write transcript that you want the assistant to generate speech from" : "Kirjuta üles see, mille alusel tahad Abilisel lasta koostada kõne",
"Output speech" : "Kõneväljund",
"The generated speech" : "Koostatud kõne",
+ "Chat" : "Vestle",
+ "Chat with the assistant" : "Vestle Abilisega",
+ "System prompt" : "Süsteemi viip",
"Generate a headline" : "Alapealkirja loomine",
"Generates a possible headline for a text." : "Võimaldab luua teksti põhjal kokkuvõtliku alapealkirja.",
"Original text" : "Lähtetekst",
diff --git a/lib/l10n/lv.js b/lib/l10n/lv.js
index e5b635a2bd3..c6eeeaa756c 100644
--- a/lib/l10n/lv.js
+++ b/lib/l10n/lv.js
@@ -31,14 +31,14 @@ OC.L10N.register(
"View profile" : "Skatīt profilu",
"today" : "šodien",
"yesterday" : "vakar",
- "_%n day ago_::_%n days ago_" : ["%n dienas atpakaļ","%n dienas atpakaļ","%n dienām"],
+ "_%n day ago_::_%n days ago_" : ["pirms %n dienām","pirms %n dienas","pirms %n dienām"],
"last month" : "pagājušajā mēnesī",
- "_%n month ago_::_%n months ago_" : ["%n mēneši atpakaļ","%n mēneši atpakaļ","%n mēnešiem"],
+ "_%n month ago_::_%n months ago_" : ["pirms %n mēnešiem","pirms %n mēneša","pirms %n mēnešiem"],
"last year" : "gājušajā gadā",
- "_%n year ago_::_%n years ago_" : ["%n gadiem","%n gadiem","%n gadiem"],
- "_%n hour ago_::_%n hours ago_" : ["%n stundas atpakaļ","%n stundas atpakaļ","%n stundām"],
- "_%n minute ago_::_%n minutes ago_" : ["%n minūtes atpakaļ","%n minūtes atpakaļ","%n minūtēm"],
- "seconds ago" : "sekundēm",
+ "_%n year ago_::_%n years ago_" : ["pirms %n gadiem","pirms %n gada","pirms %n gadiem"],
+ "_%n hour ago_::_%n hours ago_" : ["pirms %n stundām","pirms %n stundas","pirms %n stundām"],
+ "_%n minute ago_::_%n minutes ago_" : ["pirms %n minūtēm","pirms %n minūtes","pirms %n minūtēm"],
+ "seconds ago" : "pirms vairākām sekundēm",
"Empty file" : "Tukša datne",
"File already exists" : "Datne jau pastāv",
"Filename contains at least one invalid character" : "Datnes nosaukums satur vismaz vienu nederīgu rakstzīmi",
diff --git a/lib/l10n/lv.json b/lib/l10n/lv.json
index f71090c5fd4..865458737df 100644
--- a/lib/l10n/lv.json
+++ b/lib/l10n/lv.json
@@ -29,14 +29,14 @@
"View profile" : "Skatīt profilu",
"today" : "šodien",
"yesterday" : "vakar",
- "_%n day ago_::_%n days ago_" : ["%n dienas atpakaļ","%n dienas atpakaļ","%n dienām"],
+ "_%n day ago_::_%n days ago_" : ["pirms %n dienām","pirms %n dienas","pirms %n dienām"],
"last month" : "pagājušajā mēnesī",
- "_%n month ago_::_%n months ago_" : ["%n mēneši atpakaļ","%n mēneši atpakaļ","%n mēnešiem"],
+ "_%n month ago_::_%n months ago_" : ["pirms %n mēnešiem","pirms %n mēneša","pirms %n mēnešiem"],
"last year" : "gājušajā gadā",
- "_%n year ago_::_%n years ago_" : ["%n gadiem","%n gadiem","%n gadiem"],
- "_%n hour ago_::_%n hours ago_" : ["%n stundas atpakaļ","%n stundas atpakaļ","%n stundām"],
- "_%n minute ago_::_%n minutes ago_" : ["%n minūtes atpakaļ","%n minūtes atpakaļ","%n minūtēm"],
- "seconds ago" : "sekundēm",
+ "_%n year ago_::_%n years ago_" : ["pirms %n gadiem","pirms %n gada","pirms %n gadiem"],
+ "_%n hour ago_::_%n hours ago_" : ["pirms %n stundām","pirms %n stundas","pirms %n stundām"],
+ "_%n minute ago_::_%n minutes ago_" : ["pirms %n minūtēm","pirms %n minūtes","pirms %n minūtēm"],
+ "seconds ago" : "pirms vairākām sekundēm",
"Empty file" : "Tukša datne",
"File already exists" : "Datne jau pastāv",
"Filename contains at least one invalid character" : "Datnes nosaukums satur vismaz vienu nederīgu rakstzīmi",
diff --git a/lib/private/AppConfig.php b/lib/private/AppConfig.php
index 092d37c3338..a8a6f689ffa 100644
--- a/lib/private/AppConfig.php
+++ b/lib/private/AppConfig.php
@@ -488,6 +488,14 @@ class AppConfig implements IAppConfig {
* @see VALUE_ARRAY
*/
public function getValueType(string $app, string $key, ?bool $lazy = null): int {
+ $type = self::VALUE_MIXED;
+ $ignorable = $lazy ?? false;
+ $this->matchAndApplyLexiconDefinition($app, $key, $ignorable, $type);
+ if ($type !== self::VALUE_MIXED) {
+ // a modified $type means config key is set in Lexicon
+ return $type;
+ }
+
$this->assertParams($app, $key);
$this->loadConfig($app, $lazy);
diff --git a/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php b/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php
index 2b3025fccff..b3040673d0f 100644
--- a/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php
+++ b/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php
@@ -120,7 +120,7 @@ class PublicShareMiddleware extends Middleware {
private function throttle($bruteforceProtectionAction, $token): void {
$ip = $this->request->getRemoteAddress();
- $this->throttler->sleepDelay($ip, $bruteforceProtectionAction);
+ $this->throttler->sleepDelayOrThrowOnMax($ip, $bruteforceProtectionAction);
$this->throttler->registerAttempt($bruteforceProtectionAction, $ip, ['token' => $token]);
}
}
diff --git a/lib/private/Security/Bruteforce/Throttler.php b/lib/private/Security/Bruteforce/Throttler.php
index 21d50848641..065f720ba72 100644
--- a/lib/private/Security/Bruteforce/Throttler.php
+++ b/lib/private/Security/Bruteforce/Throttler.php
@@ -127,6 +127,13 @@ class Throttler implements IThrottler {
*/
public function getDelay(string $ip, string $action = ''): int {
$attempts = $this->getAttempts($ip, $action);
+ return $this->calculateDelay($attempts);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function calculateDelay(int $attempts): int {
if ($attempts === 0) {
return 0;
}
@@ -199,25 +206,29 @@ class Throttler implements IThrottler {
* {@inheritDoc}
*/
public function sleepDelayOrThrowOnMax(string $ip, string $action = ''): int {
- $delay = $this->getDelay($ip, $action);
- if (($delay === self::MAX_DELAY_MS) && $this->getAttempts($ip, $action, 0.5) > $this->config->getSystemValueInt('auth.bruteforce.max-attempts', self::MAX_ATTEMPTS)) {
- $this->logger->info('IP address blocked because it reached the maximum failed attempts in the last 30 minutes [action: {action}, ip: {ip}]', [
+ $attempts = $this->getAttempts($ip, $action, 0.5);
+ if ($attempts > $this->config->getSystemValueInt('auth.bruteforce.max-attempts', self::MAX_ATTEMPTS)) {
+ $this->logger->info('IP address blocked because it reached the maximum failed attempts in the last 30 minutes [action: {action}, attempts: {attempts}, ip: {ip}]', [
'action' => $action,
'ip' => $ip,
+ 'attempts' => $attempts,
]);
// If the ip made too many attempts within the last 30 mins we don't execute anymore
throw new MaxDelayReached('Reached maximum delay');
}
- if ($delay > 100) {
- $this->logger->info('IP address throttled because it reached the attempts limit in the last 30 minutes [action: {action}, delay: {delay}, ip: {ip}]', [
+
+ $attempts = $this->getAttempts($ip, $action);
+ if ($attempts > 10) {
+ $this->logger->info('IP address throttled because it reached the attempts limit in the last 12 hours [action: {action}, attempts: {attempts}, ip: {ip}]', [
'action' => $action,
'ip' => $ip,
- 'delay' => $delay,
+ 'attempts' => $attempts,
]);
}
- if (!$this->config->getSystemValueBool('auth.bruteforce.protection.testing')) {
- usleep($delay * 1000);
+ if ($attempts > 0) {
+ return $this->calculateDelay($attempts);
}
- return $delay;
+
+ return 0;
}
}
diff --git a/lib/private/Setup.php b/lib/private/Setup.php
index 6d3021aff71..959797fb962 100644
--- a/lib/private/Setup.php
+++ b/lib/private/Setup.php
@@ -14,6 +14,7 @@ use Exception;
use InvalidArgumentException;
use OC\Authentication\Token\PublicKeyTokenProvider;
use OC\Authentication\Token\TokenCleanupJob;
+use OC\Core\BackgroundJobs\GenerateMetadataJob;
use OC\Log\Rotate;
use OC\Preview\BackgroundCleanupJob;
use OC\TextProcessing\RemoveOldTasksBackgroundJob;
@@ -495,6 +496,7 @@ class Setup {
$jobList->add(BackgroundCleanupJob::class);
$jobList->add(RemoveOldTasksBackgroundJob::class);
$jobList->add(CleanupDeletedUsers::class);
+ $jobList->add(GenerateMetadataJob::class);
}
/**
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index a257bc4f7b5..e1eebe1e450 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -5,6 +5,7 @@
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
+
namespace OC\Share20;
use OC\Files\Cache\Cache;
@@ -31,6 +32,7 @@ use OCP\Share\IAttributes;
use OCP\Share\IManager;
use OCP\Share\IShare;
use OCP\Share\IShareProviderSupportsAccept;
+use OCP\Share\IShareProviderSupportsAllSharesInFolder;
use OCP\Share\IShareProviderWithNotification;
use Psr\Log\LoggerInterface;
use function str_starts_with;
@@ -40,7 +42,7 @@ use function str_starts_with;
*
* @package OC\Share20
*/
-class DefaultShareProvider implements IShareProviderWithNotification, IShareProviderSupportsAccept {
+class DefaultShareProvider implements IShareProviderWithNotification, IShareProviderSupportsAccept, IShareProviderSupportsAllSharesInFolder {
// Special share type for user modified group shares
public const SHARE_TYPE_USERGROUP = 2;
@@ -603,6 +605,17 @@ class DefaultShareProvider implements IShareProviderWithNotification, IShareProv
throw new \Exception('non-shallow getSharesInFolder is no longer supported');
}
+ return $this->getSharesInFolderInternal($userId, $node, $reshares);
+ }
+
+ public function getAllSharesInFolder(Folder $node): array {
+ return $this->getSharesInFolderInternal(null, $node, null);
+ }
+
+ /**
+ * @return array<int, list<IShare>>
+ */
+ private function getSharesInFolderInternal(?string $userId, Folder $node, ?bool $reshares): array {
$qb = $this->dbConn->getQueryBuilder();
$qb->select('s.*',
'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
@@ -613,18 +626,20 @@ class DefaultShareProvider implements IShareProviderWithNotification, IShareProv
$qb->andWhere($qb->expr()->in('share_type', $qb->createNamedParameter([IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_LINK], IQueryBuilder::PARAM_INT_ARRAY)));
- /**
- * Reshares for this user are shares where they are the owner.
- */
- if ($reshares === false) {
- $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
- } else {
- $qb->andWhere(
- $qb->expr()->orX(
- $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
- $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
- )
- );
+ if ($userId !== null) {
+ /**
+ * Reshares for this user are shares where they are the owner.
+ */
+ if ($reshares !== true) {
+ $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
+ } else {
+ $qb->andWhere(
+ $qb->expr()->orX(
+ $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
+ $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
+ )
+ );
+ }
}
// todo? maybe get these from the oc_mounts table
@@ -656,7 +671,6 @@ class DefaultShareProvider implements IShareProviderWithNotification, IShareProv
foreach ($chunks as $chunk) {
$qb->setParameter('chunk', $chunk, IQueryBuilder::PARAM_INT_ARRAY);
- $a = $qb->getSQL();
$cursor = $qb->executeQuery();
while ($data = $cursor->fetch()) {
$shares[$data['fileid']][] = $this->createShare($data);
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index 3b247475afa..2104c07593a 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -51,6 +51,7 @@ use OCP\Share\IProviderFactory;
use OCP\Share\IShare;
use OCP\Share\IShareProvider;
use OCP\Share\IShareProviderSupportsAccept;
+use OCP\Share\IShareProviderSupportsAllSharesInFolder;
use OCP\Share\IShareProviderWithNotification;
use Psr\Log\LoggerInterface;
@@ -1213,11 +1214,13 @@ class Manager implements IManager {
$shares = [];
foreach ($providers as $provider) {
if ($isOwnerless) {
- foreach ($node->getDirectoryListing() as $childNode) {
- $data = $provider->getSharesByPath($childNode);
- $fid = $childNode->getId();
- $shares[$fid] ??= [];
- $shares[$fid] = array_merge($shares[$fid], $data);
+ // If the provider does not implement the additional interface,
+ // we lack a performant way of querying all shares and therefore ignore the provider.
+ if ($provider instanceof IShareProviderSupportsAllSharesInFolder) {
+ foreach ($provider->getAllSharesInFolder($node) as $fid => $data) {
+ $shares[$fid] ??= [];
+ $shares[$fid] = array_merge($shares[$fid], $data);
+ }
}
} else {
foreach ($provider->getSharesInFolder($userId, $node, $reshares) as $fid => $data) {
diff --git a/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php b/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php
new file mode 100644
index 00000000000..e27da7682ce
--- /dev/null
+++ b/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Share;
+
+use OCP\Files\Folder;
+
+/**
+ * Allows defining a IShareProvider with support for the getAllSharesInFolder method.
+ *
+ * @since 32.0.0
+ */
+interface IShareProviderSupportsAllSharesInFolder extends IShareProvider {
+ /**
+ * Get all shares in a folder.
+ *
+ * @return array<int, list<IShare>>
+ * @since 32.0.0
+ */
+ public function getAllSharesInFolder(Folder $node): array;
+}