diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php index dd2df96bd19..5a939e88914 100644 --- a/apps/files_sharing/lib/Controller/ShareAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareAPIController.php @@ -12,14 +12,17 @@ namespace OCA\Files_Sharing\Controller; use Exception; use OC\Files\FileInfo; use OC\Files\Storage\Wrapper\Wrapper; +use OC\Share20\Exception\ProviderException; use OCA\Files\Helper; use OCA\Files_Sharing\Exceptions\SharingRightsException; use OCA\Files_Sharing\External\Storage; use OCA\Files_Sharing\ResponseDefinitions; use OCA\Files_Sharing\SharedStorage; +use OCA\ShareByMail\ShareByMailProvider; use OCP\App\IAppManager; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\OCS\OCSBadRequestException; use OCP\AppFramework\OCS\OCSException; use OCP\AppFramework\OCS\OCSForbiddenException; @@ -46,6 +49,7 @@ use OCP\Server; use OCP\Share\Exceptions\GenericShareException; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager; +use OCP\Share\IProviderFactory; use OCP\Share\IShare; use OCP\UserStatus\IManager as IUserStatusManager; use Psr\Container\ContainerExceptionInterface; @@ -81,6 +85,7 @@ class ShareAPIController extends OCSController { private IPreview $previewManager, private IDateTimeZone $dateTimeZone, private LoggerInterface $logger, + private IProviderFactory $factory, ?string $userId = null ) { parent::__construct($appName, $request); @@ -2025,6 +2030,50 @@ class ShareAPIController extends OCSController { } } } + } + + public function sendShareEmail(int $shareId, $emails = []) { + try { + $share = $this->shareManager->getShareById($shareId); + + // Only mail and link shares are supported + if ($share->getShareType() !== IShare::TYPE_EMAIL + && $share->getShareType() !== IShare::TYPE_LINK) { + throw new OCSBadRequestException('Only email and link shares are supported'); + } + + // Allow sending the mail again if the share is an email share + if ($share->getShareType() === IShare::TYPE_EMAIL && count($emails) !== 0) { + throw new OCSBadRequestException('Emails should not be provided for email shares'); + } + + // Allow sending a mail if the share is a link share AND a list of emails is provided + if ($share->getShareType() === IShare::TYPE_LINK && count($emails) === 0) { + throw new OCSBadRequestException('Emails should be provided for link shares'); + } + + $link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', + ['token' => $share->getToken()]); + try { + /** @var ShareByMailProvider */ + $provider = $this->factory->getProviderForType(IShare::TYPE_EMAIL); + $provider->sendMailNotification( + $share->getNode()->getName(), + $link, + $share->getSharedBy(), + $share->getSharedWith(), + $share->getExpirationDate(), + $share->getNote() + ); + return new JSONResponse(['message' => 'ok']); + } catch (ProviderException $e) { + throw new OCSBadRequestException($this->l->t('Sending mail notification is not enabled')); + } catch (Exception $e) { + throw new OCSException($this->l->t('Error while sending mail notification')); + } + } catch (ShareNotFound $e) { + throw new OCSNotFoundException($this->l->t('Wrong share ID, share does not exist')); + } } } diff --git a/apps/files_sharing/src/components/NewFileRequestDialog.vue b/apps/files_sharing/src/components/NewFileRequestDialog.vue new file mode 100644 index 00000000000..53b4408b263 --- /dev/null +++ b/apps/files_sharing/src/components/NewFileRequestDialog.vue @@ -0,0 +1,330 @@ + + + + + + + diff --git a/apps/files_sharing/src/components/NewFileRequestDialog/FileRequestDatePassword.vue b/apps/files_sharing/src/components/NewFileRequestDialog/FileRequestDatePassword.vue new file mode 100644 index 00000000000..6da342da0f1 --- /dev/null +++ b/apps/files_sharing/src/components/NewFileRequestDialog/FileRequestDatePassword.vue @@ -0,0 +1,227 @@ + + + + + + + diff --git a/apps/files_sharing/src/components/NewFileRequestDialog/FileRequestFinish.vue b/apps/files_sharing/src/components/NewFileRequestDialog/FileRequestFinish.vue new file mode 100644 index 00000000000..1162414e049 --- /dev/null +++ b/apps/files_sharing/src/components/NewFileRequestDialog/FileRequestFinish.vue @@ -0,0 +1,217 @@ + + + + + + diff --git a/apps/files_sharing/src/components/NewFileRequestDialog/FileRequestIntro.vue b/apps/files_sharing/src/components/NewFileRequestDialog/FileRequestIntro.vue new file mode 100644 index 00000000000..766fbc3fc22 --- /dev/null +++ b/apps/files_sharing/src/components/NewFileRequestDialog/FileRequestIntro.vue @@ -0,0 +1,153 @@ + + + + + + diff --git a/apps/files_sharing/src/components/SharingEntryLink.vue b/apps/files_sharing/src/components/SharingEntryLink.vue index f93e6a9c953..9410f980a54 100644 --- a/apps/files_sharing/src/components/SharingEntryLink.vue +++ b/apps/files_sharing/src/components/SharingEntryLink.vue @@ -240,7 +240,7 @@ import PlusIcon from 'vue-material-design-icons/Plus.vue' import SharingEntryQuickShareSelect from './SharingEntryQuickShareSelect.vue' import ExternalShareAction from './ExternalShareAction.vue' -import GeneratePassword from '../utils/GeneratePassword.js' +import GeneratePassword from '../utils/GeneratePassword.ts' import Share from '../models/Share.js' import SharesMixin from '../mixins/SharesMixin.js' import ShareDetails from '../mixins/ShareDetails.js' @@ -369,7 +369,7 @@ export default { }, async set(enabled) { // TODO: directly save after generation to make sure the share is always protected - Vue.set(this.share, 'password', enabled ? await GeneratePassword() : '') + Vue.set(this.share, 'password', enabled ? await GeneratePassword(true) : '') Vue.set(this.share, 'newPassword', this.share.password) }, }, @@ -590,7 +590,7 @@ export default { // ELSE, show the pending popovermenu // if password default or enforced, pre-fill with random one if (this.config.enableLinkPasswordByDefault || this.config.enforcePasswordForPublicLink) { - shareDefaults.password = await GeneratePassword() + shareDefaults.password = await GeneratePassword(true) } // create share & close menu diff --git a/apps/files_sharing/src/components/SharingInput.vue b/apps/files_sharing/src/components/SharingInput.vue index f2b2f573700..e986ff4491f 100644 --- a/apps/files_sharing/src/components/SharingInput.vue +++ b/apps/files_sharing/src/components/SharingInput.vue @@ -27,14 +27,15 @@