diff --git a/.gitattributes b/.gitattributes index 4e522fbd42..fbcb8a02f0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,6 +5,8 @@ /apps/accessibility/js/accessibility.js.map binary /apps/comments/js/*.js binary /apps/comments/js/*.js.map binary +/apps/files/js/dist/*.js binary +/apps/files/js/dist/*.js.map binary /apps/files_sharing/js/dist/*.js binary /apps/files_sharing/js/dist/*.js.map binary /apps/files_versions/js/files_versions.js binary diff --git a/apps/files/appinfo/info.xml b/apps/files/appinfo/info.xml index 67c589ed75..20f77774ae 100644 --- a/apps/files/appinfo/info.xml +++ b/apps/files/appinfo/info.xml @@ -65,4 +65,8 @@ + + OCA\Files\Settings\PersonalSettings + + diff --git a/apps/files/appinfo/routes.php b/apps/files/appinfo/routes.php index 9d889fe0e6..e235db7607 100644 --- a/apps/files/appinfo/routes.php +++ b/apps/files/appinfo/routes.php @@ -119,7 +119,22 @@ $application->registerRoutes( 'url' => '/api/v1/directEditing/create', 'verb' => 'POST' ], - ] + [ + 'name' => 'TransferOwnership#transfer', + 'url' => '/api/v1/transferownership', + 'verb' => 'POST', + ], + [ + 'name' => 'TransferOwnership#accept', + 'url' => '/api/v1/transferownership/{id}', + 'verb' => 'POST', + ], + [ + 'name' => 'TransferOwnership#reject', + 'url' => '/api/v1/transferownership/{id}', + 'verb' => 'DELETE', + ], + ], ] ); diff --git a/apps/files/composer/composer/autoload_classmap.php b/apps/files/composer/composer/autoload_classmap.php index b350bfae07..ce6223994b 100644 --- a/apps/files/composer/composer/autoload_classmap.php +++ b/apps/files/composer/composer/autoload_classmap.php @@ -23,6 +23,7 @@ return array( 'OCA\\Files\\BackgroundJob\\CleanupFileLocks' => $baseDir . '/../lib/BackgroundJob/CleanupFileLocks.php', 'OCA\\Files\\BackgroundJob\\DeleteOrphanedItems' => $baseDir . '/../lib/BackgroundJob/DeleteOrphanedItems.php', 'OCA\\Files\\BackgroundJob\\ScanFiles' => $baseDir . '/../lib/BackgroundJob/ScanFiles.php', + 'OCA\\Files\\BackgroundJob\\TransferOwnership' => $baseDir . '/../lib/BackgroundJob/TransferOwnership.php', 'OCA\\Files\\Capabilities' => $baseDir . '/../lib/Capabilities.php', 'OCA\\Files\\Collaboration\\Resources\\Listener' => $baseDir . '/../lib/Collaboration/Resources/Listener.php', 'OCA\\Files\\Collaboration\\Resources\\ResourceProvider' => $baseDir . '/../lib/Collaboration/Resources/ResourceProvider.php', @@ -34,13 +35,19 @@ return array( 'OCA\\Files\\Controller\\ApiController' => $baseDir . '/../lib/Controller/ApiController.php', 'OCA\\Files\\Controller\\DirectEditingController' => $baseDir . '/../lib/Controller/DirectEditingController.php', 'OCA\\Files\\Controller\\DirectEditingViewController' => $baseDir . '/../lib/Controller/DirectEditingViewController.php', + 'OCA\\Files\\Controller\\TransferOwnershipController' => $baseDir . '/../lib/Controller/TransferOwnershipController.php', 'OCA\\Files\\Controller\\ViewController' => $baseDir . '/../lib/Controller/ViewController.php', + 'OCA\\Files\\Db\\TransferOwnership' => $baseDir . '/../lib/Db/TransferOwnership.php', + 'OCA\\Files\\Db\\TransferOwnershipMapper' => $baseDir . '/../lib/Db/TransferOwnershipMapper.php', 'OCA\\Files\\Event\\LoadAdditionalScriptsEvent' => $baseDir . '/../lib/Event/LoadAdditionalScriptsEvent.php', 'OCA\\Files\\Event\\LoadSidebar' => $baseDir . '/../lib/Event/LoadSidebar.php', 'OCA\\Files\\Exception\\TransferOwnershipException' => $baseDir . '/../lib/Exception/TransferOwnershipException.php', 'OCA\\Files\\Helper' => $baseDir . '/../lib/Helper.php', 'OCA\\Files\\Listener\\LegacyLoadAdditionalScriptsAdapter' => $baseDir . '/../lib/Listener/LegacyLoadAdditionalScriptsAdapter.php', + 'OCA\\Files\\Migration\\Version11301Date20191113195931' => $baseDir . '/../lib/Migration/Version11301Date20191113195931.php', + 'OCA\\Files\\Notification\\Notifier' => $baseDir . '/../lib/Notification/Notifier.php', 'OCA\\Files\\Service\\DirectEditingService' => $baseDir . '/../lib/Service/DirectEditingService.php', 'OCA\\Files\\Service\\OwnershipTransferService' => $baseDir . '/../lib/Service/OwnershipTransferService.php', 'OCA\\Files\\Service\\TagService' => $baseDir . '/../lib/Service/TagService.php', + 'OCA\\Files\\Settings\\PersonalSettings' => $baseDir . '/../lib/Settings/PersonalSettings.php', ); diff --git a/apps/files/composer/composer/autoload_static.php b/apps/files/composer/composer/autoload_static.php index 34a64f3253..47aa82e84b 100644 --- a/apps/files/composer/composer/autoload_static.php +++ b/apps/files/composer/composer/autoload_static.php @@ -38,6 +38,7 @@ class ComposerStaticInitFiles 'OCA\\Files\\BackgroundJob\\CleanupFileLocks' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupFileLocks.php', 'OCA\\Files\\BackgroundJob\\DeleteOrphanedItems' => __DIR__ . '/..' . '/../lib/BackgroundJob/DeleteOrphanedItems.php', 'OCA\\Files\\BackgroundJob\\ScanFiles' => __DIR__ . '/..' . '/../lib/BackgroundJob/ScanFiles.php', + 'OCA\\Files\\BackgroundJob\\TransferOwnership' => __DIR__ . '/..' . '/../lib/BackgroundJob/TransferOwnership.php', 'OCA\\Files\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php', 'OCA\\Files\\Collaboration\\Resources\\Listener' => __DIR__ . '/..' . '/../lib/Collaboration/Resources/Listener.php', 'OCA\\Files\\Collaboration\\Resources\\ResourceProvider' => __DIR__ . '/..' . '/../lib/Collaboration/Resources/ResourceProvider.php', @@ -49,15 +50,21 @@ class ComposerStaticInitFiles 'OCA\\Files\\Controller\\ApiController' => __DIR__ . '/..' . '/../lib/Controller/ApiController.php', 'OCA\\Files\\Controller\\DirectEditingController' => __DIR__ . '/..' . '/../lib/Controller/DirectEditingController.php', 'OCA\\Files\\Controller\\DirectEditingViewController' => __DIR__ . '/..' . '/../lib/Controller/DirectEditingViewController.php', + 'OCA\\Files\\Controller\\TransferOwnershipController' => __DIR__ . '/..' . '/../lib/Controller/TransferOwnershipController.php', 'OCA\\Files\\Controller\\ViewController' => __DIR__ . '/..' . '/../lib/Controller/ViewController.php', + 'OCA\\Files\\Db\\TransferOwnership' => __DIR__ . '/..' . '/../lib/Db/TransferOwnership.php', + 'OCA\\Files\\Db\\TransferOwnershipMapper' => __DIR__ . '/..' . '/../lib/Db/TransferOwnershipMapper.php', 'OCA\\Files\\Event\\LoadAdditionalScriptsEvent' => __DIR__ . '/..' . '/../lib/Event/LoadAdditionalScriptsEvent.php', 'OCA\\Files\\Event\\LoadSidebar' => __DIR__ . '/..' . '/../lib/Event/LoadSidebar.php', 'OCA\\Files\\Exception\\TransferOwnershipException' => __DIR__ . '/..' . '/../lib/Exception/TransferOwnershipException.php', 'OCA\\Files\\Helper' => __DIR__ . '/..' . '/../lib/Helper.php', 'OCA\\Files\\Listener\\LegacyLoadAdditionalScriptsAdapter' => __DIR__ . '/..' . '/../lib/Listener/LegacyLoadAdditionalScriptsAdapter.php', + 'OCA\\Files\\Migration\\Version11301Date20191113195931' => __DIR__ . '/..' . '/../lib/Migration/Version11301Date20191113195931.php', + 'OCA\\Files\\Notification\\Notifier' => __DIR__ . '/..' . '/../lib/Notification/Notifier.php', 'OCA\\Files\\Service\\DirectEditingService' => __DIR__ . '/..' . '/../lib/Service/DirectEditingService.php', 'OCA\\Files\\Service\\OwnershipTransferService' => __DIR__ . '/..' . '/../lib/Service/OwnershipTransferService.php', 'OCA\\Files\\Service\\TagService' => __DIR__ . '/..' . '/../lib/Service/TagService.php', + 'OCA\\Files\\Settings\\PersonalSettings' => __DIR__ . '/..' . '/../lib/Settings/PersonalSettings.php', ); public static function getInitializer(ClassLoader $loader) diff --git a/apps/files/js/dist/personal-settings.js b/apps/files/js/dist/personal-settings.js new file mode 100644 index 0000000000..a25d256a2d Binary files /dev/null and b/apps/files/js/dist/personal-settings.js differ diff --git a/apps/files/js/dist/personal-settings.js.map b/apps/files/js/dist/personal-settings.js.map new file mode 100644 index 0000000000..e537e4901e Binary files /dev/null and b/apps/files/js/dist/personal-settings.js.map differ diff --git a/apps/files/js/dist/sidebar.js b/apps/files/js/dist/sidebar.js index c7e6e08b50..a120c6164e 100644 Binary files a/apps/files/js/dist/sidebar.js and b/apps/files/js/dist/sidebar.js differ diff --git a/apps/files/js/dist/sidebar.js.map b/apps/files/js/dist/sidebar.js.map index a595a32aba..217bf3fed5 100644 Binary files a/apps/files/js/dist/sidebar.js.map and b/apps/files/js/dist/sidebar.js.map differ diff --git a/apps/files/lib/AppInfo/Application.php b/apps/files/lib/AppInfo/Application.php index 1ffd5e9647..f4897d08e5 100644 --- a/apps/files/lib/AppInfo/Application.php +++ b/apps/files/lib/AppInfo/Application.php @@ -35,6 +35,7 @@ use OCA\Files\Controller\ApiController; use OCA\Files\Controller\ViewController; use OCA\Files\Event\LoadAdditionalScriptsEvent; use OCA\Files\Listener\LegacyLoadAdditionalScriptsAdapter; +use OCA\Files\Notification\Notifier; use OCA\Files\Service\TagService; use OCP\AppFramework\App; use OCP\Collaboration\Resources\IManager; @@ -42,8 +43,11 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\IContainer; class Application extends App { + + public const APP_ID = 'files'; + public function __construct(array $urlParams=array()) { - parent::__construct('files', $urlParams); + parent::__construct(self::APP_ID, $urlParams); $container = $this->getContainer(); $server = $container->getServer(); @@ -71,7 +75,7 @@ class Application extends App { return new TagService( $c->query('ServerContainer')->getUserSession(), $c->query('ServerContainer')->getActivityManager(), - $c->query('ServerContainer')->getTagManager()->load('files'), + $c->query('ServerContainer')->getTagManager()->load(self::APP_ID), $homeFolder, $server->getEventDispatcher() ); @@ -93,5 +97,9 @@ class Application extends App { /** @var IEventDispatcher $dispatcher */ $dispatcher = $container->query(IEventDispatcher::class); $dispatcher->addServiceListener(LoadAdditionalScriptsEvent::class, LegacyLoadAdditionalScriptsAdapter::class); + + /** @var \OCP\Notification\IManager $notifications */ + $notifications = $container->query(\OCP\Notification\IManager::class); + $notifications->registerNotifierService(Notifier::class); } } diff --git a/apps/files/lib/BackgroundJob/TransferOwnership.php b/apps/files/lib/BackgroundJob/TransferOwnership.php new file mode 100644 index 0000000000..3e505cb19b --- /dev/null +++ b/apps/files/lib/BackgroundJob/TransferOwnership.php @@ -0,0 +1,183 @@ + + * + * @author Roeland Jago Douma + * + * @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 . + * + */ + +namespace OCA\Files\BackgroundJob; + +use OCA\Files\AppInfo\Application; +use OCA\Files\Db\TransferOwnership as Transfer; +use OCA\Files\Db\TransferOwnershipMapper; +use OCA\Files\Exception\TransferOwnershipException; +use OCA\Files\Service\OwnershipTransferService; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\QueuedJob; +use OCP\Files\IRootFolder; +use OCP\ILogger; +use OCP\IUser; +use OCP\IUserManager; +use OCP\Notification\IManager as NotificationManager; +use function ltrim; + +class TransferOwnership extends QueuedJob { + + /** @var IUserManager $userManager */ + private $userManager; + + /** @var OwnershipTransferService */ + private $transferService; + + /** @var ILogger */ + private $logger; + + /** @var NotificationManager */ + private $notificationManager; + + /** @var TransferOwnershipMapper */ + private $mapper; + /** @var IRootFolder */ + private $rootFolder; + + public function __construct(ITimeFactory $timeFactory, + IUserManager $userManager, + OwnershipTransferService $transferService, + ILogger $logger, + NotificationManager $notificationManager, + TransferOwnershipMapper $mapper, + IRootFolder $rootFolder) { + parent::__construct($timeFactory); + + $this->userManager = $userManager; + $this->transferService = $transferService; + $this->logger = $logger; + $this->notificationManager = $notificationManager; + $this->mapper = $mapper; + $this->rootFolder = $rootFolder; + } + + protected function run($argument) { + $id = $argument['id']; + + $transfer = $this->mapper->getById($id); + $sourceUser = $transfer->getSourceUser(); + $destinationUser = $transfer->getTargetUser(); + $fileId = $transfer->getFileId(); + + $userFolder = $this->rootFolder->getUserFolder($sourceUser); + $nodes = $userFolder->getById($fileId); + + if (empty($nodes)) { + $this->logger->alert('Could not transfer ownership: Node not found'); + $this->failedNotication($transfer); + return; + } + $path = $userFolder->getRelativePath($nodes[0]->getPath()); + + $sourceUserObject = $this->userManager->get($sourceUser); + $destinationUserObject = $this->userManager->get($destinationUser); + + if (!$sourceUserObject instanceof IUser) { + $this->logger->alert('Could not transfer ownership: Unknown source user ' . $sourceUser); + $this->failedNotication($transfer); + return; + } + + if (!$destinationUserObject instanceof IUser) { + $this->logger->alert("Unknown destination user $destinationUser"); + $this->failedNotication($transfer); + return; + } + + try { + $this->transferService->transfer( + $sourceUserObject, + $destinationUserObject, + ltrim($path, '/') + ); + $this->successNotification($transfer); + } catch (TransferOwnershipException $e) { + $this->logger->logException($e); + $this->failedNotication($transfer); + } + + $this->mapper->delete($transfer); + + } + + private function failedNotication(Transfer $transfer): void { + // Send notification to source user + $notification = $this->notificationManager->createNotification(); + $notification->setUser($transfer->getSourceUser()) + ->setApp(Application::APP_ID) + ->setDateTime($this->time->getDateTime()) + ->setSubject('transferOwnershipFailedSource', [ + 'sourceUser' => $transfer->getSourceUser(), + 'targetUser' => $transfer->getTargetUser(), + 'nodeName' => $transfer->getNodeName(), + ]) + ->setObject('transfer', (string)$transfer->getId()); + $this->notificationManager->notify($notification); + + // Send notification to source user + $notification = $this->notificationManager->createNotification(); + $notification->setUser($transfer->getTargetUser()) + ->setApp(Application::APP_ID) + ->setDateTime($this->time->getDateTime()) + ->setSubject('transferOwnershipFailedTarget', [ + 'sourceUser' => $transfer->getSourceUser(), + 'targetUser' => $transfer->getTargetUser(), + 'nodeName' => $transfer->getNodeName(), + ]) + ->setObject('transfer', (string)$transfer->getId()); + $this->notificationManager->notify($notification); + } + + private function successNotification(Transfer $transfer): void { + // Send notification to source user + $notification = $this->notificationManager->createNotification(); + $notification->setUser($transfer->getSourceUser()) + ->setApp(Application::APP_ID) + ->setDateTime($this->time->getDateTime()) + ->setSubject('transferOwnershipDoneSource', [ + 'sourceUser' => $transfer->getSourceUser(), + 'targetUser' => $transfer->getTargetUser(), + 'nodeName' => $transfer->getNodeName(), + ]) + ->setObject('transfer', (string)$transfer->getId()); + $this->notificationManager->notify($notification); + + // Send notification to source user + $notification = $this->notificationManager->createNotification(); + $notification->setUser($transfer->getTargetUser()) + ->setApp(Application::APP_ID) + ->setDateTime($this->time->getDateTime()) + ->setSubject('transferOwnershipDoneTarget', [ + 'sourceUser' => $transfer->getSourceUser(), + 'targetUser' => $transfer->getTargetUser(), + 'nodeName' => $transfer->getNodeName(), + ]) + ->setObject('transfer', (string)$transfer->getId()); + $this->notificationManager->notify($notification); + } +} diff --git a/apps/files/lib/Controller/TransferOwnershipController.php b/apps/files/lib/Controller/TransferOwnershipController.php new file mode 100644 index 0000000000..b01596fc29 --- /dev/null +++ b/apps/files/lib/Controller/TransferOwnershipController.php @@ -0,0 +1,181 @@ + + * + * @author Roeland Jago Douma + * + * @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 . + * + */ + +namespace OCA\Files\Controller; + +use OCA\Files\BackgroundJob\TransferOwnership; +use OCA\Files\Db\TransferOwnershipMapper; +use OCP\AppFramework\Db\DoesNotExistException; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\OCSController; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\IJobList; +use OCP\Files\IRootFolder; +use OCP\IRequest; +use OCP\IUserManager; +use OCP\Notification\IManager as NotificationManager; + +class TransferOwnershipController extends OCSController { + + /** @var string */ + private $userId; + /** @var NotificationManager */ + private $notificationManager; + /** @var ITimeFactory */ + private $timeFactory; + /** @var IJobList */ + private $jobList; + /** @var TransferOwnershipMapper */ + private $mapper; + /** @var IUserManager */ + private $userManager; + /** @var IRootFolder */ + private $rootFolder; + + public function __construct(string $appName, + IRequest $request, + string $userId, + NotificationManager $notificationManager, + ITimeFactory $timeFactory, + IJobList $jobList, + TransferOwnershipMapper $mapper, + IUserManager $userManager, + IRootFolder $rootFolder) { + parent::__construct($appName, $request); + + $this->userId = $userId; + $this->notificationManager = $notificationManager; + $this->timeFactory = $timeFactory; + $this->jobList = $jobList; + $this->mapper = $mapper; + $this->userManager = $userManager; + $this->rootFolder = $rootFolder; + } + + + /** + * @NoAdminRequired + */ + public function transfer(string $recipient, string $path): DataResponse { + $recipientUser = $this->userManager->get($recipient); + + if ($recipientUser === null) { + return new DataResponse([], Http::STATUS_BAD_REQUEST); + } + + $userRoot = $this->rootFolder->getUserFolder($this->userId); + + try { + $node = $userRoot->get($path); + } catch (\Exception $e) { + return new DataResponse([], Http::STATUS_BAD_REQUEST); + } + + $transferOwnership = new \OCA\Files\Db\TransferOwnership(); + $transferOwnership->setSourceUser($this->userId); + $transferOwnership->setTargetUser($recipient); + $transferOwnership->setFileId($node->getId()); + $transferOwnership->setNodeName($node->getName()); + $transferOwnership = $this->mapper->insert($transferOwnership); + + $notification = $this->notificationManager->createNotification(); + $notification->setUser($recipient) + ->setApp($this->appName) + ->setDateTime($this->timeFactory->getDateTime()) + ->setSubject('transferownershipRequest', [ + 'sourceUser' => $this->userId, + 'targetUser' => $recipient, + 'nodeName' => $node->getName(), + ]) + ->setObject('transfer', (string)$transferOwnership->getId()); + + $this->notificationManager->notify($notification); + + return new DataResponse([]); + } + + /** + * @NoAdminRequired + */ + public function accept(int $id): DataResponse { + try { + $transferOwnership = $this->mapper->getById($id); + } catch (DoesNotExistException $e) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + if ($transferOwnership->getTargetUser() !== $this->userId) { + return new DataResponse([], Http::STATUS_FORBIDDEN); + } + + $this->jobList->add(TransferOwnership::class, [ + 'id' => $transferOwnership->getId(), + ]); + + $notification = $this->notificationManager->createNotification(); + $notification->setApp('files') + ->setObject('transfer', (string)$id); + $this->notificationManager->markProcessed($notification); + + return new DataResponse([], Http::STATUS_OK); + } + + /** + * @NoAdminRequired + */ + public function reject(int $id): DataResponse { + try { + $transferOwnership = $this->mapper->getById($id); + } catch (DoesNotExistException $e) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + if ($transferOwnership->getTargetUser() !== $this->userId) { + return new DataResponse([], Http::STATUS_FORBIDDEN); + } + + $notification = $this->notificationManager->createNotification(); + $notification->setApp('files') + ->setObject('transfer', (string)$id); + $this->notificationManager->markProcessed($notification); + + $notification = $this->notificationManager->createNotification(); + $notification->setUser($transferOwnership->getSourceUser()) + ->setApp($this->appName) + ->setDateTime($this->timeFactory->getDateTime()) + ->setSubject('transferownershipRequestDenied', [ + 'sourceUser' => $transferOwnership->getSourceUser(), + 'targetUser' => $transferOwnership->getTargetUser(), + 'nodeName' => $transferOwnership->getNodeName() + ]) + ->setObject('transfer', (string)$transferOwnership->getId()); + $this->notificationManager->notify($notification); + + $this->mapper->delete($transferOwnership); + + return new DataResponse([], Http::STATUS_OK); + } + +} diff --git a/apps/files/lib/Db/TransferOwnership.php b/apps/files/lib/Db/TransferOwnership.php new file mode 100644 index 0000000000..3438499135 --- /dev/null +++ b/apps/files/lib/Db/TransferOwnership.php @@ -0,0 +1,60 @@ + + * + * @author Roeland Jago Douma + * + * @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 . + * + */ + +namespace OCA\Files\Db; + +use OCP\AppFramework\Db\Entity; + +/** + * @method void setSourceUser(string $uid) + * @method string getSourceUser() + * @method void setTargetUser(string $uid) + * @method string getTargetUser() + * @method void setFileId(int $fileId) + * @method int getFileId() + * @method void setNodeName(string $name) + * @method string getNodeName() + */ +class TransferOwnership extends Entity { + /** @var string */ + protected $sourceUser; + + /** @var string */ + protected $targetUser; + + /** @var integer */ + protected $fileId; + + /** @var string */ + protected $nodeName; + + public function __construct() { + $this->addType('sourceUser', 'string'); + $this->addType('targetUser', 'string'); + $this->addType('fileId', 'integer'); + $this->addType('nodeName', 'string'); + } + + +} diff --git a/apps/files/lib/Db/TransferOwnershipMapper.php b/apps/files/lib/Db/TransferOwnershipMapper.php new file mode 100644 index 0000000000..4918d4cdbf --- /dev/null +++ b/apps/files/lib/Db/TransferOwnershipMapper.php @@ -0,0 +1,47 @@ + + * + * @author Roeland Jago Douma + * + * @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 . + * + */ + +namespace OCA\Files\Db; + +use OCP\AppFramework\Db\QBMapper; +use OCP\IDBConnection; + +class TransferOwnershipMapper extends QBMapper { + public function __construct(IDBConnection $db) { + parent::__construct($db, 'user_transfer_ownership', TransferOwnership::class); + } + + public function getById(int $id): TransferOwnership { + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id)) + ); + + return $this->findEntity($qb); + } + +} diff --git a/apps/files/lib/Migration/Version11301Date20191113195931.php b/apps/files/lib/Migration/Version11301Date20191113195931.php new file mode 100644 index 0000000000..d4044434c7 --- /dev/null +++ b/apps/files/lib/Migration/Version11301Date20191113195931.php @@ -0,0 +1,72 @@ + + * + * @author Roeland Jago Douma + * + * @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 . + * + */ + + +namespace OCA\Files\Migration; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\Migration\SimpleMigrationStep; +use OCP\Migration\IOutput; + +class Version11301Date20191113195931 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + $table = $schema->createTable('user_transfer_ownership'); + $table->addColumn('id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + 'length' => 4, + ]); + $table->addColumn('source_user', 'string', [ + 'notnull' => true, + 'length' => 64, + ]); + $table->addColumn('target_user', 'string', [ + 'notnull' => true, + 'length' => 64, + ]); + $table->addColumn('file_id', 'bigint', [ + 'notnull' => true, + 'length' => 20, + ]); + $table->addColumn('node_name', 'string', [ + 'notnull' => true, + 'length' => 255, + ]); + $table->setPrimaryKey(['id']); + + return $schema; + } + +} diff --git a/apps/files/lib/Notification/Notifier.php b/apps/files/lib/Notification/Notifier.php new file mode 100644 index 0000000000..92950b8e1b --- /dev/null +++ b/apps/files/lib/Notification/Notifier.php @@ -0,0 +1,243 @@ + + * + * @author Roeland Jago Douma + * + * @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 . + * + */ + +namespace OCA\Files\Notification; + +use OCP\IURLGenerator; +use OCP\L10N\IFactory; +use OCP\Notification\IAction; +use OCP\Notification\INotification; +use OCP\Notification\INotifier; + +class Notifier implements INotifier { + + /** @var IFactory */ + protected $l10nFactory; + + /** @var IURLGenerator */ + protected $urlGenerator; + + /** + * @param IFactory $l10nFactory + * @param IURLGenerator $urlGenerator + */ + public function __construct(IFactory $l10nFactory, IURLGenerator $urlGenerator) { + $this->l10nFactory = $l10nFactory; + $this->urlGenerator = $urlGenerator; + } + + public function getID(): string { + return 'files'; + } + + public function getName(): string { + return $this->l10nFactory->get('files')->t('Files'); + } + + /** + * @param INotification $notification + * @param string $languageCode The code of the language that should be used to prepare the notification + * @return INotification + * @throws \InvalidArgumentException When the notification was not prepared by a notifier + */ + public function prepare(INotification $notification, string $languageCode): INotification { + if ($notification->getApp() !== 'files') { + throw new \InvalidArgumentException('Unhandled app'); + } + + if ($notification->getSubject() === 'transferownershipRequest') { + return $this->handleTransferownershipRequest($notification, $languageCode); + } + if ($notification->getSubject() === 'transferOwnershipFailedSource') { + return $this->handleTransferOwnershipFailedSource($notification, $languageCode); + } + if ($notification->getSubject() === 'transferOwnershipFailedTarget') { + return $this->handleTransferOwnershipFailedTarget($notification, $languageCode); + } + if ($notification->getSubject() === 'transferOwnershipDoneSource') { + return $this->handleTransferOwnershipDoneSource($notification, $languageCode); + } + if ($notification->getSubject() === 'transferOwnershipDoneTarget') { + return $this->handleTransferOwnershipDoneTarget($notification, $languageCode); + } + + throw new \InvalidArgumentException('Unhandled subject'); + } + + public function handleTransferownershipRequest(INotification $notification, string $languageCode): INotification { + $l = $this->l10nFactory->get('files', $languageCode); + $id = $notification->getObjectId(); + $param = $notification->getSubjectParameters(); + + $approveAction = $notification->createAction() + ->setParsedLabel($l->t('Accept')) + ->setPrimary(true) + ->setLink( + $this->urlGenerator->getAbsoluteURL( + $this->urlGenerator->linkTo( + '', + 'ocs/v2.php/apps/files/api/v1/transferownership/' . $id + ) + ), + IAction::TYPE_POST + ); + + $disapproveAction = $notification->createAction() + ->setParsedLabel($l->t('Decline')) + ->setPrimary(false) + ->setLink( + $this->urlGenerator->getAbsoluteURL( + $this->urlGenerator->linkTo( + '', + 'ocs/v2.php/apps/files/api/v1/transferownership/' . $id + ) + ), + IAction::TYPE_DELETE + ); + + $notification->addParsedAction($approveAction) + ->addParsedAction($disapproveAction) + ->setRichSubject( + $l->t('Incomming file transfer from {user}'), + [ + 'user' => [ + 'type' => 'user', + 'id' => $param['sourceUser'], + 'name' => $param['sourceUser'], + ], + ]) + ->setParsedSubject(str_replace('{user}', $param['sourceUser'], $l->t('Incomming file transfer from {user}'))) + ->setRichMessage( + $l->t('Do you want to accept {path}?'), + [ + 'path' => [ + 'type' => 'highlight', + 'id' => $param['targetUser'] . '::' . $param['nodeName'], + 'name' => $param['nodeName'], + ] + ]) + ->setParsedMessage(str_replace('{path}', $param['nodeName'], $l->t('Do you want to accept {path}?'))); + + return $notification; + } + + public function handleTransferOwnershipFailedSource(INotification $notification, string $languageCode): INotification { + $l = $this->l10nFactory->get('files', $languageCode); + $param = $notification->getSubjectParameters(); + + $notification->setRichSubject($l->t('File transfer failed')) + ->setParsedSubject(str_replace(['{path}', '{user}'], [$param['nodeName'], $param['targetUser']], $l->t('Your transfer of {path} to {user} failed.'))) + ->setRichMessage( + $l->t('Your transfer of {path} to {user} failed.'), + [ + 'path' => [ + 'type' => 'highlight', + 'id' => $param['targetUser'] . '::' . $param['nodeName'], + 'name' => $param['nodeName'], + ], + 'user' => [ + 'type' => 'user', + 'id' => $param['targetUser'], + 'name' => $param['targetUser'], + ], + ]) + ->setParsedMessage($l->t('File transfer failed')); + return $notification; + } + + public function handleTransferOwnershipFailedTarget(INotification $notification, string $languageCode): INotification { + $l = $this->l10nFactory->get('files', $languageCode); + $param = $notification->getSubjectParameters(); + + $notification->setRichSubject($l->t('File transfer failed')) + ->setParsedSubject(str_replace(['{path}', '{user}'], [$param['nodeName'], $param['sourceUser']], $l->t('The transfer of {path} from {user} failed.'))) + ->setRichMessage( + $l->t('The transfer of {path} from {user} failed.'), + [ + 'path' => [ + 'type' => 'highlight', + 'id' => $param['sourceUser'] . '::' . $param['nodeName'], + 'name' => $param['nodeName'], + ], + 'user' => [ + 'type' => 'user', + 'id' => $param['sourceUser'], + 'name' => $param['sourceUser'], + ], + ]) + ->setParsedMessage($l->t('File transfer failed')); + + return $notification; + } + + public function handleTransferOwnershipDoneSource(INotification $notification, string $languageCode): INotification { + $l = $this->l10nFactory->get('files', $languageCode); + $param = $notification->getSubjectParameters(); + + $notification->setRichSubject($l->t('File transfer done')) + ->setParsedSubject(str_replace(['{path}', '{user}'], [$param['nodeName'], $param['targetUser']], $l->t('Your transfer of {path} to {user} has completed.'))) + ->setRichMessage( + $l->t('Your transfer of {path} to {user} has completed.'), + [ + 'path' => [ + 'type' => 'highlight', + 'id' => $param['targetUser'] . '::' . $param['nodeName'], + 'name' => $param['nodeName'], + ], + 'user' => [ + 'type' => 'user', + 'id' => $param['targetUser'], + 'name' => $param['targetUser'], + ], + ]) + ->setParsedMessage($l->t('File transfer done')); + + return $notification; + } + + public function handleTransferOwnershipDoneTarget(INotification $notification, string $languageCode): INotification { + $l = $this->l10nFactory->get('files', $languageCode); + $param = $notification->getSubjectParameters(); + + $notification->setRichSubject($l->t('File transfer done')) + ->setParsedSubject(str_replace(['{path}', '{user}'], [$param['nodeName'], $param['sourceUser']], $l->t('The transfer of {path} from {user} has completed.'))) + ->setRichMessage( + $l->t('The transfer of {path} from {user} has completed.'), + [ + 'path' => [ + 'type' => 'highlight', + 'id' => $param['sourceUser'] . '::' . $param['nodeName'], + 'name' => $param['nodeName'], + ], + 'user' => [ + 'type' => 'user', + 'id' => $param['sourceUser'], + 'name' => $param['sourceUser'], + ], + ]) + ->setParsedMessage($l->t('File transfer done')); + + return $notification; + } +} diff --git a/apps/files/lib/Settings/PersonalSettings.php b/apps/files/lib/Settings/PersonalSettings.php new file mode 100644 index 0000000000..3348d394dc --- /dev/null +++ b/apps/files/lib/Settings/PersonalSettings.php @@ -0,0 +1,46 @@ + + * + * @author 2019 Christoph Wurst + * + * @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 . + */ + +namespace OCA\Files\Settings; + +use OCA\Files\AppInfo\Application; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\Settings\ISettings; + +class PersonalSettings implements ISettings { + + public function getForm(): TemplateResponse { + return new TemplateResponse(Application::APP_ID, 'settings-personal'); + } + + public function getSection(): string { + return 'sharing'; + } + + public function getPriority(): int { + return 90; + } + +} diff --git a/apps/files/src/components/PersonalSettings.vue b/apps/files/src/components/PersonalSettings.vue new file mode 100644 index 0000000000..b0468ef456 --- /dev/null +++ b/apps/files/src/components/PersonalSettings.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/apps/files/src/components/TransferOwnershipDialogue.vue b/apps/files/src/components/TransferOwnershipDialogue.vue new file mode 100644 index 0000000000..0187353691 --- /dev/null +++ b/apps/files/src/components/TransferOwnershipDialogue.vue @@ -0,0 +1,143 @@ + + + + + + + diff --git a/apps/files/src/logger.js b/apps/files/src/logger.js new file mode 100644 index 0000000000..44e1c06b48 --- /dev/null +++ b/apps/files/src/logger.js @@ -0,0 +1,28 @@ +/* + * @copyright 2019 Christoph Wurst + * + * @author 2019 Christoph Wurst + * + * @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 . + */ + +import { getCurrentUser } from '@nextcloud/auth' +import { getLoggerBuilder } from '@nextcloud/logger' + +export default getLoggerBuilder() + .setApp('files') + .setUid(getCurrentUser().uid) + .build() diff --git a/apps/files/src/main-personal-settings.js b/apps/files/src/main-personal-settings.js new file mode 100644 index 0000000000..da5d91537e --- /dev/null +++ b/apps/files/src/main-personal-settings.js @@ -0,0 +1,38 @@ +// global t + +/* + * @copyright 2019 Christoph Wurst + * + * @author 2019 Christoph Wurst + * + * @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 . + */ + +import Vue from 'vue' +import { getRequestToken } from '@nextcloud/auth' +import { generateFilePath } from '@nextcloud/router' + +import PersonalSettings from './components/PersonalSettings' + +// eslint-disable-next-line camelcase +__webpack_nonce__ = btoa(getRequestToken()) +// eslint-disable-next-line camelcase +__webpack_public_path__ = generateFilePath('files', '', 'js/') + +Vue.prototype.t = t + +const View = Vue.extend(PersonalSettings) +new View().$mount('#files-personal-settings') diff --git a/apps/files/templates/settings-personal.php b/apps/files/templates/settings-personal.php new file mode 100644 index 0000000000..1cddae3d33 --- /dev/null +++ b/apps/files/templates/settings-personal.php @@ -0,0 +1,29 @@ + + * + * @author 2019 Christoph Wurst + * + * @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 . + */ + + +script(\OCA\Files\AppInfo\Application::APP_ID, 'dist/personal-settings'); + +?> +
+
diff --git a/apps/files/webpack.js b/apps/files/webpack.js index 4007722031..45be4d09d3 100644 --- a/apps/files/webpack.js +++ b/apps/files/webpack.js @@ -3,6 +3,7 @@ const path = require('path'); module.exports = { entry: { 'sidebar': path.join(__dirname, 'src', 'sidebar.js'), + 'personal-settings': path.join(__dirname, 'src', 'main-personal-settings.js'), }, output: { path: path.resolve(__dirname, './js/dist/'), diff --git a/core/js/dist/login.js b/core/js/dist/login.js index 6a9f9af7c2..3015f7440f 100644 Binary files a/core/js/dist/login.js and b/core/js/dist/login.js differ diff --git a/core/js/dist/login.js.map b/core/js/dist/login.js.map index 56ad0c61c4..e715ca50f8 100644 Binary files a/core/js/dist/login.js.map and b/core/js/dist/login.js.map differ diff --git a/core/js/dist/main.js b/core/js/dist/main.js index 14f4d34fcb..6595205252 100644 Binary files a/core/js/dist/main.js and b/core/js/dist/main.js differ diff --git a/core/js/dist/main.js.map b/core/js/dist/main.js.map index fc9df0f705..6e6dcd6d0d 100644 Binary files a/core/js/dist/main.js.map and b/core/js/dist/main.js.map differ diff --git a/core/js/dist/maintenance.js b/core/js/dist/maintenance.js index bcc01e6c55..ebcc3e8d91 100644 Binary files a/core/js/dist/maintenance.js and b/core/js/dist/maintenance.js differ diff --git a/core/js/dist/maintenance.js.map b/core/js/dist/maintenance.js.map index ef33542357..f532985732 100644 Binary files a/core/js/dist/maintenance.js.map and b/core/js/dist/maintenance.js.map differ diff --git a/core/src/OC/dialogs.js b/core/src/OC/dialogs.js index 8f50a5d060..a35af2f7c8 100644 --- a/core/src/OC/dialogs.js +++ b/core/src/OC/dialogs.js @@ -486,7 +486,7 @@ const Dialogs = { // Hence this is one of the approach to get the choose button. var getOcDialog = self.$filePicker.closest('.oc-dialog') var buttonEnableDisable = getOcDialog.find('.primary') - if (self.$filePicker.data('mimetype').indexOf('httpd/unix-directory') !== -1 && !self.$filePicker.data('.allowDirectoryChooser')) { + if (self.$filePicker.data('mimetype').indexOf('httpd/unix-directory') !== -1 || self.$filePicker.data('allowDirectoryChooser')) { buttonEnableDisable.prop('disabled', false) } else { buttonEnableDisable.prop('disabled', true) @@ -1213,7 +1213,7 @@ const Dialogs = { var getOcDialog = (event.target).closest('.oc-dialog') var buttonEnableDisable = $('.primary', getOcDialog) this._changeButtonsText(type, dir.split(/[/]+/).pop()) - if (this.$filePicker.data('mimetype').indexOf('httpd/unix-directory') !== -1) { + if (this.$filePicker.data('mimetype').indexOf('httpd/unix-directory') !== -1 || this.$filePicker.data('allowDirectoryChooser')) { buttonEnableDisable.prop('disabled', false) } else { buttonEnableDisable.prop('disabled', true) diff --git a/package-lock.json b/package-lock.json index 6db6b72fd9..a2a8a217b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2142,6 +2142,21 @@ "integrity": "sha512-f+sKpdLZXkODV+OY39K1M+Spmd4RgxmtEXmNn4Bviv4R7uBFHXuw+JX9ZdfDeOryfHjJ/TRQxQEp0GMpBwZFUw==", "dev": true }, + "@nextcloud/dialogs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-0.1.1.tgz", + "integrity": "sha512-eO3qfMdxg+ZRrP3lYX5B6R/DyEEuBieOwI6N42yaGmsniBmPnAGt7uxWKMBBCeOQLDJT2ni805GUkU2hMA3xNw==", + "requires": { + "core-js": "3.4.2" + }, + "dependencies": { + "core-js": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.4.2.tgz", + "integrity": "sha512-bUTfqFWtNKWp73oNIfRkqwYZJeNT3lstzZcAkhhiuvDraRSgOH1/+F9ZklbpR4zpdKuo4cpXN8tKP7s61yjX+g==" + } + } + }, "@nextcloud/event-bus": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/@nextcloud/event-bus/-/event-bus-0.2.1.tgz", @@ -2172,6 +2187,22 @@ } } }, + "@nextcloud/logger": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nextcloud/logger/-/logger-0.1.0.tgz", + "integrity": "sha512-8ZI9SkuY3vRe7IoQV9J83zUf6s8UpXHsG9vH8cTLiCyQihiJ6xpdvmbBk509v6MitG7H7Nx83vygSLM1gkMnNQ==", + "requires": { + "babel-plugin-transform-class-properties": "6.24.1", + "core-js": "3.1.4" + }, + "dependencies": { + "core-js": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.4.tgz", + "integrity": "sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ==" + } + } + }, "@nextcloud/paths": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@nextcloud/paths/-/paths-0.2.0.tgz", @@ -2688,6 +2719,58 @@ } } }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, "babel-eslint": { "version": "10.0.3", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz", @@ -2713,6 +2796,27 @@ } } }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, "babel-loader": { "version": "8.0.6", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", @@ -2725,6 +2829,14 @@ "pify": "^4.0.1" } }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, "babel-plugin-dynamic-import-node": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", @@ -2733,6 +2845,22 @@ "object.assign": "^4.1.0" } }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=" + }, + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, "babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", @@ -2746,7 +2874,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, "requires": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" @@ -2755,11 +2882,68 @@ "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" } } }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + }, + "dependencies": { + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" + } + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + }, + "dependencies": { + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + } + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + }, "backbone": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.4.0.tgz", @@ -3588,7 +3772,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -5515,7 +5698,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" }, @@ -5523,8 +5705,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" } } }, diff --git a/package.json b/package.json index 448fc6aaed..4b1c4a8e64 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,10 @@ "@chenfengyuan/vue-qrcode": "^1.0.1", "@nextcloud/auth": "^0.3.1", "@nextcloud/axios": "^0.5.0", + "@nextcloud/dialogs": "^0.1.1", "@nextcloud/event-bus": "^0.2.1", "@nextcloud/initial-state": "^0.2.0", + "@nextcloud/logger": "^0.1.0", "@nextcloud/paths": "^0.2.0", "@nextcloud/router": "^0.1.0", "autosize": "^4.0.2",