Merge pull request #52182 from nextcloud/feat/dav/public-share-chunked-upload

pull/52594/head
John Molakvoæ 2025-05-06 14:25:28 +07:00 committed by GitHub
commit 24c6a1ff0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
124 changed files with 328 additions and 177 deletions

@ -68,7 +68,7 @@ $requestUri = Server::get(IRequest::class)->getRequestUri();
$linkCheckPlugin = new PublicLinkCheckPlugin();
$filesDropPlugin = new FilesDropPlugin();
$server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin, $filesDropPlugin) {
$server = $serverFactory->createServer(false, $baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin, $filesDropPlugin) {
$isAjax = in_array('XMLHttpRequest', explode(',', $_SERVER['HTTP_X_REQUESTED_WITH'] ?? ''));
/** @var FederatedShareProvider $shareProvider */
$federatedShareProvider = Server::get(FederatedShareProvider::class);

@ -68,7 +68,7 @@ $authPlugin->addBackend($bearerAuthPlugin);
$requestUri = Server::get(IRequest::class)->getRequestUri();
$server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, function () {
$server = $serverFactory->createServer(false, $baseuri, $requestUri, $authPlugin, function () {
// use the view for the logged in user
return Filesystem::getView();
});

@ -14,12 +14,15 @@ use OCA\DAV\Files\Sharing\FilesDropPlugin;
use OCA\DAV\Files\Sharing\PublicLinkCheckPlugin;
use OCA\DAV\Storage\PublicOwnerWrapper;
use OCA\DAV\Storage\PublicShareWrapper;
use OCA\DAV\Upload\ChunkingPlugin;
use OCA\DAV\Upload\ChunkingV2Plugin;
use OCA\FederatedFileSharing\FederatedShareProvider;
use OCP\BeforeSabrePubliclyLoadedEvent;
use OCP\Constants;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\IRootFolder;
use OCP\Files\Mount\IMountManager;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IPreview;
@ -75,12 +78,8 @@ $serverFactory = new ServerFactory(
$linkCheckPlugin = new PublicLinkCheckPlugin();
$filesDropPlugin = new FilesDropPlugin();
// Define root url with /public.php/dav/files/TOKEN
/** @var string $baseuri defined in public.php */
preg_match('/(^files\/[a-z0-9-_]+)/i', substr($requestUri, strlen($baseuri)), $match);
$baseuri = $baseuri . $match[0];
$server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin, $filesDropPlugin) {
$server = $serverFactory->createServer(true, $baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin, $filesDropPlugin) {
// GET must be allowed for e.g. showing images and allowing Zip downloads
if ($server->httpRequest->getMethod() !== 'GET') {
// If this is *not* a GET request we only allow access to public DAV from AJAX or when Server2Server is allowed
@ -142,6 +141,8 @@ $server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, funct
$server->addPlugin($linkCheckPlugin);
$server->addPlugin($filesDropPlugin);
$server->addPlugin(new ChunkingV2Plugin(Server::get(ICacheFactory::class)));
$server->addPlugin(new ChunkingPlugin());
// allow setup of additional plugins
$event = new BeforeSabrePubliclyLoadedEvent($server);

@ -284,6 +284,7 @@ return array(
'OCA\\DAV\\Files\\RootCollection' => $baseDir . '/../lib/Files/RootCollection.php',
'OCA\\DAV\\Files\\Sharing\\FilesDropPlugin' => $baseDir . '/../lib/Files/Sharing/FilesDropPlugin.php',
'OCA\\DAV\\Files\\Sharing\\PublicLinkCheckPlugin' => $baseDir . '/../lib/Files/Sharing/PublicLinkCheckPlugin.php',
'OCA\\DAV\\Files\\Sharing\\RootCollection' => $baseDir . '/../lib/Files/Sharing/RootCollection.php',
'OCA\\DAV\\Listener\\ActivityUpdaterListener' => $baseDir . '/../lib/Listener/ActivityUpdaterListener.php',
'OCA\\DAV\\Listener\\AddMissingIndicesListener' => $baseDir . '/../lib/Listener/AddMissingIndicesListener.php',
'OCA\\DAV\\Listener\\AddressbookListener' => $baseDir . '/../lib/Listener/AddressbookListener.php',

@ -299,6 +299,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Files\\RootCollection' => __DIR__ . '/..' . '/../lib/Files/RootCollection.php',
'OCA\\DAV\\Files\\Sharing\\FilesDropPlugin' => __DIR__ . '/..' . '/../lib/Files/Sharing/FilesDropPlugin.php',
'OCA\\DAV\\Files\\Sharing\\PublicLinkCheckPlugin' => __DIR__ . '/..' . '/../lib/Files/Sharing/PublicLinkCheckPlugin.php',
'OCA\\DAV\\Files\\Sharing\\RootCollection' => __DIR__ . '/..' . '/../lib/Files/Sharing/RootCollection.php',
'OCA\\DAV\\Listener\\ActivityUpdaterListener' => __DIR__ . '/..' . '/../lib/Listener/ActivityUpdaterListener.php',
'OCA\\DAV\\Listener\\AddMissingIndicesListener' => __DIR__ . '/..' . '/../lib/Listener/AddMissingIndicesListener.php',
'OCA\\DAV\\Listener\\AddressbookListener' => __DIR__ . '/..' . '/../lib/Listener/AddressbookListener.php',

@ -17,12 +17,13 @@ class Capabilities implements ICapability {
}
/**
* @return array{dav: array{chunking: string, bulkupload?: string, absence-supported?: bool, absence-replacement?: bool}}
* @return array{dav: array{chunking: string, public_shares_chunking: bool, bulkupload?: string, absence-supported?: bool, absence-replacement?: bool}}
*/
public function getCapabilities() {
$capabilities = [
'dav' => [
'chunking' => '1.0',
'public_shares_chunking' => true,
]
];
if ($this->config->getSystemValueBool('bulkupload.enabled', true)) {

@ -13,7 +13,9 @@ use OCA\DAV\AppInfo\Application;
use OCA\DAV\Connector\Sabre\Exception\FileLocked;
use OCA\DAV\Connector\Sabre\Exception\Forbidden;
use OCA\DAV\Connector\Sabre\Exception\InvalidPath;
use OCA\DAV\Storage\PublicShareWrapper;
use OCP\App\IAppManager;
use OCP\Constants;
use OCP\Files\FileInfo;
use OCP\Files\Folder;
use OCP\Files\ForbiddenException;
@ -172,7 +174,19 @@ class Directory extends Node implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuot
* @throws \Sabre\DAV\Exception\ServiceUnavailable
*/
public function getChild($name, $info = null, ?IRequest $request = null, ?IL10N $l10n = null) {
if (!$this->info->isReadable()) {
$storage = $this->info->getStorage();
$allowDirectory = false;
if ($storage instanceof PublicShareWrapper) {
$share = $storage->getShare();
$allowDirectory =
// Only allow directories for file drops
($share->getPermissions() & Constants::PERMISSION_READ) !== Constants::PERMISSION_READ &&
// And only allow it for directories which are a direct child of the share root
$this->info->getId() === $share->getNodeId();
}
// For file drop we need to be allowed to read the directory with the nickname
if (!$allowDirectory && !$this->info->isReadable()) {
// avoid detecting files through this way
throw new NotFound();
}
@ -198,6 +212,11 @@ class Directory extends Node implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuot
if ($info->getMimeType() === FileInfo::MIMETYPE_FOLDER) {
$node = new \OCA\DAV\Connector\Sabre\Directory($this->fileView, $info, $this->tree, $this->shareManager);
} else {
// In case reading a directory was allowed but it turns out the node was a not a directory, reject it now.
if (!$this->info->isReadable()) {
throw new NotFound();
}
$node = new File($this->fileView, $info, $this->shareManager, $request, $l10n);
}
if ($this->tree) {

@ -720,15 +720,15 @@ class FilesPlugin extends ServerPlugin {
*/
public function sendFileIdHeader($filePath, ?\Sabre\DAV\INode $node = null) {
// we get the node for the given $filePath here because in case of afterCreateFile $node is the parent folder
if (!$this->server->tree->nodeExists($filePath)) {
return;
}
$node = $this->server->tree->getNodeForPath($filePath);
if ($node instanceof Node) {
$fileId = $node->getFileId();
if (!is_null($fileId)) {
$this->server->httpResponse->setHeader('OC-FileId', $fileId);
try {
$node = $this->server->tree->getNodeForPath($filePath);
if ($node instanceof Node) {
$fileId = $node->getFileId();
if (!is_null($fileId)) {
$this->server->httpResponse->setHeader('OC-FileId', $fileId);
}
}
} catch (NotFound) {
}
}
}

@ -155,6 +155,11 @@ class Principal implements BackendInterface {
'uri' => 'principals/system/' . $name,
'{DAV:}displayname' => $this->languageFactory->get('dav')->t('Accounts'),
];
} elseif ($prefix === 'principals/shares') {
return [
'uri' => 'principals/shares/' . $name,
'{DAV:}displayname' => $name,
];
}
return null;
}

@ -8,11 +8,14 @@
namespace OCA\DAV\Connector\Sabre;
use OC\Files\View;
use OC\KnownUser\KnownUserService;
use OCA\DAV\AppInfo\PluginManager;
use OCA\DAV\CalDAV\DefaultCalendarValidator;
use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCA\DAV\DAV\CustomPropertiesBackend;
use OCA\DAV\DAV\ViewOnlyPlugin;
use OCA\DAV\Files\BrowserErrorPagePlugin;
use OCA\DAV\Upload\CleanupService;
use OCA\Theming\ThemingDefaults;
use OCP\Accounts\IAccountManager;
use OCP\App\IAppManager;
@ -20,6 +23,7 @@ use OCP\Comments\ICommentsManager;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Folder;
use OCP\Files\IFilenameValidator;
use OCP\Files\IRootFolder;
use OCP\Files\Mount\IMountManager;
use OCP\IConfig;
use OCP\IDBConnection;
@ -28,12 +32,14 @@ use OCP\IL10N;
use OCP\IPreview;
use OCP\IRequest;
use OCP\ITagManager;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\SabrePluginEvent;
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ISystemTagObjectMapper;
use Psr\Log\LoggerInterface;
use Sabre\DAV\Auth\Plugin;
use Sabre\DAV\SimpleCollection;
class ServerFactory {
@ -54,13 +60,22 @@ class ServerFactory {
/**
* @param callable $viewCallBack callback that should return the view for the dav endpoint
*/
public function createServer(string $baseUri,
public function createServer(
bool $isPublicShare,
string $baseUri,
string $requestUri,
Plugin $authPlugin,
callable $viewCallBack): Server {
callable $viewCallBack,
): Server {
// Fire up server
$objectTree = new ObjectTree();
$server = new Server($objectTree);
if ($isPublicShare) {
$rootCollection = new SimpleCollection('root');
$tree = new CachingTree($rootCollection);
} else {
$rootCollection = null;
$tree = new ObjectTree();
}
$server = new Server($tree);
// Set URL explicitly due to reverse-proxy situations
$server->httpRequest->setUrl($requestUri);
$server->setBaseUri($baseUri);
@ -81,7 +96,7 @@ class ServerFactory {
$server->addPlugin(new RequestIdHeaderPlugin($this->request));
$server->addPlugin(new ZipFolderPlugin(
$objectTree,
$tree,
$this->logger,
$this->eventDispatcher,
));
@ -101,7 +116,7 @@ class ServerFactory {
}
// wait with registering these until auth is handled and the filesystem is setup
$server->on('beforeMethod:*', function () use ($server, $objectTree, $viewCallBack): void {
$server->on('beforeMethod:*', function () use ($server, $tree, $viewCallBack, $isPublicShare, $rootCollection): void {
// ensure the skeleton is copied
$userFolder = \OC::$server->getUserFolder();
@ -115,15 +130,49 @@ class ServerFactory {
// Create Nextcloud Dir
if ($rootInfo->getType() === 'dir') {
$root = new Directory($view, $rootInfo, $objectTree);
$root = new Directory($view, $rootInfo, $tree);
} else {
$root = new File($view, $rootInfo);
}
$objectTree->init($root, $view, $this->mountManager);
if ($isPublicShare) {
$userPrincipalBackend = new Principal(
\OCP\Server::get(IUserManager::class),
\OCP\Server::get(IGroupManager::class),
\OCP\Server::get(IAccountManager::class),
\OCP\Server::get(\OCP\Share\IManager::class),
\OCP\Server::get(IUserSession::class),
\OCP\Server::get(IAppManager::class),
\OCP\Server::get(ProxyMapper::class),
\OCP\Server::get(KnownUserService::class),
\OCP\Server::get(IConfig::class),
\OC::$server->getL10NFactory(),
);
// Mount the share collection at /public.php/dav/shares/<share token>
$rootCollection->addChild(new \OCA\DAV\Files\Sharing\RootCollection(
$root,
$userPrincipalBackend,
'principals/shares',
));
// Mount the upload collection at /public.php/dav/uploads/<share token>
$rootCollection->addChild(new \OCA\DAV\Upload\RootCollection(
$userPrincipalBackend,
'principals/shares',
\OCP\Server::get(CleanupService::class),
\OCP\Server::get(IRootFolder::class),
\OCP\Server::get(IUserSession::class),
\OCP\Server::get(\OCP\Share\IManager::class),
));
} else {
/** @var ObjectTree $tree */
$tree->init($root, $view, $this->mountManager);
}
$server->addPlugin(
new FilesPlugin(
$objectTree,
$tree,
$this->config,
$this->request,
$this->previewManager,
@ -143,16 +192,16 @@ class ServerFactory {
));
if ($this->userSession->isLoggedIn()) {
$server->addPlugin(new TagsPlugin($objectTree, $this->tagManager, $this->eventDispatcher, $this->userSession));
$server->addPlugin(new TagsPlugin($tree, $this->tagManager, $this->eventDispatcher, $this->userSession));
$server->addPlugin(new SharesPlugin(
$objectTree,
$tree,
$this->userSession,
$userFolder,
\OCP\Server::get(\OCP\Share\IManager::class)
));
$server->addPlugin(new CommentPropertiesPlugin(\OCP\Server::get(ICommentsManager::class), $this->userSession));
$server->addPlugin(new FilesReportPlugin(
$objectTree,
$tree,
$view,
\OCP\Server::get(ISystemTagManager::class),
\OCP\Server::get(ISystemTagObjectMapper::class),
@ -167,7 +216,7 @@ class ServerFactory {
new \Sabre\DAV\PropertyStorage\Plugin(
new CustomPropertiesBackend(
$server,
$objectTree,
$tree,
$this->databaseConnection,
$this->userSession->getUser(),
\OCP\Server::get(DefaultCalendarValidator::class),

@ -73,7 +73,7 @@ class FilesDropPlugin extends ServerPlugin {
if ($isFileRequest && ($nickName == null || trim($nickName) === '')) {
throw new MethodNotAllowed('Nickname is required for file requests');
}
// If this is a file request we need to create a folder for the user
if ($isFileRequest) {
// Check if the folder already exists
@ -83,9 +83,9 @@ class FilesDropPlugin extends ServerPlugin {
// Put all files in the subfolder
$path = $nickName . '/' . $path;
}
$newName = \OC_Helper::buildNotExistingFileNameForView('/', $path, $this->view);
$url = $request->getBaseUrl() . $newName;
$url = $request->getBaseUrl() . '/files/' . $this->share->getToken() . $newName;
$request->setUrl($url);
}

@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\DAV\Files\Sharing;
use Sabre\DAV\INode;
use Sabre\DAVACL\AbstractPrincipalCollection;
use Sabre\DAVACL\PrincipalBackend\BackendInterface;
class RootCollection extends AbstractPrincipalCollection {
public function __construct(
private INode $root,
BackendInterface $principalBackend,
string $principalPrefix = 'principals',
) {
parent::__construct($principalBackend, $principalPrefix);
}
public function getChildForPrincipal(array $principalInfo): INode {
return $this->root;
}
public function getName() {
return 'files';
}
}

@ -160,6 +160,7 @@ class RootCollection extends SimpleCollection {
Server::get(CleanupService::class),
$rootFolder,
$userSession,
$shareManager,
);
$uploadCollection->disableListing = $disableListing;

@ -10,20 +10,18 @@ namespace OCA\DAV\Upload;
use OCA\DAV\BackgroundJob\UploadCleanup;
use OCP\BackgroundJob\IJobList;
use OCP\IUserSession;
class CleanupService {
public function __construct(
private IUserSession $userSession,
private IJobList $jobList,
) {
}
public function addJob(string $folder) {
$this->jobList->add(UploadCleanup::class, ['uid' => $this->userSession->getUser()->getUID(), 'folder' => $folder]);
public function addJob(string $uid, string $folder) {
$this->jobList->add(UploadCleanup::class, ['uid' => $uid, 'folder' => $folder]);
}
public function removeJob(string $folder) {
$this->jobList->remove(UploadCleanup::class, ['uid' => $this->userSession->getUser()->getUID(), 'folder' => $folder]);
public function removeJob(string $uid, string $folder) {
$this->jobList->remove(UploadCleanup::class, ['uid' => $uid, 'folder' => $folder]);
}
}

@ -11,6 +11,7 @@ namespace OCA\DAV\Upload;
use OCP\Files\IRootFolder;
use OCP\IUserSession;
use OCP\Share\IManager;
use Sabre\DAVACL\AbstractPrincipalCollection;
use Sabre\DAVACL\PrincipalBackend;
@ -22,6 +23,7 @@ class RootCollection extends AbstractPrincipalCollection {
private CleanupService $cleanupService,
private IRootFolder $rootFolder,
private IUserSession $userSession,
private IManager $shareManager,
) {
parent::__construct($principalBackend, $principalPrefix);
}
@ -30,7 +32,13 @@ class RootCollection extends AbstractPrincipalCollection {
* @inheritdoc
*/
public function getChildForPrincipal(array $principalInfo): UploadHome {
return new UploadHome($principalInfo, $this->cleanupService, $this->rootFolder, $this->userSession);
return new UploadHome(
$principalInfo,
$this->cleanupService,
$this->rootFolder,
$this->userSession,
$this->shareManager,
);
}
/**

@ -21,6 +21,7 @@ class UploadFolder implements ICollection {
private Directory $node,
private CleanupService $cleanupService,
private IStorage $storage,
private string $uid,
) {
}
@ -89,7 +90,7 @@ class UploadFolder implements ICollection {
$this->node->delete();
// Background cleanup job is not needed anymore
$this->cleanupService->removeJob($this->getName());
$this->cleanupService->removeJob($this->uid, $this->getName());
}
public function getName() {

@ -17,6 +17,7 @@ use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\ICollection;
class UploadHome implements ICollection {
private string $uid;
private ?Folder $uploadFolder = null;
public function __construct(
@ -24,7 +25,19 @@ class UploadHome implements ICollection {
private readonly CleanupService $cleanupService,
private readonly IRootFolder $rootFolder,
private readonly IUserSession $userSession,
private readonly \OCP\Share\IManager $shareManager,
) {
[$prefix, $name] = \Sabre\Uri\split($principalInfo['uri']);
if ($prefix === 'principals/shares') {
$this->uid = $this->shareManager->getShareByToken($name)->getShareOwner();
} else {
$user = $this->userSession->getUser();
if (!$user) {
throw new Forbidden('Not logged in');
}
$this->uid = $user->getUID();
}
}
public function createFile($name, $data = null) {
@ -35,16 +48,26 @@ class UploadHome implements ICollection {
$this->impl()->createDirectory($name);
// Add a cleanup job
$this->cleanupService->addJob($name);
$this->cleanupService->addJob($this->uid, $name);
}
public function getChild($name): UploadFolder {
return new UploadFolder($this->impl()->getChild($name), $this->cleanupService, $this->getStorage());
return new UploadFolder(
$this->impl()->getChild($name),
$this->cleanupService,
$this->getStorage(),
$this->uid,
);
}
public function getChildren(): array {
return array_map(function ($node) {
return new UploadFolder($node, $this->cleanupService, $this->getStorage());
return new UploadFolder(
$node,
$this->cleanupService,
$this->getStorage(),
$this->uid,
);
}, $this->impl()->getChildren());
}
@ -71,11 +94,7 @@ class UploadHome implements ICollection {
private function getUploadFolder(): Folder {
if ($this->uploadFolder === null) {
$user = $this->userSession->getUser();
if (!$user) {
throw new Forbidden('Not logged in');
}
$path = '/' . $user->getUID() . '/uploads';
$path = '/' . $this->uid . '/uploads';
try {
$folder = $this->rootFolder->get($path);
if (!$folder instanceof Folder) {

@ -29,12 +29,16 @@
"dav": {
"type": "object",
"required": [
"chunking"
"chunking",
"public_shares_chunking"
],
"properties": {
"chunking": {
"type": "string"
},
"public_shares_chunking": {
"type": "boolean"
},
"bulkupload": {
"type": "string"
},

@ -28,6 +28,7 @@ class CapabilitiesTest extends TestCase {
$expected = [
'dav' => [
'chunking' => '1.0',
'public_shares_chunking' => true,
],
];
$this->assertSame($expected, $capabilities->getCapabilities());
@ -47,6 +48,7 @@ class CapabilitiesTest extends TestCase {
$expected = [
'dav' => [
'chunking' => '1.0',
'public_shares_chunking' => true,
'bulkupload' => '1.0',
],
];
@ -67,6 +69,7 @@ class CapabilitiesTest extends TestCase {
$expected = [
'dav' => [
'chunking' => '1.0',
'public_shares_chunking' => true,
'absence-supported' => true,
'absence-replacement' => true,
],

@ -137,7 +137,7 @@ abstract class RequestTestCase extends TestCase {
$authBackend = new Auth($user, $password);
$authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
$server = $this->serverFactory->createServer('/', 'dummy', $authPlugin, function () use ($view) {
$server = $this->serverFactory->createServer(false, '/', 'dummy', $authPlugin, function () use ($view) {
return $view;
});
$server->addPlugin($exceptionPlugin);

@ -53,6 +53,10 @@ class FilesDropPluginTest extends TestCase {
$this->share->expects($this->any())
->method('getAttributes')
->willReturn($attributes);
$this->share
->method('getToken')
->willReturn('token');
}
public function testInitialize(): void {
@ -86,7 +90,7 @@ class FilesDropPluginTest extends TestCase {
->willReturn('PUT');
$this->request->method('getPath')
->willReturn('file.txt');
->willReturn('/files/token/file.txt');
$this->request->method('getBaseUrl')
->willReturn('https://example.com');
@ -97,7 +101,7 @@ class FilesDropPluginTest extends TestCase {
$this->request->expects($this->once())
->method('setUrl')
->with('https://example.com/file.txt');
->with('https://example.com/files/token/file.txt');
$this->plugin->beforeMethod($this->request, $this->response);
}
@ -111,7 +115,7 @@ class FilesDropPluginTest extends TestCase {
->willReturn('PUT');
$this->request->method('getPath')
->willReturn('file.txt');
->willReturn('/files/token/file.txt');
$this->request->method('getBaseUrl')
->willReturn('https://example.com');
@ -127,7 +131,7 @@ class FilesDropPluginTest extends TestCase {
$this->request->expects($this->once())
->method('setUrl')
->with($this->equalTo('https://example.com/file (2).txt'));
->with($this->equalTo('https://example.com/files/token/file (2).txt'));
$this->plugin->beforeMethod($this->request, $this->response);
}
@ -154,7 +158,7 @@ class FilesDropPluginTest extends TestCase {
->willReturn('PUT');
$this->request->method('getPath')
->willReturn('folder/file.txt');
->willReturn('/files/token/folder/file.txt');
$this->request->method('getBaseUrl')
->willReturn('https://example.com');
@ -170,7 +174,7 @@ class FilesDropPluginTest extends TestCase {
$this->request->expects($this->once())
->method('setUrl')
->with($this->equalTo('https://example.com/file (2).txt'));
->with($this->equalTo('https://example.com/files/token/file (2).txt'));
$this->plugin->beforeMethod($this->request, $this->response);
}

2
dist/1656-1656.js vendored

@ -0,0 +1,2 @@
"use strict";(self.webpackChunknextcloud=self.webpackChunknextcloud||[]).push([[1656],{4466:(e,t,a)=>{a.d(t,{A:()=>l});var n=a(71354),i=a.n(n),r=a(76314),s=a.n(r)()(i());s.push([e.id,"\n.invalid-filename-dialog__input[data-v-3a479259] {\n\t/* Ensure the helper text can always be shown without jumping */\n\tmin-height: calc(var(--default-clickable-area) + 4 * var(--default-font-size));\n}\n","",{version:3,sources:["webpack://./node_modules/@nextcloud/upload/dist/assets/InvalidFilenameDialog-YDOzIzS6.css"],names:[],mappings:";AACA;CACC,+DAA+D;CAC/D,8EAA8E;AAC/E",sourcesContent:["\n.invalid-filename-dialog__input[data-v-3a479259] {\n\t/* Ensure the helper text can always be shown without jumping */\n\tmin-height: calc(var(--default-clickable-area) + 4 * var(--default-font-size));\n}\n"],sourceRoot:""}]);const l=s},11656:(e,t,a)=>{a.r(t),a.d(t,{default:()=>_});var n=a(85072),i=a.n(n),r=a(97825),s=a.n(r),l=a(77659),o=a.n(l),c=a(55056),d=a.n(c),m=a(10540),u=a.n(m),h=a(41113),p=a.n(h),f=a(4466),v={};v.styleTagTransform=p(),v.setAttributes=d(),v.insert=o().bind(null,"head"),v.domAPI=s(),v.insertStyleElement=u(),i()(f.A,v),f.A&&f.A.locals&&f.A.locals;var g=a(35810),w=a(85471),A=a(85748),E=a(94219),b=a(82182),N=a(40083);const y=(0,w.pM)({components:{NcDialog:E.A,NcNoteCard:N.A,NcTextField:b.A},props:{error:{type:g.di,required:!0},validateFilename:{type:Function,required:!0}},setup:()=>({t:A.t}),data:()=>({newName:"",validationError:""}),computed:{isValidName(){return""===this.validationError},isInvalidFileType(){return this.error.reason===g.nF.Extension&&null!==this.error.segment.match(/^\.\w/)},canRename(){return!this.isInvalidFileType},dialogButtons(){const e=[{label:(0,A.t)("Cancel"),type:"error",callback:()=>{this.$emit("close",{cancel:!0})}},{label:(0,A.t)("Skip"),callback:()=>{this.$emit("close",{skip:!0})}}];return this.canRename&&e.push({label:(0,A.t)("Rename"),type:"primary",disabled:!this.isValidName,callback:()=>{this.$emit("close",{rename:this.newName.trimEnd()})}}),e}},watch:{error:{handler(){this.validationError=this.getErrorText(this.error),this.newName=this.error.filename},immediate:!0},newName(){try{this.validateFilename(this.newName.trimEnd()),this.validationError=""}catch(e){this.validationError=this.getErrorText(e)}finally{const e=this.$refs.textfield?.$el.querySelector("input");e&&(e.setCustomValidity(this.validationError),e.reportValidity())}}},methods:{getErrorText(e){switch(e.reason){case g.nF.Character:return(0,A.t)('"{segment}" is not allowed inside a file or folder name.',{segment:e.segment});case g.nF.ReservedName:return(0,A.t)('"{segment}" is a forbidden file or folder name.',{segment:e.segment});case g.nF.Extension:return e.segment.match(/\.\w/)?(0,A.t)('"{segment}" is a forbidden file type.',{segment:e.segment}):(0,A.t)('Filenames must not end with "{segment}".',{segment:e.segment})}}}});var x=function(){var e=this,t=e._self._c;return e._self._setupProxy,t("NcDialog",{attrs:{buttons:e.dialogButtons,name:e.t("Invalid filename")},on:{close:function(t){return e.$emit("close",{cancel:!0})}}},[t("NcNoteCard",{attrs:{severity:"error"}},[e._v(" "+e._s(e.getErrorText(e.error))+" "+e._s(e.t("You can either rename the file, skip this file or cancel the whole operation."))+" ")]),e.canRename?t("NcTextField",{ref:"textfield",staticClass:"invalid-filename-dialog__input",attrs:{error:!e.isValidName,"helper-text":e.validationError,label:e.t("New filename"),value:e.newName},on:{"update:value":function(t){e.newName=t}}}):e._e()],1)},C=[];const _=(0,A.n)(y,x,C,!1,null,"3a479259").exports}}]);
//# sourceMappingURL=1656-1656.js.map?v=05d90ab05fafdbaeed35

@ -78,7 +78,7 @@ This file is generated from multiple sources. Included packages:
- version: 0.2.4
- license: GPL-3.0-or-later
- @nextcloud/upload
- version: 1.9.1
- version: 1.10.0
- license: AGPL-3.0-or-later
- @nextcloud/vue
- version: 8.25.1
@ -93,7 +93,7 @@ This file is generated from multiple sources. Included packages:
- version: 4.5.0
- license: Apache-2.0
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
1656-1656.js.license

2
dist/3485-3485.js vendored

File diff suppressed because one or more lines are too long

@ -78,7 +78,7 @@ This file is generated from multiple sources. Included packages:
- version: 0.2.4
- license: GPL-3.0-or-later
- @nextcloud/upload
- version: 1.9.1
- version: 1.10.0
- license: AGPL-3.0-or-later
- @nextcloud/vue
- version: 8.25.1
@ -93,7 +93,7 @@ This file is generated from multiple sources. Included packages:
- version: 4.5.0
- license: Apache-2.0
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
3485-3485.js.license

4
dist/358-358.js vendored

File diff suppressed because one or more lines are too long

@ -82,7 +82,7 @@ This file is generated from multiple sources. Included packages:
- version: 0.2.4
- license: GPL-3.0-or-later
- @nextcloud/upload
- version: 1.9.1
- version: 1.10.0
- license: AGPL-3.0-or-later
- @nextcloud/vue
- version: 8.25.1
@ -97,7 +97,7 @@ This file is generated from multiple sources. Included packages:
- version: 4.5.0
- license: Apache-2.0
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

File diff suppressed because one or more lines are too long

@ -111,7 +111,7 @@ This file is generated from multiple sources. Included packages:
- version: 1.0.7
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- balanced-match
- version: 1.0.2

@ -93,7 +93,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -60,7 +60,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -109,7 +109,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- bail
- version: 2.0.2

@ -54,7 +54,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -113,7 +113,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- bail
- version: 2.0.2

@ -147,7 +147,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- bail
- version: 2.0.2

2
dist/6445-6445.js vendored

@ -1,2 +0,0 @@
"use strict";(self.webpackChunknextcloud=self.webpackChunknextcloud||[]).push([[6445],{4466:(e,t,a)=>{a.d(t,{A:()=>l});var n=a(71354),i=a.n(n),r=a(76314),s=a.n(r)()(i());s.push([e.id,"\n.invalid-filename-dialog__input[data-v-3a479259] {\n\t/* Ensure the helper text can always be shown without jumping */\n\tmin-height: calc(var(--default-clickable-area) + 4 * var(--default-font-size));\n}\n","",{version:3,sources:["webpack://./node_modules/@nextcloud/upload/dist/assets/InvalidFilenameDialog-YDOzIzS6.css"],names:[],mappings:";AACA;CACC,+DAA+D;CAC/D,8EAA8E;AAC/E",sourcesContent:["\n.invalid-filename-dialog__input[data-v-3a479259] {\n\t/* Ensure the helper text can always be shown without jumping */\n\tmin-height: calc(var(--default-clickable-area) + 4 * var(--default-font-size));\n}\n"],sourceRoot:""}]);const l=s},46445:(e,t,a)=>{a.r(t),a.d(t,{default:()=>_});var n=a(85072),i=a.n(n),r=a(97825),s=a.n(r),l=a(77659),o=a.n(l),c=a(55056),d=a.n(c),m=a(10540),u=a.n(m),h=a(41113),p=a.n(h),f=a(4466),v={};v.styleTagTransform=p(),v.setAttributes=d(),v.insert=o().bind(null,"head"),v.domAPI=s(),v.insertStyleElement=u(),i()(f.A,v),f.A&&f.A.locals&&f.A.locals;var g=a(35810),w=a(85471),A=a(4011),E=a(94219),b=a(82182),N=a(40083);const y=(0,w.pM)({components:{NcDialog:E.A,NcNoteCard:N.A,NcTextField:b.A},props:{error:{type:g.di,required:!0},validateFilename:{type:Function,required:!0}},setup:()=>({t:A.t}),data:()=>({newName:"",validationError:""}),computed:{isValidName(){return""===this.validationError},isInvalidFileType(){return this.error.reason===g.nF.Extension&&null!==this.error.segment.match(/^\.\w/)},canRename(){return!this.isInvalidFileType},dialogButtons(){const e=[{label:(0,A.t)("Cancel"),type:"error",callback:()=>{this.$emit("close",{cancel:!0})}},{label:(0,A.t)("Skip"),callback:()=>{this.$emit("close",{skip:!0})}}];return this.canRename&&e.push({label:(0,A.t)("Rename"),type:"primary",disabled:!this.isValidName,callback:()=>{this.$emit("close",{rename:this.newName.trimEnd()})}}),e}},watch:{error:{handler(){this.validationError=this.getErrorText(this.error),this.newName=this.error.filename},immediate:!0},newName(){try{this.validateFilename(this.newName.trimEnd()),this.validationError=""}catch(e){this.validationError=this.getErrorText(e)}finally{const e=this.$refs.textfield?.$el.querySelector("input");e&&(e.setCustomValidity(this.validationError),e.reportValidity())}}},methods:{getErrorText(e){switch(e.reason){case g.nF.Character:return(0,A.t)('"{segment}" is not allowed inside a file or folder name.',{segment:e.segment});case g.nF.ReservedName:return(0,A.t)('"{segment}" is a forbidden file or folder name.',{segment:e.segment});case g.nF.Extension:return e.segment.match(/\.\w/)?(0,A.t)('"{segment}" is a forbidden file type.',{segment:e.segment}):(0,A.t)('Filenames must not end with "{segment}".',{segment:e.segment})}}}});var x=function(){var e=this,t=e._self._c;return e._self._setupProxy,t("NcDialog",{attrs:{buttons:e.dialogButtons,name:e.t("Invalid filename")},on:{close:function(t){return e.$emit("close",{cancel:!0})}}},[t("NcNoteCard",{attrs:{severity:"error"}},[e._v(" "+e._s(e.getErrorText(e.error))+" "+e._s(e.t("You can either rename the file, skip this file or cancel the whole operation."))+" ")]),e.canRename?t("NcTextField",{ref:"textfield",staticClass:"invalid-filename-dialog__input",attrs:{error:!e.isValidName,"helper-text":e.validationError,label:e.t("New filename"),value:e.newName},on:{"update:value":function(t){e.newName=t}}}):e._e()],1)},C=[];const _=(0,A.n)(y,x,C,!1,null,"3a479259").exports}}]);
//# sourceMappingURL=6445-6445.js.map?v=9acae0b42cd0cd19da0e

@ -1 +0,0 @@
6445-6445.js.license

@ -111,7 +111,7 @@ This file is generated from multiple sources. Included packages:
- version: 1.0.7
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- balanced-match
- version: 1.0.2

2
dist/7527-7527.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
7527-7527.js.license

@ -66,7 +66,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -82,7 +82,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -111,7 +111,7 @@ This file is generated from multiple sources. Included packages:
- version: 1.0.7
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- balanced-match
- version: 1.0.2

@ -80,7 +80,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -125,7 +125,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -60,7 +60,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -72,7 +72,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -101,7 +101,7 @@ This file is generated from multiple sources. Included packages:
- version: 1.0.7
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- balanced-match
- version: 1.0.2

@ -111,7 +111,7 @@ This file is generated from multiple sources. Included packages:
- version: 1.0.7
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- balanced-match
- version: 1.0.2

File diff suppressed because one or more lines are too long

@ -175,7 +175,7 @@ This file is generated from multiple sources. Included packages:
- version: 0.2.4
- license: GPL-3.0-or-later
- @nextcloud/upload
- version: 1.9.1
- version: 1.10.0
- license: AGPL-3.0-or-later
- @nextcloud/vue-select
- version: 3.25.1
@ -205,7 +205,7 @@ This file is generated from multiple sources. Included packages:
- version: 4.5.0
- license: Apache-2.0
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- bail
- version: 2.0.2

File diff suppressed because one or more lines are too long

@ -52,7 +52,7 @@ This file is generated from multiple sources. Included packages:
- version: 8.25.1
- license: AGPL-3.0-or-later
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -77,7 +77,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -103,7 +103,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- backbone
- version: 1.6.1

@ -114,7 +114,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- backbone
- version: 1.6.1

@ -33,7 +33,7 @@ This file is generated from multiple sources. Included packages:
- version: 3.0.1
- license: GPL-3.0-or-later
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -79,7 +79,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -50,7 +50,7 @@ This file is generated from multiple sources. Included packages:
- version: 8.25.1
- license: AGPL-3.0-or-later
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -79,7 +79,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -75,7 +75,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -47,7 +47,7 @@ This file is generated from multiple sources. Included packages:
- version: 8.25.1
- license: AGPL-3.0-or-later
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -139,7 +139,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- bail
- version: 2.0.2

@ -129,7 +129,7 @@ This file is generated from multiple sources. Included packages:
- version: 1.0.7
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- balanced-match
- version: 1.0.2

@ -67,7 +67,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -70,7 +70,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

File diff suppressed because one or more lines are too long

@ -103,7 +103,7 @@ This file is generated from multiple sources. Included packages:
- version: 0.2.4
- license: GPL-3.0-or-later
- @nextcloud/upload
- version: 1.9.1
- version: 1.10.0
- license: AGPL-3.0-or-later
- @nextcloud/vue
- version: 8.25.1
@ -124,7 +124,7 @@ This file is generated from multiple sources. Included packages:
- version: 4.5.0
- license: Apache-2.0
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -109,7 +109,7 @@ This file is generated from multiple sources. Included packages:
- version: 0.2.4
- license: GPL-3.0-or-later
- @nextcloud/upload
- version: 1.9.1
- version: 1.10.0
- license: AGPL-3.0-or-later
- @nextcloud/vue
- version: 8.25.1
@ -130,7 +130,7 @@ This file is generated from multiple sources. Included packages:
- version: 4.5.0
- license: Apache-2.0
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

File diff suppressed because one or more lines are too long

@ -126,7 +126,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- bail
- version: 2.0.2

@ -91,7 +91,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -143,7 +143,7 @@ This file is generated from multiple sources. Included packages:
- version: 1.0.7
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- balanced-match
- version: 1.0.2

@ -86,7 +86,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -71,7 +71,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -82,7 +82,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -114,7 +114,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -63,7 +63,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

File diff suppressed because one or more lines are too long

@ -78,7 +78,7 @@ This file is generated from multiple sources. Included packages:
- version: 0.2.4
- license: GPL-3.0-or-later
- @nextcloud/upload
- version: 1.9.1
- version: 1.10.0
- license: AGPL-3.0-or-later
- @nextcloud/vue
- version: 8.25.1
@ -93,7 +93,7 @@ This file is generated from multiple sources. Included packages:
- version: 4.5.0
- license: Apache-2.0
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

File diff suppressed because one or more lines are too long

@ -106,7 +106,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -138,7 +138,7 @@ This file is generated from multiple sources. Included packages:
- version: 1.0.7
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- balanced-match
- version: 1.0.2

@ -52,7 +52,7 @@ This file is generated from multiple sources. Included packages:
- version: 8.25.1
- license: AGPL-3.0-or-later
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -123,7 +123,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- bail
- version: 2.0.2

@ -122,7 +122,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -33,7 +33,7 @@ This file is generated from multiple sources. Included packages:
- version: 3.0.1
- license: GPL-3.0-or-later
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -91,7 +91,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -34,7 +34,7 @@ This file is generated from multiple sources. Included packages:
- version: 3.0.1
- license: GPL-3.0-or-later
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

@ -156,7 +156,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- bail
- version: 2.0.2

@ -86,7 +86,7 @@ This file is generated from multiple sources. Included packages:
- version: 11.3.0
- license: MIT
- axios
- version: 1.8.4
- version: 1.9.0
- license: MIT
- base64-js
- version: 1.5.1

Some files were not shown because too many files have changed in this diff Show More