aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.editorconfig4
-rw-r--r--.github/workflows/lint.yml16
-rw-r--r--apps/accessibility/l10n/zh_CN.js8
-rw-r--r--apps/accessibility/l10n/zh_CN.json8
-rw-r--r--apps/dav/lib/CalDAV/WebcalCaching/RefreshWebcalService.php53
-rw-r--r--apps/dav/lib/Connector/Sabre/File.php31
-rw-r--r--apps/dav/lib/Upload/ChunkingPlugin.php16
-rw-r--r--apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php55
-rw-r--r--apps/dav/tests/unit/Upload/ChunkingPluginTest.php42
-rw-r--r--apps/federation/l10n/vi.js17
-rw-r--r--apps/federation/l10n/vi.json15
-rw-r--r--apps/files/l10n/vi.js4
-rw-r--r--apps/files/l10n/vi.json4
-rw-r--r--apps/files_external/l10n/pl.js6
-rw-r--r--apps/files_external/l10n/pl.json6
-rw-r--r--apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php1
-rw-r--r--apps/files_external/lib/Lib/Backend/Swift.php3
-rw-r--r--apps/files_sharing/lib/Controller/ExternalSharesController.php2
-rw-r--r--apps/files_sharing/tests/Controller/ExternalShareControllerTest.php1
-rw-r--r--apps/provisioning_api/tests/Controller/GroupsControllerTest.php2
-rw-r--r--apps/settings/l10n/cs.js2
-rw-r--r--apps/settings/l10n/cs.json2
-rw-r--r--apps/settings/l10n/de.js2
-rw-r--r--apps/settings/l10n/de.json2
-rw-r--r--apps/settings/l10n/de_DE.js2
-rw-r--r--apps/settings/l10n/de_DE.json2
-rw-r--r--apps/settings/l10n/el.js2
-rw-r--r--apps/settings/l10n/el.json2
-rw-r--r--apps/settings/l10n/it.js2
-rw-r--r--apps/settings/l10n/it.json2
-rw-r--r--apps/settings/l10n/pl.js2
-rw-r--r--apps/settings/l10n/pl.json2
-rw-r--r--apps/settings/l10n/pt_BR.js2
-rw-r--r--apps/settings/l10n/pt_BR.json2
-rw-r--r--apps/settings/l10n/vi.js2
-rw-r--r--apps/settings/l10n/vi.json2
-rw-r--r--apps/settings/lib/Controller/CheckSetupController.php2
-rw-r--r--apps/theming/l10n/vi.js1
-rw-r--r--apps/theming/l10n/vi.json1
-rwxr-xr-xbuild/integration/run.sh2
-rw-r--r--build/package-lock.json472
-rw-r--r--build/package.json2
-rw-r--r--config/config.sample.php7
-rw-r--r--core/Controller/LoginController.php2
-rw-r--r--core/js/mimetypelist.js6
-rw-r--r--core/l10n/is.js3
-rw-r--r--core/l10n/is.json3
-rw-r--r--core/l10n/vi.js2
-rw-r--r--core/l10n/vi.json2
-rw-r--r--lib/composer/composer/autoload_classmap.php2
-rw-r--r--lib/composer/composer/autoload_static.php2
-rw-r--r--lib/private/DB/QueryBuilder/ExpressionBuilder/MySqlExpressionBuilder.php8
-rw-r--r--lib/private/Files/ObjectStore/SwiftFactory.php4
-rw-r--r--lib/private/Files/Storage/Common.php9
-rw-r--r--lib/private/Files/Stream/HashWrapper.php72
-rw-r--r--lib/private/Http/Client/Client.php65
-rw-r--r--lib/private/Http/Client/ClientService.php11
-rw-r--r--lib/private/Server.php1
-rw-r--r--lib/private/Share20/DefaultShareProvider.php2
-rw-r--r--lib/private/Share20/Manager.php8
-rw-r--r--lib/private/User/Manager.php2
-rw-r--r--lib/public/Http/Client/LocalServerException.php29
-rw-r--r--resources/codesigning/root.crl35
-rw-r--r--resources/config/mimetypealiases.dist.json5
-rw-r--r--resources/config/mimetypemapping.dist.json3
-rw-r--r--tests/Core/Controller/LoginControllerTest.php8
-rw-r--r--tests/karma.config.js6
-rw-r--r--tests/lib/Files/Stream/HashWrapperTest.php55
-rw-r--r--tests/lib/Http/Client/ClientServiceTest.php6
-rw-r--r--tests/lib/Http/Client/ClientTest.php131
70 files changed, 1078 insertions, 217 deletions
diff --git a/.editorconfig b/.editorconfig
index 0b4e725ad8f..51117a6e796 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -14,6 +14,10 @@ trim_trailing_whitespace = true
indent_size = 2
indent_style = space
+[*.yml]
+indent_size = 2
+indent_style = space
+
[*.md]
trim_trailing_whitespace = false
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index ca027676da0..4de6de68656 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -18,3 +18,19 @@ jobs:
coverage: none
- name: Lint
run: composer run lint
+
+ php-cs-fixer:
+ name: php-cs check
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@master
+ - name: Set up php
+ uses: shivammathur/setup-php@master
+ with:
+ php-version: 7.4
+ coverage: none
+ - name: Install dependencies
+ run: composer i
+ - name: Run coding standards check
+ run: composer run cs:check || ( echo 'Please run `composer run cs:fix` to format your code' && exit 1 )
diff --git a/apps/accessibility/l10n/zh_CN.js b/apps/accessibility/l10n/zh_CN.js
index 6ae15398cf1..ccad83dc5bc 100644
--- a/apps/accessibility/l10n/zh_CN.js
+++ b/apps/accessibility/l10n/zh_CN.js
@@ -1,12 +1,12 @@
OC.L10N.register(
"accessibility",
{
- "Dark theme" : "深色主题",
- "Enable dark theme" : "启用深色主题",
- "A dark theme to ease your eyes by reducing the overall luminosity and brightness. It is still under development, so please report any issues you may find." : "一款通过降低整体亮度来使您的眼睛放松的深色主题。它仍在开发中,因此请报告您发现的任何问题。",
+ "Dark theme" : "暗黑模式",
+ "Enable dark theme" : "启用暗黑模式 ",
+ "A dark theme to ease your eyes by reducing the overall luminosity and brightness. It is still under development, so please report any issues you may find." : "一款通过降低整体亮度来使您的眼睛放松的深色主题。目前还在开发中,如发现问题请及时反馈。",
"High contrast mode" : "高对比度模式",
"Enable high contrast mode" : "启用高对比度模式",
- "A high contrast mode to ease your navigation. Visual quality will be reduced but clarity will be increased." : "使用高对比度模式。图像质量会下降但清晰度会提升。",
+ "A high contrast mode to ease your navigation. Visual quality will be reduced but clarity will be increased." : "使用高对比度模式。图像质量会下降,但清晰度会提升。",
"Dyslexia font" : "阅读障碍字体",
"Enable dyslexia font" : "启用阅读障碍字体",
"OpenDyslexic is a free typeface/font designed to mitigate some of the common reading errors caused by dyslexia." : "OpenDyslexic是一款免费的字样/字体,这款字体的设计目的是缓解由阅读障碍引起的一些常见阅读错误。",
diff --git a/apps/accessibility/l10n/zh_CN.json b/apps/accessibility/l10n/zh_CN.json
index e70d1c2c735..b9ed4112bab 100644
--- a/apps/accessibility/l10n/zh_CN.json
+++ b/apps/accessibility/l10n/zh_CN.json
@@ -1,10 +1,10 @@
{ "translations": {
- "Dark theme" : "深色主题",
- "Enable dark theme" : "启用深色主题",
- "A dark theme to ease your eyes by reducing the overall luminosity and brightness. It is still under development, so please report any issues you may find." : "一款通过降低整体亮度来使您的眼睛放松的深色主题。它仍在开发中,因此请报告您发现的任何问题。",
+ "Dark theme" : "暗黑模式",
+ "Enable dark theme" : "启用暗黑模式 ",
+ "A dark theme to ease your eyes by reducing the overall luminosity and brightness. It is still under development, so please report any issues you may find." : "一款通过降低整体亮度来使您的眼睛放松的深色主题。目前还在开发中,如发现问题请及时反馈。",
"High contrast mode" : "高对比度模式",
"Enable high contrast mode" : "启用高对比度模式",
- "A high contrast mode to ease your navigation. Visual quality will be reduced but clarity will be increased." : "使用高对比度模式。图像质量会下降但清晰度会提升。",
+ "A high contrast mode to ease your navigation. Visual quality will be reduced but clarity will be increased." : "使用高对比度模式。图像质量会下降,但清晰度会提升。",
"Dyslexia font" : "阅读障碍字体",
"Enable dyslexia font" : "启用阅读障碍字体",
"OpenDyslexic is a free typeface/font designed to mitigate some of the common reading errors caused by dyslexia." : "OpenDyslexic是一款免费的字样/字体,这款字体的设计目的是缓解由阅读障碍引起的一些常见阅读错误。",
diff --git a/apps/dav/lib/CalDAV/WebcalCaching/RefreshWebcalService.php b/apps/dav/lib/CalDAV/WebcalCaching/RefreshWebcalService.php
index fadf61fd7de..8883a5d353c 100644
--- a/apps/dav/lib/CalDAV/WebcalCaching/RefreshWebcalService.php
+++ b/apps/dav/lib/CalDAV/WebcalCaching/RefreshWebcalService.php
@@ -32,6 +32,7 @@ use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use OCA\DAV\CalDAV\CalDavBackend;
use OCP\Http\Client\IClientService;
+use OCP\Http\Client\LocalServerException;
use OCP\IConfig;
use OCP\ILogger;
use Psr\Http\Message\RequestInterface;
@@ -215,48 +216,15 @@ class RefreshWebcalService {
return null;
}
- if ($allowLocalAccess !== 'yes') {
- $host = strtolower(parse_url($url, PHP_URL_HOST));
- // remove brackets from IPv6 addresses
- if (strpos($host, '[') === 0 && substr($host, -1) === ']') {
- $host = substr($host, 1, -1);
- }
-
- // Disallow localhost and local network
- if ($host === 'localhost' || substr($host, -6) === '.local' || substr($host, -10) === '.localhost') {
- $this->logger->warning("Subscription $subscriptionId was not refreshed because it violates local access rules");
- return null;
- }
-
- // Disallow hostname only
- if (substr_count($host, '.') === 0) {
- $this->logger->warning("Subscription $subscriptionId was not refreshed because it violates local access rules");
- return null;
- }
-
- if ((bool)filter_var($host, FILTER_VALIDATE_IP) && !filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
- $this->logger->warning("Subscription $subscriptionId was not refreshed because it violates local access rules");
- return null;
- }
-
- // Also check for IPv6 IPv4 nesting, because that's not covered by filter_var
- if ((bool)filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && substr_count($host, '.') > 0) {
- $delimiter = strrpos($host, ':'); // Get last colon
- $ipv4Address = substr($host, $delimiter + 1);
-
- if (!filter_var($ipv4Address, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
- $this->logger->warning("Subscription $subscriptionId was not refreshed because it violates local access rules");
- return null;
- }
- }
- }
-
try {
$params = [
'allow_redirects' => [
'redirects' => 10
],
'handler' => $handlerStack,
+ 'nextcloud' => [
+ 'allow_local_address' => $allowLocalAccess === 'yes',
+ ]
];
$user = parse_url($subscription['source'], PHP_URL_USER);
@@ -306,9 +274,18 @@ class RefreshWebcalService {
}
return $vCalendar->serialize();
}
+ } catch (LocalServerException $ex) {
+ $this->logger->logException($ex, [
+ 'message' => "Subscription $subscriptionId was not refreshed because it violates local access rules",
+ 'level' => ILogger::WARN,
+ ]);
+
+ return null;
} catch (Exception $ex) {
- $this->logger->logException($ex);
- $this->logger->warning("Subscription $subscriptionId could not be refreshed due to a network error");
+ $this->logger->logException($ex, [
+ 'message' => "Subscription $subscriptionId could not be refreshed due to a network error",
+ 'level' => ILogger::WARN,
+ ]);
return null;
}
diff --git a/apps/dav/lib/Connector/Sabre/File.php b/apps/dav/lib/Connector/Sabre/File.php
index 2c108819e9f..4e456616059 100644
--- a/apps/dav/lib/Connector/Sabre/File.php
+++ b/apps/dav/lib/Connector/Sabre/File.php
@@ -41,6 +41,7 @@ namespace OCA\DAV\Connector\Sabre;
use Icewind\Streams\CallbackWrapper;
use OC\AppFramework\Http\Request;
use OC\Files\Filesystem;
+use OC\Files\Stream\HashWrapper;
use OC\Files\View;
use OCA\DAV\Connector\Sabre\Exception\EntityTooLarge;
use OCA\DAV\Connector\Sabre\Exception\FileLocked;
@@ -173,16 +174,26 @@ class File extends Node implements IFile {
$this->changeLock(ILockingProvider::LOCK_EXCLUSIVE);
}
- if ($partStorage->instanceOfStorage(Storage\IWriteStreamStorage::class)) {
- if (!is_resource($data)) {
- $tmpData = fopen('php://temp', 'r+');
- if ($data !== null) {
- fwrite($tmpData, $data);
- rewind($tmpData);
- }
- $data = $tmpData;
+ if (!is_resource($data)) {
+ $tmpData = fopen('php://temp', 'r+');
+ if ($data !== null) {
+ fwrite($tmpData, $data);
+ rewind($tmpData);
}
+ $data = $tmpData;
+ }
+ $data = HashWrapper::wrap($data, 'md5', function ($hash) {
+ $this->header('X-Hash-MD5: ' . $hash);
+ });
+ $data = HashWrapper::wrap($data, 'sha1', function ($hash) {
+ $this->header('X-Hash-SHA1: ' . $hash);
+ });
+ $data = HashWrapper::wrap($data, 'sha256', function ($hash) {
+ $this->header('X-Hash-SHA256: ' . $hash);
+ });
+
+ if ($partStorage->instanceOfStorage(Storage\IWriteStreamStorage::class)) {
$isEOF = false;
$wrappedData = CallbackWrapper::wrap($data, null, null, null, null, function ($stream) use (&$isEOF) {
$isEOF = feof($stream);
@@ -665,6 +676,8 @@ class File extends Node implements IFile {
}
protected function header($string) {
- \header($string);
+ if (!\OC::$CLI) {
+ \header($string);
+ }
}
}
diff --git a/apps/dav/lib/Upload/ChunkingPlugin.php b/apps/dav/lib/Upload/ChunkingPlugin.php
index 35487f61429..5a8d762de80 100644
--- a/apps/dav/lib/Upload/ChunkingPlugin.php
+++ b/apps/dav/lib/Upload/ChunkingPlugin.php
@@ -23,7 +23,10 @@
namespace OCA\DAV\Upload;
+use OCA\DAV\Connector\Sabre\Directory;
use Sabre\DAV\Exception\BadRequest;
+use Sabre\DAV\Exception\NotFound;
+use Sabre\DAV\INode;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;
@@ -45,6 +48,9 @@ class ChunkingPlugin extends ServerPlugin {
/**
* @param string $sourcePath source path
* @param string $destination destination path
+ * @return bool|void
+ * @throws BadRequest
+ * @throws NotFound
*/
public function beforeMove($sourcePath, $destination) {
$this->sourceNode = $this->server->tree->getNodeForPath($sourcePath);
@@ -53,6 +59,16 @@ class ChunkingPlugin extends ServerPlugin {
return;
}
+ try {
+ /** @var INode $destinationNode */
+ $destinationNode = $this->server->tree->getNodeForPath($destination);
+ if ($destinationNode instanceof Directory) {
+ throw new BadRequest("The given destination $destination is a directory.");
+ }
+ } catch (NotFound $e) {
+ // If the destination does not exist yet it's not a directory either ;)
+ }
+
$this->verifySize();
return $this->performMove($sourcePath, $destination);
}
diff --git a/apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php b/apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php
index 8de32ad8c35..e662f4651a0 100644
--- a/apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php
+++ b/apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php
@@ -31,6 +31,7 @@ use OCA\DAV\CalDAV\WebcalCaching\RefreshWebcalService;
use OCP\Http\Client\IClient;
use OCP\Http\Client\IClientService;
use OCP\Http\Client\IResponse;
+use OCP\Http\Client\LocalServerException;
use OCP\IConfig;
use OCP\ILogger;
use PHPUnit\Framework\MockObject\MockObject;
@@ -170,8 +171,12 @@ class RefreshWebcalServiceTest extends TestCase {
* @param string $source
*/
public function testRunLocalURL($source) {
- $refreshWebcalService = new RefreshWebcalService($this->caldavBackend,
- $this->clientService, $this->config, $this->logger);
+ $refreshWebcalService = new RefreshWebcalService(
+ $this->caldavBackend,
+ $this->clientService,
+ $this->config,
+ $this->logger
+ );
$this->caldavBackend->expects($this->once())
->method('getSubscriptionsForUser')
@@ -199,8 +204,13 @@ class RefreshWebcalServiceTest extends TestCase {
->with('dav', 'webcalAllowLocalAccess', 'no')
->willReturn('no');
- $client->expects($this->never())
- ->method('get');
+ $client->expects($this->once())
+ ->method('get')
+ ->willThrowException(new LocalServerException());
+
+ $this->logger->expects($this->once())
+ ->method('logException')
+ ->with($this->isInstanceOf(LocalServerException::class), $this->anything());
$refreshWebcalService->refreshSubscription('principals/users/testuser', 'sub123');
}
@@ -221,7 +231,42 @@ class RefreshWebcalServiceTest extends TestCase {
['10.0.0.1'],
['another-host.local'],
['service.localhost'],
- ['!@#$'], // test invalid url
];
}
+
+ public function testInvalidUrl() {
+ $refreshWebcalService = new RefreshWebcalService($this->caldavBackend,
+ $this->clientService, $this->config, $this->logger);
+
+ $this->caldavBackend->expects($this->once())
+ ->method('getSubscriptionsForUser')
+ ->with('principals/users/testuser')
+ ->willReturn([
+ [
+ 'id' => 42,
+ 'uri' => 'sub123',
+ 'refreshreate' => 'P1H',
+ 'striptodos' => 1,
+ 'stripalarms' => 1,
+ 'stripattachments' => 1,
+ 'source' => '!@#$'
+ ],
+ ]);
+
+ $client = $this->createMock(IClient::class);
+ $this->clientService->expects($this->once())
+ ->method('newClient')
+ ->with()
+ ->willReturn($client);
+
+ $this->config->expects($this->once())
+ ->method('getAppValue')
+ ->with('dav', 'webcalAllowLocalAccess', 'no')
+ ->willReturn('no');
+
+ $client->expects($this->never())
+ ->method('get');
+
+ $refreshWebcalService->refreshSubscription('principals/users/testuser', 'sub123');
+ }
}
diff --git a/apps/dav/tests/unit/Upload/ChunkingPluginTest.php b/apps/dav/tests/unit/Upload/ChunkingPluginTest.php
index abbded089db..3a3fcec66d6 100644
--- a/apps/dav/tests/unit/Upload/ChunkingPluginTest.php
+++ b/apps/dav/tests/unit/Upload/ChunkingPluginTest.php
@@ -27,6 +27,7 @@ namespace OCA\DAV\Tests\unit\Upload;
use OCA\DAV\Connector\Sabre\Directory;
use OCA\DAV\Upload\ChunkingPlugin;
use OCA\DAV\Upload\FutureFile;
+use Sabre\DAV\Exception\NotFound;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
use Test\TestCase;
@@ -87,16 +88,41 @@ class ChunkingPluginTest extends TestCase {
$this->assertNull($this->plugin->beforeMove('source', 'target'));
}
+ public function testBeforeMoveDestinationIsDirectory() {
+ $this->expectException(\Sabre\DAV\Exception\BadRequest::class);
+ $this->expectExceptionMessage('The given destination target is a directory.');
+
+ $sourceNode = $this->createMock(FutureFile::class);
+ $targetNode = $this->createMock(Directory::class);
+
+ $this->tree->expects($this->at(0))
+ ->method('getNodeForPath')
+ ->with('source')
+ ->willReturn($sourceNode);
+ $this->tree->expects($this->at(1))
+ ->method('getNodeForPath')
+ ->with('target')
+ ->willReturn($targetNode);
+ $this->response->expects($this->never())
+ ->method('setStatus');
+
+ $this->assertNull($this->plugin->beforeMove('source', 'target'));
+ }
+
public function testBeforeMoveFutureFileSkipNonExisting() {
$sourceNode = $this->createMock(FutureFile::class);
$sourceNode->expects($this->once())
->method('getSize')
->willReturn(4);
- $this->tree->expects($this->any())
+ $this->tree->expects($this->at(0))
->method('getNodeForPath')
->with('source')
->willReturn($sourceNode);
+ $this->tree->expects($this->at(1))
+ ->method('getNodeForPath')
+ ->with('target')
+ ->willThrowException(new NotFound());
$this->tree->expects($this->any())
->method('nodeExists')
->with('target')
@@ -117,10 +143,14 @@ class ChunkingPluginTest extends TestCase {
->method('getSize')
->willReturn(4);
- $this->tree->expects($this->any())
+ $this->tree->expects($this->at(0))
->method('getNodeForPath')
->with('source')
->willReturn($sourceNode);
+ $this->tree->expects($this->at(1))
+ ->method('getNodeForPath')
+ ->with('target')
+ ->willThrowException(new NotFound());
$this->tree->expects($this->any())
->method('nodeExists')
->with('target')
@@ -143,7 +173,7 @@ class ChunkingPluginTest extends TestCase {
$this->assertFalse($this->plugin->beforeMove('source', 'target'));
}
-
+
public function testBeforeMoveSizeIsWrong() {
$this->expectException(\Sabre\DAV\Exception\BadRequest::class);
$this->expectExceptionMessage('Chunks on server do not sum up to 4 but to 3 bytes');
@@ -153,10 +183,14 @@ class ChunkingPluginTest extends TestCase {
->method('getSize')
->willReturn(3);
- $this->tree->expects($this->any())
+ $this->tree->expects($this->at(0))
->method('getNodeForPath')
->with('source')
->willReturn($sourceNode);
+ $this->tree->expects($this->at(1))
+ ->method('getNodeForPath')
+ ->with('target')
+ ->willThrowException(new NotFound());
$this->request->expects($this->once())
->method('getHeader')
->with('OC-Total-Length')
diff --git a/apps/federation/l10n/vi.js b/apps/federation/l10n/vi.js
new file mode 100644
index 00000000000..2b471acb968
--- /dev/null
+++ b/apps/federation/l10n/vi.js
@@ -0,0 +1,17 @@
+OC.L10N.register(
+ "federation",
+ {
+ "Added to the list of trusted servers" : "Đã thêm vào danh sách của các máy chủ được tin tưởng",
+ "Server is already in the list of trusted servers." : "Máy chủ đã ở trong danh sách của các máy chủ được tin tưởng",
+ "No server to federate with found" : "Không tìm thấy máy chủ để liên kết Liên Bang với",
+ "Could not add server" : "Không thể thêm máy chủ",
+ "Federation" : "Kết nối Liên Bang ",
+ "Federation allows you to connect with other trusted servers to exchange the user directory." : "Kết nối Liên Bang cho phép bạn có thể kết nối với các máy chủ được tin tưởng khác để trao đổi chỉ mục người dùng",
+ "Federation allows you to connect with other trusted servers to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Kết nối Liên Bang cho phép bạn kết nối với các máy chủ tin tưởng khác để trao đổi chỉ mục người dùng. Lấy ví dụ, kết nối này sẽ được dùng để tự-động-điền các người dùng bên ngoài cho các chia sẻ Liên Bang.",
+ "Trusted servers" : "Các máy chủ được tin tưởng",
+ "Add server automatically once a federated share was created successfully" : "Thêm máy chủ một cách tự động mỗi khi một chia sẻ Liên Bang được tạo thành công",
+ "+ Add trusted server" : "+ Thêm máy chủ được tin cậy",
+ "Trusted server" : "Máy chủ được tin cậy",
+ "Add" : "Thêm"
+},
+"nplurals=1; plural=0;");
diff --git a/apps/federation/l10n/vi.json b/apps/federation/l10n/vi.json
new file mode 100644
index 00000000000..b8a282adc49
--- /dev/null
+++ b/apps/federation/l10n/vi.json
@@ -0,0 +1,15 @@
+{ "translations": {
+ "Added to the list of trusted servers" : "Đã thêm vào danh sách của các máy chủ được tin tưởng",
+ "Server is already in the list of trusted servers." : "Máy chủ đã ở trong danh sách của các máy chủ được tin tưởng",
+ "No server to federate with found" : "Không tìm thấy máy chủ để liên kết Liên Bang với",
+ "Could not add server" : "Không thể thêm máy chủ",
+ "Federation" : "Kết nối Liên Bang ",
+ "Federation allows you to connect with other trusted servers to exchange the user directory." : "Kết nối Liên Bang cho phép bạn có thể kết nối với các máy chủ được tin tưởng khác để trao đổi chỉ mục người dùng",
+ "Federation allows you to connect with other trusted servers to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Kết nối Liên Bang cho phép bạn kết nối với các máy chủ tin tưởng khác để trao đổi chỉ mục người dùng. Lấy ví dụ, kết nối này sẽ được dùng để tự-động-điền các người dùng bên ngoài cho các chia sẻ Liên Bang.",
+ "Trusted servers" : "Các máy chủ được tin tưởng",
+ "Add server automatically once a federated share was created successfully" : "Thêm máy chủ một cách tự động mỗi khi một chia sẻ Liên Bang được tạo thành công",
+ "+ Add trusted server" : "+ Thêm máy chủ được tin cậy",
+ "Trusted server" : "Máy chủ được tin cậy",
+ "Add" : "Thêm"
+},"pluralForm" :"nplurals=1; plural=0;"
+} \ No newline at end of file
diff --git a/apps/files/l10n/vi.js b/apps/files/l10n/vi.js
index a2bc643f1ab..00faadee70d 100644
--- a/apps/files/l10n/vi.js
+++ b/apps/files/l10n/vi.js
@@ -14,7 +14,10 @@ OC.L10N.register(
"Home" : "Nhà",
"Close" : "Đóng",
"Could not create folder \"{dir}\"" : "Không thể tạo thư mục “{dir}”",
+ "This will stop your current uploads." : "Hành động này sẽ dừng các tải lên hiện hành.",
"Upload cancelled." : "Hủy tải lên",
+ "Processing files …" : "Đang xử lý các tệp tin...",
+ "…" : "...",
"Unable to upload {filename} as it is a directory or has 0 bytes" : "không thể tải {filename} lên do nó là một thư mục hoặc có kích thước bằng 0 byte",
"Not enough free space, you are uploading {size1} but only {size2} is left" : "Không đủ dung lượng trống, bạn đang tải {size1} nhưng chỉ còn {size2} trống",
"Target folder \"{dir}\" does not exist any more" : "Thư mục đích \"{dir}\" không còn tồn tại",
@@ -110,6 +113,7 @@ OC.L10N.register(
"A file or folder has been <strong>restored</strong>" : "Tệp hoặc thư mục đã được <strong>khôi phục</strong>",
"Unlimited" : "Không giới hạn",
"Upload (max. %s)" : "Tải lên (tối đa. %s)",
+ "Accept" : "Đồng ý",
"Change" : "Chỉnh sửa",
"Tags" : "Nhãn",
"%1$s of %2$s used" : "%1$s trên %2$s đã sử dụng",
diff --git a/apps/files/l10n/vi.json b/apps/files/l10n/vi.json
index 01fa0d9aee0..58c928d22a2 100644
--- a/apps/files/l10n/vi.json
+++ b/apps/files/l10n/vi.json
@@ -12,7 +12,10 @@
"Home" : "Nhà",
"Close" : "Đóng",
"Could not create folder \"{dir}\"" : "Không thể tạo thư mục “{dir}”",
+ "This will stop your current uploads." : "Hành động này sẽ dừng các tải lên hiện hành.",
"Upload cancelled." : "Hủy tải lên",
+ "Processing files …" : "Đang xử lý các tệp tin...",
+ "…" : "...",
"Unable to upload {filename} as it is a directory or has 0 bytes" : "không thể tải {filename} lên do nó là một thư mục hoặc có kích thước bằng 0 byte",
"Not enough free space, you are uploading {size1} but only {size2} is left" : "Không đủ dung lượng trống, bạn đang tải {size1} nhưng chỉ còn {size2} trống",
"Target folder \"{dir}\" does not exist any more" : "Thư mục đích \"{dir}\" không còn tồn tại",
@@ -108,6 +111,7 @@
"A file or folder has been <strong>restored</strong>" : "Tệp hoặc thư mục đã được <strong>khôi phục</strong>",
"Unlimited" : "Không giới hạn",
"Upload (max. %s)" : "Tải lên (tối đa. %s)",
+ "Accept" : "Đồng ý",
"Change" : "Chỉnh sửa",
"Tags" : "Nhãn",
"%1$s of %2$s used" : "%1$s trên %2$s đã sử dụng",
diff --git a/apps/files_external/l10n/pl.js b/apps/files_external/l10n/pl.js
index af3c76c7a1b..8651afbca3a 100644
--- a/apps/files_external/l10n/pl.js
+++ b/apps/files_external/l10n/pl.js
@@ -6,7 +6,7 @@ OC.L10N.register(
"System" : "System",
"Grant access" : "Udziel dostępu",
"Error configuring OAuth1" : "Błąd konfiguracji OAuth1",
- "Please provide a valid app key and secret." : "Proszę podać prawidłowy klucz aplikacji i klucz sekretny.",
+ "Please provide a valid app key and secret." : "Podaj prawidłowy klucz aplikacji i klucz tajny.",
"Error configuring OAuth2" : "Błąd konfiguracji OAuth2",
"Generate keys" : "Wygeneruj klucze",
"Error generating key pair" : "Błąd podczas generowania pary kluczy",
@@ -54,7 +54,7 @@ OC.L10N.register(
"%s" : "%s",
"Storage with ID \"%d\" is not user editable" : "Magazyn o ID \"%d\" nie może być edytowany przez użytkownika",
"Access key" : "Klucz dostępu",
- "Secret key" : "Sekretny klucz",
+ "Secret key" : "Tajny klucz",
"Builtin" : "Wbudowane",
"None" : "Nic",
"OAuth1" : "OAuth1",
@@ -101,7 +101,7 @@ OC.L10N.register(
"Nextcloud" : "Nextcloud",
"SFTP" : "SFTP",
"Root" : "Root",
- "SFTP with secret key login" : "Logowanie prywatnym kluczem do SFTP",
+ "SFTP with secret key login" : "Logowanie tajnym kluczem do SFTP",
"SMB / CIFS" : "SMB/CIFS",
"Share" : "Udostępnij",
"Show hidden files" : "Pokaż ukryte pliki",
diff --git a/apps/files_external/l10n/pl.json b/apps/files_external/l10n/pl.json
index 26887c02117..134b10456c6 100644
--- a/apps/files_external/l10n/pl.json
+++ b/apps/files_external/l10n/pl.json
@@ -4,7 +4,7 @@
"System" : "System",
"Grant access" : "Udziel dostępu",
"Error configuring OAuth1" : "Błąd konfiguracji OAuth1",
- "Please provide a valid app key and secret." : "Proszę podać prawidłowy klucz aplikacji i klucz sekretny.",
+ "Please provide a valid app key and secret." : "Podaj prawidłowy klucz aplikacji i klucz tajny.",
"Error configuring OAuth2" : "Błąd konfiguracji OAuth2",
"Generate keys" : "Wygeneruj klucze",
"Error generating key pair" : "Błąd podczas generowania pary kluczy",
@@ -52,7 +52,7 @@
"%s" : "%s",
"Storage with ID \"%d\" is not user editable" : "Magazyn o ID \"%d\" nie może być edytowany przez użytkownika",
"Access key" : "Klucz dostępu",
- "Secret key" : "Sekretny klucz",
+ "Secret key" : "Tajny klucz",
"Builtin" : "Wbudowane",
"None" : "Nic",
"OAuth1" : "OAuth1",
@@ -99,7 +99,7 @@
"Nextcloud" : "Nextcloud",
"SFTP" : "SFTP",
"Root" : "Root",
- "SFTP with secret key login" : "Logowanie prywatnym kluczem do SFTP",
+ "SFTP with secret key login" : "Logowanie tajnym kluczem do SFTP",
"SMB / CIFS" : "SMB/CIFS",
"Share" : "Udostępnij",
"Show hidden files" : "Pokaż ukryte pliki",
diff --git a/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php b/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php
index c8a78f52c41..ee6db4818a6 100644
--- a/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php
+++ b/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php
@@ -46,6 +46,7 @@ class OpenStackV3 extends AuthMechanism {
new DefinitionParameter('domain', $l->t('Domain')),
(new DefinitionParameter('password', $l->t('Password')))
->setType(DefinitionParameter::VALUE_PASSWORD),
+ new DefinitionParameter('tenant', $l->t('Tenant name')),
new DefinitionParameter('url', $l->t('Identity endpoint URL'))
])
;
diff --git a/apps/files_external/lib/Lib/Backend/Swift.php b/apps/files_external/lib/Lib/Backend/Swift.php
index 25ed72337a1..5ac4346b422 100644
--- a/apps/files_external/lib/Lib/Backend/Swift.php
+++ b/apps/files_external/lib/Lib/Backend/Swift.php
@@ -44,8 +44,7 @@ class Swift extends Backend {
->addParameters([
(new DefinitionParameter('service_name', $l->t('Service name')))
->setFlag(DefinitionParameter::FLAG_OPTIONAL),
- (new DefinitionParameter('region', $l->t('Region')))
- ->setFlag(DefinitionParameter::FLAG_OPTIONAL),
+ new DefinitionParameter('region', $l->t('Region')),
new DefinitionParameter('bucket', $l->t('Bucket')),
(new DefinitionParameter('timeout', $l->t('Request timeout (seconds)')))
->setFlag(DefinitionParameter::FLAG_OPTIONAL),
diff --git a/apps/files_sharing/lib/Controller/ExternalSharesController.php b/apps/files_sharing/lib/Controller/ExternalSharesController.php
index c5dd21cda30..96b9ebffac8 100644
--- a/apps/files_sharing/lib/Controller/ExternalSharesController.php
+++ b/apps/files_sharing/lib/Controller/ExternalSharesController.php
@@ -131,7 +131,7 @@ class ExternalSharesController extends Controller {
* @return DataResponse
*/
public function testRemote($remote) {
- if (strpos($remote, '#') !== false || strpos($remote, '?') !== false) {
+ if (strpos($remote, '#') !== false || strpos($remote, '?') !== false || strpos($remote, ';') !== false) {
return new DataResponse(false);
}
diff --git a/apps/files_sharing/tests/Controller/ExternalShareControllerTest.php b/apps/files_sharing/tests/Controller/ExternalShareControllerTest.php
index 9d8ee9a9d42..d6a4ee8d4f3 100644
--- a/apps/files_sharing/tests/Controller/ExternalShareControllerTest.php
+++ b/apps/files_sharing/tests/Controller/ExternalShareControllerTest.php
@@ -162,6 +162,7 @@ class ExternalShareControllerTest extends \Test\TestCase {
return [
['nextcloud.com?query'],
['nextcloud.com/#anchor'],
+ ['nextcloud.com/;tomcat'],
];
}
diff --git a/apps/provisioning_api/tests/Controller/GroupsControllerTest.php b/apps/provisioning_api/tests/Controller/GroupsControllerTest.php
index 34bcdd4e645..72f0cd5537b 100644
--- a/apps/provisioning_api/tests/Controller/GroupsControllerTest.php
+++ b/apps/provisioning_api/tests/Controller/GroupsControllerTest.php
@@ -558,7 +558,7 @@ class GroupsControllerTest extends \Test\TestCase {
$this->userManager->expects($this->any())
->method('get')
- ->willReturnCallback(function(string $uid) use ($users) {
+ ->willReturnCallback(function (string $uid) use ($users) {
return isset($users[$uid]) ? $users[$uid] : null;
});
diff --git a/apps/settings/l10n/cs.js b/apps/settings/l10n/cs.js
index 9c4133be850..bd27612264d 100644
--- a/apps/settings/l10n/cs.js
+++ b/apps/settings/l10n/cs.js
@@ -47,6 +47,7 @@ OC.L10N.register(
"{actor} changed your password" : "{actor} změnil(a) vaše heslo",
"You changed your password" : "Změnili jste si své heslo",
"Your password was reset by an administrator" : "Vaše heslo bylo resetováno správcem",
+ "Your password was reset" : "Vaše heslo bylo nastaveno znovu",
"{actor} changed your email address" : "{actor} změnil(a) vaši e-mailovou adresu",
"You changed your email address" : "Změnili jste si svou e-mailovou adresu",
"Your email address was changed by an administrator" : "Vaše e-mailová adresa byla změněna správcem",
@@ -88,6 +89,7 @@ OC.L10N.register(
"%1$s changed your password on %2$s." : "%1$s změnil(a) vaše heslo na %2$s.",
"Your password on %s was changed." : "Vaše heslo na %s bylo změněno.",
"Your password on %s was reset by an administrator." : "Vaše heslo na %s bylo resetováno správcem.",
+ "Your password on %s was reset." : "Vaše heslo na %s bylo nastaveno znovu.",
"Password for %1$s changed on %2$s" : "Heslo pro %1$s na %2$s změněno ",
"Password changed for %s" : "Změna hesla pro %s",
"If you did not request this, please contact an administrator." : "Pokud jste o toto nežádali, obraťte se na správce.",
diff --git a/apps/settings/l10n/cs.json b/apps/settings/l10n/cs.json
index d866ffdb0dd..6c0d9a7e434 100644
--- a/apps/settings/l10n/cs.json
+++ b/apps/settings/l10n/cs.json
@@ -45,6 +45,7 @@
"{actor} changed your password" : "{actor} změnil(a) vaše heslo",
"You changed your password" : "Změnili jste si své heslo",
"Your password was reset by an administrator" : "Vaše heslo bylo resetováno správcem",
+ "Your password was reset" : "Vaše heslo bylo nastaveno znovu",
"{actor} changed your email address" : "{actor} změnil(a) vaši e-mailovou adresu",
"You changed your email address" : "Změnili jste si svou e-mailovou adresu",
"Your email address was changed by an administrator" : "Vaše e-mailová adresa byla změněna správcem",
@@ -86,6 +87,7 @@
"%1$s changed your password on %2$s." : "%1$s změnil(a) vaše heslo na %2$s.",
"Your password on %s was changed." : "Vaše heslo na %s bylo změněno.",
"Your password on %s was reset by an administrator." : "Vaše heslo na %s bylo resetováno správcem.",
+ "Your password on %s was reset." : "Vaše heslo na %s bylo nastaveno znovu.",
"Password for %1$s changed on %2$s" : "Heslo pro %1$s na %2$s změněno ",
"Password changed for %s" : "Změna hesla pro %s",
"If you did not request this, please contact an administrator." : "Pokud jste o toto nežádali, obraťte se na správce.",
diff --git a/apps/settings/l10n/de.js b/apps/settings/l10n/de.js
index b4177c4e3f1..1fad1bd92a8 100644
--- a/apps/settings/l10n/de.js
+++ b/apps/settings/l10n/de.js
@@ -47,6 +47,7 @@ OC.L10N.register(
"{actor} changed your password" : "{actor} hat Dein Passwort geändert",
"You changed your password" : "Du hast Dein Passwort geändert",
"Your password was reset by an administrator" : "Dein Passwort wurde vom Administrator zurückgesetzt",
+ "Your password was reset" : "Dein Passwort wurde zurückgesetzt",
"{actor} changed your email address" : "{actor} hat Deine E-Mail-Adresse geändert",
"You changed your email address" : "Du hast Deine E-Mail-Adresse geändert",
"Your email address was changed by an administrator" : "Deine E-Mail-Adresse wurde von einem Administrator geändert",
@@ -88,6 +89,7 @@ OC.L10N.register(
"%1$s changed your password on %2$s." : "%1$s hat Dein Passwort auf %2$s geändert.",
"Your password on %s was changed." : "Dein Passwort auf %s wurde geändert.",
"Your password on %s was reset by an administrator." : "Dein Passwort auf %s wurde vom Administrator zurückgesetzt.",
+ "Your password on %s was reset." : "Dein Passwort auf %s wurde zurückgesetzt",
"Password for %1$s changed on %2$s" : "Passwort für %1$s geändert auf %2$s",
"Password changed for %s" : "Passwort geändert für %s",
"If you did not request this, please contact an administrator." : "Wenn Du das nicht angefordert haben solltest, wende Dich bitte an den Administrator.",
diff --git a/apps/settings/l10n/de.json b/apps/settings/l10n/de.json
index dceba38e047..01cb644d3a2 100644
--- a/apps/settings/l10n/de.json
+++ b/apps/settings/l10n/de.json
@@ -45,6 +45,7 @@
"{actor} changed your password" : "{actor} hat Dein Passwort geändert",
"You changed your password" : "Du hast Dein Passwort geändert",
"Your password was reset by an administrator" : "Dein Passwort wurde vom Administrator zurückgesetzt",
+ "Your password was reset" : "Dein Passwort wurde zurückgesetzt",
"{actor} changed your email address" : "{actor} hat Deine E-Mail-Adresse geändert",
"You changed your email address" : "Du hast Deine E-Mail-Adresse geändert",
"Your email address was changed by an administrator" : "Deine E-Mail-Adresse wurde von einem Administrator geändert",
@@ -86,6 +87,7 @@
"%1$s changed your password on %2$s." : "%1$s hat Dein Passwort auf %2$s geändert.",
"Your password on %s was changed." : "Dein Passwort auf %s wurde geändert.",
"Your password on %s was reset by an administrator." : "Dein Passwort auf %s wurde vom Administrator zurückgesetzt.",
+ "Your password on %s was reset." : "Dein Passwort auf %s wurde zurückgesetzt",
"Password for %1$s changed on %2$s" : "Passwort für %1$s geändert auf %2$s",
"Password changed for %s" : "Passwort geändert für %s",
"If you did not request this, please contact an administrator." : "Wenn Du das nicht angefordert haben solltest, wende Dich bitte an den Administrator.",
diff --git a/apps/settings/l10n/de_DE.js b/apps/settings/l10n/de_DE.js
index d79bc21263e..1c3a136047f 100644
--- a/apps/settings/l10n/de_DE.js
+++ b/apps/settings/l10n/de_DE.js
@@ -47,6 +47,7 @@ OC.L10N.register(
"{actor} changed your password" : "{actor} hat Ihr Passwort geändert",
"You changed your password" : "Sie haben Ihr Passwort geändert",
"Your password was reset by an administrator" : "Ihr Passwort wurde vom Administrator zurückgesetzt",
+ "Your password was reset" : "Ihr Passwort wurde zurückgesetzt",
"{actor} changed your email address" : "{actor} hat Ihre E-Mail-Adresse geändert",
"You changed your email address" : "Sie haben Ihre E-Mail-Adresse geändert",
"Your email address was changed by an administrator" : "Ihre E-Mail-Adresse wurde von einem Administrator geändert",
@@ -88,6 +89,7 @@ OC.L10N.register(
"%1$s changed your password on %2$s." : "%1$s hat Ihr Passwort auf %2$s geändert.",
"Your password on %s was changed." : "Ihr Passwort auf %s wurde geändert.",
"Your password on %s was reset by an administrator." : "Ihr Passwort auf %s wurde vom Administrator zurückgesetzt.",
+ "Your password on %s was reset." : "Ihr Passwort auf %s wurde zurückgesetzt",
"Password for %1$s changed on %2$s" : "Passwort für %1$s geändert auf %2$s",
"Password changed for %s" : "Passwort geändert für %s ",
"If you did not request this, please contact an administrator." : "Wenn Sie das nicht angefordert haben sollten, wenden Sie sich bitte an den Administrator.",
diff --git a/apps/settings/l10n/de_DE.json b/apps/settings/l10n/de_DE.json
index 5085e9bcabf..2447d1f905c 100644
--- a/apps/settings/l10n/de_DE.json
+++ b/apps/settings/l10n/de_DE.json
@@ -45,6 +45,7 @@
"{actor} changed your password" : "{actor} hat Ihr Passwort geändert",
"You changed your password" : "Sie haben Ihr Passwort geändert",
"Your password was reset by an administrator" : "Ihr Passwort wurde vom Administrator zurückgesetzt",
+ "Your password was reset" : "Ihr Passwort wurde zurückgesetzt",
"{actor} changed your email address" : "{actor} hat Ihre E-Mail-Adresse geändert",
"You changed your email address" : "Sie haben Ihre E-Mail-Adresse geändert",
"Your email address was changed by an administrator" : "Ihre E-Mail-Adresse wurde von einem Administrator geändert",
@@ -86,6 +87,7 @@
"%1$s changed your password on %2$s." : "%1$s hat Ihr Passwort auf %2$s geändert.",
"Your password on %s was changed." : "Ihr Passwort auf %s wurde geändert.",
"Your password on %s was reset by an administrator." : "Ihr Passwort auf %s wurde vom Administrator zurückgesetzt.",
+ "Your password on %s was reset." : "Ihr Passwort auf %s wurde zurückgesetzt",
"Password for %1$s changed on %2$s" : "Passwort für %1$s geändert auf %2$s",
"Password changed for %s" : "Passwort geändert für %s ",
"If you did not request this, please contact an administrator." : "Wenn Sie das nicht angefordert haben sollten, wenden Sie sich bitte an den Administrator.",
diff --git a/apps/settings/l10n/el.js b/apps/settings/l10n/el.js
index 79445c67f0e..fd922c98693 100644
--- a/apps/settings/l10n/el.js
+++ b/apps/settings/l10n/el.js
@@ -47,6 +47,7 @@ OC.L10N.register(
"{actor} changed your password" : "{actor} το συθηματικό σας άλλαξε",
"You changed your password" : "Αλλάξατε το συνθηματικό σας",
"Your password was reset by an administrator" : "Έχει γίνει επαναφορά του συνθηματικού σας από τον διαχειριστή",
+ "Your password was reset" : "Έγινε επαναφορά του κωδικού πρόσβασης",
"{actor} changed your email address" : "{actor} άλλαξε τη διεύθυνσή του ηλεκτρονικού ταχυδρομείου σας",
"You changed your email address" : "Έχετε αλλάξει τη διεύθυνση ηλεκτρονικού ταχυδρομείου σας",
"Your email address was changed by an administrator" : "Η διεύθυνση ηλεκτρονικής αλληλογραφίας άλλαξε από τον διαχειριστή",
@@ -88,6 +89,7 @@ OC.L10N.register(
"%1$s changed your password on %2$s." : "%1$sάλλαξε το συνθηματικό σε %2$s.",
"Your password on %s was changed." : "Ο κωδικός πρόσβασης στο %s έχει αλλάξει.",
"Your password on %s was reset by an administrator." : "Έχει γίνει επαναφορά του κωδικού πρόσβασης στο %s από τον διαχειριστή.",
+ "Your password on %s was reset." : "Έχει γίνει επαναφορά του κωδικού πρόσβασης στο %s. ",
"Password for %1$s changed on %2$s" : "Ο κωδικός πρόσβασης για το %1$s άλλαξε σε %2$s",
"Password changed for %s" : "Το συνθηματικό άλλαξε για τον %s",
"If you did not request this, please contact an administrator." : "Εάν δεν το αιτηθήκατε, παρακαλούμε επικοινωνήστε με τον διαχειριστή.",
diff --git a/apps/settings/l10n/el.json b/apps/settings/l10n/el.json
index 5640cd0a7ca..7dd5e02088a 100644
--- a/apps/settings/l10n/el.json
+++ b/apps/settings/l10n/el.json
@@ -45,6 +45,7 @@
"{actor} changed your password" : "{actor} το συθηματικό σας άλλαξε",
"You changed your password" : "Αλλάξατε το συνθηματικό σας",
"Your password was reset by an administrator" : "Έχει γίνει επαναφορά του συνθηματικού σας από τον διαχειριστή",
+ "Your password was reset" : "Έγινε επαναφορά του κωδικού πρόσβασης",
"{actor} changed your email address" : "{actor} άλλαξε τη διεύθυνσή του ηλεκτρονικού ταχυδρομείου σας",
"You changed your email address" : "Έχετε αλλάξει τη διεύθυνση ηλεκτρονικού ταχυδρομείου σας",
"Your email address was changed by an administrator" : "Η διεύθυνση ηλεκτρονικής αλληλογραφίας άλλαξε από τον διαχειριστή",
@@ -86,6 +87,7 @@
"%1$s changed your password on %2$s." : "%1$sάλλαξε το συνθηματικό σε %2$s.",
"Your password on %s was changed." : "Ο κωδικός πρόσβασης στο %s έχει αλλάξει.",
"Your password on %s was reset by an administrator." : "Έχει γίνει επαναφορά του κωδικού πρόσβασης στο %s από τον διαχειριστή.",
+ "Your password on %s was reset." : "Έχει γίνει επαναφορά του κωδικού πρόσβασης στο %s. ",
"Password for %1$s changed on %2$s" : "Ο κωδικός πρόσβασης για το %1$s άλλαξε σε %2$s",
"Password changed for %s" : "Το συνθηματικό άλλαξε για τον %s",
"If you did not request this, please contact an administrator." : "Εάν δεν το αιτηθήκατε, παρακαλούμε επικοινωνήστε με τον διαχειριστή.",
diff --git a/apps/settings/l10n/it.js b/apps/settings/l10n/it.js
index 523671ddb27..062e292d8a7 100644
--- a/apps/settings/l10n/it.js
+++ b/apps/settings/l10n/it.js
@@ -47,6 +47,7 @@ OC.L10N.register(
"{actor} changed your password" : "{actor} ha cambiato la tua password",
"You changed your password" : "Hai cambiato la tua password",
"Your password was reset by an administrator" : "La tua password è stata reimpostata da un amministratore",
+ "Your password was reset" : "La tua password è stata reimpostata",
"{actor} changed your email address" : "{actor} ha cambiato il tuo indirizzo email",
"You changed your email address" : "Hai cambiato il tuo indirizzo email",
"Your email address was changed by an administrator" : "Il tuo indirizzo email è stato cambiato da un amministratore",
@@ -88,6 +89,7 @@ OC.L10N.register(
"%1$s changed your password on %2$s." : "%1$s ha cambiato la tua password su %2$s.",
"Your password on %s was changed." : "La tua password su %s è stata modificata.",
"Your password on %s was reset by an administrator." : "La tua password su %s è stata reimpostata da un amministratore",
+ "Your password on %s was reset." : "La tua password su %s è stata reimpostata.",
"Password for %1$s changed on %2$s" : "Password per %1$s cambiata su %2$s",
"Password changed for %s" : "Password modificata per %s",
"If you did not request this, please contact an administrator." : "Se non lo hai richiesto, contatta un amministratore.",
diff --git a/apps/settings/l10n/it.json b/apps/settings/l10n/it.json
index 8d8ca2094c0..4614cc1340f 100644
--- a/apps/settings/l10n/it.json
+++ b/apps/settings/l10n/it.json
@@ -45,6 +45,7 @@
"{actor} changed your password" : "{actor} ha cambiato la tua password",
"You changed your password" : "Hai cambiato la tua password",
"Your password was reset by an administrator" : "La tua password è stata reimpostata da un amministratore",
+ "Your password was reset" : "La tua password è stata reimpostata",
"{actor} changed your email address" : "{actor} ha cambiato il tuo indirizzo email",
"You changed your email address" : "Hai cambiato il tuo indirizzo email",
"Your email address was changed by an administrator" : "Il tuo indirizzo email è stato cambiato da un amministratore",
@@ -86,6 +87,7 @@
"%1$s changed your password on %2$s." : "%1$s ha cambiato la tua password su %2$s.",
"Your password on %s was changed." : "La tua password su %s è stata modificata.",
"Your password on %s was reset by an administrator." : "La tua password su %s è stata reimpostata da un amministratore",
+ "Your password on %s was reset." : "La tua password su %s è stata reimpostata.",
"Password for %1$s changed on %2$s" : "Password per %1$s cambiata su %2$s",
"Password changed for %s" : "Password modificata per %s",
"If you did not request this, please contact an administrator." : "Se non lo hai richiesto, contatta un amministratore.",
diff --git a/apps/settings/l10n/pl.js b/apps/settings/l10n/pl.js
index 5f602c1321d..116af818273 100644
--- a/apps/settings/l10n/pl.js
+++ b/apps/settings/l10n/pl.js
@@ -47,6 +47,7 @@ OC.L10N.register(
"{actor} changed your password" : "{actor} zmienił Twoje hasło",
"You changed your password" : "Zmieniłeś swoje hasło",
"Your password was reset by an administrator" : "Twoje hasło zostało zresetowane przez administratora",
+ "Your password was reset" : "Twoje hasło zostało zresetowane",
"{actor} changed your email address" : "{actor} zmienił Twój adres e-mail",
"You changed your email address" : "Zmieniłeś swój adres e-mail",
"Your email address was changed by an administrator" : "Twój adres e-mail został zmieniony przez administratora",
@@ -88,6 +89,7 @@ OC.L10N.register(
"%1$s changed your password on %2$s." : "%1$s zmienił Twoje hasło w %2$s.",
"Your password on %s was changed." : "Twoje hasło w %s zostało zmienione.",
"Your password on %s was reset by an administrator." : "Twoje hasło w %s zostało zresetowane przez administratora",
+ "Your password on %s was reset." : "Twoje hasło w %s zostało zresetowane.",
"Password for %1$s changed on %2$s" : "Hasło dla %1$s zostało zmienione w %2$s",
"Password changed for %s" : "Hasło zmieniono dla %s",
"If you did not request this, please contact an administrator." : "Jeśli nie żądałeś tego, skontaktuj się z administratorem.",
diff --git a/apps/settings/l10n/pl.json b/apps/settings/l10n/pl.json
index 9756e20fa18..74257d0b457 100644
--- a/apps/settings/l10n/pl.json
+++ b/apps/settings/l10n/pl.json
@@ -45,6 +45,7 @@
"{actor} changed your password" : "{actor} zmienił Twoje hasło",
"You changed your password" : "Zmieniłeś swoje hasło",
"Your password was reset by an administrator" : "Twoje hasło zostało zresetowane przez administratora",
+ "Your password was reset" : "Twoje hasło zostało zresetowane",
"{actor} changed your email address" : "{actor} zmienił Twój adres e-mail",
"You changed your email address" : "Zmieniłeś swój adres e-mail",
"Your email address was changed by an administrator" : "Twój adres e-mail został zmieniony przez administratora",
@@ -86,6 +87,7 @@
"%1$s changed your password on %2$s." : "%1$s zmienił Twoje hasło w %2$s.",
"Your password on %s was changed." : "Twoje hasło w %s zostało zmienione.",
"Your password on %s was reset by an administrator." : "Twoje hasło w %s zostało zresetowane przez administratora",
+ "Your password on %s was reset." : "Twoje hasło w %s zostało zresetowane.",
"Password for %1$s changed on %2$s" : "Hasło dla %1$s zostało zmienione w %2$s",
"Password changed for %s" : "Hasło zmieniono dla %s",
"If you did not request this, please contact an administrator." : "Jeśli nie żądałeś tego, skontaktuj się z administratorem.",
diff --git a/apps/settings/l10n/pt_BR.js b/apps/settings/l10n/pt_BR.js
index 7fc97e1adca..5d098fecca0 100644
--- a/apps/settings/l10n/pt_BR.js
+++ b/apps/settings/l10n/pt_BR.js
@@ -47,6 +47,7 @@ OC.L10N.register(
"{actor} changed your password" : "{actor} alterou sua senha",
"You changed your password" : "Você alterou sua senha",
"Your password was reset by an administrator" : "Sua senha foi redefinida pelo administrador",
+ "Your password was reset" : "Sua senha foi redefinida",
"{actor} changed your email address" : "{actor} alterou seu endereço de e-mail",
"You changed your email address" : "Você alterou seu e-mail",
"Your email address was changed by an administrator" : "Seu e-mail foi alterado pelo administrador",
@@ -88,6 +89,7 @@ OC.L10N.register(
"%1$s changed your password on %2$s." : "%1$s mudou sua senha em %2$s.",
"Your password on %s was changed." : "Sua senha em %s foi alterada.",
"Your password on %s was reset by an administrator." : "Sua senha em %s foi redefinida por um administrador.",
+ "Your password on %s was reset." : "Sua senha em %s foi redefinida.",
"Password for %1$s changed on %2$s" : "Senha para %1$s alterada em %2$s",
"Password changed for %s" : "Senha alterada para %s",
"If you did not request this, please contact an administrator." : "Se você não solicitou isso, por favor contacte o administrador.",
diff --git a/apps/settings/l10n/pt_BR.json b/apps/settings/l10n/pt_BR.json
index c3f358ca2b9..175a1bb077d 100644
--- a/apps/settings/l10n/pt_BR.json
+++ b/apps/settings/l10n/pt_BR.json
@@ -45,6 +45,7 @@
"{actor} changed your password" : "{actor} alterou sua senha",
"You changed your password" : "Você alterou sua senha",
"Your password was reset by an administrator" : "Sua senha foi redefinida pelo administrador",
+ "Your password was reset" : "Sua senha foi redefinida",
"{actor} changed your email address" : "{actor} alterou seu endereço de e-mail",
"You changed your email address" : "Você alterou seu e-mail",
"Your email address was changed by an administrator" : "Seu e-mail foi alterado pelo administrador",
@@ -86,6 +87,7 @@
"%1$s changed your password on %2$s." : "%1$s mudou sua senha em %2$s.",
"Your password on %s was changed." : "Sua senha em %s foi alterada.",
"Your password on %s was reset by an administrator." : "Sua senha em %s foi redefinida por um administrador.",
+ "Your password on %s was reset." : "Sua senha em %s foi redefinida.",
"Password for %1$s changed on %2$s" : "Senha para %1$s alterada em %2$s",
"Password changed for %s" : "Senha alterada para %s",
"If you did not request this, please contact an administrator." : "Se você não solicitou isso, por favor contacte o administrador.",
diff --git a/apps/settings/l10n/vi.js b/apps/settings/l10n/vi.js
index c9a1d54075f..479a970472a 100644
--- a/apps/settings/l10n/vi.js
+++ b/apps/settings/l10n/vi.js
@@ -118,6 +118,7 @@ OC.L10N.register(
"Save changes" : "Lưu thay đổi",
"This app is supported via your current Nextcloud subscription." : "Ứng dụng này được hỗ trợ thông qua thuê bao Nextcloud hiện tại của bạn.",
"Supported" : "Đã hỗ trợ",
+ "Featured" : "Tính năng được trang bị",
"by" : "bởi",
"Update to {version}" : "Cập nhật tới {version}",
"Remove" : "Xóa",
@@ -254,6 +255,7 @@ OC.L10N.register(
"Upload new" : "Tải lên",
"Remove image" : "Xóa ",
"Details" : "Thông tin",
+ "Full name" : "Tên đầy đủ",
"Your email address" : "Email của bạn",
"Phone number" : "Số điện thoại",
"Address" : "Địa chỉ",
diff --git a/apps/settings/l10n/vi.json b/apps/settings/l10n/vi.json
index 4d16181c7e3..b27308fa34f 100644
--- a/apps/settings/l10n/vi.json
+++ b/apps/settings/l10n/vi.json
@@ -116,6 +116,7 @@
"Save changes" : "Lưu thay đổi",
"This app is supported via your current Nextcloud subscription." : "Ứng dụng này được hỗ trợ thông qua thuê bao Nextcloud hiện tại của bạn.",
"Supported" : "Đã hỗ trợ",
+ "Featured" : "Tính năng được trang bị",
"by" : "bởi",
"Update to {version}" : "Cập nhật tới {version}",
"Remove" : "Xóa",
@@ -252,6 +253,7 @@
"Upload new" : "Tải lên",
"Remove image" : "Xóa ",
"Details" : "Thông tin",
+ "Full name" : "Tên đầy đủ",
"Your email address" : "Email của bạn",
"Phone number" : "Số điện thoại",
"Address" : "Địa chỉ",
diff --git a/apps/settings/lib/Controller/CheckSetupController.php b/apps/settings/lib/Controller/CheckSetupController.php
index 02886d16f4d..b48ec4a45bb 100644
--- a/apps/settings/lib/Controller/CheckSetupController.php
+++ b/apps/settings/lib/Controller/CheckSetupController.php
@@ -521,7 +521,7 @@ Raw output
}
protected function hasOpcacheLoaded(): bool {
- return function_exists('opcache_get_status');
+ return extension_loaded('Zend OPcache');
}
/**
diff --git a/apps/theming/l10n/vi.js b/apps/theming/l10n/vi.js
index 68870d7aaf8..06467c619a3 100644
--- a/apps/theming/l10n/vi.js
+++ b/apps/theming/l10n/vi.js
@@ -20,6 +20,7 @@ OC.L10N.register(
"No file uploaded" : "Không có tệp nào được tải lên",
"Unsupported image type" : "Loại hình ảnh không được hỗ trợ",
"Theming" : "Điều chỉnh giao diện",
+ "Privacy policy" : "Chính sách riêng tư",
"Theming makes it possible to easily customize the look and feel of your instance and supported clients. This will be visible for all users." : "Điều chỉnh giao diện cho phép bạn có thể dễ dàng tùy biến bố cục trình bày của hệ thống. Khi thực hiện nó sẽ hiện hữu đối với tất cả người dùng",
"Name" : "Tên",
"Reset to default" : "Đặt lại về mặc định",
diff --git a/apps/theming/l10n/vi.json b/apps/theming/l10n/vi.json
index 7d37032e74a..ed775dcc5a0 100644
--- a/apps/theming/l10n/vi.json
+++ b/apps/theming/l10n/vi.json
@@ -18,6 +18,7 @@
"No file uploaded" : "Không có tệp nào được tải lên",
"Unsupported image type" : "Loại hình ảnh không được hỗ trợ",
"Theming" : "Điều chỉnh giao diện",
+ "Privacy policy" : "Chính sách riêng tư",
"Theming makes it possible to easily customize the look and feel of your instance and supported clients. This will be visible for all users." : "Điều chỉnh giao diện cho phép bạn có thể dễ dàng tùy biến bố cục trình bày của hệ thống. Khi thực hiện nó sẽ hiện hữu đối với tất cả người dùng",
"Name" : "Tên",
"Reset to default" : "Đặt lại về mặc định",
diff --git a/build/integration/run.sh b/build/integration/run.sh
index fc6e35f078b..4808ab58ef5 100755
--- a/build/integration/run.sh
+++ b/build/integration/run.sh
@@ -16,6 +16,8 @@ INSTALLED=$($OCC status | grep installed: | cut -d " " -f 5)
if [ "$INSTALLED" == "true" ]; then
# Disable bruteforce protection because the integration tests do trigger them
$OCC config:system:set auth.bruteforce.protection.enabled --value false --type bool
+ # Allow local remote urls otherwise we can not share
+ $OCC config:system:set allow_local_remote_servers --value true --type bool
else
if [ "$SCENARIO_TO_RUN" != "setup_features/setup.feature" ]; then
echo "Nextcloud instance needs to be installed" >&2
diff --git a/build/package-lock.json b/build/package-lock.json
index 9e7738e2ad6..6b96f63ec76 100644
--- a/build/package-lock.json
+++ b/build/package-lock.json
@@ -4,12 +4,165 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "@babel/code-frame": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
+ "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.8.3"
+ }
+ },
+ "@babel/generator": {
+ "version": "7.9.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz",
+ "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.9.5",
+ "jsesc": "^2.5.1",
+ "lodash": "^4.17.13",
+ "source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.9.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz",
+ "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-get-function-arity": "^7.8.3",
+ "@babel/template": "^7.8.3",
+ "@babel/types": "^7.9.5"
+ }
+ },
+ "@babel/helper-get-function-arity": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
+ "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.8.3"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
+ "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.8.3"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.9.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
+ "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
+ "dev": true
+ },
+ "@babel/highlight": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
+ "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.9.0",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ }
+ }
+ },
"@babel/parser": {
"version": "7.9.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz",
"integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==",
"dev": true
},
+ "@babel/template": {
+ "version": "7.8.6",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz",
+ "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.8.3",
+ "@babel/parser": "^7.8.6",
+ "@babel/types": "^7.8.6"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.9.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz",
+ "integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.8.3",
+ "@babel/generator": "^7.9.5",
+ "@babel/helper-function-name": "^7.9.5",
+ "@babel/helper-split-export-declaration": "^7.8.3",
+ "@babel/parser": "^7.9.0",
+ "@babel/types": "^7.9.5",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0",
+ "lodash": "^4.17.13"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/types": {
+ "version": "7.9.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz",
+ "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.9.5",
+ "lodash": "^4.17.13",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
"@sinonjs/commons": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.6.0.tgz",
@@ -755,6 +908,21 @@
"object-visit": "^1.0.0"
}
},
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
"colors": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
@@ -1159,16 +1327,47 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
+ "escodegen": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
+ "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
+ "dev": true,
+ "requires": {
+ "esprima": "^2.7.1",
+ "estraverse": "^1.9.1",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1",
+ "source-map": "~0.2.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
+ "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "amdefine": ">=0.0.4"
+ }
+ }
+ }
+ },
"esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "dev": true
+ },
+ "estraverse": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
+ "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
"dev": true
},
"esutils": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
- "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
"eventemitter3": {
@@ -1584,8 +1783,7 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"aproba": {
"version": "1.2.0",
@@ -1606,14 +1804,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -1622,20 +1818,17 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -1743,8 +1936,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -1756,7 +1948,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -1771,7 +1962,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -1867,8 +2057,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -1880,7 +2069,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -2003,7 +2191,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -2023,7 +2210,6 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -2052,8 +2238,7 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -2156,6 +2341,12 @@
}
}
},
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true
+ },
"globule": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
@@ -2308,6 +2499,12 @@
"integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
"dev": true
},
+ "html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
"http-errors": {
"version": "1.6.3",
"resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
@@ -2636,31 +2833,6 @@
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
},
- "escodegen": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
- "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
- "dev": true,
- "requires": {
- "esprima": "^2.7.1",
- "estraverse": "^1.9.1",
- "esutils": "^2.0.2",
- "optionator": "^0.8.1",
- "source-map": "~0.2.0"
- }
- },
- "esprima": {
- "version": "2.7.3",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
- "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
- "dev": true
- },
- "estraverse": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
- "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
- "dev": true
- },
"glob": {
"version": "5.0.15",
"resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
@@ -2680,16 +2852,6 @@
"integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
"dev": true
},
- "source-map": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
- "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
- "dev": true,
- "optional": true,
- "requires": {
- "amdefine": ">=0.0.4"
- }
- },
"supports-color": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
@@ -2707,6 +2869,105 @@
}
}
},
+ "istanbul-lib-coverage": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
+ "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==",
+ "dev": true
+ },
+ "istanbul-lib-instrument": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz",
+ "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==",
+ "dev": true,
+ "requires": {
+ "@babel/generator": "^7.4.0",
+ "@babel/parser": "^7.4.3",
+ "@babel/template": "^7.4.0",
+ "@babel/traverse": "^7.4.3",
+ "@babel/types": "^7.4.0",
+ "istanbul-lib-coverage": "^2.0.5",
+ "semver": "^6.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "istanbul-lib-report": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz",
+ "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==",
+ "dev": true,
+ "requires": {
+ "istanbul-lib-coverage": "^2.0.5",
+ "make-dir": "^2.1.0",
+ "supports-color": "^6.1.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "istanbul-lib-source-maps": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz",
+ "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^2.0.5",
+ "make-dir": "^2.1.0",
+ "rimraf": "^2.6.3",
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "istanbul-reports": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz",
+ "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==",
+ "dev": true,
+ "requires": {
+ "html-escaper": "^2.0.0"
+ }
+ },
"jasmine-core": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.5.2.tgz",
@@ -2728,6 +2989,12 @@
"integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==",
"dev": true
},
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
"js-yaml": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
@@ -2736,6 +3003,14 @@
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ }
}
},
"js2xmlparser": {
@@ -2795,6 +3070,12 @@
}
}
},
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true
+ },
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
@@ -2883,14 +3164,19 @@
}
},
"karma-coverage": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.2.tgz",
- "integrity": "sha512-eQawj4Cl3z/CjxslYy9ariU4uDh7cCNFZHNWXWRpl0pNeblY/4wHR7M7boTYXWrn9bY0z2pZmr11eKje/S/hIw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.0.1.tgz",
+ "integrity": "sha512-SnFkHsnLsaXfxkey51rRN9JDLAEKYW2Lb0qOEvcruukk0NkSNDkjobNDZPt9Ni3kIhLZkLtpGOz661hN7OaZvQ==",
"dev": true,
"requires": {
"dateformat": "^1.0.6",
"istanbul": "^0.4.0",
- "lodash": "^4.17.0",
+ "istanbul-lib-coverage": "^2.0.5",
+ "istanbul-lib-instrument": "^3.3.0",
+ "istanbul-lib-report": "^2.0.8",
+ "istanbul-lib-source-maps": "^3.0.6",
+ "istanbul-reports": "^2.2.4",
+ "lodash": "^4.17.11",
"minimatch": "^3.0.0",
"source-map": "^0.5.1"
},
@@ -3081,6 +3367,24 @@
"yallist": "^2.1.2"
}
},
+ "make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "requires": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true
+ }
+ }
+ },
"map-cache": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
@@ -3227,7 +3531,6 @@
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
"dev": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -3237,8 +3540,7 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -3587,25 +3889,17 @@
}
},
"optionator": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
- "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
"dev": true,
"requires": {
"deep-is": "~0.1.3",
- "fast-levenshtein": "~2.0.4",
+ "fast-levenshtein": "~2.0.6",
"levn": "~0.3.0",
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
- "wordwrap": "~1.0.0"
- },
- "dependencies": {
- "wordwrap": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
- "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
- "dev": true
- }
+ "word-wrap": "~1.2.3"
}
},
"os-homedir": {
@@ -4635,6 +4929,12 @@
"integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=",
"dev": true
},
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+ "dev": true
+ },
"to-object-path": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
@@ -4944,6 +5244,12 @@
"string-width": "^1.0.2 || 2"
}
},
+ "word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true
+ },
"wordwrap": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
diff --git a/build/package.json b/build/package.json
index 239c0e2468d..5fe6457390d 100644
--- a/build/package.json
+++ b/build/package.json
@@ -16,7 +16,7 @@
"jasmine-sinon": "^0.4.0",
"jsdoc": "^3.6.4",
"karma": "^3.1.4",
- "karma-coverage": "*",
+ "karma-coverage": "2.0.1",
"karma-jasmine": "^1.1.2",
"karma-jasmine-sinon": "^1.0.4",
"karma-junit-reporter": "^1.2.0",
diff --git a/config/config.sample.php b/config/config.sample.php
index 9e5f7b6baf6..00e3a6779fd 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -559,6 +559,13 @@ $CONFIG = [
'proxyexclude' => [],
/**
+ * Allow remote servers with local addresses e.g. in federated shares, webcal services and more
+ *
+ * Defaults to false
+ */
+'allow_local_remote_servers' => true,
+
+/**
* Deleted Items (trash bin)
*
* These parameters control the Deleted files app.
diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php
index 0fcadd21c8a..a2828599251 100644
--- a/core/Controller/LoginController.php
+++ b/core/Controller/LoginController.php
@@ -259,7 +259,7 @@ class LoginController extends Controller {
private function generateRedirect(?string $redirectUrl): RedirectResponse {
if ($redirectUrl !== null && $this->userSession->isLoggedIn()) {
- $location = $this->urlGenerator->getAbsoluteURL(urldecode($redirectUrl));
+ $location = $this->urlGenerator->getAbsoluteURL($redirectUrl);
// Deny the redirect if the URL contains a @
// This prevents unvalidated redirects like ?redirect_url=:user@domain.com
if (strpos($location, '@') === false) {
diff --git a/core/js/mimetypelist.js b/core/js/mimetypelist.js
index 760d503f23e..bd9b2bd69f1 100644
--- a/core/js/mimetypelist.js
+++ b/core/js/mimetypelist.js
@@ -101,7 +101,10 @@ OC.MimeTypeList={
"text/x-python": "text/code",
"text/x-shellscript": "text/code",
"web": "text/code",
- "application/internet-shortcut": "link"
+ "application/internet-shortcut": "link",
+ "application/km": "mindmap",
+ "application/x-freemind": "mindmap",
+ "application/vnd.xmind.workbook": "mindmap"
},
files: [
"application",
@@ -118,6 +121,7 @@ OC.MimeTypeList={
"image",
"link",
"location",
+ "mindmap",
"package-x-generic",
"text",
"text-calendar",
diff --git a/core/l10n/is.js b/core/l10n/is.js
index 7647602c66c..388919bd2d9 100644
--- a/core/l10n/is.js
+++ b/core/l10n/is.js
@@ -143,8 +143,10 @@ OC.L10N.register(
"I know what I'm doing" : "Ég veit hvað ég er að gera",
"Resetting password" : "Endurstilli lykilorð",
"Recommended apps" : "Ráðlögð forrit",
+ "Nextcloud {app}" : "Nextcloud {app}",
"Cancel" : "Hætta við",
"Forgot password?" : "Gleymdirðu lykilorði?",
+ "Log in with a device" : "Skrá inn með tæki",
"Back" : "Til baka",
"Settings" : "Stillingar",
"Could not load your contacts" : "Gat ekki hlaðið inn tengiliðalistanum þínum",
@@ -239,6 +241,7 @@ OC.L10N.register(
"For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">documentation</a>." : "Til að fá upplýsingar hvernig á að stilla miðlarann almennilega, skaltu skoða <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">hjálparskjölin</a>.",
"Create an <strong>admin account</strong>" : "Útbúa <strong>kerfisstjóraaðgang</strong>",
"Username" : "Notandanafn",
+ "Show password" : "Sýna lykilorð",
"Storage & database" : "Geymsla & gagnagrunnur",
"Data folder" : "Gagnamappa",
"Configure the database" : "Stilla gagnagrunninn",
diff --git a/core/l10n/is.json b/core/l10n/is.json
index 19d4286fd23..1fc2c9f05c0 100644
--- a/core/l10n/is.json
+++ b/core/l10n/is.json
@@ -141,8 +141,10 @@
"I know what I'm doing" : "Ég veit hvað ég er að gera",
"Resetting password" : "Endurstilli lykilorð",
"Recommended apps" : "Ráðlögð forrit",
+ "Nextcloud {app}" : "Nextcloud {app}",
"Cancel" : "Hætta við",
"Forgot password?" : "Gleymdirðu lykilorði?",
+ "Log in with a device" : "Skrá inn með tæki",
"Back" : "Til baka",
"Settings" : "Stillingar",
"Could not load your contacts" : "Gat ekki hlaðið inn tengiliðalistanum þínum",
@@ -237,6 +239,7 @@
"For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">documentation</a>." : "Til að fá upplýsingar hvernig á að stilla miðlarann almennilega, skaltu skoða <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">hjálparskjölin</a>.",
"Create an <strong>admin account</strong>" : "Útbúa <strong>kerfisstjóraaðgang</strong>",
"Username" : "Notandanafn",
+ "Show password" : "Sýna lykilorð",
"Storage & database" : "Geymsla & gagnagrunnur",
"Data folder" : "Gagnamappa",
"Configure the database" : "Stilla gagnagrunninn",
diff --git a/core/l10n/vi.js b/core/l10n/vi.js
index 9c9a38aed33..676f932a169 100644
--- a/core/l10n/vi.js
+++ b/core/l10n/vi.js
@@ -200,6 +200,7 @@ OC.L10N.register(
"App token" : "Dấu hiệu ứng dụng",
"Grant access" : "Cấp quyền truy cập",
"Account access" : "Truy cập tài khoản",
+ "This share is password-protected" : "Chia sẽ này được bảo vệ bởi mật khẩu",
"The password is wrong. Try again." : "Sai mật khẩu. Hãy thử lại.",
"Two-factor authentication" : "Xác thực 2 bước",
"Use backup code" : "Sử dụng mã dự phòng",
@@ -248,6 +249,7 @@ OC.L10N.register(
"Expiration" : "Hết hạn",
"Expiration date" : "Ngày kết thúc",
"Unshare" : "Bỏ chia sẻ",
+ "Delete share link" : "Xóa liên kết chia sẻ",
"Share to {name}" : "Chia sẻ với {name}",
"Share link" : "Chia sẻ liên kết",
"Password protect by Talk" : "Mật khẩu bảo vệ bằng đàm thoại",
diff --git a/core/l10n/vi.json b/core/l10n/vi.json
index 6472beb109e..61663558612 100644
--- a/core/l10n/vi.json
+++ b/core/l10n/vi.json
@@ -198,6 +198,7 @@
"App token" : "Dấu hiệu ứng dụng",
"Grant access" : "Cấp quyền truy cập",
"Account access" : "Truy cập tài khoản",
+ "This share is password-protected" : "Chia sẽ này được bảo vệ bởi mật khẩu",
"The password is wrong. Try again." : "Sai mật khẩu. Hãy thử lại.",
"Two-factor authentication" : "Xác thực 2 bước",
"Use backup code" : "Sử dụng mã dự phòng",
@@ -246,6 +247,7 @@
"Expiration" : "Hết hạn",
"Expiration date" : "Ngày kết thúc",
"Unshare" : "Bỏ chia sẻ",
+ "Delete share link" : "Xóa liên kết chia sẻ",
"Share to {name}" : "Chia sẻ với {name}",
"Share link" : "Chia sẻ liên kết",
"Password protect by Talk" : "Mật khẩu bảo vệ bằng đàm thoại",
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index c600c15068d..01dcecb0e47 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -323,6 +323,7 @@ return array(
'OCP\\Http\\Client\\IClient' => $baseDir . '/lib/public/Http/Client/IClient.php',
'OCP\\Http\\Client\\IClientService' => $baseDir . '/lib/public/Http/Client/IClientService.php',
'OCP\\Http\\Client\\IResponse' => $baseDir . '/lib/public/Http/Client/IResponse.php',
+ 'OCP\\Http\\Client\\LocalServerException' => $baseDir . '/lib/public/Http/Client/LocalServerException.php',
'OCP\\IAddressBook' => $baseDir . '/lib/public/IAddressBook.php',
'OCP\\IAppConfig' => $baseDir . '/lib/public/IAppConfig.php',
'OCP\\IAvatar' => $baseDir . '/lib/public/IAvatar.php',
@@ -1024,6 +1025,7 @@ return array(
'OC\\Files\\Storage\\Wrapper\\Quota' => $baseDir . '/lib/private/Files/Storage/Wrapper/Quota.php',
'OC\\Files\\Storage\\Wrapper\\Wrapper' => $baseDir . '/lib/private/Files/Storage/Wrapper/Wrapper.php',
'OC\\Files\\Stream\\Encryption' => $baseDir . '/lib/private/Files/Stream/Encryption.php',
+ 'OC\\Files\\Stream\\HashWrapper' => $baseDir . '/lib/private/Files/Stream/HashWrapper.php',
'OC\\Files\\Stream\\Quota' => $baseDir . '/lib/private/Files/Stream/Quota.php',
'OC\\Files\\Stream\\SeekableHttpStream' => $baseDir . '/lib/private/Files/Stream/SeekableHttpStream.php',
'OC\\Files\\Type\\Detection' => $baseDir . '/lib/private/Files/Type/Detection.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 87a9460f77b..7a9bd5652d6 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -352,6 +352,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OCP\\Http\\Client\\IClient' => __DIR__ . '/../../..' . '/lib/public/Http/Client/IClient.php',
'OCP\\Http\\Client\\IClientService' => __DIR__ . '/../../..' . '/lib/public/Http/Client/IClientService.php',
'OCP\\Http\\Client\\IResponse' => __DIR__ . '/../../..' . '/lib/public/Http/Client/IResponse.php',
+ 'OCP\\Http\\Client\\LocalServerException' => __DIR__ . '/../../..' . '/lib/public/Http/Client/LocalServerException.php',
'OCP\\IAddressBook' => __DIR__ . '/../../..' . '/lib/public/IAddressBook.php',
'OCP\\IAppConfig' => __DIR__ . '/../../..' . '/lib/public/IAppConfig.php',
'OCP\\IAvatar' => __DIR__ . '/../../..' . '/lib/public/IAvatar.php',
@@ -1053,6 +1054,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Files\\Storage\\Wrapper\\Quota' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/Quota.php',
'OC\\Files\\Storage\\Wrapper\\Wrapper' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/Wrapper.php',
'OC\\Files\\Stream\\Encryption' => __DIR__ . '/../../..' . '/lib/private/Files/Stream/Encryption.php',
+ 'OC\\Files\\Stream\\HashWrapper' => __DIR__ . '/../../..' . '/lib/private/Files/Stream/HashWrapper.php',
'OC\\Files\\Stream\\Quota' => __DIR__ . '/../../..' . '/lib/private/Files/Stream/Quota.php',
'OC\\Files\\Stream\\SeekableHttpStream' => __DIR__ . '/../../..' . '/lib/private/Files/Stream/SeekableHttpStream.php',
'OC\\Files\\Type\\Detection' => __DIR__ . '/../../..' . '/lib/private/Files/Type/Detection.php',
diff --git a/lib/private/DB/QueryBuilder/ExpressionBuilder/MySqlExpressionBuilder.php b/lib/private/DB/QueryBuilder/ExpressionBuilder/MySqlExpressionBuilder.php
index 899f9277439..3b81f11c4dc 100644
--- a/lib/private/DB/QueryBuilder/ExpressionBuilder/MySqlExpressionBuilder.php
+++ b/lib/private/DB/QueryBuilder/ExpressionBuilder/MySqlExpressionBuilder.php
@@ -52,4 +52,12 @@ class MySqlExpressionBuilder extends ExpressionBuilder {
$y = $this->helper->quoteColumnName($y);
return $this->expressionBuilder->comparison($x, ' COLLATE ' . $this->charset . '_general_ci LIKE', $y);
}
+
+ public function eq($x, $y, $type = null) {
+ return 'BINARY ' . parent::eq($x, $y, $type);
+ }
+
+ public function neq($x, $y, $type = null) {
+ return 'BINARY ' . parent::neq($x, $y, $type);
+ }
}
diff --git a/lib/private/Files/ObjectStore/SwiftFactory.php b/lib/private/Files/ObjectStore/SwiftFactory.php
index 59446576400..7c8a1b995b4 100644
--- a/lib/private/Files/ObjectStore/SwiftFactory.php
+++ b/lib/private/Files/ObjectStore/SwiftFactory.php
@@ -119,6 +119,10 @@ class SwiftFactory {
if (!isset($this->params['tenantName']) && isset($this->params['tenant'])) {
$this->params['tenantName'] = $this->params['tenant'];
}
+ if (isset($this->params['domain'])) {
+ $this->params['scope']['project']['name'] = $this->params['tenant'];
+ $this->params['scope']['project']['domain']['name'] = $this->params['domain'];
+ }
$this->params = array_merge(self::DEFAULT_OPTIONS, $this->params);
$cacheKey = $userName . '@' . $this->params['url'] . '/' . $this->params['container'];
diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php
index edad9cc874c..bb672f3a0ea 100644
--- a/lib/private/Files/Storage/Common.php
+++ b/lib/private/Files/Storage/Common.php
@@ -859,9 +859,12 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage {
if (!$target) {
return 0;
}
- list($count, $result) = \OC_Helper::streamCopy($stream, $target);
- fclose($stream);
- fclose($target);
+ try {
+ [$count, $result] = \OC_Helper::streamCopy($stream, $target);
+ } finally {
+ fclose($target);
+ fclose($stream);
+ }
return $count;
}
}
diff --git a/lib/private/Files/Stream/HashWrapper.php b/lib/private/Files/Stream/HashWrapper.php
new file mode 100644
index 00000000000..048e50794e8
--- /dev/null
+++ b/lib/private/Files/Stream/HashWrapper.php
@@ -0,0 +1,72 @@
+<?php declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2020 Robin Appelman <robin@icewind.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Files\Stream;
+
+use Icewind\Streams\Wrapper;
+
+class HashWrapper extends Wrapper {
+ protected $callback;
+ protected $hash;
+
+ public static function wrap($source, string $algo, callable $callback) {
+ $hash = hash_init($algo);
+ $context = stream_context_create([
+ 'hash' => [
+ 'source' => $source,
+ 'callback' => $callback,
+ 'hash' => $hash,
+ ],
+ ]);
+ return Wrapper::wrapSource($source, $context, 'hash', self::class);
+ }
+
+ protected function open() {
+ $context = $this->loadContext('hash');
+
+ $this->callback = $context['callback'];
+ $this->hash = $context['hash'];
+ return true;
+ }
+
+ public function dir_opendir($path, $options) {
+ return $this->open();
+ }
+
+ public function stream_open($path, $mode, $options, &$opened_path) {
+ return $this->open();
+ }
+
+ public function stream_read($count) {
+ $result = parent::stream_read($count);
+ hash_update($this->hash, $result);
+ return $result;
+ }
+
+ public function stream_close() {
+ if (is_callable($this->callback)) {
+ call_user_func($this->callback, hash_final($this->hash));
+ // prevent further calls by potential PHP 7 GC ghosts
+ $this->callback = null;
+ }
+ return parent::stream_close();
+ }
+}
diff --git a/lib/private/Http/Client/Client.php b/lib/private/Http/Client/Client.php
index 19d5877f9fb..d21ce413f1a 100644
--- a/lib/private/Http/Client/Client.php
+++ b/lib/private/Http/Client/Client.php
@@ -34,8 +34,10 @@ use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\RequestOptions;
use OCP\Http\Client\IClient;
use OCP\Http\Client\IResponse;
+use OCP\Http\Client\LocalServerException;
use OCP\ICertificateManager;
use OCP\IConfig;
+use OCP\ILogger;
/**
* Class Client
@@ -47,20 +49,19 @@ class Client implements IClient {
private $client;
/** @var IConfig */
private $config;
+ /** @var ILogger */
+ private $logger;
/** @var ICertificateManager */
private $certificateManager;
- /**
- * @param IConfig $config
- * @param ICertificateManager $certificateManager
- * @param GuzzleClient $client
- */
public function __construct(
IConfig $config,
+ ILogger $logger,
ICertificateManager $certificateManager,
GuzzleClient $client
) {
$this->config = $config;
+ $this->logger = $logger;
$this->client = $client;
$this->certificateManager = $certificateManager;
}
@@ -144,6 +145,53 @@ class Client implements IClient {
return $proxy;
}
+ protected function preventLocalAddress(string $uri, array $options): void {
+ if (($options['nextcloud']['allow_local_address'] ?? false) ||
+ $this->config->getSystemValueBool('allow_local_remote_servers', false)) {
+ return;
+ }
+
+ $host = parse_url($uri, PHP_URL_HOST);
+ if ($host === false) {
+ $this->logger->warning("Could not detect any host in $uri");
+ throw new LocalServerException('Could not detect any host');
+ }
+
+ $host = strtolower($host);
+ // remove brackets from IPv6 addresses
+ if (strpos($host, '[') === 0 && substr($host, -1) === ']') {
+ $host = substr($host, 1, -1);
+ }
+
+ // Disallow localhost and local network
+ if ($host === 'localhost' || substr($host, -6) === '.local' || substr($host, -10) === '.localhost') {
+ $this->logger->warning("Host $host was not connected to because it violates local access rules");
+ throw new LocalServerException('Host violates local access rules');
+ }
+
+ // Disallow hostname only
+ if (substr_count($host, '.') === 0) {
+ $this->logger->warning("Host $host was not connected to because it violates local access rules");
+ throw new LocalServerException('Host violates local access rules');
+ }
+
+ if ((bool)filter_var($host, FILTER_VALIDATE_IP) && !filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
+ $this->logger->warning("Host $host was not connected to because it violates local access rules");
+ throw new LocalServerException('Host violates local access rules');
+ }
+
+ // Also check for IPv6 IPv4 nesting, because that's not covered by filter_var
+ if ((bool)filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && substr_count($host, '.') > 0) {
+ $delimiter = strrpos($host, ':'); // Get last colon
+ $ipv4Address = substr($host, $delimiter + 1);
+
+ if (!filter_var($ipv4Address, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
+ $this->logger->warning("Host $host was not connected to because it violates local access rules");
+ throw new LocalServerException('Host violates local access rules');
+ }
+ }
+ }
+
/**
* Sends a GET request
*
@@ -174,6 +222,7 @@ class Client implements IClient {
* @throws \Exception If the request could not get completed
*/
public function get(string $uri, array $options = []): IResponse {
+ $this->preventLocalAddress($uri, $options);
$response = $this->client->request('get', $uri, $this->buildRequestOptions($options));
$isStream = isset($options['stream']) && $options['stream'];
return new Response($response, $isStream);
@@ -204,6 +253,7 @@ class Client implements IClient {
* @throws \Exception If the request could not get completed
*/
public function head(string $uri, array $options = []): IResponse {
+ $this->preventLocalAddress($uri, $options);
$response = $this->client->request('head', $uri, $this->buildRequestOptions($options));
return new Response($response);
}
@@ -238,6 +288,8 @@ class Client implements IClient {
* @throws \Exception If the request could not get completed
*/
public function post(string $uri, array $options = []): IResponse {
+ $this->preventLocalAddress($uri, $options);
+
if (isset($options['body']) && is_array($options['body'])) {
$options['form_params'] = $options['body'];
unset($options['body']);
@@ -276,6 +328,7 @@ class Client implements IClient {
* @throws \Exception If the request could not get completed
*/
public function put(string $uri, array $options = []): IResponse {
+ $this->preventLocalAddress($uri, $options);
$response = $this->client->request('put', $uri, $this->buildRequestOptions($options));
return new Response($response);
}
@@ -310,6 +363,7 @@ class Client implements IClient {
* @throws \Exception If the request could not get completed
*/
public function delete(string $uri, array $options = []): IResponse {
+ $this->preventLocalAddress($uri, $options);
$response = $this->client->request('delete', $uri, $this->buildRequestOptions($options));
return new Response($response);
}
@@ -344,6 +398,7 @@ class Client implements IClient {
* @throws \Exception If the request could not get completed
*/
public function options(string $uri, array $options = []): IResponse {
+ $this->preventLocalAddress($uri, $options);
$response = $this->client->request('options', $uri, $this->buildRequestOptions($options));
return new Response($response);
}
diff --git a/lib/private/Http/Client/ClientService.php b/lib/private/Http/Client/ClientService.php
index 2b18daaf737..55f03f30399 100644
--- a/lib/private/Http/Client/ClientService.php
+++ b/lib/private/Http/Client/ClientService.php
@@ -32,6 +32,7 @@ use OCP\Http\Client\IClient;
use OCP\Http\Client\IClientService;
use OCP\ICertificateManager;
use OCP\IConfig;
+use OCP\ILogger;
/**
* Class ClientService
@@ -41,16 +42,16 @@ use OCP\IConfig;
class ClientService implements IClientService {
/** @var IConfig */
private $config;
+ /** @var ILogger */
+ private $logger;
/** @var ICertificateManager */
private $certificateManager;
- /**
- * @param IConfig $config
- * @param ICertificateManager $certificateManager
- */
public function __construct(IConfig $config,
+ ILogger $logger,
ICertificateManager $certificateManager) {
$this->config = $config;
+ $this->logger = $logger;
$this->certificateManager = $certificateManager;
}
@@ -58,6 +59,6 @@ class ClientService implements IClientService {
* @return Client
*/
public function newClient(): IClient {
- return new Client($this->config, $this->certificateManager, new GuzzleClient());
+ return new Client($this->config, $this->logger, $this->certificateManager, new GuzzleClient());
}
}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 1a3eabc852e..a7432342a27 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -804,6 +804,7 @@ class Server extends ServerContainer implements IServerContainer {
$uid = $user ? $user : null;
return new ClientService(
$c->getConfig(),
+ $c->getLogger(),
new \OC\Security\CertificateManager(
$uid,
new View(),
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index 75745a7fe97..ff46badee3b 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -823,7 +823,7 @@ class DefaultShareProvider implements IShareProvider {
*/
private function isAccessibleResult($data) {
// exclude shares leading to deleted file entries
- if ($data['fileid'] === null) {
+ if ($data['fileid'] === null || $data['path'] === null) {
return false;
}
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index b9a97e4225f..78d79b5c4da 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -302,7 +302,7 @@ class Manager implements IManager {
$isFederatedShare = $share->getNode()->getStorage()->instanceOfStorage('\OCA\Files_Sharing\External\Storage');
$permissions = 0;
$mount = $share->getNode()->getMountPoint();
- if (!$isFederatedShare && $share->getNode()->getOwner()->getUID() !== $share->getSharedBy()) {
+ if (!$isFederatedShare && $share->getNode()->getOwner() && $share->getNode()->getOwner()->getUID() !== $share->getSharedBy()) {
// When it's a reshare use the parent share permissions as maximum
$userMountPointId = $mount->getStorageRootId();
$userMountPoints = $userFolder->getById($userMountPointId);
@@ -710,7 +710,11 @@ class Manager implements IManager {
}
$share->setShareOwner($parent->getOwner()->getUID());
} else {
- $share->setShareOwner($share->getNode()->getOwner()->getUID());
+ if ($share->getNode()->getOwner()) {
+ $share->setShareOwner($share->getNode()->getOwner()->getUID());
+ } else {
+ $share->setShareOwner($share->getSharedBy());
+ }
}
//Verify share type
diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php
index 303050a7716..e55d4395191 100644
--- a/lib/private/User/Manager.php
+++ b/lib/private/User/Manager.php
@@ -188,7 +188,7 @@ class Manager extends PublicEmitter implements IUserManager {
*/
public function userExists($uid) {
$user = $this->get($uid);
- return ($user !== null);
+ return $user !== null && $user->getUID() === $uid;
}
/**
diff --git a/lib/public/Http/Client/LocalServerException.php b/lib/public/Http/Client/LocalServerException.php
new file mode 100644
index 00000000000..22e533bf197
--- /dev/null
+++ b/lib/public/Http/Client/LocalServerException.php
@@ -0,0 +1,29 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCP\Http\Client;
+
+/**
+ * @since 19.0.0
+ */
+class LocalServerException extends \RuntimeException {
+}
diff --git a/resources/codesigning/root.crl b/resources/codesigning/root.crl
index dfcf6b56bd9..0853033488b 100644
--- a/resources/codesigning/root.crl
+++ b/resources/codesigning/root.crl
@@ -1,24 +1,25 @@
-----BEGIN X509 CRL-----
-MIID8zCCAtsCAQEwDQYJKoZIhvcNAQELBQAwezELMAkGA1UEBhMCREUxGzAZBgNV
+MIIEHTCCAwUCAQEwDQYJKoZIhvcNAQELBQAwezELMAkGA1UEBhMCREUxGzAZBgNV
BAgMEkJhZGVuLVd1ZXJ0dGVtYmVyZzEXMBUGA1UECgwOTmV4dGNsb3VkIEdtYkgx
NjA0BgNVBAMMLU5leHRjbG91ZCBDb2RlIFNpZ25pbmcgSW50ZXJtZWRpYXRlIEF1
-dGhvcml0eRcNMTkxMjEyMDkzOTIxWhcNMjkxMDIwMDkzOTIxWjCCAfgwEwICEBAX
+dGhvcml0eRcNMjAwNDE0MTIzNTQ5WhcNMzAwMjIxMTIzNTQ5WjCCAiIwEwICEBAX
DTE2MTAxNzEyMDkxOVowEwICEBYXDTE3MTEyMzE3MzUyOVowEwICEBcXDTE3MDIy
MDEwMDIzOFowEwICEBgXDTE5MDEzMDEzMDEyNVowEwICEBwXDTE4MDIwMjEwNTIz
OVowEwICEB8XDTE5MDEzMDEzMDEzM1owEwICECMXDTE5MTIxMjA5MzUzMVowEwIC
-EE0XDTE4MTIyMTE1MzIxOFowEwICEGoXDTE5MDIxMjA5MDgxNFowEwICEG4XDTE5
-MTEyMDE5NDYyOFowEwICEG8XDTE4MDQxNzA5MzkzNlowEwICEHQXDTE3MTEyMzE2
-NTQ1OVowEwICEHUXDTE5MTIxMjA5MzkwNVowEwICEHYXDTE5MTIxMjA5MzkxMlow
-EwICEJAXDTE4MDIwOTA4Mzg1OFowEwICEKcXDTE4MDgxMzA3NTIwOFowEwICEK8X
-DTE4MDgxMzA4MjYyMFowEwICELUXDTE4MTAwOTA5NTMxMVowEwICELcXDTE4MTIy
-MTE1MzAyN1owEwICEMIXDTE4MTAxNzE5MjAyNFowEwICEMMXDTE4MTAxNzE5MjUz
-M1owEwICENcXDTE5MDIxNDEwMzMwNlowEwICEOAXDTE5MDUyMDA5MzAxMFowEwIC
-EP0XDTE5MTIxMjA5MzUzNlqgMDAuMB8GA1UdIwQYMBaAFG3qbqqpNyw8iS0XPv1G
-7sOeeO10MAsGA1UdFAQEAgIQEzANBgkqhkiG9w0BAQsFAAOCAQEAKZFC6MoPE4Mu
-3vPa80ow6X1CkNvATBI6w64UABbKVjed0oCFsU2lGhltqBOIB6tKB97wNFqxp9qX
-T87w6bWE+S2W+0jJqctsmO7B5rFqaNecWdB6LaFbJiG1upGD/i53BC2OKGhImo2q
-XkLlRbFa7Z9uA1AwF8kxopYZF5YWUQZLoZrvDrOuRf2dOJgWja/1It0O3ZtTRXtP
-PxmqTAFp2pUF2DX3U21cxicMXlvF5vrtGPnBXCwszG7YJVYV+DpXWtENLpQTBJ7Z
-FZRNcs0827D7/2eAd2PKxTGKFcj5r8Pq+BVlcxVowGv3dFBR6FD3bGG5atw58CKv
-/42CRQsiEw==
+EE0XDTE4MTIyMTE1MzIxOFowEwICEE4XDTIwMDEwNzEzNTc0NlowEwICEGoXDTE5
+MDIxMjA5MDgxNFowEwICEG4XDTE5MTEyMDE5NDYyOFowEwICEG8XDTE4MDQxNzA5
+MzkzNlowEwICEHQXDTE3MTEyMzE2NTQ1OVowEwICEHUXDTE5MTIxMjA5MzkwNVow
+EwICEHYXDTE5MTIxMjA5MzkxMlowEwICEJAXDTE4MDIwOTA4Mzg1OFowEwICEKcX
+DTE4MDgxMzA3NTIwOFowEwICEK8XDTE4MDgxMzA4MjYyMFowEwICELUXDTE4MTAw
+OTA5NTMxMVowEwICELcXDTE4MTIyMTE1MzAyN1owEwICEMIXDTE4MTAxNzE5MjAy
+NFowEwICEMMXDTE4MTAxNzE5MjUzM1owEwICENcXDTE5MDIxNDEwMzMwNlowEwIC
+EOAXDTE5MDUyMDA5MzAxMFowEwICEP0XDTE5MTIxMjA5MzUzNlowEwICEQEXDTIw
+MDQxNDEyMzU0M1qgMDAuMB8GA1UdIwQYMBaAFG3qbqqpNyw8iS0XPv1G7sOeeO10
+MAsGA1UdFAQEAgIQFTANBgkqhkiG9w0BAQsFAAOCAQEAM63JxPsoymGhFCWPxlOH
+98qB6ehO8PeBGUdkvFwVZammUZn93uAnFLGnCbWKfS45UwZmecndH2ZNVVkpDiaC
+NpUHuaegVjDObS+bIK3ezPkt8QiA9rkWVA0u6/HQRvJm4c0mOsEFW5+WBzuAy6xR
+sCQV8EMfHZMDNzuAYgt+ODkQhMDZHOY8YgDtX8XEHDISXSs2z/KBR5+dCwBxyrgA
+glNFcPKbGYzveiXJ4xyfkJbF6SakoCznTpmXykRkgubY5cigJ7EcOMM460JiP+8+
+ptE1WPm0jkJlvYJlH+zhDOtXAmMNzNCdNz1dBNT7PeVkQdIhLS6Lke77Jk0NM/18
+Bw==
-----END X509 CRL-----
diff --git a/resources/config/mimetypealiases.dist.json b/resources/config/mimetypealiases.dist.json
index 922ef7acf12..332daea197b 100644
--- a/resources/config/mimetypealiases.dist.json
+++ b/resources/config/mimetypealiases.dist.json
@@ -101,6 +101,9 @@
"text/x-python": "text/code",
"text/x-shellscript": "text/code",
"web": "text/code",
- "application/internet-shortcut": "link"
+ "application/internet-shortcut": "link",
+ "application/km": "mindmap",
+ "application/x-freemind": "mindmap",
+ "application/vnd.xmind.workbook": "mindmap"
}
diff --git a/resources/config/mimetypemapping.dist.json b/resources/config/mimetypemapping.dist.json
index 59f0e0a17cb..c59dfaefd30 100644
--- a/resources/config/mimetypemapping.dist.json
+++ b/resources/config/mimetypemapping.dist.json
@@ -85,6 +85,7 @@
"kdc": ["image/x-dcraw"],
"key": ["application/x-iwork-keynote-sffkey"],
"keynote": ["application/x-iwork-keynote-sffkey"],
+ "km": ["application/km"],
"kml": ["application/vnd.google-earth.kml+xml"],
"kmz": ["application/vnd.google-earth.kmz"],
"kra": ["application/x-krita"],
@@ -104,6 +105,7 @@
"mkd": ["text/markdown"],
"mef": ["image/x-dcraw"],
"mkv": ["video/x-matroska"],
+ "mm": ["application/x-freemind"],
"mobi": ["application/x-mobipocket-ebook"],
"mov": ["video/quicktime"],
"mp3": ["audio/mpeg"],
@@ -201,6 +203,7 @@
"xlt": ["application/vnd.ms-excel"],
"xltm": ["application/vnd.ms-excel.template.macroEnabled.12"],
"xltx": ["application/vnd.openxmlformats-officedocument.spreadsheetml.template"],
+ "xmind": ["application/vnd.xmind.workbook"],
"xml": ["application/xml", "text/plain"],
"xrf": ["image/x-dcraw"],
"yaml": ["application/yaml", "text/plain"],
diff --git a/tests/Core/Controller/LoginControllerTest.php b/tests/Core/Controller/LoginControllerTest.php
index 80be53ed26d..e9d4a89aa7d 100644
--- a/tests/Core/Controller/LoginControllerTest.php
+++ b/tests/Core/Controller/LoginControllerTest.php
@@ -509,7 +509,7 @@ class LoginControllerTest extends TestCase {
->method('getUID')
->willReturn('jane');
$password = 'secret';
- $originalUrl = 'another%20url';
+ $originalUrl = 'another url';
$redirectUrl = 'http://localhost/another url';
$this->request
@@ -551,7 +551,7 @@ class LoginControllerTest extends TestCase {
$this->request,
$user,
$password,
- '%2Fapps%2Fmail'
+ '/apps/mail'
);
$loginResult = LoginResult::success($loginData);
$this->chain->expects($this->once())
@@ -563,11 +563,11 @@ class LoginControllerTest extends TestCase {
->willReturn(true);
$this->urlGenerator->expects($this->once())
->method('getAbsoluteURL')
- ->with(urldecode('/apps/mail'))
+ ->with('/apps/mail')
->willReturn($redirectUrl);
$expected = new \OCP\AppFramework\Http\RedirectResponse($redirectUrl);
- $response = $this->loginController->tryLogin($user, $password, '%2Fapps%2Fmail');
+ $response = $this->loginController->tryLogin($user, $password, '/apps/mail');
$this->assertEquals($expected, $response);
}
diff --git a/tests/karma.config.js b/tests/karma.config.js
index 06503bf9bf8..14e01d36101 100644
--- a/tests/karma.config.js
+++ b/tests/karma.config.js
@@ -84,12 +84,6 @@ module.exports = function(config) {
'apps/comments/js/comments.js'
],
testFiles: ['apps/comments/tests/js/**/*.js']
- },
- {
- name: 'settings',
- srcFiles: [
- 'settings/js/apps.js'
- ]
}
];
}
diff --git a/tests/lib/Files/Stream/HashWrapperTest.php b/tests/lib/Files/Stream/HashWrapperTest.php
new file mode 100644
index 00000000000..7066bf857aa
--- /dev/null
+++ b/tests/lib/Files/Stream/HashWrapperTest.php
@@ -0,0 +1,55 @@
+<?php declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2020 Robin Appelman <robin@icewind.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Test\Files\Stream;
+
+use OC\Files\Stream\HashWrapper;
+use Test\TestCase;
+
+class HashWrapperTest extends TestCase {
+ /**
+ * @dataProvider hashProvider
+ */
+ public function testHashStream($data, string $algo, string $hash) {
+ if (!is_resource($data)) {
+ $tmpData = fopen('php://temp', 'r+');
+ if ($data !== null) {
+ fwrite($tmpData, $data);
+ rewind($tmpData);
+ }
+ $data = $tmpData;
+ }
+
+ $wrapper = HashWrapper::wrap($data, $algo, function ($result) use ($hash) {
+ $this->assertEquals($hash, $result);
+ });
+ stream_get_contents($wrapper);
+ }
+
+ public function hashProvider() {
+ return [
+ ['foo', 'md5', 'acbd18db4cc2f85cedef654fccc4a4d8'],
+ ['foo', 'sha1', '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'],
+ ['foo', 'sha256', '2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae'],
+ [str_repeat('foo', 8192), 'md5', '96684d2b796a2c54a026b5d60f9de819'],
+ ];
+ }
+}
diff --git a/tests/lib/Http/Client/ClientServiceTest.php b/tests/lib/Http/Client/ClientServiceTest.php
index 02f331483de..b1bc5a188ce 100644
--- a/tests/lib/Http/Client/ClientServiceTest.php
+++ b/tests/lib/Http/Client/ClientServiceTest.php
@@ -13,6 +13,7 @@ use OC\Http\Client\Client;
use OC\Http\Client\ClientService;
use OCP\ICertificateManager;
use OCP\IConfig;
+use OCP\ILogger;
/**
* Class ClientServiceTest
@@ -23,10 +24,11 @@ class ClientServiceTest extends \Test\TestCase {
$config = $this->createMock(IConfig::class);
/** @var ICertificateManager $certificateManager */
$certificateManager = $this->createMock(ICertificateManager::class);
+ $logger = $this->createMock(ILogger::class);
- $clientService = new ClientService($config, $certificateManager);
+ $clientService = new ClientService($config, $logger, $certificateManager);
$this->assertEquals(
- new Client($config, $certificateManager, new GuzzleClient()),
+ new Client($config, $logger, $certificateManager, new GuzzleClient()),
$clientService->newClient()
);
}
diff --git a/tests/lib/Http/Client/ClientTest.php b/tests/lib/Http/Client/ClientTest.php
index 2f9e70a8bb9..b136a0ca300 100644
--- a/tests/lib/Http/Client/ClientTest.php
+++ b/tests/lib/Http/Client/ClientTest.php
@@ -11,33 +11,38 @@ namespace Test\Http\Client;
use GuzzleHttp\Psr7\Response;
use OC\Http\Client\Client;
use OC\Security\CertificateManager;
+use OCP\Http\Client\LocalServerException;
use OCP\ICertificateManager;
use OCP\IConfig;
+use OCP\ILogger;
+use PHPUnit\Framework\MockObject\MockObject;
/**
* Class ClientTest
*/
class ClientTest extends \Test\TestCase {
- /** @var \GuzzleHttp\Client|\PHPUnit_Framework_MockObject_MockObject */
+ /** @var \GuzzleHttp\Client|MockObject */
private $guzzleClient;
- /** @var CertificateManager|\PHPUnit_Framework_MockObject_MockObject */
+ /** @var CertificateManager|MockObject */
private $certificateManager;
/** @var Client */
private $client;
- /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
+ /** @var IConfig|MockObject */
private $config;
+ /** @var ILogger|MockObject */
+ private $logger;
/** @var array */
private $defaultRequestOptions;
protected function setUp(): void {
parent::setUp();
$this->config = $this->createMock(IConfig::class);
- $this->guzzleClient = $this->getMockBuilder(\GuzzleHttp\Client::class)
- ->disableOriginalConstructor()
- ->getMock();
+ $this->logger = $this->createMock(ILogger::class);
+ $this->guzzleClient = $this->createMock(\GuzzleHttp\Client::class);
$this->certificateManager = $this->createMock(ICertificateManager::class);
$this->client = new Client(
$this->config,
+ $this->logger,
$this->certificateManager,
$this->guzzleClient
);
@@ -149,19 +154,127 @@ class ClientTest extends \Test\TestCase {
], self::invokePrivate($this->client, 'getProxyUri'));
}
+ public function dataPreventLocalAddress():array {
+ return [
+ ['localhost/foo.bar'],
+ ['localHost/foo.bar'],
+ ['random-host/foo.bar'],
+ ['[::1]/bla.blub'],
+ ['[::]/bla.blub'],
+ ['192.168.0.1'],
+ ['172.16.42.1'],
+ ['[fdf8:f53b:82e4::53]/secret.ics'],
+ ['[fe80::200:5aee:feaa:20a2]/secret.ics'],
+ ['[0:0:0:0:0:0:10.0.0.1]/secret.ics'],
+ ['[0:0:0:0:0:ffff:127.0.0.0]/secret.ics'],
+ ['10.0.0.1'],
+ ['another-host.local'],
+ ['service.localhost'],
+ ['!@#$'], // test invalid url
+ ];
+ }
+
+ /**
+ * @dataProvider dataPreventLocalAddress
+ * @param string $uri
+ */
+ public function testPreventLocalAddress(string $uri): void {
+ $this->expectException(LocalServerException::class);
+ self::invokePrivate($this->client, 'preventLocalAddress', ['http://' . $uri, []]);
+ }
+
+ /**
+ * @dataProvider dataPreventLocalAddress
+ * @param string $uri
+ */
+ public function testPreventLocalAddressDisabledByGlobalConfig(string $uri): void {
+ $this->config->expects($this->once())
+ ->method('getSystemValueBool')
+ ->with('allow_local_remote_servers', false)
+ ->willReturn(true);
+
+// $this->expectException(LocalServerException::class);
+
+ self::invokePrivate($this->client, 'preventLocalAddress', ['http://' . $uri, []]);
+ }
+
+ /**
+ * @dataProvider dataPreventLocalAddress
+ * @param string $uri
+ */
+ public function testPreventLocalAddressDisabledByOption(string $uri): void {
+ $this->config->expects($this->never())
+ ->method('getSystemValueBool');
+
+// $this->expectException(LocalServerException::class);
+
+ self::invokePrivate($this->client, 'preventLocalAddress', ['http://' . $uri, [
+ 'nextcloud' => ['allow_local_address' => true],
+ ]]);
+ }
+
+ /**
+ * @dataProvider dataPreventLocalAddress
+ * @param string $uri
+ */
+ public function testPreventLocalAddressOnGet(string $uri): void {
+ $this->expectException(LocalServerException::class);
+ $this->client->get('http://' . $uri);
+ }
+
+ /**
+ * @dataProvider dataPreventLocalAddress
+ * @param string $uri
+ */
+ public function testPreventLocalAddressOnHead(string $uri): void {
+ $this->expectException(LocalServerException::class);
+ $this->client->head('http://' . $uri);
+ }
+
+ /**
+ * @dataProvider dataPreventLocalAddress
+ * @param string $uri
+ */
+ public function testPreventLocalAddressOnPost(string $uri): void {
+ $this->expectException(LocalServerException::class);
+ $this->client->post('http://' . $uri);
+ }
+
+ /**
+ * @dataProvider dataPreventLocalAddress
+ * @param string $uri
+ */
+ public function testPreventLocalAddressOnPut(string $uri): void {
+ $this->expectException(LocalServerException::class);
+ $this->client->put('http://' . $uri);
+ }
+
+ /**
+ * @dataProvider dataPreventLocalAddress
+ * @param string $uri
+ */
+ public function testPreventLocalAddressOnDelete(string $uri): void {
+ $this->expectException(LocalServerException::class);
+ $this->client->delete('http://' . $uri);
+ }
+
private function setUpDefaultRequestOptions(): void {
+ $this->config->expects($this->once())
+ ->method('getSystemValueBool')
+ ->with('allow_local_remote_servers', false)
+ ->willReturn(true);
$this->config
- ->expects($this->at(0))
+ ->expects($this->at(1))
->method('getSystemValue')
->with('proxy', null)
->willReturn('foo');
$this->config
- ->expects($this->at(1))
+ ->expects($this->at(2))
->method('getSystemValue')
->with('proxyuserpwd', null)
->willReturn(null);
$this->config
- ->expects($this->at(2))
+ ->expects($this->at(3))
->method('getSystemValue')
->with('proxyexclude', [])
->willReturn([]);