Compare commits
172 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0de4631714 | |||
| ff6d2fc353 | |||
| d341c2011f | |||
| 7eea3b7742 | |||
| 7c526b4de3 | |||
| 635e26dfdc | |||
| c2cd236411 | |||
| acfec22652 | |||
| 328a4608aa | |||
| 7e188433a1 | |||
| acb3e68a93 | |||
| fbb551311e | |||
| c2ae99a668 | |||
| 932523e844 | |||
| 6fd76bfa0e | |||
| 510c203dfe | |||
| 0514ecfb96 | |||
| 91a544ef45 | |||
| a0c922cc7f | |||
| 2da078f258 | |||
| 36b0d7c189 | |||
| fe34ea5ec7 | |||
| ae250777fd | |||
| 17aa77e29f | |||
| 43f2470f90 | |||
| d5eab95414 | |||
| 7e4c4f2f3c | |||
| de286709f8 | |||
| d86975e9fa | |||
| 03adb7e184 | |||
| 8eb24155c4 | |||
| 377de23bf5 | |||
| 73dd45be4f | |||
| adf7ea5f0b | |||
| cc89a2a2b8 | |||
| 5403284b23 | |||
| f56f747f46 | |||
| 7a2606b894 | |||
| eb91d8671d | |||
| 1a5ad32063 | |||
| a1fbd55992 | |||
| a6a320498b | |||
| 3e4e544096 | |||
| 1a7f2f878e | |||
| f6a783e07b | |||
| 7436340f4c | |||
| 58c6a8387b | |||
| 6af64a5495 | |||
| 66c8f9c4dc | |||
| 52cfd57af9 | |||
| 6a75cd9454 | |||
| 8e5ae53e02 | |||
| ab122ac15d | |||
| f2e2e4ea21 | |||
| 15b45975e2 | |||
| 2d22c4f654 | |||
| 07eef5eaf4 | |||
| 09e0f06678 | |||
| 47acb66b9c | |||
| 6b3d3fd2d3 | |||
| f42493bf1e | |||
| fe393c5dbf | |||
| bd815595d4 | |||
| 86c90221f1 | |||
| 0cdd19271d | |||
| 513b37916f | |||
| 9e516beb85 | |||
| 6b6deefee9 | |||
| 8d55b13641 | |||
| 2bd2cc71e5 | |||
| 40b79f5af8 | |||
| 6eb1609b35 | |||
| 58de51160c | |||
| a430702caa | |||
| 351351a832 | |||
| 944341543e | |||
| e5c989066f | |||
| 62513dfd92 | |||
| 649e042568 | |||
| 71fa5937b2 | |||
| 6ee8325b3e | |||
| 47de164946 | |||
| c57c4843e8 | |||
| 7c64394617 | |||
| c09168e911 | |||
| 9f7d4d055e | |||
| c3be0b8814 | |||
| 1432c97584 | |||
| 178fb77be8 | |||
| 86fe44d9f4 | |||
| fdfaf6b363 | |||
| ad13a8acc7 | |||
| 693a2263cc | |||
| 65d44b0007 | |||
| ec9cac90e0 | |||
| e63c4afdab | |||
| e1d19b2c24 | |||
| 72ad2edcd7 | |||
| 72632faaf1 | |||
| ebab99ec9a | |||
| 7c1a8a4060 | |||
| 5f797ebc32 | |||
| a100ede789 | |||
| f546daada7 | |||
| c32009fd32 | |||
| 72be2f41b3 | |||
| 758a9c26db | |||
| 0c6565ea44 | |||
| 33e5f2d345 | |||
| 0a3cc4dd6f | |||
| c6b095234e | |||
| f9d4bb2ba8 | |||
| ad61aa7a30 | |||
| 8cc588fc42 | |||
| 35bfa1d2f0 | |||
| 5d3e1f70b2 | |||
| 8a05a3e01b | |||
| afa23291d6 | |||
| c50c5a9e6b | |||
| eb0369705a | |||
| fe0c56a1d7 | |||
| 98a4b959ec | |||
| fd96a32dda | |||
| 3726596ad0 | |||
| f9a137ea87 | |||
| 7077685bf8 | |||
| 34511e9036 | |||
| 493c371a22 | |||
| 4a9cdeb01f | |||
| 7abd46fb53 | |||
| fb18804192 | |||
| 513c0cceb6 | |||
| 867a8d1088 | |||
| dc5d199e3a | |||
| 41c739d370 | |||
| 24ec0e85e5 | |||
| eafbb5a23c | |||
| 8cfb49012d | |||
| 39c8141f0c | |||
| 5c51b42d3f | |||
| 80caedb050 | |||
| 853db93601 | |||
| 355d6637ff | |||
| 183136d166 | |||
| b872208285 | |||
| b28176458d | |||
| 69249a3ce3 | |||
| 3555e00754 | |||
| c11cc64470 | |||
| a6184661bd | |||
| 981e987bd0 | |||
| f9157c85c2 | |||
| fbe2023d39 | |||
| d59d8db1d6 | |||
| 694651de3a | |||
| 70ed393b34 | |||
| 3de06a2b33 | |||
| d3432482cc | |||
| e456f116b8 | |||
| b6ea2bc0f5 | |||
| 65aa731ef3 | |||
| 812f12ecc4 | |||
| a9b17a1a16 | |||
| 5f5bb77bf3 | |||
| fbe5238d7f | |||
| cc96a16df5 | |||
| 04f30cad62 | |||
| 23546013e1 | |||
| 45eb87ba6e | |||
| 01e0ca7298 | |||
| 3bb5ed502a | |||
| 13bfd8b292 |
@@ -15,6 +15,7 @@ on:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
concurrency:
|
||||
group: static-code-analysis-${{ github.head_ref || github.run_id }}
|
||||
|
||||
+1
-1
Submodule 3rdparty updated: 086aa0783e...08d9ba0139
@@ -18,7 +18,7 @@ class TagManagement extends Action {
|
||||
$this->log('System tag "%s" (%s, %s) created',
|
||||
[
|
||||
'name' => $tag->getName(),
|
||||
'visbility' => $tag->isUserVisible() ? 'visible' : 'invisible',
|
||||
'visibility' => $tag->isUserVisible() ? 'visible' : 'invisible',
|
||||
'assignable' => $tag->isUserAssignable() ? 'user assignable' : 'system only',
|
||||
],
|
||||
['name', 'visibility', 'assignable']
|
||||
|
||||
@@ -25,6 +25,15 @@ return [
|
||||
'url' => '/invite-accepted',
|
||||
'verb' => 'POST',
|
||||
'root' => '/ocm',
|
||||
]
|
||||
],
|
||||
|
||||
// needs to be kept at the bottom of the list
|
||||
[
|
||||
'name' => 'OCMRequest#manageOCMRequests',
|
||||
'url' => '/{ocmPath}',
|
||||
'requirements' => ['ocmPath' => '.*'],
|
||||
'verb' => ['GET', 'POST', 'PUT', 'DELETE'],
|
||||
'root' => '/ocm',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -10,6 +10,7 @@ return array(
|
||||
'OCA\\CloudFederationAPI\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
|
||||
'OCA\\CloudFederationAPI\\Capabilities' => $baseDir . '/../lib/Capabilities.php',
|
||||
'OCA\\CloudFederationAPI\\Config' => $baseDir . '/../lib/Config.php',
|
||||
'OCA\\CloudFederationAPI\\Controller\\OCMRequestController' => $baseDir . '/../lib/Controller/OCMRequestController.php',
|
||||
'OCA\\CloudFederationAPI\\Controller\\RequestHandlerController' => $baseDir . '/../lib/Controller/RequestHandlerController.php',
|
||||
'OCA\\CloudFederationAPI\\Db\\FederatedInvite' => $baseDir . '/../lib/Db/FederatedInvite.php',
|
||||
'OCA\\CloudFederationAPI\\Db\\FederatedInviteMapper' => $baseDir . '/../lib/Db/FederatedInviteMapper.php',
|
||||
|
||||
@@ -25,6 +25,7 @@ class ComposerStaticInitCloudFederationAPI
|
||||
'OCA\\CloudFederationAPI\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
|
||||
'OCA\\CloudFederationAPI\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php',
|
||||
'OCA\\CloudFederationAPI\\Config' => __DIR__ . '/..' . '/../lib/Config.php',
|
||||
'OCA\\CloudFederationAPI\\Controller\\OCMRequestController' => __DIR__ . '/..' . '/../lib/Controller/OCMRequestController.php',
|
||||
'OCA\\CloudFederationAPI\\Controller\\RequestHandlerController' => __DIR__ . '/..' . '/../lib/Controller/RequestHandlerController.php',
|
||||
'OCA\\CloudFederationAPI\\Db\\FederatedInvite' => __DIR__ . '/..' . '/../lib/Db/FederatedInvite.php',
|
||||
'OCA\\CloudFederationAPI\\Db\\FederatedInviteMapper' => __DIR__ . '/..' . '/../lib/Db/FederatedInviteMapper.php',
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\CloudFederationAPI\Controller;
|
||||
|
||||
use JsonException;
|
||||
use NCU\Security\Signature\Exceptions\IncomingRequestException;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\BruteForceProtection;
|
||||
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
|
||||
use OCP\AppFramework\Http\Attribute\PublicPage;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\IRequest;
|
||||
use OCP\OCM\Events\OCMEndpointRequestEvent;
|
||||
use OCP\OCM\Exceptions\OCMArgumentException;
|
||||
use OCP\OCM\IOCMDiscoveryService;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class OCMRequestController extends Controller {
|
||||
public function __construct(
|
||||
string $appName,
|
||||
IRequest $request,
|
||||
private readonly IEventDispatcher $eventDispatcher,
|
||||
private readonly IOCMDiscoveryService $ocmDiscoveryService,
|
||||
private readonly LoggerInterface $logger,
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method will catch any request done to /ocm/[...] and will broadcast an event.
|
||||
* The first parameter of the remaining subpath (post-/ocm/) is defined as
|
||||
* capability and should be used by listeners to filter incoming requests.
|
||||
*
|
||||
* @see OCMEndpointRequestEvent
|
||||
* @see OCMEndpointRequestEvent::getArgs
|
||||
*
|
||||
* @param string $ocmPath
|
||||
* @return Response
|
||||
* @throws OCMArgumentException
|
||||
*/
|
||||
#[NoCSRFRequired]
|
||||
#[PublicPage]
|
||||
#[BruteForceProtection(action: 'receiveOcmRequest')]
|
||||
public function manageOCMRequests(string $ocmPath): Response {
|
||||
if (!mb_check_encoding($ocmPath, 'UTF-8')) {
|
||||
throw new OCMArgumentException('path is not UTF-8');
|
||||
}
|
||||
|
||||
try {
|
||||
// if request is signed and well signed, no exceptions are thrown
|
||||
// if request is not signed and host is known for not supporting signed request, no exceptions are thrown
|
||||
$signedRequest = $this->ocmDiscoveryService->getIncomingSignedRequest();
|
||||
} catch (IncomingRequestException $e) {
|
||||
$this->logger->warning('incoming ocm request exception', ['exception' => $e]);
|
||||
return new JSONResponse(['message' => $e->getMessage(), 'validationErrors' => []], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
// assuming that ocm request contains a json array
|
||||
$payload = $signedRequest?->getBody() ?? file_get_contents('php://input');
|
||||
try {
|
||||
$payload = ($payload) ? json_decode($payload, true, 512, JSON_THROW_ON_ERROR) : null;
|
||||
} catch (JsonException $e) {
|
||||
$this->logger->debug('json decode error', ['exception' => $e]);
|
||||
$payload = null;
|
||||
}
|
||||
|
||||
$event = new OCMEndpointRequestEvent(
|
||||
$this->request->getMethod(),
|
||||
preg_replace('@/+@', '/', $ocmPath),
|
||||
$payload,
|
||||
$signedRequest?->getOrigin()
|
||||
);
|
||||
$this->eventDispatcher->dispatchTyped($event);
|
||||
|
||||
return $event->getResponse() ?? new DataResponse('', Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,6 @@ use NCU\Federation\ISignedCloudFederationProvider;
|
||||
use NCU\Security\Signature\Exceptions\IdentityNotFoundException;
|
||||
use NCU\Security\Signature\Exceptions\IncomingRequestException;
|
||||
use NCU\Security\Signature\Exceptions\SignatoryNotFoundException;
|
||||
use NCU\Security\Signature\Exceptions\SignatureException;
|
||||
use NCU\Security\Signature\Exceptions\SignatureNotFoundException;
|
||||
use NCU\Security\Signature\IIncomingSignedRequest;
|
||||
use NCU\Security\Signature\ISignatureManager;
|
||||
use OC\OCM\OCMSignatoryManager;
|
||||
@@ -44,6 +42,7 @@ use OCP\IGroupManager;
|
||||
use OCP\IRequest;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUserManager;
|
||||
use OCP\OCM\IOCMDiscoveryService;
|
||||
use OCP\Share\Exceptions\ShareNotFound;
|
||||
use OCP\Util;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@@ -74,8 +73,8 @@ class RequestHandlerController extends Controller {
|
||||
private readonly IAppConfig $appConfig,
|
||||
private ICloudFederationFactory $factory,
|
||||
private ICloudIdManager $cloudIdManager,
|
||||
private readonly IOCMDiscoveryService $ocmDiscoveryService,
|
||||
private readonly ISignatureManager $signatureManager,
|
||||
private readonly OCMSignatoryManager $signatoryManager,
|
||||
private ITimeFactory $timeFactory,
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
@@ -108,9 +107,9 @@ class RequestHandlerController extends Controller {
|
||||
public function addShare($shareWith, $name, $description, $providerId, $owner, $ownerDisplayName, $sharedBy, $sharedByDisplayName, $protocol, $shareType, $resourceType) {
|
||||
if (!$this->appConfig->getValueBool('core', OCMSignatoryManager::APPCONFIG_SIGN_DISABLED, lazy: true)) {
|
||||
try {
|
||||
// if request is signed and well signed, no exception are thrown
|
||||
// if request is signed and well signed, no exceptions are thrown
|
||||
// if request is not signed and host is known for not supporting signed request, no exception are thrown
|
||||
$signedRequest = $this->getSignedRequest();
|
||||
$signedRequest = $this->ocmDiscoveryService->getIncomingSignedRequest();
|
||||
$this->confirmSignedOrigin($signedRequest, 'owner', $owner);
|
||||
} catch (IncomingRequestException $e) {
|
||||
$this->logger->warning('incoming request exception', ['exception' => $e]);
|
||||
@@ -360,7 +359,7 @@ class RequestHandlerController extends Controller {
|
||||
try {
|
||||
// if request is signed and well signed, no exception are thrown
|
||||
// if request is not signed and host is known for not supporting signed request, no exception are thrown
|
||||
$signedRequest = $this->getSignedRequest();
|
||||
$signedRequest = $this->ocmDiscoveryService->getIncomingSignedRequest();
|
||||
$this->confirmNotificationIdentity($signedRequest, $resourceType, $notification);
|
||||
} catch (IncomingRequestException $e) {
|
||||
$this->logger->warning('incoming request exception', ['exception' => $e]);
|
||||
@@ -434,37 +433,6 @@ class RequestHandlerController extends Controller {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns signed request if available.
|
||||
* throw an exception:
|
||||
* - if request is signed, but wrongly signed
|
||||
* - if request is not signed but instance is configured to only accept signed ocm request
|
||||
*
|
||||
* @return IIncomingSignedRequest|null null if remote does not (and never did) support signed request
|
||||
* @throws IncomingRequestException
|
||||
*/
|
||||
private function getSignedRequest(): ?IIncomingSignedRequest {
|
||||
try {
|
||||
$signedRequest = $this->signatureManager->getIncomingSignedRequest($this->signatoryManager);
|
||||
$this->logger->debug('signed request available', ['signedRequest' => $signedRequest]);
|
||||
return $signedRequest;
|
||||
} catch (SignatureNotFoundException|SignatoryNotFoundException $e) {
|
||||
$this->logger->debug('remote does not support signed request', ['exception' => $e]);
|
||||
// remote does not support signed request.
|
||||
// currently we still accept unsigned request until lazy appconfig
|
||||
// core.enforce_signed_ocm_request is set to true (default: false)
|
||||
if ($this->appConfig->getValueBool('core', OCMSignatoryManager::APPCONFIG_SIGN_ENFORCED, lazy: true)) {
|
||||
$this->logger->notice('ignored unsigned request', ['exception' => $e]);
|
||||
throw new IncomingRequestException('Unsigned request');
|
||||
}
|
||||
} catch (SignatureException $e) {
|
||||
$this->logger->warning('wrongly signed request', ['exception' => $e]);
|
||||
throw new IncomingRequestException('Invalid signature');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* confirm that the value related to $key entry from the payload is in format userid@hostname
|
||||
* and compare hostname with the origin of the signed request.
|
||||
|
||||
@@ -10,7 +10,6 @@ declare(strict_types=1);
|
||||
namespace OCA\CloudFederationApi\Tests;
|
||||
|
||||
use NCU\Security\Signature\ISignatureManager;
|
||||
use OC\OCM\OCMSignatoryManager;
|
||||
use OCA\CloudFederationAPI\Config;
|
||||
use OCA\CloudFederationAPI\Controller\RequestHandlerController;
|
||||
use OCA\CloudFederationAPI\Db\FederatedInvite;
|
||||
@@ -29,6 +28,7 @@ use OCP\IRequest;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\OCM\IOCMDiscoveryService;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
@@ -45,10 +45,11 @@ class RequestHandlerControllerTest extends TestCase {
|
||||
private FederatedInviteMapper&MockObject $federatedInviteMapper;
|
||||
private AddressHandler&MockObject $addressHandler;
|
||||
private IAppConfig&MockObject $appConfig;
|
||||
|
||||
private ICloudFederationFactory&MockObject $cloudFederationFactory;
|
||||
private ICloudIdManager&MockObject $cloudIdManager;
|
||||
private IOCMDiscoveryService&MockObject $discoveryService;
|
||||
private ISignatureManager&MockObject $signatureManager;
|
||||
private OCMSignatoryManager&MockObject $signatoryManager;
|
||||
private ITimeFactory&MockObject $timeFactory;
|
||||
|
||||
private RequestHandlerController $requestHandlerController;
|
||||
@@ -69,8 +70,8 @@ class RequestHandlerControllerTest extends TestCase {
|
||||
$this->appConfig = $this->createMock(IAppConfig::class);
|
||||
$this->cloudFederationFactory = $this->createMock(ICloudFederationFactory::class);
|
||||
$this->cloudIdManager = $this->createMock(ICloudIdManager::class);
|
||||
$this->discoveryService = $this->createMock(IOCMDiscoveryService::class);
|
||||
$this->signatureManager = $this->createMock(ISignatureManager::class);
|
||||
$this->signatoryManager = $this->createMock(OCMSignatoryManager::class);
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
|
||||
$this->requestHandlerController = new RequestHandlerController(
|
||||
@@ -88,8 +89,8 @@ class RequestHandlerControllerTest extends TestCase {
|
||||
$this->appConfig,
|
||||
$this->cloudFederationFactory,
|
||||
$this->cloudIdManager,
|
||||
$this->discoveryService,
|
||||
$this->signatureManager,
|
||||
$this->signatoryManager,
|
||||
$this->timeFactory,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
</providers>
|
||||
</activity>
|
||||
|
||||
<openmetrics>
|
||||
<exporter>OCA\Comments\OpenMetrics\CommentsCountMetric</exporter>
|
||||
</openmetrics>
|
||||
|
||||
<collaboration>
|
||||
<plugins>
|
||||
<plugin type="autocomplete-sort">OCA\Comments\Collaboration\CommentersSorter</plugin>
|
||||
|
||||
@@ -22,5 +22,6 @@ return array(
|
||||
'OCA\\Comments\\MaxAutoCompleteResultsInitialState' => $baseDir . '/../lib/MaxAutoCompleteResultsInitialState.php',
|
||||
'OCA\\Comments\\Notification\\Listener' => $baseDir . '/../lib/Notification/Listener.php',
|
||||
'OCA\\Comments\\Notification\\Notifier' => $baseDir . '/../lib/Notification/Notifier.php',
|
||||
'OCA\\Comments\\OpenMetrics\\CommentsCountMetric' => $baseDir . '/../lib/OpenMetrics/CommentsCountMetric.php',
|
||||
'OCA\\Comments\\Search\\CommentsSearchProvider' => $baseDir . '/../lib/Search/CommentsSearchProvider.php',
|
||||
);
|
||||
|
||||
@@ -37,6 +37,7 @@ class ComposerStaticInitComments
|
||||
'OCA\\Comments\\MaxAutoCompleteResultsInitialState' => __DIR__ . '/..' . '/../lib/MaxAutoCompleteResultsInitialState.php',
|
||||
'OCA\\Comments\\Notification\\Listener' => __DIR__ . '/..' . '/../lib/Notification/Listener.php',
|
||||
'OCA\\Comments\\Notification\\Notifier' => __DIR__ . '/..' . '/../lib/Notification/Notifier.php',
|
||||
'OCA\\Comments\\OpenMetrics\\CommentsCountMetric' => __DIR__ . '/..' . '/../lib/OpenMetrics/CommentsCountMetric.php',
|
||||
'OCA\\Comments\\Search\\CommentsSearchProvider' => __DIR__ . '/..' . '/../lib/Search/CommentsSearchProvider.php',
|
||||
);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ OC.L10N.register(
|
||||
"Delete comment" : "Ezabatu iruzkina",
|
||||
"Cancel edit" : "Utzi editatzeari",
|
||||
"New comment" : "Iruzkin berria",
|
||||
"Write a comment …" : "Idatzi iruzkin bat …",
|
||||
"Post comment" : "Argitaratu iruzkina",
|
||||
"@ for mentions, : for emoji, / for smart picker" : "@ aipamenetarako, : emojientzako, / hautatzaile adimentsurako",
|
||||
"Could not reload comments" : "Ezin izan dira iruzkinak freskatu",
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"Delete comment" : "Ezabatu iruzkina",
|
||||
"Cancel edit" : "Utzi editatzeari",
|
||||
"New comment" : "Iruzkin berria",
|
||||
"Write a comment …" : "Idatzi iruzkin bat …",
|
||||
"Post comment" : "Argitaratu iruzkina",
|
||||
"@ for mentions, : for emoji, / for smart picker" : "@ aipamenetarako, : emojientzako, / hautatzaile adimentsurako",
|
||||
"Could not reload comments" : "Ezin izan dira iruzkinak freskatu",
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\Comments\OpenMetrics;
|
||||
|
||||
use Generator;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\OpenMetrics\IMetricFamily;
|
||||
use OCP\OpenMetrics\Metric;
|
||||
use OCP\OpenMetrics\MetricType;
|
||||
use Override;
|
||||
|
||||
class CommentsCountMetric implements IMetricFamily {
|
||||
public function __construct(
|
||||
private IDBConnection $connection,
|
||||
) {
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function name(): string {
|
||||
return 'comments';
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function type(): MetricType {
|
||||
return MetricType::gauge;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function unit(): string {
|
||||
return 'comments';
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function help(): string {
|
||||
return 'Number of comments';
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function metrics(): Generator {
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$result = $qb->select($qb->func()->count())
|
||||
->from('comments')
|
||||
->where($qb->expr()->eq('verb', $qb->expr()->literal('comment')))
|
||||
->executeQuery();
|
||||
|
||||
yield new Metric($result->fetchOne(), [], time());
|
||||
}
|
||||
}
|
||||
@@ -180,14 +180,12 @@ describe('Inline unread comments action enabled tests', () => {
|
||||
describe('Inline unread comments action execute tests', () => {
|
||||
test('Action opens sidebar', async () => {
|
||||
const openMock = vi.fn()
|
||||
const setActiveTabMock = vi.fn()
|
||||
window.OCA = {
|
||||
Files: {
|
||||
// @ts-expect-error Mocking for testing
|
||||
Sidebar: {
|
||||
_sidebar: () => ({
|
||||
open: openMock,
|
||||
setActiveTab: setActiveTabMock,
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -211,22 +209,19 @@ describe('Inline unread comments action execute tests', () => {
|
||||
})
|
||||
|
||||
expect(result).toBe(null)
|
||||
expect(setActiveTabMock).toBeCalledWith('comments')
|
||||
expect(openMock).toBeCalledWith('/foobar.txt')
|
||||
expect(openMock).toBeCalledWith(file, 'comments')
|
||||
})
|
||||
|
||||
test('Action handles sidebar open failure', async () => {
|
||||
const openMock = vi.fn(() => {
|
||||
throw new Error('Mock error')
|
||||
})
|
||||
const setActiveTabMock = vi.fn()
|
||||
window.OCA = {
|
||||
Files: {
|
||||
// @ts-expect-error Mocking for testing
|
||||
Sidebar: {
|
||||
_sidebar: () => ({
|
||||
open: openMock,
|
||||
setActiveTab: setActiveTabMock,
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
vi.spyOn(logger, 'error').mockImplementation(() => vi.fn())
|
||||
@@ -251,8 +246,7 @@ describe('Inline unread comments action execute tests', () => {
|
||||
})
|
||||
|
||||
expect(result).toBe(false)
|
||||
expect(setActiveTabMock).toBeCalledWith('comments')
|
||||
expect(openMock).toBeCalledWith('/foobar.txt')
|
||||
expect(openMock).toBeCalledWith(file, 'comments')
|
||||
expect(logger.error).toBeCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
/**
|
||||
/*!
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import CommentProcessingSvg from '@mdi/svg/svg/comment-processing.svg?raw'
|
||||
import { FileAction } from '@nextcloud/files'
|
||||
import { FileAction, getSidebar } from '@nextcloud/files'
|
||||
import { n, t } from '@nextcloud/l10n'
|
||||
import logger from '../logger.js'
|
||||
|
||||
@@ -34,8 +35,8 @@ export const action = new FileAction({
|
||||
}
|
||||
|
||||
try {
|
||||
window.OCA.Files.Sidebar.setActiveTab('comments')
|
||||
await window.OCA.Files.Sidebar.open(nodes[0].path)
|
||||
const sidebar = getSidebar()
|
||||
sidebar.open(nodes[0], 'comments')
|
||||
return null
|
||||
} catch (error) {
|
||||
logger.error('Error while opening sidebar', { error })
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import MessageReplyText from '@mdi/svg/svg/message-reply-text.svg?raw'
|
||||
import { getCSPNonce } from '@nextcloud/auth'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { registerCommentsPlugins } from './comments-activity-tab.ts'
|
||||
|
||||
// @ts-expect-error __webpack_nonce__ is injected by webpack
|
||||
__webpack_nonce__ = getCSPNonce()
|
||||
|
||||
if (loadState('comments', 'activityEnabled', false) && OCA?.Activity?.registerSidebarAction !== undefined) {
|
||||
// Do not mount own tab but mount into activity
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
registerCommentsPlugins()
|
||||
})
|
||||
} else {
|
||||
// Init Comments tab component
|
||||
let TabInstance = null
|
||||
const commentTab = new OCA.Files.Sidebar.Tab({
|
||||
id: 'comments',
|
||||
name: t('comments', 'Comments'),
|
||||
iconSvg: MessageReplyText,
|
||||
|
||||
async mount(el, fileInfo, context) {
|
||||
if (TabInstance) {
|
||||
TabInstance.$destroy()
|
||||
}
|
||||
TabInstance = new OCA.Comments.View('files', {
|
||||
// Better integration with vue parent component
|
||||
parent: context,
|
||||
propsData: {
|
||||
resourceId: fileInfo.id,
|
||||
},
|
||||
})
|
||||
// Only mount after we have all the info we need
|
||||
await TabInstance.update(fileInfo.id)
|
||||
TabInstance.$mount(el)
|
||||
},
|
||||
update(fileInfo) {
|
||||
TabInstance.update(fileInfo.id)
|
||||
},
|
||||
destroy() {
|
||||
TabInstance.$destroy()
|
||||
TabInstance = null
|
||||
},
|
||||
scrollBottomReached() {
|
||||
TabInstance.onScrollBottomReached()
|
||||
},
|
||||
})
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
if (OCA.Files && OCA.Files.Sidebar) {
|
||||
OCA.Files.Sidebar.registerTab(commentTab)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import MessageReplyText from '@mdi/svg/svg/message-reply-text.svg?raw'
|
||||
import { getCSPNonce } from '@nextcloud/auth'
|
||||
import { registerSidebarTab } from '@nextcloud/files'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import wrap from '@vue/web-component-wrapper'
|
||||
import { createPinia, PiniaVuePlugin } from 'pinia'
|
||||
import Vue from 'vue'
|
||||
import FilesSidebarTab from './views/FilesSidebarTab.vue'
|
||||
import { registerCommentsPlugins } from './comments-activity-tab.ts'
|
||||
|
||||
__webpack_nonce__ = getCSPNonce()
|
||||
|
||||
const tagName = 'comments_files-sidebar-tab'
|
||||
|
||||
if (loadState('comments', 'activityEnabled', false) && OCA?.Activity?.registerSidebarAction !== undefined) {
|
||||
// Do not mount own tab but mount into activity
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
registerCommentsPlugins()
|
||||
})
|
||||
} else {
|
||||
registerSidebarTab({
|
||||
id: 'comments',
|
||||
displayName: t('comments', 'Comments'),
|
||||
iconSvgInline: MessageReplyText,
|
||||
order: 50,
|
||||
tagName,
|
||||
enabled() {
|
||||
if (!window.customElements.get(tagName)) {
|
||||
setupSidebarTab()
|
||||
}
|
||||
return true
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the sidebar tab as a web component
|
||||
*/
|
||||
function setupSidebarTab() {
|
||||
Vue.use(PiniaVuePlugin)
|
||||
Vue.mixin({ pinia: createPinia() })
|
||||
const webComponent = wrap(Vue, FilesSidebarTab)
|
||||
// In Vue 2, wrap doesn't support disabling shadow. Disable with a hack
|
||||
Object.defineProperty(webComponent.prototype, 'attachShadow', {
|
||||
value() { return this },
|
||||
})
|
||||
Object.defineProperty(webComponent.prototype, 'shadowRoot', {
|
||||
get() { return this },
|
||||
})
|
||||
window.customElements.define(tagName, webComponent)
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
/**
|
||||
/*!
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import axios from '@nextcloud/axios'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { generateOcsUrl } from '@nextcloud/router'
|
||||
@@ -32,7 +33,7 @@ export default defineComponent({
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Autocomplete @mentions
|
||||
* Autocomplete `@mentions`
|
||||
*
|
||||
* @param search the query
|
||||
* @param callback the callback to process the results with
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<!--
|
||||
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { IFolder, INode, IView } from '@nextcloud/files'
|
||||
|
||||
import { computed } from 'vue'
|
||||
import Comments from './Comments.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
node?: INode
|
||||
// eslint-disable-next-line vue/no-unused-properties -- Required on the web component interface
|
||||
folder?: IFolder
|
||||
// eslint-disable-next-line vue/no-unused-properties -- Required on the web component interface
|
||||
view?: IView
|
||||
}>()
|
||||
|
||||
defineExpose({ setActive })
|
||||
|
||||
const resourceId = computed(() => props.node?.fileid)
|
||||
|
||||
/**
|
||||
* Set this tab as active
|
||||
*
|
||||
* @param active - The active state
|
||||
*/
|
||||
function setActive(active: boolean) {
|
||||
return active
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Comments
|
||||
v-if="resourceId !== undefined"
|
||||
:key="resourceId"
|
||||
:resource-id="resourceId"
|
||||
resource-type="files" />
|
||||
</template>
|
||||
@@ -24,6 +24,7 @@ use OCA\DAV\Connector\Sabre\Principal;
|
||||
use OCP\Accounts\IAccountManager;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
@@ -56,7 +57,7 @@ $principalBackend = new Principal(
|
||||
Server::get(ProxyMapper::class),
|
||||
Server::get(KnownUserService::class),
|
||||
Server::get(IConfig::class),
|
||||
\OC::$server->getL10NFactory(),
|
||||
Server::get(IL10NFactory::class),
|
||||
'principals/'
|
||||
);
|
||||
$db = Server::get(IDBConnection::class);
|
||||
@@ -84,7 +85,7 @@ $calDavBackend = new CalDavBackend(
|
||||
);
|
||||
|
||||
$debugging = Server::get(IConfig::class)->getSystemValue('debug', false);
|
||||
$sendInvitations = Server::get(IConfig::class)->getAppValue('dav', 'sendInvitations', 'yes') === 'yes';
|
||||
$sendInvitations = Server::get(IAppConfig::class)->getValueBool('dav', 'sendInvitations', true);
|
||||
|
||||
// Root nodes
|
||||
$principalCollection = new \Sabre\CalDAV\Principal\Collection($principalBackend);
|
||||
@@ -102,6 +103,7 @@ $nodes = [
|
||||
$server = new \Sabre\DAV\Server($nodes);
|
||||
$server::$exposeVersion = false;
|
||||
$server->httpRequest->setUrl(Server::get(IRequest::class)->getRequestUri());
|
||||
/** @var string $baseuri defined in remote.php */
|
||||
$server->setBaseUri($baseuri);
|
||||
|
||||
// Add plugins
|
||||
@@ -126,4 +128,4 @@ $server->addPlugin(Server::get(RateLimitingPlugin::class));
|
||||
$server->addPlugin(Server::get(CalDavValidatePlugin::class));
|
||||
|
||||
// And off we go!
|
||||
$server->exec();
|
||||
$server->start();
|
||||
|
||||
@@ -30,6 +30,7 @@ use OCP\IRequest;
|
||||
use OCP\ISession;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserSession;
|
||||
use OCP\L10N\IFactory as IL10nFactory;
|
||||
use OCP\Security\Bruteforce\IThrottler;
|
||||
use OCP\Server;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@@ -53,7 +54,7 @@ $principalBackend = new Principal(
|
||||
Server::get(ProxyMapper::class),
|
||||
Server::get(KnownUserService::class),
|
||||
Server::get(IConfig::class),
|
||||
\OC::$server->getL10NFactory(),
|
||||
Server::get(IL10nFactory::class),
|
||||
'principals/'
|
||||
);
|
||||
$db = Server::get(IDBConnection::class);
|
||||
@@ -85,9 +86,10 @@ $nodes = [
|
||||
$server = new \Sabre\DAV\Server($nodes);
|
||||
$server::$exposeVersion = false;
|
||||
$server->httpRequest->setUrl(Server::get(IRequest::class)->getRequestUri());
|
||||
/** @var string $baseuri defined in remote.php */
|
||||
$server->setBaseUri($baseuri);
|
||||
// Add plugins
|
||||
$server->addPlugin(new MaintenancePlugin(Server::get(IConfig::class), \OC::$server->getL10N('dav')));
|
||||
$server->addPlugin(new MaintenancePlugin(Server::get(IConfig::class), \OCP\Server::get(IL10nFactory::class)->get('dav')));
|
||||
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend));
|
||||
$server->addPlugin(new Plugin());
|
||||
|
||||
@@ -104,4 +106,4 @@ $server->addPlugin(Server::get(CardDavRateLimitingPlugin::class));
|
||||
$server->addPlugin(Server::get(CardDavValidatePlugin::class));
|
||||
|
||||
// And off we go!
|
||||
$server->exec();
|
||||
$server->start();
|
||||
|
||||
@@ -14,6 +14,7 @@ use OCA\DAV\Files\Sharing\FilesDropPlugin;
|
||||
use OCA\DAV\Files\Sharing\PublicLinkCheckPlugin;
|
||||
use OCA\DAV\Storage\PublicOwnerWrapper;
|
||||
use OCA\FederatedFileSharing\FederatedShareProvider;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\BeforeSabrePubliclyLoadedEvent;
|
||||
use OCP\Constants;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
@@ -26,16 +27,19 @@ use OCP\IRequest;
|
||||
use OCP\ISession;
|
||||
use OCP\ITagManager;
|
||||
use OCP\IUserSession;
|
||||
use OCP\L10N\IFactory as IL10nFactory;
|
||||
use OCP\Security\Bruteforce\IThrottler;
|
||||
use OCP\Server;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
// load needed apps
|
||||
$RUNTIME_APPTYPES = ['filesystem', 'authentication', 'logging'];
|
||||
Server::get(IAppManager::class)->loadApps($RUNTIME_APPTYPES);
|
||||
|
||||
OC_App::loadApps($RUNTIME_APPTYPES);
|
||||
|
||||
OC_Util::obEnd();
|
||||
// Turn off output buffering to prevent memory problems
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
Server::get(ISession::class)->close();
|
||||
|
||||
// Backends
|
||||
@@ -60,7 +64,7 @@ $serverFactory = new ServerFactory(
|
||||
Server::get(IRequest::class),
|
||||
Server::get(IPreview::class),
|
||||
$eventDispatcher,
|
||||
\OC::$server->getL10N('dav')
|
||||
Server::get(IL10nFactory::class)->get('dav')
|
||||
);
|
||||
|
||||
$requestUri = Server::get(IRequest::class)->getRequestUri();
|
||||
@@ -68,6 +72,7 @@ $requestUri = Server::get(IRequest::class)->getRequestUri();
|
||||
$linkCheckPlugin = new PublicLinkCheckPlugin();
|
||||
$filesDropPlugin = new FilesDropPlugin();
|
||||
|
||||
/** @var string $baseuri defined in public.php */
|
||||
$server = $serverFactory->createServer(
|
||||
true,
|
||||
$baseuri,
|
||||
@@ -125,4 +130,4 @@ $event = new BeforeSabrePubliclyLoadedEvent($server);
|
||||
$eventDispatcher->dispatchTyped($event);
|
||||
|
||||
// And off we go!
|
||||
$server->exec();
|
||||
$server->start();
|
||||
|
||||
@@ -19,6 +19,7 @@ use OCP\IRequest;
|
||||
use OCP\ISession;
|
||||
use OCP\ITagManager;
|
||||
use OCP\IUserSession;
|
||||
use OCP\L10N\IFactory as IL10nFactory;
|
||||
use OCP\SabrePluginEvent;
|
||||
use OCP\Security\Bruteforce\IThrottler;
|
||||
use OCP\Server;
|
||||
@@ -31,7 +32,9 @@ if (!str_contains(@ini_get('disable_functions'), 'set_time_limit')) {
|
||||
ignore_user_abort(true);
|
||||
|
||||
// Turn off output buffering to prevent memory problems
|
||||
\OC_Util::obEnd();
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
$dispatcher = Server::get(IEventDispatcher::class);
|
||||
|
||||
@@ -45,7 +48,7 @@ $serverFactory = new ServerFactory(
|
||||
Server::get(IRequest::class),
|
||||
Server::get(IPreview::class),
|
||||
$dispatcher,
|
||||
\OC::$server->getL10N('dav')
|
||||
Server::get(IL10nFactory::class)->get('dav')
|
||||
);
|
||||
|
||||
// Backends
|
||||
@@ -68,6 +71,7 @@ $authPlugin->addBackend($bearerAuthPlugin);
|
||||
|
||||
$requestUri = Server::get(IRequest::class)->getRequestUri();
|
||||
|
||||
/** @var string $baseuri defined in remote.php */
|
||||
$server = $serverFactory->createServer(false, $baseuri, $requestUri, $authPlugin, function () {
|
||||
// use the view for the logged in user
|
||||
return Filesystem::getView();
|
||||
@@ -80,4 +84,4 @@ $event = new SabrePluginAddEvent($server);
|
||||
$dispatcher->dispatchTyped($event);
|
||||
|
||||
// And off we go!
|
||||
$server->exec();
|
||||
$server->start();
|
||||
|
||||
@@ -21,12 +21,15 @@ if (!str_contains(@ini_get('disable_functions'), 'set_time_limit')) {
|
||||
ignore_user_abort(true);
|
||||
|
||||
// Turn off output buffering to prevent memory problems
|
||||
\OC_Util::obEnd();
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
$requestUri = Server::get(IRequest::class)->getRequestUri();
|
||||
|
||||
/** @var ServerFactory $serverFactory */
|
||||
$serverFactory = Server::get(ServerFactory::class);
|
||||
/** @var string $baseuri defined in remote.php */
|
||||
$server = $serverFactory->createServer(
|
||||
$baseuri,
|
||||
$requestUri,
|
||||
@@ -37,4 +40,4 @@ $server = $serverFactory->createServer(
|
||||
Server::get(IRequest::class)
|
||||
);
|
||||
|
||||
$server->exec();
|
||||
$server->start();
|
||||
|
||||
@@ -17,6 +17,7 @@ use OCA\DAV\Storage\PublicShareWrapper;
|
||||
use OCA\DAV\Upload\ChunkingPlugin;
|
||||
use OCA\DAV\Upload\ChunkingV2Plugin;
|
||||
use OCA\FederatedFileSharing\FederatedShareProvider;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\BeforeSabrePubliclyLoadedEvent;
|
||||
use OCP\Constants;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
@@ -41,8 +42,12 @@ use Sabre\DAV\Exception\NotFound;
|
||||
|
||||
// load needed apps
|
||||
$RUNTIME_APPTYPES = ['filesystem', 'authentication', 'logging'];
|
||||
OC_App::loadApps($RUNTIME_APPTYPES);
|
||||
OC_Util::obEnd();
|
||||
Server::get(IAppManager::class)->loadApps($RUNTIME_APPTYPES);
|
||||
|
||||
// Turn off output buffering to prevent memory problems
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
$session = Server::get(ISession::class);
|
||||
$request = Server::get(IRequest::class);
|
||||
|
||||
@@ -15,8 +15,11 @@ if (!str_contains(@ini_get('disable_functions'), 'set_time_limit')) {
|
||||
ignore_user_abort(true);
|
||||
|
||||
// Turn off output buffering to prevent memory problems
|
||||
\OC_Util::obEnd();
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
$request = \OCP\Server::get(IRequest::class);
|
||||
/** @var string $baseuri defined in remote.php */
|
||||
$server = new Server($request, $baseuri);
|
||||
$server->exec();
|
||||
|
||||
@@ -254,6 +254,7 @@ return array(
|
||||
'OCA\\DAV\\Connector\\Sabre\\SharesPlugin' => $baseDir . '/../lib/Connector/Sabre/SharesPlugin.php',
|
||||
'OCA\\DAV\\Connector\\Sabre\\TagList' => $baseDir . '/../lib/Connector/Sabre/TagList.php',
|
||||
'OCA\\DAV\\Connector\\Sabre\\TagsPlugin' => $baseDir . '/../lib/Connector/Sabre/TagsPlugin.php',
|
||||
'OCA\\DAV\\Connector\\Sabre\\UserIdHeaderPlugin' => $baseDir . '/../lib/Connector/Sabre/UserIdHeaderPlugin.php',
|
||||
'OCA\\DAV\\Connector\\Sabre\\ZipFolderPlugin' => $baseDir . '/../lib/Connector/Sabre/ZipFolderPlugin.php',
|
||||
'OCA\\DAV\\Controller\\BirthdayCalendarController' => $baseDir . '/../lib/Controller/BirthdayCalendarController.php',
|
||||
'OCA\\DAV\\Controller\\DirectController' => $baseDir . '/../lib/Controller/DirectController.php',
|
||||
|
||||
@@ -269,6 +269,7 @@ class ComposerStaticInitDAV
|
||||
'OCA\\DAV\\Connector\\Sabre\\SharesPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/SharesPlugin.php',
|
||||
'OCA\\DAV\\Connector\\Sabre\\TagList' => __DIR__ . '/..' . '/../lib/Connector/Sabre/TagList.php',
|
||||
'OCA\\DAV\\Connector\\Sabre\\TagsPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/TagsPlugin.php',
|
||||
'OCA\\DAV\\Connector\\Sabre\\UserIdHeaderPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/UserIdHeaderPlugin.php',
|
||||
'OCA\\DAV\\Connector\\Sabre\\ZipFolderPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/ZipFolderPlugin.php',
|
||||
'OCA\\DAV\\Controller\\BirthdayCalendarController' => __DIR__ . '/..' . '/../lib/Controller/BirthdayCalendarController.php',
|
||||
'OCA\\DAV\\Controller\\DirectController' => __DIR__ . '/..' . '/../lib/Controller/DirectController.php',
|
||||
|
||||
@@ -234,6 +234,8 @@ OC.L10N.register(
|
||||
"Could not rename part file to final file, canceled by hook" : "Could not rename part file to final file, cancelled by hook",
|
||||
"Could not rename part file to final file" : "Could not rename part file to final file",
|
||||
"Failed to check file size: %1$s" : "Failed to check file size: %1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "Could not open file: %1$s (%2$d), file does seem to exist",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "Could not open file: %1$s (%2$d), file doesn't seem to exist",
|
||||
"Encryption not ready: %1$s" : "Encryption not ready: %1$s",
|
||||
"Failed to open file: %1$s" : "Failed to open file: %1$s",
|
||||
"Failed to unlink: %1$s" : "Failed to unlink: %1$s",
|
||||
|
||||
@@ -232,6 +232,8 @@
|
||||
"Could not rename part file to final file, canceled by hook" : "Could not rename part file to final file, cancelled by hook",
|
||||
"Could not rename part file to final file" : "Could not rename part file to final file",
|
||||
"Failed to check file size: %1$s" : "Failed to check file size: %1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "Could not open file: %1$s (%2$d), file does seem to exist",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "Could not open file: %1$s (%2$d), file doesn't seem to exist",
|
||||
"Encryption not ready: %1$s" : "Encryption not ready: %1$s",
|
||||
"Failed to open file: %1$s" : "Failed to open file: %1$s",
|
||||
"Failed to unlink: %1$s" : "Failed to unlink: %1$s",
|
||||
|
||||
@@ -73,7 +73,19 @@ OC.L10N.register(
|
||||
"Where: %s" : "Kus: %s",
|
||||
"%1$s via %2$s" : "%1$s %2$s kaudu",
|
||||
"In the past on %1$s for the entire day" : "Minevikus kogu päeva: %1$s",
|
||||
"_In %n minute on %1$s for the entire day_::_In %n minutes on %1$s for the entire day_" : ["%n minuti pärast %1$s kogu päeva kestel","%n minuti pärast %1$s kogu päeva kestel"],
|
||||
"_In %n hour on %1$s for the entire day_::_In %n hours on %1$s for the entire day_" : ["%n tunni pärast %1$s kogu päeva kestel","%n tunni pärast %1$s kogu päeva kestel"],
|
||||
"_In %n day on %1$s for the entire day_::_In %n days on %1$s for the entire day_" : ["%n tunni päeva %1$s kogu päeva kestel","%n tunni pärast %1$s kogu päeva kestel"],
|
||||
"_In %n week on %1$s for the entire day_::_In %n weeks on %1$s for the entire day_" : ["%n nädala pärast %1$s kogu päeva kestel","%n nädala pärast %1$s kogu päeva kestel"],
|
||||
"_In %n month on %1$s for the entire day_::_In %n months on %1$s for the entire day_" : ["%n kuu pärast %1$s kogu päeva kestel","%n kuu pärast %1$s kogu päeva kestel"],
|
||||
"_In %n year on %1$s for the entire day_::_In %n years on %1$s for the entire day_" : ["%n aasta pärast %1$s kogu päeva kestel","%n aasta pärast %1$s kogu päeva kestel"],
|
||||
"In the past on %1$s between %2$s - %3$s" : "Minevikus: %1$s ajavahemikus %2$s - %3$s",
|
||||
"_In %n minute on %1$s between %2$s - %3$s_::_In %n minutes on %1$s between %2$s - %3$s_" : ["%n minuti pärast %1$s ajavahemikus %2$s kuni %3$s","%n minuti pärast %1$s ajavahemikus %2$s kuni %3$s"],
|
||||
"_In %n hour on %1$s between %2$s - %3$s_::_In %n hours on %1$s between %2$s - %3$s_" : ["%n tunni pärast %1$s ajavahemikus %2$s kuni %3$s","%n tunni pärast %1$s ajavahemikus %2$s kuni %3$s"],
|
||||
"_In %n day on %1$s between %2$s - %3$s_::_In %n days on %1$s between %2$s - %3$s_" : ["%n päeva pärast %1$s ajavahemikus %2$s kuni %3$s","%n päeva pärast %1$s ajavahemikus %2$s kuni %3$s"],
|
||||
"_In %n week on %1$s between %2$s - %3$s_::_In %n weeks on %1$s between %2$s - %3$s_" : ["%n nädala pärast %1$s ajavahemikus %2$s kuni %3$s","%n nädala pärast %1$s ajavahemikus %2$s kuni %3$s"],
|
||||
"_In %n month on %1$s between %2$s - %3$s_::_In %n months on %1$s between %2$s - %3$s_" : ["%n kuu pärast %1$s ajavahemikus %2$s kuni %3$s","%n kuu pärast %1$s ajavahemikus %2$s kuni %3$s"],
|
||||
"_In %n year on %1$s between %2$s - %3$s_::_In %n years on %1$s between %2$s - %3$s_" : ["%n aasta pärast %1$s ajavahemikus %2$s kuni %3$s","%n aasta pärast %1$s ajavahemikus %2$s kuni %3$s"],
|
||||
"Could not generate when statement" : "Ei õnnestunud koostada tingimuslikku „when“ lausendit",
|
||||
"Every Day for the entire day" : "Iga päev kogu päeva jooksul",
|
||||
"Every Day for the entire day until %1$s" : "Iga päev kogu päeva jooksul kuni %1$s",
|
||||
@@ -111,8 +123,26 @@ OC.L10N.register(
|
||||
"On specific dates for the entire day until %1$s" : "Kindlatel päevadel kogu päeva jooksul kuni %1$s",
|
||||
"On specific dates between %1$s - %2$s until %3$s" : "Kindlatel päevadel ajavahemikus %1$s - %2$s kuni %3$s",
|
||||
"In the past on %1$s" : "Minevikus %1$s",
|
||||
"_In %n minute on %1$s_::_In %n minutes on %1$s_" : ["%n minuti pärast %1$s","%n minuti pärast %1$s"],
|
||||
"_In %n hour on %1$s_::_In %n hours on %1$s_" : ["%n tunni pärast %1$s","%n tunni pärast %1$s"],
|
||||
"_In %n day on %1$s_::_In %n days on %1$s_" : ["%n päeva pärast %1$s","%n päeva pärast %1$s"],
|
||||
"_In %n week on %1$s_::_In %n weeks on %1$s_" : ["%n nädala pärast %1$s","%n nädala pärast %1$s"],
|
||||
"_In %n month on %1$s_::_In %n months on %1$s_" : ["%n kuu pärast %1$s","%n kuu pärast %1$s"],
|
||||
"_In %n year on %1$s_::_In %n years on %1$s_" : ["%n aasta pärast %1$s","%n aasta pärast %1$s"],
|
||||
"In the past on %1$s then on %2$s" : "Minevikus: %1$s ja siis %2$s",
|
||||
"_In %n minute on %1$s then on %2$s_::_In %n minutes on %1$s then on %2$s_" : ["%n minuti pärast %1$s, seejärel %2$s","%n minuti pärast %1$s, seejärel %2$s"],
|
||||
"_In %n hour on %1$s then on %2$s_::_In %n hours on %1$s then on %2$s_" : ["%n tunni pärast %1$s, seejärel %2$s","%n tunni pärast %1$s, seejärel %2$s"],
|
||||
"_In %n day on %1$s then on %2$s_::_In %n days on %1$s then on %2$s_" : ["%n päeva pärast %1$s, seejärel %2$s","%n päeva pärast %1$s, seejärel %2$s"],
|
||||
"_In %n week on %1$s then on %2$s_::_In %n weeks on %1$s then on %2$s_" : ["%n nädala pärast %1$s, seejärel %2$s","%n nädala pärast %1$s, seejärel %2$s"],
|
||||
"_In %n month on %1$s then on %2$s_::_In %n months on %1$s then on %2$s_" : ["%n kuu pärast %1$s, seejärel %2$s","%n kuu pärast %1$s, seejärel %2$s"],
|
||||
"_In %n year on %1$s then on %2$s_::_In %n years on %1$s then on %2$s_" : ["%n aasta pärast %1$s, seejärel %2$s","%n aasta pärast %1$s, seejärel %2$s"],
|
||||
"In the past on %1$s then on %2$s and %3$s" : "Minevikus: %1$s ja siis %2$s ning %3$s",
|
||||
"_In %n minute on %1$s then on %2$s and %3$s_::_In %n minutes on %1$s then on %2$s and %3$s_" : ["%n minuti pärast %1$s, seejärel %2$s ja %3$s","%n minuti pärast %1$s, seejärel %2$s ja %3$s"],
|
||||
"_In %n hour on %1$s then on %2$s and %3$s_::_In %n hours on %1$s then on %2$s and %3$s_" : ["%n tunni pärast %1$s, seejärel %2$s ja %3$s","%n tunni pärast %1$s, seejärel %2$s ja %3$s"],
|
||||
"_In %n day on %1$s then on %2$s and %3$s_::_In %n days on %1$s then on %2$s and %3$s_" : ["%n päeva pärast %1$s, seejärel %2$s ja %3$s","%n päeva pärast %1$s, seejärel %2$s ja %3$s"],
|
||||
"_In %n week on %1$s then on %2$s and %3$s_::_In %n weeks on %1$s then on %2$s and %3$s_" : ["%n nädala pärast %1$s, seejärel %2$s ja %3$s","%n nädala pärast %1$s, seejärel %2$s ja %3$s"],
|
||||
"_In %n month on %1$s then on %2$s and %3$s_::_In %n months on %1$s then on %2$s and %3$s_" : ["%n kuu pärast %1$s, seejärel %2$s ja %3$s","%n kuu pärast %1$s, seejärel %2$s ja %3$s"],
|
||||
"_In %n year on %1$s then on %2$s and %3$s_::_In %n years on %1$s then on %2$s and %3$s_" : ["%n aasta pärast %1$s, seejärel %2$s ja %3$s","%n aasta pärast %1$s, seejärel %2$s ja %3$s"],
|
||||
"Could not generate next recurrence statement" : "Ei õnnestunud koostada korduva ürituse järgmise toimumise lausendit",
|
||||
"Cancelled: %1$s" : "Tühistatud: %1$s",
|
||||
"\"%1$s\" has been canceled" : "„%1$s“ on tühistatud",
|
||||
@@ -204,6 +234,8 @@ OC.L10N.register(
|
||||
"Could not rename part file to final file, canceled by hook" : "Osalise faili nime muutmine lõplikuks nimeks ei õnnestunud, selle katkestas programmi haak",
|
||||
"Could not rename part file to final file" : "Osalise faili nime muutmine lõplikuks nimeks ei õnnestunud",
|
||||
"Failed to check file size: %1$s" : "Faili suuruse kontrollimine ei õnnestunud: %1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "„%1$s“ (%2$d) faili avamine ei õnnestunud, aga tundub, et ta on olemas",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "„%1$s“ (%2$d) faili avamine ei õnnestunud, tundub, et teda pole olemas",
|
||||
"Encryption not ready: %1$s" : "Krüptimine pole veel kasutatav: %1$s",
|
||||
"Failed to open file: %1$s" : "Faili avamine ei õnnestunud: %1$s",
|
||||
"Failed to unlink: %1$s" : "Lingi eemaldamine ei õnnestunud: %1$s",
|
||||
|
||||
@@ -71,7 +71,19 @@
|
||||
"Where: %s" : "Kus: %s",
|
||||
"%1$s via %2$s" : "%1$s %2$s kaudu",
|
||||
"In the past on %1$s for the entire day" : "Minevikus kogu päeva: %1$s",
|
||||
"_In %n minute on %1$s for the entire day_::_In %n minutes on %1$s for the entire day_" : ["%n minuti pärast %1$s kogu päeva kestel","%n minuti pärast %1$s kogu päeva kestel"],
|
||||
"_In %n hour on %1$s for the entire day_::_In %n hours on %1$s for the entire day_" : ["%n tunni pärast %1$s kogu päeva kestel","%n tunni pärast %1$s kogu päeva kestel"],
|
||||
"_In %n day on %1$s for the entire day_::_In %n days on %1$s for the entire day_" : ["%n tunni päeva %1$s kogu päeva kestel","%n tunni pärast %1$s kogu päeva kestel"],
|
||||
"_In %n week on %1$s for the entire day_::_In %n weeks on %1$s for the entire day_" : ["%n nädala pärast %1$s kogu päeva kestel","%n nädala pärast %1$s kogu päeva kestel"],
|
||||
"_In %n month on %1$s for the entire day_::_In %n months on %1$s for the entire day_" : ["%n kuu pärast %1$s kogu päeva kestel","%n kuu pärast %1$s kogu päeva kestel"],
|
||||
"_In %n year on %1$s for the entire day_::_In %n years on %1$s for the entire day_" : ["%n aasta pärast %1$s kogu päeva kestel","%n aasta pärast %1$s kogu päeva kestel"],
|
||||
"In the past on %1$s between %2$s - %3$s" : "Minevikus: %1$s ajavahemikus %2$s - %3$s",
|
||||
"_In %n minute on %1$s between %2$s - %3$s_::_In %n minutes on %1$s between %2$s - %3$s_" : ["%n minuti pärast %1$s ajavahemikus %2$s kuni %3$s","%n minuti pärast %1$s ajavahemikus %2$s kuni %3$s"],
|
||||
"_In %n hour on %1$s between %2$s - %3$s_::_In %n hours on %1$s between %2$s - %3$s_" : ["%n tunni pärast %1$s ajavahemikus %2$s kuni %3$s","%n tunni pärast %1$s ajavahemikus %2$s kuni %3$s"],
|
||||
"_In %n day on %1$s between %2$s - %3$s_::_In %n days on %1$s between %2$s - %3$s_" : ["%n päeva pärast %1$s ajavahemikus %2$s kuni %3$s","%n päeva pärast %1$s ajavahemikus %2$s kuni %3$s"],
|
||||
"_In %n week on %1$s between %2$s - %3$s_::_In %n weeks on %1$s between %2$s - %3$s_" : ["%n nädala pärast %1$s ajavahemikus %2$s kuni %3$s","%n nädala pärast %1$s ajavahemikus %2$s kuni %3$s"],
|
||||
"_In %n month on %1$s between %2$s - %3$s_::_In %n months on %1$s between %2$s - %3$s_" : ["%n kuu pärast %1$s ajavahemikus %2$s kuni %3$s","%n kuu pärast %1$s ajavahemikus %2$s kuni %3$s"],
|
||||
"_In %n year on %1$s between %2$s - %3$s_::_In %n years on %1$s between %2$s - %3$s_" : ["%n aasta pärast %1$s ajavahemikus %2$s kuni %3$s","%n aasta pärast %1$s ajavahemikus %2$s kuni %3$s"],
|
||||
"Could not generate when statement" : "Ei õnnestunud koostada tingimuslikku „when“ lausendit",
|
||||
"Every Day for the entire day" : "Iga päev kogu päeva jooksul",
|
||||
"Every Day for the entire day until %1$s" : "Iga päev kogu päeva jooksul kuni %1$s",
|
||||
@@ -109,8 +121,26 @@
|
||||
"On specific dates for the entire day until %1$s" : "Kindlatel päevadel kogu päeva jooksul kuni %1$s",
|
||||
"On specific dates between %1$s - %2$s until %3$s" : "Kindlatel päevadel ajavahemikus %1$s - %2$s kuni %3$s",
|
||||
"In the past on %1$s" : "Minevikus %1$s",
|
||||
"_In %n minute on %1$s_::_In %n minutes on %1$s_" : ["%n minuti pärast %1$s","%n minuti pärast %1$s"],
|
||||
"_In %n hour on %1$s_::_In %n hours on %1$s_" : ["%n tunni pärast %1$s","%n tunni pärast %1$s"],
|
||||
"_In %n day on %1$s_::_In %n days on %1$s_" : ["%n päeva pärast %1$s","%n päeva pärast %1$s"],
|
||||
"_In %n week on %1$s_::_In %n weeks on %1$s_" : ["%n nädala pärast %1$s","%n nädala pärast %1$s"],
|
||||
"_In %n month on %1$s_::_In %n months on %1$s_" : ["%n kuu pärast %1$s","%n kuu pärast %1$s"],
|
||||
"_In %n year on %1$s_::_In %n years on %1$s_" : ["%n aasta pärast %1$s","%n aasta pärast %1$s"],
|
||||
"In the past on %1$s then on %2$s" : "Minevikus: %1$s ja siis %2$s",
|
||||
"_In %n minute on %1$s then on %2$s_::_In %n minutes on %1$s then on %2$s_" : ["%n minuti pärast %1$s, seejärel %2$s","%n minuti pärast %1$s, seejärel %2$s"],
|
||||
"_In %n hour on %1$s then on %2$s_::_In %n hours on %1$s then on %2$s_" : ["%n tunni pärast %1$s, seejärel %2$s","%n tunni pärast %1$s, seejärel %2$s"],
|
||||
"_In %n day on %1$s then on %2$s_::_In %n days on %1$s then on %2$s_" : ["%n päeva pärast %1$s, seejärel %2$s","%n päeva pärast %1$s, seejärel %2$s"],
|
||||
"_In %n week on %1$s then on %2$s_::_In %n weeks on %1$s then on %2$s_" : ["%n nädala pärast %1$s, seejärel %2$s","%n nädala pärast %1$s, seejärel %2$s"],
|
||||
"_In %n month on %1$s then on %2$s_::_In %n months on %1$s then on %2$s_" : ["%n kuu pärast %1$s, seejärel %2$s","%n kuu pärast %1$s, seejärel %2$s"],
|
||||
"_In %n year on %1$s then on %2$s_::_In %n years on %1$s then on %2$s_" : ["%n aasta pärast %1$s, seejärel %2$s","%n aasta pärast %1$s, seejärel %2$s"],
|
||||
"In the past on %1$s then on %2$s and %3$s" : "Minevikus: %1$s ja siis %2$s ning %3$s",
|
||||
"_In %n minute on %1$s then on %2$s and %3$s_::_In %n minutes on %1$s then on %2$s and %3$s_" : ["%n minuti pärast %1$s, seejärel %2$s ja %3$s","%n minuti pärast %1$s, seejärel %2$s ja %3$s"],
|
||||
"_In %n hour on %1$s then on %2$s and %3$s_::_In %n hours on %1$s then on %2$s and %3$s_" : ["%n tunni pärast %1$s, seejärel %2$s ja %3$s","%n tunni pärast %1$s, seejärel %2$s ja %3$s"],
|
||||
"_In %n day on %1$s then on %2$s and %3$s_::_In %n days on %1$s then on %2$s and %3$s_" : ["%n päeva pärast %1$s, seejärel %2$s ja %3$s","%n päeva pärast %1$s, seejärel %2$s ja %3$s"],
|
||||
"_In %n week on %1$s then on %2$s and %3$s_::_In %n weeks on %1$s then on %2$s and %3$s_" : ["%n nädala pärast %1$s, seejärel %2$s ja %3$s","%n nädala pärast %1$s, seejärel %2$s ja %3$s"],
|
||||
"_In %n month on %1$s then on %2$s and %3$s_::_In %n months on %1$s then on %2$s and %3$s_" : ["%n kuu pärast %1$s, seejärel %2$s ja %3$s","%n kuu pärast %1$s, seejärel %2$s ja %3$s"],
|
||||
"_In %n year on %1$s then on %2$s and %3$s_::_In %n years on %1$s then on %2$s and %3$s_" : ["%n aasta pärast %1$s, seejärel %2$s ja %3$s","%n aasta pärast %1$s, seejärel %2$s ja %3$s"],
|
||||
"Could not generate next recurrence statement" : "Ei õnnestunud koostada korduva ürituse järgmise toimumise lausendit",
|
||||
"Cancelled: %1$s" : "Tühistatud: %1$s",
|
||||
"\"%1$s\" has been canceled" : "„%1$s“ on tühistatud",
|
||||
@@ -202,6 +232,8 @@
|
||||
"Could not rename part file to final file, canceled by hook" : "Osalise faili nime muutmine lõplikuks nimeks ei õnnestunud, selle katkestas programmi haak",
|
||||
"Could not rename part file to final file" : "Osalise faili nime muutmine lõplikuks nimeks ei õnnestunud",
|
||||
"Failed to check file size: %1$s" : "Faili suuruse kontrollimine ei õnnestunud: %1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "„%1$s“ (%2$d) faili avamine ei õnnestunud, aga tundub, et ta on olemas",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "„%1$s“ (%2$d) faili avamine ei õnnestunud, tundub, et teda pole olemas",
|
||||
"Encryption not ready: %1$s" : "Krüptimine pole veel kasutatav: %1$s",
|
||||
"Failed to open file: %1$s" : "Faili avamine ei õnnestunud: %1$s",
|
||||
"Failed to unlink: %1$s" : "Lingi eemaldamine ei õnnestunud: %1$s",
|
||||
|
||||
@@ -234,6 +234,8 @@ OC.L10N.register(
|
||||
"Could not rename part file to final file, canceled by hook" : "Níorbh fhéidir páirtchomhad a athainmniú go comhad deiridh, curtha ar ceal le hook",
|
||||
"Could not rename part file to final file" : "Níorbh fhéidir páirtchomhad a athainmniú go dtí an comhad deiridh",
|
||||
"Failed to check file size: %1$s" : "Níorbh fhéidir méid an chomhaid a sheiceáil: %1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "Níorbh fhéidir an comhad a oscailt: %1$s (%2$d), is cosúil go bhfuil an comhad ann",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "Níorbh fhéidir an comhad a oscailt: %1$s (%2$d), is cosúil nach bhfuil an comhad ann.",
|
||||
"Encryption not ready: %1$s" : "Níl an criptiúchán réidh: %1$s",
|
||||
"Failed to open file: %1$s" : "Níorbh fhéidir an comhad a oscailt: %1$s",
|
||||
"Failed to unlink: %1$s" : "Theip ar dhínascadh: %1$s",
|
||||
|
||||
@@ -232,6 +232,8 @@
|
||||
"Could not rename part file to final file, canceled by hook" : "Níorbh fhéidir páirtchomhad a athainmniú go comhad deiridh, curtha ar ceal le hook",
|
||||
"Could not rename part file to final file" : "Níorbh fhéidir páirtchomhad a athainmniú go dtí an comhad deiridh",
|
||||
"Failed to check file size: %1$s" : "Níorbh fhéidir méid an chomhaid a sheiceáil: %1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "Níorbh fhéidir an comhad a oscailt: %1$s (%2$d), is cosúil go bhfuil an comhad ann",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "Níorbh fhéidir an comhad a oscailt: %1$s (%2$d), is cosúil nach bhfuil an comhad ann.",
|
||||
"Encryption not ready: %1$s" : "Níl an criptiúchán réidh: %1$s",
|
||||
"Failed to open file: %1$s" : "Níorbh fhéidir an comhad a oscailt: %1$s",
|
||||
"Failed to unlink: %1$s" : "Theip ar dhínascadh: %1$s",
|
||||
|
||||
@@ -234,6 +234,8 @@ OC.L10N.register(
|
||||
"Could not rename part file to final file, canceled by hook" : "Non foi posíbel cambiar o nome do ficheiro parcial ao ficheiro final, foi cancelado polo sistema",
|
||||
"Could not rename part file to final file" : "Non foi posíbel cambiar o nome do ficheiro parcial ao ficheiro final",
|
||||
"Failed to check file size: %1$s" : "Produciuse un erro ao comprobar o tamaño do ficheiro: %1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "Non foi posíbel abrir o ficheiro: %1$s (%2$d), semella o ficheiro existe",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "Non foi posíbel abrir o ficheiro: %1$s (%2$d), semella o ficheiro non existe",
|
||||
"Encryption not ready: %1$s" : "A cifraxe non está preparada: %1$s",
|
||||
"Failed to open file: %1$s" : "Produciuse un erro ao abrir o ficheiro: %1$s",
|
||||
"Failed to unlink: %1$s" : "Produciuse un erro ao desligar: %1$s",
|
||||
|
||||
@@ -232,6 +232,8 @@
|
||||
"Could not rename part file to final file, canceled by hook" : "Non foi posíbel cambiar o nome do ficheiro parcial ao ficheiro final, foi cancelado polo sistema",
|
||||
"Could not rename part file to final file" : "Non foi posíbel cambiar o nome do ficheiro parcial ao ficheiro final",
|
||||
"Failed to check file size: %1$s" : "Produciuse un erro ao comprobar o tamaño do ficheiro: %1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "Non foi posíbel abrir o ficheiro: %1$s (%2$d), semella o ficheiro existe",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "Non foi posíbel abrir o ficheiro: %1$s (%2$d), semella o ficheiro non existe",
|
||||
"Encryption not ready: %1$s" : "A cifraxe non está preparada: %1$s",
|
||||
"Failed to open file: %1$s" : "Produciuse un erro ao abrir o ficheiro: %1$s",
|
||||
"Failed to unlink: %1$s" : "Produciuse un erro ao desligar: %1$s",
|
||||
|
||||
@@ -234,6 +234,8 @@ OC.L10N.register(
|
||||
"Could not rename part file to final file, canceled by hook" : "无法将部分文件重命名为最终文件,操作被插件取消",
|
||||
"Could not rename part file to final file" : "无法将部分文件重命名为最终文件",
|
||||
"Failed to check file size: %1$s" : "检查文件大小失败:%1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "无法打开文件:%1$s(%2$d),文件似乎不存在",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "无法打开文件:%1$s(%2$d),文件似乎不存在",
|
||||
"Encryption not ready: %1$s" : "加密不可用:%1$s",
|
||||
"Failed to open file: %1$s" : "打开文件失败:%1$s",
|
||||
"Failed to unlink: %1$s" : "解除链接失败:%1$s",
|
||||
|
||||
@@ -232,6 +232,8 @@
|
||||
"Could not rename part file to final file, canceled by hook" : "无法将部分文件重命名为最终文件,操作被插件取消",
|
||||
"Could not rename part file to final file" : "无法将部分文件重命名为最终文件",
|
||||
"Failed to check file size: %1$s" : "检查文件大小失败:%1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "无法打开文件:%1$s(%2$d),文件似乎不存在",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "无法打开文件:%1$s(%2$d),文件似乎不存在",
|
||||
"Encryption not ready: %1$s" : "加密不可用:%1$s",
|
||||
"Failed to open file: %1$s" : "打开文件失败:%1$s",
|
||||
"Failed to unlink: %1$s" : "解除链接失败:%1$s",
|
||||
|
||||
@@ -234,6 +234,8 @@ OC.L10N.register(
|
||||
"Could not rename part file to final file, canceled by hook" : "無法將部份檔案重新命名為最終檔案,被連動取消",
|
||||
"Could not rename part file to final file" : "無法將部份檔案重新命名為最終檔案",
|
||||
"Failed to check file size: %1$s" : "檢查檔案大小失敗:%1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "無法開啟檔案:%1$s (%2$d),檔案似乎存在",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "無法開啟檔案:%1$s(%2$d),檔案似乎不存在",
|
||||
"Encryption not ready: %1$s" : "尚未準備好加密:%1$s",
|
||||
"Failed to open file: %1$s" : "開啟檔案失敗:%1$s",
|
||||
"Failed to unlink: %1$s" : "解除連結失敗:%1$s",
|
||||
|
||||
@@ -232,6 +232,8 @@
|
||||
"Could not rename part file to final file, canceled by hook" : "無法將部份檔案重新命名為最終檔案,被連動取消",
|
||||
"Could not rename part file to final file" : "無法將部份檔案重新命名為最終檔案",
|
||||
"Failed to check file size: %1$s" : "檢查檔案大小失敗:%1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "無法開啟檔案:%1$s (%2$d),檔案似乎存在",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "無法開啟檔案:%1$s(%2$d),檔案似乎不存在",
|
||||
"Encryption not ready: %1$s" : "尚未準備好加密:%1$s",
|
||||
"Failed to open file: %1$s" : "開啟檔案失敗:%1$s",
|
||||
"Failed to unlink: %1$s" : "解除連結失敗:%1$s",
|
||||
|
||||
@@ -217,7 +217,7 @@ class BirthdayService {
|
||||
$vEvent->DTSTART['VALUE'] = 'DATE';
|
||||
$vEvent->add('DTEND');
|
||||
|
||||
$dtEndDate = (new \DateTime())->setTimestamp($date->getTimeStamp());
|
||||
$dtEndDate = \DateTime::createFromInterface($date);
|
||||
$dtEndDate->add(new \DateInterval('P1D'));
|
||||
$vEvent->DTEND->setDateTime(
|
||||
$dtEndDate
|
||||
|
||||
@@ -126,6 +126,18 @@ class IMipPlugin extends SabreIMipPlugin {
|
||||
$iTipMessage->scheduleStatus = '5.0; EMail delivery failed';
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if external attendees are disabled
|
||||
$externalAttendeesDisabled = $this->config->getValueBool('dav', 'caldav_external_attendees_disabled', false);
|
||||
if ($externalAttendeesDisabled && !$this->imipService->isSystemUser($recipient)) {
|
||||
$this->logger->debug('Invitation not sent to external attendee (external attendees disabled)', [
|
||||
'uid' => $iTipMessage->uid,
|
||||
'attendee' => $recipient,
|
||||
]);
|
||||
$iTipMessage->scheduleStatus = '5.0; External attendees are disabled';
|
||||
return;
|
||||
}
|
||||
|
||||
$recipientName = $iTipMessage->recipientName ? (string)$iTipMessage->recipientName : null;
|
||||
|
||||
$newEvents = $iTipMessage->message;
|
||||
|
||||
@@ -875,6 +875,16 @@ class IMipService {
|
||||
return $dtStart->getDateTime()->getTimeStamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an email address belongs to a system user
|
||||
*
|
||||
* @param string $email
|
||||
* @return bool True if the email belongs to a system user, false otherwise
|
||||
*/
|
||||
public function isSystemUser(string $email): bool {
|
||||
return !empty($this->userManager->getByEmail($email));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Property $attendee
|
||||
*/
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-FileCopyrightText: 2012 entreCables S.L. All rights reserved
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* SPDX-FileContributor: Sergio Cambra
|
||||
* SPDX-License-Identifier: AGPL-3.0-only AND BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\Connector\Sabre;
|
||||
|
||||
use OC\Files\View;
|
||||
use OCA\DAV\Upload\UploadFolder;
|
||||
use OCP\Files\StorageNotAvailableException;
|
||||
use OCP\Util;
|
||||
use Sabre\DAV\Exception\InsufficientStorage;
|
||||
use Sabre\DAV\Exception\ServiceUnavailable;
|
||||
use Sabre\DAV\IFile;
|
||||
@@ -19,42 +23,41 @@ use Sabre\HTTP\RequestInterface;
|
||||
use Sabre\HTTP\ResponseInterface;
|
||||
|
||||
/**
|
||||
* This plugin check user quota and deny creating files when they exceeds the quota.
|
||||
* This plugin enforces user storage quotas by preventing file operations that would
|
||||
* exceed the user’s allotted quota.
|
||||
*
|
||||
* @author Sergio Cambra
|
||||
* @copyright Copyright (C) 2012 entreCables S.L. All rights reserved.
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
* @property-read View $view The Nextcloud file view for quota operations.
|
||||
*/
|
||||
class QuotaPlugin extends \Sabre\DAV\ServerPlugin {
|
||||
/**
|
||||
* Reference to main server object
|
||||
* The Sabre\DAV server instance (set during initialize()).
|
||||
*
|
||||
* @var \Sabre\DAV\Server
|
||||
* @var \Sabre\DAV\Server|null
|
||||
*/
|
||||
private $server;
|
||||
private ?\Sabre\DAV\Server $server = null;
|
||||
|
||||
/**
|
||||
* @param View $view
|
||||
* QuotaPlugin constructor.
|
||||
*
|
||||
* @param View $view The Nextcloud Files View instance.
|
||||
*/
|
||||
public function __construct(
|
||||
private $view,
|
||||
private View $view,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This initializes the plugin.
|
||||
* Initializes the quota plugin and subscribes to relevant Sabre\DAV server events.
|
||||
*
|
||||
* This function is called by \Sabre\DAV\Server, after
|
||||
* addPlugin is called.
|
||||
* @link https://sabre.io/dav/writing-plugins/#events
|
||||
*
|
||||
* This method should set up the requires event subscriptions.
|
||||
*
|
||||
* @param \Sabre\DAV\Server $server
|
||||
* @param \Sabre\DAV\Server $server The Sabre\DAV server instance.
|
||||
* @return void
|
||||
*/
|
||||
public function initialize(\Sabre\DAV\Server $server) {
|
||||
public function initialize(\Sabre\DAV\Server $server): void {
|
||||
$this->server = $server;
|
||||
|
||||
// Register event handlers for quota checks on various file operations
|
||||
$server->on('beforeWriteContent', [$this, 'beforeWriteContent'], 10);
|
||||
$server->on('beforeCreateFile', [$this, 'beforeCreateFile'], 10);
|
||||
$server->on('method:MKCOL', [$this, 'onCreateCollection'], 30);
|
||||
@@ -63,78 +66,91 @@ class QuotaPlugin extends \Sabre\DAV\ServerPlugin {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check quota before creating file
|
||||
* Checks quota before creating a new file.
|
||||
* For chunked uploads (with 'Destination' and 'OC-Total-Length'), checks quota for the destination folder.
|
||||
* Otherwise, checks quota for the parent node plus the new filename.
|
||||
*
|
||||
* @param string $uri target file URI
|
||||
* @param resource $data data
|
||||
* @param INode $parent Sabre Node
|
||||
* @param bool $modified modified
|
||||
* @param string $uri Target file URI (unused).
|
||||
* @param resource $data The data to write (unused).
|
||||
* @param INode $parent Parent Sabre node.
|
||||
* @param bool $modified Whether the node is modified (unused).
|
||||
* @return bool True if quota is sufficient, otherwise throws InsufficientStorage.
|
||||
*/
|
||||
public function beforeCreateFile($uri, $data, INode $parent, $modified) {
|
||||
public function beforeCreateFile(string $uri, $data, INode $parent, bool $modified): bool {
|
||||
$request = $this->server->httpRequest;
|
||||
|
||||
// Check quota during chunked uploads
|
||||
if ($parent instanceof UploadFolder && $request->getHeader('Destination')) {
|
||||
// If chunked upload and Total-Length header is set, use that
|
||||
// value for quota check. This allows us to also check quota while
|
||||
// uploading chunks and not only when the file is assembled.
|
||||
$length = $request->getHeader('OC-Total-Length');
|
||||
$destinationPath = $this->server->calculateUri($request->getHeader('Destination'));
|
||||
$totalLength = $request->getHeader('OC-Total-Length');
|
||||
$destinationUri = $request->getHeader('Destination');
|
||||
$destinationPath = $this->server->calculateUri($destinationUri);
|
||||
$quotaPath = $this->getPathForDestination($destinationPath);
|
||||
if ($quotaPath && is_numeric($length)) {
|
||||
return $this->checkQuota($quotaPath, (int)$length);
|
||||
|
||||
if ($quotaPath && is_numeric($totalLength)) {
|
||||
return $this->checkQuota($quotaPath, Util::numericToNumber($totalLength));
|
||||
}
|
||||
// If quota cannot be checked, allow by default
|
||||
// NOTE: We can still check during assembly.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$parent instanceof Node) {
|
||||
return;
|
||||
// No quota check for non-Node parents
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->checkQuota($parent->getPath() . '/' . basename($uri));
|
||||
$filePath = $parent->getPath() . '/' . basename($uri);
|
||||
return $this->checkQuota($filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check quota before creating directory
|
||||
* Checks quota before creating a new collection (directory) via MKCOL.
|
||||
* Assumes a fixed size (4096 bytes) for quota check as MKCOL lacks a Content-Length header.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return bool
|
||||
* @throws InsufficientStorage
|
||||
* @throws \Sabre\DAV\Exception\Forbidden
|
||||
* @param RequestInterface $request The HTTP request for the MKCOL operation.
|
||||
* @param ResponseInterface $response The HTTP response object.
|
||||
* @return bool True if there is enough quota, otherwise throws InsufficientStorage or \Sabre\DAV\Exception\Forbidden (?).
|
||||
*/
|
||||
public function onCreateCollection(RequestInterface $request, ResponseInterface $response): bool {
|
||||
try {
|
||||
$destinationPath = $this->server->calculateUri($request->getUrl());
|
||||
$quotaPath = $this->getPathForDestination($destinationPath);
|
||||
$collectionPath = $this->getPathForDestination($destinationPath);
|
||||
} catch (\Exception $e) {
|
||||
return true;
|
||||
// Optionally log: e.g. ('Quota check failed during onCreateCollection: ' . $e->getMessage());
|
||||
return true; // Quota cannot be checked, allow by default
|
||||
}
|
||||
if ($quotaPath) {
|
||||
// MKCOL does not have a Content-Length header, so we can use
|
||||
// a fixed value for the quota check.
|
||||
return $this->checkQuota($quotaPath, 4096, true);
|
||||
if ($collectionPath) {
|
||||
// Default directory size for quota check since MKCOL doesn't specify one
|
||||
return $this->checkQuota($collectionPath, 4096, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
return true; // No path to check, allow by default
|
||||
}
|
||||
|
||||
/**
|
||||
* Check quota before writing content
|
||||
* Checks quota before writing content to a node.
|
||||
*
|
||||
* @param string $uri target file URI
|
||||
* @param INode $node Sabre Node
|
||||
* @param resource $data data
|
||||
* @param bool $modified modified
|
||||
* @param string $uri Target file URI (unused).
|
||||
* @param INode $node Sabre node to which content will be written.
|
||||
* @param resource $data Content data (unused).
|
||||
* @param bool $modified Whether the node is modified (unused).
|
||||
* @return bool True if there is enough quota, otherwise throws InsufficientStorage.
|
||||
*/
|
||||
public function beforeWriteContent($uri, INode $node, $data, $modified) {
|
||||
public function beforeWriteContent(string $uri, INode $node, $data, bool $modified): bool {
|
||||
if (!$node instanceof Node) {
|
||||
return;
|
||||
// No quota check for non-Node objects
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->checkQuota($node->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we're moving a FutureFile in which case we need to check
|
||||
* the quota on the target destination.
|
||||
* Checks quota before moving a FutureFile node to a new destination.
|
||||
*
|
||||
* @param string $sourcePath Path to the source node.
|
||||
* @param string $destinationPath Path where the node will be moved to.
|
||||
* @return bool True if there is enough quota, otherwise throws InsufficientStorage.
|
||||
*/
|
||||
public function beforeMove(string $sourcePath, string $destinationPath): bool {
|
||||
$sourceNode = $this->server->tree->getNodeForPath($sourcePath);
|
||||
@@ -143,17 +159,22 @@ class QuotaPlugin extends \Sabre\DAV\ServerPlugin {
|
||||
}
|
||||
|
||||
try {
|
||||
// The final path is not known yet, we check the quota on the parent
|
||||
$path = $this->getPathForDestination($destinationPath);
|
||||
// The final path is not known yet, check quota on the parent of the destination
|
||||
$quotaPath = $this->getPathForDestination($destinationPath);
|
||||
} catch (\Exception $e) {
|
||||
// Optionally log: e.g. ('Quota check failed during beforeMove: ' . $e->getMessage());
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->checkQuota($path, $sourceNode->getSize());
|
||||
return $this->checkQuota($quotaPath, $sourceNode->getSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check quota on the target destination before a copy.
|
||||
* Checks quota before allowing a file copy operation.
|
||||
*
|
||||
* @param string $sourcePath Path to the source node.
|
||||
* @param string $destinationPath Path where the node will be copied to.
|
||||
* @return bool True if there is enough quota, otherwise throws InsufficientStorage.
|
||||
*/
|
||||
public function beforeCopy(string $sourcePath, string $destinationPath): bool {
|
||||
$sourceNode = $this->server->tree->getNodeForPath($sourcePath);
|
||||
@@ -162,101 +183,132 @@ class QuotaPlugin extends \Sabre\DAV\ServerPlugin {
|
||||
}
|
||||
|
||||
try {
|
||||
$path = $this->getPathForDestination($destinationPath);
|
||||
$quotaPath = $this->getPathForDestination($destinationPath);
|
||||
} catch (\Exception $e) {
|
||||
// Optionally log: e.g. ('Quota check failed during beforeCopy: ' . $e->getMessage());
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->checkQuota($path, $sourceNode->getSize());
|
||||
return $this->checkQuota($quotaPath, $sourceNode->getSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the path for quota checking, given a destination path.
|
||||
*
|
||||
* If the destination node exists, returns its internal path.
|
||||
* If it does not exist, returns the internal path of its parent node.
|
||||
* Throws an exception if the relevant node is not a valid Node instance.
|
||||
*
|
||||
* @param string $destinationPath Destination path within the virtual file tree.
|
||||
* @return string Internal path to use for quota checking.
|
||||
* @throws \Exception If the destination or parent node is not a valid Node.
|
||||
*/
|
||||
private function getPathForDestination(string $destinationPath): string {
|
||||
// get target node for proper path conversion
|
||||
// If the node exists, return its actual path
|
||||
if ($this->server->tree->nodeExists($destinationPath)) {
|
||||
$destinationNode = $this->server->tree->getNodeForPath($destinationPath);
|
||||
if (!$destinationNode instanceof Node) {
|
||||
throw new \Exception('Invalid destination node');
|
||||
throw new \Exception("Destination node at '$destinationPath' is not a valid Node instance.");
|
||||
}
|
||||
return $destinationNode->getPath();
|
||||
}
|
||||
|
||||
// Otherwise, use the parent directory's path
|
||||
$parent = dirname($destinationPath);
|
||||
if ($parent === '.') {
|
||||
$parent = '';
|
||||
}
|
||||
$parent = ($parent === '.') ? '' : $parent;
|
||||
|
||||
$parentNode = $this->server->tree->getNodeForPath($parent);
|
||||
if (!$parentNode instanceof Node) {
|
||||
throw new \Exception('Invalid destination node');
|
||||
throw new \Exception("Parent node at '$parent' is not a valid Node instance.");
|
||||
}
|
||||
|
||||
return $parentNode->getPath();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is called before any HTTP method and validates there is enough free space to store the file
|
||||
* Validates there is enough free space to store the file at the given path.
|
||||
*
|
||||
* @param string $path relative to the users home
|
||||
* @param int|float|null $length
|
||||
* Called before relevant HTTP DAV events (when there is an associated View).
|
||||
* @see initialize() for specific events we're registered for.
|
||||
*
|
||||
* @internal
|
||||
* @param string $path Path relative to the user's home.
|
||||
* @param int|float|null $length Size to check for, or null to auto-detect.
|
||||
* @param bool $isDir Whether the target is a directory.
|
||||
* @throws InsufficientStorage
|
||||
* @return bool
|
||||
* @return bool True if there is enough space, otherwise throws.
|
||||
*/
|
||||
public function checkQuota(string $path, $length = null, $isDir = false) {
|
||||
public function checkQuota(string $path, int|float|null $length = null, bool $isDir = false): bool {
|
||||
// Auto-detect length if not provided
|
||||
if ($length === null) {
|
||||
$length = $this->getLength();
|
||||
}
|
||||
if (empty($length)) {
|
||||
return true; // No length to check, assume okay
|
||||
}
|
||||
|
||||
if ($length) {
|
||||
[$parentPath, $newName] = \Sabre\Uri\split($path);
|
||||
if (is_null($parentPath)) {
|
||||
$parentPath = '';
|
||||
}
|
||||
$req = $this->server->httpRequest;
|
||||
$normalizedPath = str_replace('//', '/', $path);
|
||||
$freeSpace = $this->getFreeSpace($normalizedPath);
|
||||
|
||||
// Strip any duplicate slashes
|
||||
$path = str_replace('//', '/', $path);
|
||||
// Explicitly handle unknown/invalid free space
|
||||
if ($freeSpace === false || $freeSpace < 0) {
|
||||
// You might log here; currently allows the operation
|
||||
return true;
|
||||
}
|
||||
|
||||
$freeSpace = $this->getFreeSpace($path);
|
||||
if ($freeSpace >= 0 && $length > $freeSpace) {
|
||||
if ($isDir) {
|
||||
throw new InsufficientStorage("Insufficient space in $path. $freeSpace available. Cannot create directory");
|
||||
}
|
||||
|
||||
throw new InsufficientStorage("Insufficient space in $path, $length required, $freeSpace available");
|
||||
}
|
||||
if ($length > $freeSpace) {
|
||||
$msg = $isDir
|
||||
? "Insufficient space in $normalizedPath. $freeSpace available. Cannot create directory"
|
||||
: "Insufficient space in $normalizedPath, $length required, $freeSpace available";
|
||||
throw new InsufficientStorage($msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLength() {
|
||||
$req = $this->server->httpRequest;
|
||||
$length = $req->getHeader('X-Expected-Entity-Length');
|
||||
if (!is_numeric($length)) {
|
||||
$length = $req->getHeader('Content-Length');
|
||||
$length = is_numeric($length) ? $length : null;
|
||||
}
|
||||
/**
|
||||
* Returns the largest valid content length found in any of the following HTTP headers:
|
||||
* - X-Expected-Entity-Length
|
||||
* - Content-Length
|
||||
* - OC-Total-Length
|
||||
*
|
||||
* Only numeric values are considered. If none of the headers contain a valid numeric value,
|
||||
* returns null.
|
||||
*
|
||||
* @internal
|
||||
* @return int|float|null The largest valid content length, or null if none is found.
|
||||
*/
|
||||
public function getLength(): int|float|null {
|
||||
$request = $this->server->httpRequest;
|
||||
|
||||
$ocLength = $req->getHeader('OC-Total-Length');
|
||||
if (!is_numeric($ocLength)) {
|
||||
return $length;
|
||||
}
|
||||
if (!is_numeric($length)) {
|
||||
return $ocLength;
|
||||
}
|
||||
return max($length, $ocLength);
|
||||
// Get headers as strings
|
||||
$expectedLength = $request->getHeader('X-Expected-Entity-Length');
|
||||
$contentLength = $request->getHeader('Content-Length');
|
||||
$ocTotalLength = $request->getHeader('OC-Total-Length');
|
||||
|
||||
// Filter out non-numeric values, use Util::numericToNumber for safe conversion
|
||||
$lengths = array_filter([
|
||||
is_numeric($expectedLength) ? Util::numericToNumber($expectedLength) : null,
|
||||
is_numeric($contentLength) ? Util::numericToNumber($contentLength) : null,
|
||||
is_numeric($ocTotalLength) ? Util::numericToNumber($ocTotalLength) : null,
|
||||
], fn ($v) => $v !== null);
|
||||
|
||||
// Return the largest valid length, or null if none
|
||||
return !empty($lengths) ? max($lengths) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @return mixed
|
||||
* @throws ServiceUnavailable
|
||||
* Returns the available free space for the given URI.
|
||||
*
|
||||
* TODO: `false` can probably be dropped here, if not now when free_space is cleaned up.
|
||||
*
|
||||
* @param string $uri The resource URI whose free space is being queried.
|
||||
* @return int|float|false The amount of free space in bytes,
|
||||
* @throws ServiceUnavailable If the underlying storage is not available.
|
||||
*/
|
||||
public function getFreeSpace($uri) {
|
||||
private function getFreeSpace(string $uri): int|float|false {
|
||||
try {
|
||||
$freeSpace = $this->view->free_space(ltrim($uri, '/'));
|
||||
return $freeSpace;
|
||||
return $this->view->free_space(ltrim($uri, '/'));
|
||||
} catch (StorageNotAvailableException $e) {
|
||||
throw new ServiceUnavailable($e->getMessage());
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ class ServerFactory {
|
||||
$server->addPlugin(new LockPlugin());
|
||||
|
||||
$server->addPlugin(new RequestIdHeaderPlugin($this->request));
|
||||
$server->addPlugin(new UserIdHeaderPlugin($this->userSession));
|
||||
|
||||
$server->addPlugin(new ZipFolderPlugin(
|
||||
$tree,
|
||||
|
||||
@@ -261,6 +261,14 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// if the share recipient is allow to delete from the share, they are allowed to move the file out of the share
|
||||
// the user moving the file out of the share to their home storage would give them share permissions and allow moving into the share
|
||||
//
|
||||
// since the 2-step move is allowed, we also allow both steps at once
|
||||
if ($sourceNode->isDeletable()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Forbidden('You cannot move a non-shareable node into a share');
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\Connector\Sabre;
|
||||
|
||||
use OCP\IUserSession;
|
||||
use Sabre\HTTP\RequestInterface;
|
||||
use Sabre\HTTP\ResponseInterface;
|
||||
|
||||
class UserIdHeaderPlugin extends \Sabre\DAV\ServerPlugin {
|
||||
public function __construct(
|
||||
private readonly IUserSession $userSession,
|
||||
) {
|
||||
}
|
||||
|
||||
public function initialize(\Sabre\DAV\Server $server): void {
|
||||
$server->on('afterMethod:*', [$this, 'afterMethod']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the request id as a header in the response
|
||||
*
|
||||
* @param RequestInterface $request request
|
||||
* @param ResponseInterface $response response
|
||||
*/
|
||||
public function afterMethod(RequestInterface $request, ResponseInterface $response): void {
|
||||
if ($user = $this->userSession->getUser()) {
|
||||
$response->setHeader('X-User-Id', $user->getUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,7 @@ use OCA\DAV\Connector\Sabre\QuotaPlugin;
|
||||
use OCA\DAV\Connector\Sabre\RequestIdHeaderPlugin;
|
||||
use OCA\DAV\Connector\Sabre\SharesPlugin;
|
||||
use OCA\DAV\Connector\Sabre\TagsPlugin;
|
||||
use OCA\DAV\Connector\Sabre\UserIdHeaderPlugin;
|
||||
use OCA\DAV\Connector\Sabre\ZipFolderPlugin;
|
||||
use OCA\DAV\DAV\CustomPropertiesBackend;
|
||||
use OCA\DAV\DAV\PublicAuth;
|
||||
@@ -244,6 +245,7 @@ class Server {
|
||||
// performance improvement plugins
|
||||
$this->server->addPlugin(new CopyEtagHeaderPlugin());
|
||||
$this->server->addPlugin(new RequestIdHeaderPlugin(\OCP\Server::get(IRequest::class)));
|
||||
$this->server->addPlugin(new UserIdHeaderPlugin(\OCP\Server::get(IUserSession::class)));
|
||||
$this->server->addPlugin(new UploadAutoMkcolPlugin());
|
||||
$this->server->addPlugin(new ChunkingV2Plugin(\OCP\Server::get(ICacheFactory::class)));
|
||||
$this->server->addPlugin(new ChunkingPlugin());
|
||||
|
||||
@@ -130,6 +130,10 @@ class IMipPluginTest extends TestCase {
|
||||
$message->senderName = 'Mr. Wizard';
|
||||
$message->recipient = 'mailto:' . 'frodo@hobb.it';
|
||||
$message->significantChange = false;
|
||||
|
||||
$this->config->expects(self::never())
|
||||
->method('getValueBool');
|
||||
|
||||
$this->plugin->schedule($message);
|
||||
$this->assertEquals('1.0', $message->getScheduleStatus());
|
||||
}
|
||||
@@ -177,6 +181,12 @@ class IMipPluginTest extends TestCase {
|
||||
$this->service->expects(self::once())
|
||||
->method('getLastOccurrence')
|
||||
->willReturn(1496912700);
|
||||
$this->config->expects(self::exactly(2))
|
||||
->method('getValueBool')
|
||||
->willReturnMap([
|
||||
['dav', 'caldav_external_attendees_disabled', false, false],
|
||||
['core', 'mail_providers_enabled', true, false],
|
||||
]);
|
||||
$this->eventComparisonService->expects(self::once())
|
||||
->method('findModified')
|
||||
->willReturn(['new' => [$newVevent], 'old' => [$oldVEvent]]);
|
||||
@@ -280,6 +290,10 @@ class IMipPluginTest extends TestCase {
|
||||
$this->service->expects(self::once())
|
||||
->method('getLastOccurrence')
|
||||
->willReturn(1496912700);
|
||||
$this->config->expects(self::once())
|
||||
->method('getValueBool')
|
||||
->with('dav', 'caldav_external_attendees_disabled', false)
|
||||
->willReturn(false);
|
||||
$this->eventComparisonService->expects(self::once())
|
||||
->method('findModified')
|
||||
->willReturn(['new' => [$newVevent], 'old' => [$oldVEvent]]);
|
||||
@@ -354,6 +368,10 @@ class IMipPluginTest extends TestCase {
|
||||
$this->service->expects(self::once())
|
||||
->method('getLastOccurrence')
|
||||
->willReturn(1496912700);
|
||||
$this->config->expects(self::once())
|
||||
->method('getValueBool')
|
||||
->with('dav', 'caldav_external_attendees_disabled', false)
|
||||
->willReturn(false);
|
||||
$this->eventComparisonService->expects(self::once())
|
||||
->method('findModified')
|
||||
->willReturn(['new' => [$newVevent], 'old' => null]);
|
||||
@@ -455,6 +473,12 @@ class IMipPluginTest extends TestCase {
|
||||
$this->service->expects(self::once())
|
||||
->method('getLastOccurrence')
|
||||
->willReturn(1496912700);
|
||||
$this->config->expects(self::exactly(2))
|
||||
->method('getValueBool')
|
||||
->willReturnMap([
|
||||
['dav', 'caldav_external_attendees_disabled', false, false],
|
||||
['core', 'mail_providers_enabled', true, false],
|
||||
]);
|
||||
$this->eventComparisonService->expects(self::once())
|
||||
->method('findModified')
|
||||
->willReturn(['old' => [] ,'new' => [$newVevent]]);
|
||||
@@ -695,6 +719,12 @@ class IMipPluginTest extends TestCase {
|
||||
$this->service->expects(self::once())
|
||||
->method('getLastOccurrence')
|
||||
->willReturn(1496912700);
|
||||
$this->config->expects(self::exactly(2))
|
||||
->method('getValueBool')
|
||||
->willReturnMap([
|
||||
['dav', 'caldav_external_attendees_disabled', false, false],
|
||||
['core', 'mail_providers_enabled', true, true],
|
||||
]);
|
||||
$this->service->expects(self::once())
|
||||
->method('getCurrentAttendee')
|
||||
->with($message)
|
||||
@@ -837,10 +867,12 @@ class IMipPluginTest extends TestCase {
|
||||
->method('getValueString')
|
||||
->with('dav', 'invitation_link_recipients', 'yes')
|
||||
->willReturn('yes');
|
||||
$this->config->expects(self::once())
|
||||
$this->config->expects(self::exactly(2))
|
||||
->method('getValueBool')
|
||||
->with('core', 'mail_providers_enabled', true)
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['dav', 'caldav_external_attendees_disabled', false, false],
|
||||
['core', 'mail_providers_enabled', true, false],
|
||||
]);
|
||||
$this->service->expects(self::once())
|
||||
->method('createInvitationToken')
|
||||
->with($message, $newVevent, 1496912700)
|
||||
@@ -888,6 +920,12 @@ class IMipPluginTest extends TestCase {
|
||||
$this->service->expects(self::once())
|
||||
->method('getLastOccurrence')
|
||||
->willReturn(1496912700);
|
||||
$this->config->expects(self::exactly(2))
|
||||
->method('getValueBool')
|
||||
->willReturnMap([
|
||||
['dav', 'caldav_external_attendees_disabled', false, false],
|
||||
['core', 'mail_providers_enabled', true, false],
|
||||
]);
|
||||
$this->eventComparisonService->expects(self::once())
|
||||
->method('findModified')
|
||||
->with($newVCalendar, null)
|
||||
@@ -981,6 +1019,12 @@ class IMipPluginTest extends TestCase {
|
||||
$this->service->expects(self::once())
|
||||
->method('getLastOccurrence')
|
||||
->willReturn(1496912700);
|
||||
$this->config->expects(self::exactly(2))
|
||||
->method('getValueBool')
|
||||
->willReturnMap([
|
||||
['dav', 'caldav_external_attendees_disabled', false, false],
|
||||
['core', 'mail_providers_enabled', true, false],
|
||||
]);
|
||||
$this->eventComparisonService->expects(self::once())
|
||||
->method('findModified')
|
||||
->with($newVCalendar, null)
|
||||
@@ -1040,4 +1084,156 @@ class IMipPluginTest extends TestCase {
|
||||
$this->plugin->schedule($message);
|
||||
$this->assertEquals('1.1', $message->getScheduleStatus());
|
||||
}
|
||||
|
||||
public function testExternalAttendeesDisabledForExternalUser(): void {
|
||||
$message = new Message();
|
||||
$message->method = 'REQUEST';
|
||||
$newVCalendar = new VCalendar();
|
||||
$newVevent = new VEvent($newVCalendar, 'one', array_merge([
|
||||
'UID' => 'uid-1234',
|
||||
'SEQUENCE' => 1,
|
||||
'SUMMARY' => 'Fellowship meeting',
|
||||
'DTSTART' => new \DateTime('2016-01-01 00:00:00')
|
||||
], []));
|
||||
$newVevent->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
|
||||
$newVevent->add('ATTENDEE', 'mailto:external@example.com', ['RSVP' => 'TRUE', 'CN' => 'External User']);
|
||||
$message->message = $newVCalendar;
|
||||
$message->sender = 'mailto:gandalf@wiz.ard';
|
||||
$message->senderName = 'Mr. Wizard';
|
||||
$message->recipient = 'mailto:external@example.com';
|
||||
|
||||
$this->service->expects(self::once())
|
||||
->method('getLastOccurrence')
|
||||
->willReturn(1496912700);
|
||||
$this->config->expects(self::once())
|
||||
->method('getValueBool')
|
||||
->with('dav', 'caldav_external_attendees_disabled', false)
|
||||
->willReturn(true);
|
||||
$this->service->expects(self::once())
|
||||
->method('isSystemUser')
|
||||
->with('external@example.com')
|
||||
->willReturn(false);
|
||||
$this->eventComparisonService->expects(self::never())
|
||||
->method('findModified');
|
||||
$this->service->expects(self::never())
|
||||
->method('getCurrentAttendee');
|
||||
$this->mailer->expects(self::never())
|
||||
->method('send');
|
||||
|
||||
$this->plugin->schedule($message);
|
||||
$this->assertEquals('5.0', $message->getScheduleStatus());
|
||||
}
|
||||
|
||||
public function testExternalAttendeesDisabledForSystemUser(): void {
|
||||
$message = new Message();
|
||||
$message->method = 'REQUEST';
|
||||
$newVCalendar = new VCalendar();
|
||||
$newVevent = new VEvent($newVCalendar, 'one', array_merge([
|
||||
'UID' => 'uid-1234',
|
||||
'SEQUENCE' => 1,
|
||||
'SUMMARY' => 'Fellowship meeting',
|
||||
'DTSTART' => new \DateTime('2016-01-01 00:00:00')
|
||||
], []));
|
||||
$newVevent->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
|
||||
$newVevent->add('ATTENDEE', 'mailto:frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
|
||||
$message->message = $newVCalendar;
|
||||
$message->sender = 'mailto:gandalf@wiz.ard';
|
||||
$message->senderName = 'Mr. Wizard';
|
||||
$message->recipient = 'mailto:frodo@hobb.it';
|
||||
|
||||
$oldVCalendar = new VCalendar();
|
||||
$oldVEvent = new VEvent($oldVCalendar, 'one', [
|
||||
'UID' => 'uid-1234',
|
||||
'SEQUENCE' => 0,
|
||||
'SUMMARY' => 'Fellowship meeting',
|
||||
'DTSTART' => new \DateTime('2016-01-01 00:00:00')
|
||||
]);
|
||||
$oldVEvent->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
|
||||
$oldVEvent->add('ATTENDEE', 'mailto:frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
|
||||
$oldVCalendar->add($oldVEvent);
|
||||
|
||||
$data = ['invitee_name' => 'Mr. Wizard',
|
||||
'meeting_title' => 'Fellowship meeting',
|
||||
'attendee_name' => 'frodo@hobb.it'
|
||||
];
|
||||
$attendees = $newVevent->select('ATTENDEE');
|
||||
$atnd = '';
|
||||
foreach ($attendees as $attendee) {
|
||||
if (strcasecmp($attendee->getValue(), $message->recipient) === 0) {
|
||||
$atnd = $attendee;
|
||||
}
|
||||
}
|
||||
$this->plugin->setVCalendar($oldVCalendar);
|
||||
$this->service->expects(self::once())
|
||||
->method('getLastOccurrence')
|
||||
->willReturn(1496912700);
|
||||
$this->config->expects(self::exactly(2))
|
||||
->method('getValueBool')
|
||||
->willReturnMap([
|
||||
['dav', 'caldav_external_attendees_disabled', false, true],
|
||||
['core', 'mail_providers_enabled', true, false],
|
||||
]);
|
||||
$this->service->expects(self::once())
|
||||
->method('isSystemUser')
|
||||
->with('frodo@hobb.it')
|
||||
->willReturn(true);
|
||||
$this->eventComparisonService->expects(self::once())
|
||||
->method('findModified')
|
||||
->willReturn(['new' => [$newVevent], 'old' => [$oldVEvent]]);
|
||||
$this->service->expects(self::once())
|
||||
->method('getCurrentAttendee')
|
||||
->with($message)
|
||||
->willReturn($atnd);
|
||||
$this->service->expects(self::once())
|
||||
->method('isRoomOrResource')
|
||||
->with($atnd)
|
||||
->willReturn(false);
|
||||
$this->service->expects(self::once())
|
||||
->method('isCircle')
|
||||
->with($atnd)
|
||||
->willReturn(false);
|
||||
$this->service->expects(self::once())
|
||||
->method('buildBodyData')
|
||||
->with($newVevent, $oldVEvent)
|
||||
->willReturn($data);
|
||||
$this->user->expects(self::any())
|
||||
->method('getUID')
|
||||
->willReturn('user1');
|
||||
$this->user->expects(self::any())
|
||||
->method('getDisplayName')
|
||||
->willReturn('Mr. Wizard');
|
||||
$this->userSession->expects(self::any())
|
||||
->method('getUser')
|
||||
->willReturn($this->user);
|
||||
$this->service->expects(self::once())
|
||||
->method('getFrom');
|
||||
$this->service->expects(self::once())
|
||||
->method('addSubjectAndHeading')
|
||||
->with($this->emailTemplate, 'request', 'Mr. Wizard', 'Fellowship meeting', true);
|
||||
$this->service->expects(self::once())
|
||||
->method('addBulletList')
|
||||
->with($this->emailTemplate, $newVevent, $data);
|
||||
$this->service->expects(self::once())
|
||||
->method('getAttendeeRsvpOrReqForParticipant')
|
||||
->willReturn(true);
|
||||
$this->config->expects(self::once())
|
||||
->method('getValueString')
|
||||
->with('dav', 'invitation_link_recipients', 'yes')
|
||||
->willReturn('yes');
|
||||
$this->service->expects(self::once())
|
||||
->method('createInvitationToken')
|
||||
->with($message, $newVevent, 1496912700)
|
||||
->willReturn('token');
|
||||
$this->service->expects(self::once())
|
||||
->method('addResponseButtons')
|
||||
->with($this->emailTemplate, 'token');
|
||||
$this->service->expects(self::once())
|
||||
->method('addMoreOptionsButton')
|
||||
->with($this->emailTemplate, 'token');
|
||||
$this->mailer->expects(self::once())
|
||||
->method('send')
|
||||
->willReturn([]);
|
||||
$this->plugin->schedule($message);
|
||||
$this->assertEquals('1.1', $message->getScheduleStatus());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +161,31 @@ class IMipServiceTest extends TestCase {
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
public function testIsSystemUserWhenUserExists(): void {
|
||||
$email = 'user@example.com';
|
||||
$user = $this->createMock(\OCP\IUser::class);
|
||||
|
||||
$this->userManager->expects(self::once())
|
||||
->method('getByEmail')
|
||||
->with($email)
|
||||
->willReturn([$user]);
|
||||
|
||||
$result = $this->service->isSystemUser($email);
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testIsSystemUserWhenUserDoesNotExist(): void {
|
||||
$email = 'external@example.com';
|
||||
|
||||
$this->userManager->expects(self::once())
|
||||
->method('getByEmail')
|
||||
->with($email)
|
||||
->willReturn([]);
|
||||
|
||||
$result = $this->service->isSystemUser($email);
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
public function testBuildBodyDataCreated(): void {
|
||||
|
||||
// construct l10n return(s)
|
||||
|
||||
@@ -19,7 +19,7 @@ class QuotaPluginTest extends TestCase {
|
||||
private QuotaPlugin $plugin;
|
||||
|
||||
private function init(int $quota, string $checkedPath = ''): void {
|
||||
$view = $this->buildFileViewMock((string)$quota, $checkedPath);
|
||||
$view = $this->buildFileViewMock($quota, $checkedPath);
|
||||
$this->server = new \Sabre\DAV\Server();
|
||||
$this->plugin = new QuotaPlugin($view);
|
||||
$this->plugin->initialize($this->server);
|
||||
@@ -136,7 +136,14 @@ class QuotaPluginTest extends TestCase {
|
||||
];
|
||||
}
|
||||
|
||||
private function buildFileViewMock(string $quota, string $checkedPath): View {
|
||||
/**
|
||||
* Build a mock for the View class with a controlled free_space() response.
|
||||
*
|
||||
* @param int|float|false $quota The quota value to return from free_space().
|
||||
* @param string $checkedPath The path expected as a parameter to free_space().
|
||||
* @return View&\PHPUnit\Framework\MockObject\MockObject
|
||||
*/
|
||||
private function buildFileViewMock(int|float|false $quota, string $checkedPath): View {
|
||||
// mock filesystem
|
||||
$view = $this->getMockBuilder(View::class)
|
||||
->onlyMethods(['free_space'])
|
||||
|
||||
@@ -44,7 +44,6 @@ use OCP\Share\Exceptions\ShareNotFound;
|
||||
use OCP\Share\IManager;
|
||||
use OCP\Share\IProviderFactory;
|
||||
use OCP\Share\IShare;
|
||||
use OCP\Snowflake\IGenerator;
|
||||
use OCP\Util;
|
||||
use Override;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@@ -70,7 +69,6 @@ class CloudFederationProviderFiles implements ISignedCloudFederationProvider {
|
||||
private readonly IFilenameValidator $filenameValidator,
|
||||
private readonly IProviderFactory $shareProviderFactory,
|
||||
private readonly SetupManager $setupManager,
|
||||
private readonly IGenerator $snowflakeGenerator,
|
||||
private readonly ExternalShareMapper $externalShareMapper,
|
||||
) {
|
||||
}
|
||||
@@ -145,7 +143,7 @@ class CloudFederationProviderFiles implements ISignedCloudFederationProvider {
|
||||
}
|
||||
|
||||
$externalShare = new ExternalShare();
|
||||
$externalShare->setId($this->snowflakeGenerator->nextId());
|
||||
$externalShare->generateId();
|
||||
$externalShare->setRemote($remote);
|
||||
$externalShare->setRemoteId($remoteId);
|
||||
$externalShare->setShareToken($token);
|
||||
@@ -177,9 +175,9 @@ class CloudFederationProviderFiles implements ISignedCloudFederationProvider {
|
||||
->setType('remote_share')
|
||||
->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/'), $ownerDisplayName])
|
||||
->setAffectedUser($shareWith)
|
||||
->setObject('remote_share', $externalShare->getId(), $name);
|
||||
->setObject('remote_share', (string)$externalShare->getId(), $name);
|
||||
Server::get(IActivityManager::class)->publish($event);
|
||||
$this->notifyAboutNewShare($shareWith, $externalShare->getId(), $ownerFederatedId, $sharedByFederatedId, $name, $ownerDisplayName);
|
||||
$this->notifyAboutNewShare($shareWith, (string)$externalShare->getId(), $ownerFederatedId, $sharedByFederatedId, $name, $ownerDisplayName);
|
||||
|
||||
// If auto-accept is enabled, accept the share
|
||||
if ($this->federatedShareProvider->isFederatedTrustedShareAutoAccept() && $trustedServers?->isTrustedServer($remote) === true) {
|
||||
@@ -193,9 +191,9 @@ class CloudFederationProviderFiles implements ISignedCloudFederationProvider {
|
||||
->setType('remote_share')
|
||||
->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/'), $ownerDisplayName])
|
||||
->setAffectedUser($user->getUID())
|
||||
->setObject('remote_share', $externalShare->getId(), $name);
|
||||
->setObject('remote_share', (string)$externalShare->getId(), $name);
|
||||
Server::get(IActivityManager::class)->publish($event);
|
||||
$this->notifyAboutNewShare($user->getUID(), $externalShare->getId(), $ownerFederatedId, $sharedByFederatedId, $name, $ownerDisplayName);
|
||||
$this->notifyAboutNewShare($user->getUID(), (string)$externalShare->getId(), $ownerFederatedId, $sharedByFederatedId, $name, $ownerDisplayName);
|
||||
|
||||
// If auto-accept is enabled, accept the share
|
||||
if ($this->federatedShareProvider->isFederatedTrustedShareAutoAccept() && $trustedServers?->isTrustedServer($remote) === true) {
|
||||
@@ -204,7 +202,7 @@ class CloudFederationProviderFiles implements ISignedCloudFederationProvider {
|
||||
}
|
||||
}
|
||||
|
||||
return $externalShare->getId();
|
||||
return (string)$externalShare->getId();
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Server can not add remote share.', [
|
||||
'app' => 'files_sharing',
|
||||
@@ -466,7 +464,7 @@ class CloudFederationProviderFiles implements ISignedCloudFederationProvider {
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$notification->setApp('files_sharing')
|
||||
->setUser($share->getUser())
|
||||
->setObject('remote_share', $share->getId());
|
||||
->setObject('remote_share', (string)$share->getId());
|
||||
$this->notificationManager->markProcessed($notification);
|
||||
|
||||
$event = $this->activityManager->generateEvent();
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
/*!
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param $ - The jQuery instance
|
||||
*/
|
||||
(function($) {
|
||||
// ocFederationAddServer
|
||||
$.fn.ocFederationAddServer = function() {
|
||||
/* Go easy on jquery and define some vars
|
||||
========================================================================== */
|
||||
|
||||
const $wrapper = $(this),
|
||||
|
||||
// Buttons
|
||||
$btnAddServer = $wrapper.find('#ocFederationAddServerButton'),
|
||||
$btnSubmit = $wrapper.find('#ocFederationSubmit'),
|
||||
|
||||
// Inputs
|
||||
$inpServerUrl = $wrapper.find('#serverUrl'),
|
||||
|
||||
// misc
|
||||
$msgBox = $wrapper.find('#ocFederationAddServer .msg'),
|
||||
$srvList = $wrapper.find('#listOfTrustedServers')
|
||||
|
||||
/* Interaction
|
||||
========================================================================== */
|
||||
|
||||
$btnAddServer.on('click', function() {
|
||||
$btnAddServer.addClass('hidden')
|
||||
$wrapper.find('.serverUrl').removeClass('hidden')
|
||||
$inpServerUrl
|
||||
.focus()
|
||||
})
|
||||
|
||||
// trigger server removal
|
||||
$srvList.on('click', 'li > .icon-delete', function() {
|
||||
const $this = $(this).parent()
|
||||
const id = $this.attr('id')
|
||||
|
||||
removeServer(id)
|
||||
})
|
||||
|
||||
$btnSubmit.on('click', function() {
|
||||
addServer($inpServerUrl.val())
|
||||
})
|
||||
|
||||
$inpServerUrl.on('change keyup', function(e) {
|
||||
const url = $(this).val()
|
||||
|
||||
// toggle add-button visibility based on input length
|
||||
if (url.length > 0) { $btnSubmit.removeClass('hidden') } else { $btnSubmit.addClass('hidden') }
|
||||
|
||||
if (e.keyCode === 13) { // add server on "enter"
|
||||
addServer(url)
|
||||
} else if (e.keyCode === 27) { // hide input filed again in ESC
|
||||
$btnAddServer.removeClass('hidden')
|
||||
$inpServerUrl.val('').addClass('hidden')
|
||||
$btnSubmit.addClass('hidden')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* private Functions
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
*
|
||||
* @param url
|
||||
*/
|
||||
function addServer(url) {
|
||||
OC.msg.startSaving('#ocFederationAddServer .msg')
|
||||
|
||||
$.post(
|
||||
OC.getRootPath() + '/ocs/v2.php/apps/federation/trusted-servers',
|
||||
{
|
||||
url,
|
||||
},
|
||||
null,
|
||||
'json',
|
||||
).done(function({ ocs }) {
|
||||
const data = ocs.data
|
||||
$('#serverUrl').attr('value', '')
|
||||
$('#listOfTrustedServers').prepend($('<li>')
|
||||
.attr('id', data.id)
|
||||
.html('<span class="status indeterminate"></span>'
|
||||
+ data.url
|
||||
+ '<span class="icon icon-delete"></span>'))
|
||||
OC.msg.finishedSuccess('#ocFederationAddServer .msg', data.message)
|
||||
})
|
||||
.fail(function(jqXHR) {
|
||||
OC.msg.finishedError('#ocFederationAddServer .msg', JSON.parse(jqXHR.responseText).ocs.meta.message)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
function removeServer(id) {
|
||||
$.ajax({
|
||||
url: OC.getRootPath() + '/ocs/v2.php/apps/federation/trusted-servers/' + id,
|
||||
type: 'DELETE',
|
||||
success: function(response) {
|
||||
$('#ocFederationSettings').find('#' + id).remove()
|
||||
},
|
||||
})
|
||||
}
|
||||
})(jQuery)
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
$('#ocFederationSettings').ocFederationAddServer()
|
||||
})
|
||||
@@ -11,11 +11,12 @@ OC.L10N.register(
|
||||
"Federation" : "الربط عبر السحابة الموحدة",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "يسمح لك الاتحاد بالاتصال بخوادم موثوقة أخرى لتبادل أدلة الحسابات معها.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "يسمح لك الاتحاد بالاتصال بخوادم موثوقة أخرى لتبادل أدلة الحسابات معها. على سبيل المثال، سيتم استخدام هذا للإكمال التلقائي للحسابات الخارجية عند المشاركة عبر السحابة الموحدة federated sharing.",
|
||||
"External documentation for Federated Cloud Sharing" : "التوثيق الخارجي لمشاركة السحابة الاتحادية",
|
||||
"Add" : "إضافة",
|
||||
"Delete" : "حذف",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "يسمح لك الاتحاد بالاتصال بخوادم موثوقة أخرى لتبادل أدلة الحسابات معها. على سبيل المثال، سيتم استخدام هذا للإكمال التلقائي للحسابات الخارجية عند المشاركة الاتحادية. ليس من الضروري إضافة خادم كخادم موثوق به لإنشاء مشاركة السحابة الموحدة.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "يجب على كل خادوم أن يُصادِق على الآخر. هذه العملية يمكن أن تستغرق عدة دورات من مهام الخلفية cron.",
|
||||
"External documentation for Federated Cloud Sharing" : "التوثيق الخارجي لمشاركة السحابة الاتحادية",
|
||||
"+ Add trusted server" : "+ إضافة خادم موثوق",
|
||||
"Trusted server" : "خادم موثوق",
|
||||
"Add" : "إضافة"
|
||||
"Trusted server" : "خادم موثوق"
|
||||
},
|
||||
"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;");
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
"Federation" : "الربط عبر السحابة الموحدة",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "يسمح لك الاتحاد بالاتصال بخوادم موثوقة أخرى لتبادل أدلة الحسابات معها.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "يسمح لك الاتحاد بالاتصال بخوادم موثوقة أخرى لتبادل أدلة الحسابات معها. على سبيل المثال، سيتم استخدام هذا للإكمال التلقائي للحسابات الخارجية عند المشاركة عبر السحابة الموحدة federated sharing.",
|
||||
"External documentation for Federated Cloud Sharing" : "التوثيق الخارجي لمشاركة السحابة الاتحادية",
|
||||
"Add" : "إضافة",
|
||||
"Delete" : "حذف",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "يسمح لك الاتحاد بالاتصال بخوادم موثوقة أخرى لتبادل أدلة الحسابات معها. على سبيل المثال، سيتم استخدام هذا للإكمال التلقائي للحسابات الخارجية عند المشاركة الاتحادية. ليس من الضروري إضافة خادم كخادم موثوق به لإنشاء مشاركة السحابة الموحدة.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "يجب على كل خادوم أن يُصادِق على الآخر. هذه العملية يمكن أن تستغرق عدة دورات من مهام الخلفية cron.",
|
||||
"External documentation for Federated Cloud Sharing" : "التوثيق الخارجي لمشاركة السحابة الاتحادية",
|
||||
"+ Add trusted server" : "+ إضافة خادم موثوق",
|
||||
"Trusted server" : "خادم موثوق",
|
||||
"Add" : "إضافة"
|
||||
"Trusted server" : "خادم موثوق"
|
||||
},"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Amestóse a la llista de sirvidores d'enfotu",
|
||||
"Server is already in the list of trusted servers." : "El sirvidor yá ta na llista de los sirvidores d'enfotu.",
|
||||
"No server to federate with found" : "Nun s'atopó nengún sirvidor col que se federar",
|
||||
"Could not add server" : "Nun se pudo amestar el sirvidor",
|
||||
"Trusted servers" : "Sirvidores d'enfotu",
|
||||
"Federation" : "Federación",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "La federación permíte que te conectes con otros sirvidores d'enfotu pa intercambiar el direutoriu de cuentes.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "La federación permite que te conectes a otros sirvidores d'enfotu pa intercambiar el direutoriu de cuentes. Por exemplu, va usase pa completar automáticamente les cuentes esternes de la compartición federada.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "La federación permite que te conectes a otros sirvidores d'enfotu pa intercambiar el direutoriu de cuentes. Por exemplu, va usase pa completar automáticamente les cuentes esternes de la compartición federada. Nun ye necesario amestar un sirvidor como sirvidor d'enfotu pa crear una compartición federada.",
|
||||
"+ Add trusted server" : "+ Amestar un sirvidor d'enfotu",
|
||||
"Trusted server" : "Sirvidor d'enfotu",
|
||||
"Add" : "Amestar"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
@@ -1,15 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Amestóse a la llista de sirvidores d'enfotu",
|
||||
"Server is already in the list of trusted servers." : "El sirvidor yá ta na llista de los sirvidores d'enfotu.",
|
||||
"No server to federate with found" : "Nun s'atopó nengún sirvidor col que se federar",
|
||||
"Could not add server" : "Nun se pudo amestar el sirvidor",
|
||||
"Trusted servers" : "Sirvidores d'enfotu",
|
||||
"Federation" : "Federación",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "La federación permíte que te conectes con otros sirvidores d'enfotu pa intercambiar el direutoriu de cuentes.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "La federación permite que te conectes a otros sirvidores d'enfotu pa intercambiar el direutoriu de cuentes. Por exemplu, va usase pa completar automáticamente les cuentes esternes de la compartición federada.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "La federación permite que te conectes a otros sirvidores d'enfotu pa intercambiar el direutoriu de cuentes. Por exemplu, va usase pa completar automáticamente les cuentes esternes de la compartición federada. Nun ye necesario amestar un sirvidor como sirvidor d'enfotu pa crear una compartición federada.",
|
||||
"+ Add trusted server" : "+ Amestar un sirvidor d'enfotu",
|
||||
"Trusted server" : "Sirvidor d'enfotu",
|
||||
"Add" : "Amestar"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Добавен към списъка с доверени сървъри",
|
||||
"Server is already in the list of trusted servers." : "Сървъра вече присъства в списъка с доверени сървъри",
|
||||
"No server to federate with found" : "Не е намерен сървър за федериране",
|
||||
"Could not add server" : "Не можа да се добави сървър",
|
||||
"Trusted servers" : "Доверени сървъри",
|
||||
"Federation" : "Федерация",
|
||||
"+ Add trusted server" : "+ Добави доверен сървър",
|
||||
"Trusted server" : "Доверен сървър",
|
||||
"Add" : "Добави"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Добавен към списъка с доверени сървъри",
|
||||
"Server is already in the list of trusted servers." : "Сървъра вече присъства в списъка с доверени сървъри",
|
||||
"No server to federate with found" : "Не е намерен сървър за федериране",
|
||||
"Could not add server" : "Не можа да се добави сървър",
|
||||
"Trusted servers" : "Доверени сървъри",
|
||||
"Federation" : "Федерация",
|
||||
"+ Add trusted server" : "+ Добави доверен сървър",
|
||||
"Trusted server" : "Доверен сървър",
|
||||
"Add" : "Добави"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Ouzhpennañ d'ar roll ar servijourienn fiziet",
|
||||
"Server is already in the list of trusted servers." : "Er roll ar servijour fiziet eo dija",
|
||||
"No server to federate with found" : "Servijour da gevredañ ebet kavet",
|
||||
"Could not add server" : "Dibosupl ouzhpennañ ar servijour",
|
||||
"Trusted servers" : "Servijourienn fiziet",
|
||||
"Federation" : "Kevread",
|
||||
"+ Add trusted server" : "+ Ouzhpenna ur servijour fiziet",
|
||||
"Trusted server" : "Servijour fiziet",
|
||||
"Add" : "Ouzhpennañ"
|
||||
},
|
||||
"nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Ouzhpennañ d'ar roll ar servijourienn fiziet",
|
||||
"Server is already in the list of trusted servers." : "Er roll ar servijour fiziet eo dija",
|
||||
"No server to federate with found" : "Servijour da gevredañ ebet kavet",
|
||||
"Could not add server" : "Dibosupl ouzhpennañ ar servijour",
|
||||
"Trusted servers" : "Servijourienn fiziet",
|
||||
"Federation" : "Kevread",
|
||||
"+ Add trusted server" : "+ Ouzhpenna ur servijour fiziet",
|
||||
"Trusted server" : "Servijour fiziet",
|
||||
"Add" : "Ouzhpennañ"
|
||||
},"pluralForm" :"nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);"
|
||||
}
|
||||
@@ -11,11 +11,12 @@ OC.L10N.register(
|
||||
"Federation" : "Federació",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "La federació us permet connectar-vos amb altres servidors de confiança per a intercanviar la carpeta del compte.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "La federació us permet connectar-vos amb altres servidors de confiança per a intercanviar carpetes de compte. Per exemple, s'utilitzarà per a proporcionar resultats d'emplenament automàtic de comptes externs per a l'ús compartit federat.",
|
||||
"External documentation for Federated Cloud Sharing" : "Documentació externa per a compartició federada de núvol",
|
||||
"Add" : "Afegeix",
|
||||
"Delete" : "Suprimir",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "La federació us permet connectar-vos amb altres servidors de confiança per a intercanviar carpetes de compte. Per exemple, s'utilitzarà per a proporcionar resultats d'emplenament automàtic de comptes externs per a l'ús compartit federat. No cal afegir un servidor com a servidor de confiança per a crear un recurs d'ús compartit federat.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Cada servidor ha de validar l'altre. Aquest procés pot requerir uns quants cicles cron.",
|
||||
"External documentation for Federated Cloud Sharing" : "Documentació externa per a compartició federada de núvol",
|
||||
"+ Add trusted server" : "+ Afegeix un servidor de confiança",
|
||||
"Trusted server" : "Servidor de confiança",
|
||||
"Add" : "Afegeix"
|
||||
"Trusted server" : "Servidor de confiança"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
"Federation" : "Federació",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "La federació us permet connectar-vos amb altres servidors de confiança per a intercanviar la carpeta del compte.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "La federació us permet connectar-vos amb altres servidors de confiança per a intercanviar carpetes de compte. Per exemple, s'utilitzarà per a proporcionar resultats d'emplenament automàtic de comptes externs per a l'ús compartit federat.",
|
||||
"External documentation for Federated Cloud Sharing" : "Documentació externa per a compartició federada de núvol",
|
||||
"Add" : "Afegeix",
|
||||
"Delete" : "Suprimir",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "La federació us permet connectar-vos amb altres servidors de confiança per a intercanviar carpetes de compte. Per exemple, s'utilitzarà per a proporcionar resultats d'emplenament automàtic de comptes externs per a l'ús compartit federat. No cal afegir un servidor com a servidor de confiança per a crear un recurs d'ús compartit federat.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Cada servidor ha de validar l'altre. Aquest procés pot requerir uns quants cicles cron.",
|
||||
"External documentation for Federated Cloud Sharing" : "Documentació externa per a compartició federada de núvol",
|
||||
"+ Add trusted server" : "+ Afegeix un servidor de confiança",
|
||||
"Trusted server" : "Servidor de confiança",
|
||||
"Add" : "Afegeix"
|
||||
"Trusted server" : "Servidor de confiança"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -11,11 +11,12 @@ OC.L10N.register(
|
||||
"Federation" : "Federování",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Federování umožňuje propojit s ostatními servery, kterým věříte a vyměňovat si tak adresář účtů.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Federování umožňuje propojit s ostatními servery, kterým věříte a vyměňovat si tak adresář uživatelských účtů. Používá se toho například pro automatické doplňování externích účtů při federovaném sdílení.",
|
||||
"External documentation for Federated Cloud Sharing" : "Externí dokumentace pro sdílení v rámci federovaného cloudu",
|
||||
"Add" : "Přidat",
|
||||
"Delete" : "Smazat",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Federování umožňuje propojit se s ostatními servery, kterým věříte a vyměňovat si tak adresář uživatelských účtů. Používá se toho například pro automatické dokončování externích účtů při federovaném sdílení. Nicméně pro vytvoření federovaného sdílení jako takového není nezbytné přidávat server jako důvěryhodný.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Je třeba, aby každý server ověřil ten druhý. Tento proces může vyžadovat několik cyklů plánovače.",
|
||||
"External documentation for Federated Cloud Sharing" : "Externí dokumentace pro sdílení v rámci federovaného cloudu",
|
||||
"+ Add trusted server" : "+ Přidat důvěryhodný server",
|
||||
"Trusted server" : "Důvěryhodný server",
|
||||
"Add" : "Přidat"
|
||||
"Trusted server" : "Důvěryhodný server"
|
||||
},
|
||||
"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;");
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
"Federation" : "Federování",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Federování umožňuje propojit s ostatními servery, kterým věříte a vyměňovat si tak adresář účtů.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Federování umožňuje propojit s ostatními servery, kterým věříte a vyměňovat si tak adresář uživatelských účtů. Používá se toho například pro automatické doplňování externích účtů při federovaném sdílení.",
|
||||
"External documentation for Federated Cloud Sharing" : "Externí dokumentace pro sdílení v rámci federovaného cloudu",
|
||||
"Add" : "Přidat",
|
||||
"Delete" : "Smazat",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Federování umožňuje propojit se s ostatními servery, kterým věříte a vyměňovat si tak adresář uživatelských účtů. Používá se toho například pro automatické dokončování externích účtů při federovaném sdílení. Nicméně pro vytvoření federovaného sdílení jako takového není nezbytné přidávat server jako důvěryhodný.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Je třeba, aby každý server ověřil ten druhý. Tento proces může vyžadovat několik cyklů plánovače.",
|
||||
"External documentation for Federated Cloud Sharing" : "Externí dokumentace pro sdílení v rámci federovaného cloudu",
|
||||
"+ Add trusted server" : "+ Přidat důvěryhodný server",
|
||||
"Trusted server" : "Důvěryhodný server",
|
||||
"Add" : "Přidat"
|
||||
"Trusted server" : "Důvěryhodný server"
|
||||
},"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;"
|
||||
}
|
||||
@@ -11,11 +11,12 @@ OC.L10N.register(
|
||||
"Federation" : "Sammenkobling",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Sammenkobling giver dig mulighed for at oprette forbindelse til andre betroede servere for at udveksle kontobiblioteket.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Sammenkobling giver dig mulighed for at oprette forbindelse til andre betroede servere for at udveksle kontobiblioteket. For eksempel vil dette blive brugt til automatisk at fuldføre eksterne konti til deling.",
|
||||
"External documentation for Federated Cloud Sharing" : "Ekstern dokumentation for Sammenkoblings Cloud deling",
|
||||
"Add" : "Tilføj",
|
||||
"Delete" : "Slet",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Føderering giver dig mulighed for at oprette forbindelse til andre betroede servere for at udveksle kontobiblioteket. For eksempel vil dette blive brugt til automatisk at fuldføre eksterne konti til fødereret deling. Det er ikke nødvendigt at tilføje en server som betroet server for at oprette en fødereret deling.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Hver server skal validere den anden. Denne proces kan kræve et par cron cyklusser.",
|
||||
"External documentation for Federated Cloud Sharing" : "Ekstern dokumentation for Sammenkoblings Cloud deling",
|
||||
"+ Add trusted server" : "+ Tilføj pålidelig server",
|
||||
"Trusted server" : "Pålidelig server",
|
||||
"Add" : "Tilføj"
|
||||
"Trusted server" : "Pålidelig server"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
"Federation" : "Sammenkobling",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Sammenkobling giver dig mulighed for at oprette forbindelse til andre betroede servere for at udveksle kontobiblioteket.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Sammenkobling giver dig mulighed for at oprette forbindelse til andre betroede servere for at udveksle kontobiblioteket. For eksempel vil dette blive brugt til automatisk at fuldføre eksterne konti til deling.",
|
||||
"External documentation for Federated Cloud Sharing" : "Ekstern dokumentation for Sammenkoblings Cloud deling",
|
||||
"Add" : "Tilføj",
|
||||
"Delete" : "Slet",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Føderering giver dig mulighed for at oprette forbindelse til andre betroede servere for at udveksle kontobiblioteket. For eksempel vil dette blive brugt til automatisk at fuldføre eksterne konti til fødereret deling. Det er ikke nødvendigt at tilføje en server som betroet server for at oprette en fødereret deling.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Hver server skal validere den anden. Denne proces kan kræve et par cron cyklusser.",
|
||||
"External documentation for Federated Cloud Sharing" : "Ekstern dokumentation for Sammenkoblings Cloud deling",
|
||||
"+ Add trusted server" : "+ Tilføj pålidelig server",
|
||||
"Trusted server" : "Pålidelig server",
|
||||
"Add" : "Tilføj"
|
||||
"Trusted server" : "Pålidelig server"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -11,11 +11,23 @@ OC.L10N.register(
|
||||
"Federation" : "Federation",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Federation ermöglicht die Verbindung mit anderen vertrauenswürdigen Servern, um das Kontenverzeichnis auszutauschen.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Federation ermöglicht es dir, dich mit anderen vertrauenswürdigen Servern zu verbinden, um das Kontoverzeichnis auszutauschen. Dies wird zum Beispiel für die automatische Vervollständigung externer Konten beim Federated-Sharing verwendet.",
|
||||
"External documentation for Federated Cloud Sharing" : "Externe Dokumentation für das Teilen über Federated Cloud",
|
||||
"Could not add trusted server. Please try again later." : "Vertrauenswürdiger Server konnte nicht hinzugefügt werden. Bitte später erneut versuchen.",
|
||||
"Add trusted server" : "Vertrauenswürdigen Server hinzufügen",
|
||||
"Server url" : "Server-URL",
|
||||
"Add" : "Hinzufügen",
|
||||
"Server ok" : "Server OK",
|
||||
"User list was exchanged at least once successfully with the remote server." : "Die Benutzerliste wurde mindestens einmal erfolgreich mit dem Remote-Server ausgetauscht.",
|
||||
"Server pending" : "Server ausstehend",
|
||||
"Waiting for shared secret or initial user list exchange." : "Warten auf den Austausch gemeinsamer Geheimnisse oder erster Benutzerliste.",
|
||||
"Server access revoked" : "Serverzugriff widerrufen",
|
||||
"Server failure" : "Serverfehler",
|
||||
"Connection to the remote server failed or the remote server is misconfigured." : "Die Verbindung zum Remote-Server ist fehlgeschlagen oder der Remote-Server ist falsch konfiguriert.",
|
||||
"Failed to delete trusted server. Please try again later." : "Vertrauenswürdiger Server konnte nicht gelöscht werden. Bitte später erneut versuchen.",
|
||||
"Delete" : "Löschen",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Federation ermöglicht es dir, dich mit anderen vertrauenswürdigen Servern zu verbinden, um das Kontoverzeichnis auszutauschen. Dies wird zum Beispiel für die automatische Vervollständigung externer Konten beim Federated-Sharing verwendet. Es ist nicht erforderlich einen Server als vertrauenswürdig hinzuzufügen, um eine \"federated\" Freigabe zu erstellen.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Jeder Server muss den anderen validieren. Dieser Vorgang kann einige Cron-Zyklen benötigen.",
|
||||
"External documentation for Federated Cloud Sharing" : "Externe Dokumentation für das Teilen über Federated Cloud",
|
||||
"+ Add trusted server" : "+ Vertrauenswürdigen Server hinzufügen",
|
||||
"Trusted server" : "Vertrauenswürdiger Server",
|
||||
"Add" : "Hinzufügen"
|
||||
"Trusted server" : "Vertrauenswürdiger Server"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
|
||||
@@ -9,11 +9,23 @@
|
||||
"Federation" : "Federation",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Federation ermöglicht die Verbindung mit anderen vertrauenswürdigen Servern, um das Kontenverzeichnis auszutauschen.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Federation ermöglicht es dir, dich mit anderen vertrauenswürdigen Servern zu verbinden, um das Kontoverzeichnis auszutauschen. Dies wird zum Beispiel für die automatische Vervollständigung externer Konten beim Federated-Sharing verwendet.",
|
||||
"External documentation for Federated Cloud Sharing" : "Externe Dokumentation für das Teilen über Federated Cloud",
|
||||
"Could not add trusted server. Please try again later." : "Vertrauenswürdiger Server konnte nicht hinzugefügt werden. Bitte später erneut versuchen.",
|
||||
"Add trusted server" : "Vertrauenswürdigen Server hinzufügen",
|
||||
"Server url" : "Server-URL",
|
||||
"Add" : "Hinzufügen",
|
||||
"Server ok" : "Server OK",
|
||||
"User list was exchanged at least once successfully with the remote server." : "Die Benutzerliste wurde mindestens einmal erfolgreich mit dem Remote-Server ausgetauscht.",
|
||||
"Server pending" : "Server ausstehend",
|
||||
"Waiting for shared secret or initial user list exchange." : "Warten auf den Austausch gemeinsamer Geheimnisse oder erster Benutzerliste.",
|
||||
"Server access revoked" : "Serverzugriff widerrufen",
|
||||
"Server failure" : "Serverfehler",
|
||||
"Connection to the remote server failed or the remote server is misconfigured." : "Die Verbindung zum Remote-Server ist fehlgeschlagen oder der Remote-Server ist falsch konfiguriert.",
|
||||
"Failed to delete trusted server. Please try again later." : "Vertrauenswürdiger Server konnte nicht gelöscht werden. Bitte später erneut versuchen.",
|
||||
"Delete" : "Löschen",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Federation ermöglicht es dir, dich mit anderen vertrauenswürdigen Servern zu verbinden, um das Kontoverzeichnis auszutauschen. Dies wird zum Beispiel für die automatische Vervollständigung externer Konten beim Federated-Sharing verwendet. Es ist nicht erforderlich einen Server als vertrauenswürdig hinzuzufügen, um eine \"federated\" Freigabe zu erstellen.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Jeder Server muss den anderen validieren. Dieser Vorgang kann einige Cron-Zyklen benötigen.",
|
||||
"External documentation for Federated Cloud Sharing" : "Externe Dokumentation für das Teilen über Federated Cloud",
|
||||
"+ Add trusted server" : "+ Vertrauenswürdigen Server hinzufügen",
|
||||
"Trusted server" : "Vertrauenswürdiger Server",
|
||||
"Add" : "Hinzufügen"
|
||||
"Trusted server" : "Vertrauenswürdiger Server"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -11,11 +11,23 @@ OC.L10N.register(
|
||||
"Federation" : "Federation",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Federation ermöglicht die Verbindung mit anderen vertrauenswürdigen Servern, um das Kontenverzeichnis auszutauschen.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Federation ermöglicht es Ihnen, sich mit anderen vertrauenswürdigen Servern zu verbinden, um das Kontoverzeichnis auszutauschen. Dies wird zum Beispiel für die automatische Vervollständigung externer Konten beim Federated-Sharing verwendet.",
|
||||
"External documentation for Federated Cloud Sharing" : "Externe Dokumentation für Teilen über Federated Cloud",
|
||||
"Could not add trusted server. Please try again later." : "Vertrauenswürdiger Server konnte nicht hinzugefügt werden. Bitte später erneut versuchen.",
|
||||
"Add trusted server" : "Vertrauenswürdigen Server hinzufügen",
|
||||
"Server url" : "Server-URL",
|
||||
"Add" : "Hinzufügen",
|
||||
"Server ok" : "Server OK",
|
||||
"User list was exchanged at least once successfully with the remote server." : "Die Benutzerliste wurde mindestens einmal erfolgreich mit dem Remote-Server ausgetauscht.",
|
||||
"Server pending" : "Server ausstehend",
|
||||
"Waiting for shared secret or initial user list exchange." : "Warten auf den Austausch gemeinsamer Geheimnisse oder erster Benutzerliste.",
|
||||
"Server access revoked" : "Serverzugriff widerrufen",
|
||||
"Server failure" : "Serverfehler",
|
||||
"Connection to the remote server failed or the remote server is misconfigured." : "Die Verbindung zum Remote-Server ist fehlgeschlagen oder der Remote-Server ist falsch konfiguriert.",
|
||||
"Failed to delete trusted server. Please try again later." : "Vertrauenswürdiger Server konnte nicht gelöscht werden. Bitte später erneut versuchen.",
|
||||
"Delete" : "Löschen",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Federation ermöglicht es Ihnen, sich mit anderen vertrauenswürdigen Servern zu verbinden, um das Kontoverzeichnis auszutauschen. Dies wird zum Beispiel für die automatische Vervollständigung externer Konten beim Federated-Sharing verwendet. Es ist nicht erforderlich einen Server als vertrauenswürdig hinzuzufügen, um eine \"federated\" Freigabe zu erstellen.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Jeder Server muss den anderen validieren. Dieser Vorgang kann einige Cron-Zyklen erfordern.",
|
||||
"External documentation for Federated Cloud Sharing" : "Externe Dokumentation für Teilen über Federated Cloud",
|
||||
"+ Add trusted server" : "+ Vertrauenswürdigen Server hinzufügen",
|
||||
"Trusted server" : "Vertrauenswürdiger Server",
|
||||
"Add" : "Hinzufügen"
|
||||
"Trusted server" : "Vertrauenswürdiger Server"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
|
||||
@@ -9,11 +9,23 @@
|
||||
"Federation" : "Federation",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Federation ermöglicht die Verbindung mit anderen vertrauenswürdigen Servern, um das Kontenverzeichnis auszutauschen.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Federation ermöglicht es Ihnen, sich mit anderen vertrauenswürdigen Servern zu verbinden, um das Kontoverzeichnis auszutauschen. Dies wird zum Beispiel für die automatische Vervollständigung externer Konten beim Federated-Sharing verwendet.",
|
||||
"External documentation for Federated Cloud Sharing" : "Externe Dokumentation für Teilen über Federated Cloud",
|
||||
"Could not add trusted server. Please try again later." : "Vertrauenswürdiger Server konnte nicht hinzugefügt werden. Bitte später erneut versuchen.",
|
||||
"Add trusted server" : "Vertrauenswürdigen Server hinzufügen",
|
||||
"Server url" : "Server-URL",
|
||||
"Add" : "Hinzufügen",
|
||||
"Server ok" : "Server OK",
|
||||
"User list was exchanged at least once successfully with the remote server." : "Die Benutzerliste wurde mindestens einmal erfolgreich mit dem Remote-Server ausgetauscht.",
|
||||
"Server pending" : "Server ausstehend",
|
||||
"Waiting for shared secret or initial user list exchange." : "Warten auf den Austausch gemeinsamer Geheimnisse oder erster Benutzerliste.",
|
||||
"Server access revoked" : "Serverzugriff widerrufen",
|
||||
"Server failure" : "Serverfehler",
|
||||
"Connection to the remote server failed or the remote server is misconfigured." : "Die Verbindung zum Remote-Server ist fehlgeschlagen oder der Remote-Server ist falsch konfiguriert.",
|
||||
"Failed to delete trusted server. Please try again later." : "Vertrauenswürdiger Server konnte nicht gelöscht werden. Bitte später erneut versuchen.",
|
||||
"Delete" : "Löschen",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Federation ermöglicht es Ihnen, sich mit anderen vertrauenswürdigen Servern zu verbinden, um das Kontoverzeichnis auszutauschen. Dies wird zum Beispiel für die automatische Vervollständigung externer Konten beim Federated-Sharing verwendet. Es ist nicht erforderlich einen Server als vertrauenswürdig hinzuzufügen, um eine \"federated\" Freigabe zu erstellen.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Jeder Server muss den anderen validieren. Dieser Vorgang kann einige Cron-Zyklen erfordern.",
|
||||
"External documentation for Federated Cloud Sharing" : "Externe Dokumentation für Teilen über Federated Cloud",
|
||||
"+ Add trusted server" : "+ Vertrauenswürdigen Server hinzufügen",
|
||||
"Trusted server" : "Vertrauenswürdiger Server",
|
||||
"Add" : "Hinzufügen"
|
||||
"Trusted server" : "Vertrauenswürdiger Server"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -11,11 +11,12 @@ OC.L10N.register(
|
||||
"Federation" : "Ομοσπονδία",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Η ομοσπονδία σας επιτρέπει να συνδέεστε με άλλους έμπιστους διακομιστές για ανταλλαγή καταλόγου λογαριασμών.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Η ομοσπονδία σας επιτρέπει να συνδέεστε με άλλους έμπιστους διακομιστές για ανταλλαγή καταλόγου λογαριασμών. Για παράδειγμα, χρησιμοποιείται για την αυτομάτη συμπλήρωση εξωτερικών λογαριασμών κατά τη συνένωση κοινής χρήσης.",
|
||||
"External documentation for Federated Cloud Sharing" : "Εξωτερική τεκμηρίωση για τον διαμοιρασμό σε ομοσπονδοποιημένο υπολογιστικό νέφος",
|
||||
"Add" : "Προσθήκη",
|
||||
"Delete" : "Διαγραφή",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Η ομοσπονδία σας επιτρέπει να συνδέεστε με άλλους έμπιστους διακομιστές για ανταλλαγή καταλόγου λογαριασμών. Για παράδειγμα, χρησιμοποιείται για την αυτομάτη συμπλήρωση εξωτερικών λογαριασμών κατά τη συνένωση κοινής χρήσης. Δεν είναι απαραίτητο να προσθέσετε έναν διακομιστή ως έμπιστο για τη δημιουργία μιας συνενωμένης κοινής χρήσης.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Κάθε διακομιστής πρέπει να επικυρώσει τον άλλο. Αυτή η διαδικασία μπορεί να απαιτήσει μερικούς κύκλους cron.",
|
||||
"External documentation for Federated Cloud Sharing" : "Εξωτερική τεκμηρίωση για τον διαμοιρασμό σε ομοσπονδοποιημένο υπολογιστικό νέφος",
|
||||
"+ Add trusted server" : "+Προσθήκη έμπιστων διακομιστών",
|
||||
"Trusted server" : "Έμπιστοι διακομιστές",
|
||||
"Add" : "Προσθήκη"
|
||||
"Trusted server" : "Έμπιστοι διακομιστές"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
"Federation" : "Ομοσπονδία",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Η ομοσπονδία σας επιτρέπει να συνδέεστε με άλλους έμπιστους διακομιστές για ανταλλαγή καταλόγου λογαριασμών.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Η ομοσπονδία σας επιτρέπει να συνδέεστε με άλλους έμπιστους διακομιστές για ανταλλαγή καταλόγου λογαριασμών. Για παράδειγμα, χρησιμοποιείται για την αυτομάτη συμπλήρωση εξωτερικών λογαριασμών κατά τη συνένωση κοινής χρήσης.",
|
||||
"External documentation for Federated Cloud Sharing" : "Εξωτερική τεκμηρίωση για τον διαμοιρασμό σε ομοσπονδοποιημένο υπολογιστικό νέφος",
|
||||
"Add" : "Προσθήκη",
|
||||
"Delete" : "Διαγραφή",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Η ομοσπονδία σας επιτρέπει να συνδέεστε με άλλους έμπιστους διακομιστές για ανταλλαγή καταλόγου λογαριασμών. Για παράδειγμα, χρησιμοποιείται για την αυτομάτη συμπλήρωση εξωτερικών λογαριασμών κατά τη συνένωση κοινής χρήσης. Δεν είναι απαραίτητο να προσθέσετε έναν διακομιστή ως έμπιστο για τη δημιουργία μιας συνενωμένης κοινής χρήσης.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Κάθε διακομιστής πρέπει να επικυρώσει τον άλλο. Αυτή η διαδικασία μπορεί να απαιτήσει μερικούς κύκλους cron.",
|
||||
"External documentation for Federated Cloud Sharing" : "Εξωτερική τεκμηρίωση για τον διαμοιρασμό σε ομοσπονδοποιημένο υπολογιστικό νέφος",
|
||||
"+ Add trusted server" : "+Προσθήκη έμπιστων διακομιστών",
|
||||
"Trusted server" : "Έμπιστοι διακομιστές",
|
||||
"Add" : "Προσθήκη"
|
||||
"Trusted server" : "Έμπιστοι διακομιστές"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -11,11 +11,12 @@ OC.L10N.register(
|
||||
"Federation" : "Federation",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Federation allows you to connect with other trusted servers to exchange the account directory.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing.",
|
||||
"External documentation for Federated Cloud Sharing" : "External documentation for Federated Cloud Sharing",
|
||||
"Add" : "Add",
|
||||
"Delete" : "Delete",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Each server must validate the other. This process may require a few cron cycles.",
|
||||
"External documentation for Federated Cloud Sharing" : "External documentation for Federated Cloud Sharing",
|
||||
"+ Add trusted server" : "+ Add trusted server",
|
||||
"Trusted server" : "Trusted server",
|
||||
"Add" : "Add"
|
||||
"Trusted server" : "Trusted server"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
"Federation" : "Federation",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Federation allows you to connect with other trusted servers to exchange the account directory.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing.",
|
||||
"External documentation for Federated Cloud Sharing" : "External documentation for Federated Cloud Sharing",
|
||||
"Add" : "Add",
|
||||
"Delete" : "Delete",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Each server must validate the other. This process may require a few cron cycles.",
|
||||
"External documentation for Federated Cloud Sharing" : "External documentation for Federated Cloud Sharing",
|
||||
"+ Add trusted server" : "+ Add trusted server",
|
||||
"Trusted server" : "Trusted server",
|
||||
"Add" : "Add"
|
||||
"Trusted server" : "Trusted server"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Aldonita al la listo de fidindaj serviloj",
|
||||
"Server is already in the list of trusted servers." : "Servilo jam estas en la listo de fidindaj serviloj.",
|
||||
"No server to federate with found" : "Neniu federota servilo trovata",
|
||||
"Could not add server" : "Ne eblas aldoni servilon",
|
||||
"Trusted servers" : "Fidindaj serviloj",
|
||||
"Federation" : "Federado",
|
||||
"+ Add trusted server" : "+ Aldoni fidindan servilon",
|
||||
"Trusted server" : "Fidinda servilo",
|
||||
"Add" : "Aldoni"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Aldonita al la listo de fidindaj serviloj",
|
||||
"Server is already in the list of trusted servers." : "Servilo jam estas en la listo de fidindaj serviloj.",
|
||||
"No server to federate with found" : "Neniu federota servilo trovata",
|
||||
"Could not add server" : "Ne eblas aldoni servilon",
|
||||
"Trusted servers" : "Fidindaj serviloj",
|
||||
"Federation" : "Federado",
|
||||
"+ Add trusted server" : "+ Aldoni fidindan servilon",
|
||||
"Trusted server" : "Fidinda servilo",
|
||||
"Add" : "Aldoni"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -11,11 +11,12 @@ OC.L10N.register(
|
||||
"Federation" : "Federación",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "La federación le permite conectarse con otros servidores de confianza para intercambiar el directorio de usuarios.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "La Federación le permite conectarse con otros servidores de confianza para intercambiar el directorio de usuarios. Por ejemplo, esto se utilizará para auto-completar a los usuarios externos para el intercambio federado.",
|
||||
"External documentation for Federated Cloud Sharing" : "Documentación externa para Compartir con Nube Federada",
|
||||
"Add" : "Añadir",
|
||||
"Delete" : "Eliminar",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "La Federación le permite conectarse con otros servidores de confianza para intercambiar el directorio de usuarios. Por ejemplo, esto se utilizará para auto-completar a los usuarios externos para el intercambio federado. No es necesario añadir un servidor como servidor de confianza para crear una recurso compartido federado.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Cada servidor debe validar al otro. Este proceso puede necesitar algunos ciclos de cron.",
|
||||
"External documentation for Federated Cloud Sharing" : "Documentación externa para Compartir con Nube Federada",
|
||||
"+ Add trusted server" : "+ Añadir servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Añadir"
|
||||
"Trusted server" : "Servidor de confianza"
|
||||
},
|
||||
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
"Federation" : "Federación",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "La federación le permite conectarse con otros servidores de confianza para intercambiar el directorio de usuarios.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "La Federación le permite conectarse con otros servidores de confianza para intercambiar el directorio de usuarios. Por ejemplo, esto se utilizará para auto-completar a los usuarios externos para el intercambio federado.",
|
||||
"External documentation for Federated Cloud Sharing" : "Documentación externa para Compartir con Nube Federada",
|
||||
"Add" : "Añadir",
|
||||
"Delete" : "Eliminar",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "La Federación le permite conectarse con otros servidores de confianza para intercambiar el directorio de usuarios. Por ejemplo, esto se utilizará para auto-completar a los usuarios externos para el intercambio federado. No es necesario añadir un servidor como servidor de confianza para crear una recurso compartido federado.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Cada servidor debe validar al otro. Este proceso puede necesitar algunos ciclos de cron.",
|
||||
"External documentation for Federated Cloud Sharing" : "Documentación externa para Compartir con Nube Federada",
|
||||
"+ Add trusted server" : "+ Añadir servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Añadir"
|
||||
"Trusted server" : "Servidor de confianza"
|
||||
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},
|
||||
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},
|
||||
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},
|
||||
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},
|
||||
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},
|
||||
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},
|
||||
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},
|
||||
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},
|
||||
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},
|
||||
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"federation",
|
||||
{
|
||||
"Added to the list of trusted servers" : "Agregado a la lista de servidores de confianza",
|
||||
"Server is already in the list of trusted servers." : "El servidor ya se encuentra en la lista de servidores de confianza.",
|
||||
"No server to federate with found" : "No se encontraron servidores para integrar a la federación",
|
||||
"Could not add server" : "No fue posible agregar el servidor",
|
||||
"Trusted servers" : "Servidores de confianza",
|
||||
"Federation" : "Federación",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "La Federación permite conectarse con otros servidores de confianza para intercambiar el directorio de usuarios.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "La Federación permite conectarse con otros servidores de confianza para intercambiar el directorio de usuarios. Por ejemplo, esto se usará para autocompletar usuarios externos en el recurso compartido federado.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "La Federación permite conectarse con otros servidores de confianza para intercambiar el directorio de usuarios. Por ejemplo, esto se usará para autocompletar usuarios externos en el recurso compartido federado. No es necesario añadir un servidor como servidor de confianza para crear un recurso compartido federado.",
|
||||
"+ Add trusted server" : "+ Agregar servidor de confianza",
|
||||
"Trusted server" : "Servidor de confianza",
|
||||
"Add" : "Agregar"
|
||||
},
|
||||
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user