From 31a25dc6b0545eb9bcb215990c8a71f1792f61f8 Mon Sep 17 00:00:00 2001 From: Brad Rubenstein Date: Sat, 10 Nov 2018 02:35:42 -0800 Subject: [PATCH] Customize presentation of accept/decline buttons in iMip mail Fix Issue #11230 Only present accept/decline button links in iMip mail for REQUEST, not CANCEL or others. Fix Issue #12156 Implement config setting "dav.invitation_link_recipients", to control which invitation recipients see accept/decline button links. The default, for public internet facing servers, is to always include them. For a server on a private intranet, this setting can be set to the email addresses or email domains of users whose browsers can access the nextcloud server referenced by those accept/decline button links. It can also be set to "false" to exclude the links from all requests. Signed-off-by: Brad Rubenstein --- apps/dav/lib/CalDAV/Schedule/IMipPlugin.php | 42 +++++++++++++++++++-- config/config.sample.php | 27 +++++++++++++ 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php b/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php index 3ff3ed0c56..4375c081d5 100644 --- a/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php +++ b/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php @@ -144,11 +144,11 @@ class IMipPlugin extends SabreIMipPlugin { $summary = $iTipMessage->message->VEVENT->SUMMARY; - if (parse_url($iTipMessage->sender, PHP_URL_SCHEME) !== 'mailto') { + if (strcasecmp(parse_url($iTipMessage->sender, PHP_URL_SCHEME), 'mailto') !== 0) { return; } - if (parse_url($iTipMessage->recipient, PHP_URL_SCHEME) !== 'mailto') { + if (strcasecmp(parse_url($iTipMessage->recipient, PHP_URL_SCHEME), 'mailto') !== 0) { return; } @@ -239,9 +239,44 @@ class IMipPlugin extends SabreIMipPlugin { $meetingAttendeeName, $meetingInviteeName); $this->addBulletList($template, $l10n, $meetingWhen, $meetingLocation, $meetingDescription, $meetingUrl); - $this->addResponseButtons($template, $l10n, $iTipMessage, $lastOccurrence); + + + // Only add response buttons to invitation requests: Fix Issue #11230 + if ($method == self::METHOD_REQUEST) { + + /* + ** Only offer invitation accept/reject buttons, which link back to the + ** nextcloud server, to recipients who can access the nextcloud server via + ** their internet/intranet. Issue #12156 + ** + ** For nextcloud servers accessible to the public internet, the default + ** "dav.invitation_link_recipients" value "true" (all recipients) is appropriate. + ** + ** When the nextcloud server is restricted behind a firewall, accessible + ** only via an internal network or via vpn, you can set "dav.invitation_link_recipients" + ** to the email address or email domain, or array of addresses or domains, + ** of recipients who can access the server. + ** + ** To deliver URL's always, set invitation_link_recipients to boolean "true". + ** To suppress URL's entirely, set invitation_link_recipients to boolean "false". + */ + + $recipientDomain = substr(strrchr($recipient, "@"), 1); + $invitationLinkRecipients = $this->config->getSystemValue('dav.invitation_link_recipients', true); + if (is_array($invitationLinkRecipients)) { + $invitationLinkRecipients = array_map('strtolower', $invitationLinkRecipients); // for case insensitive in_array + } + if ($invitationLinkRecipients === true + || (is_string($invitationLinkRecipients) && strcasecmp($recipient, $invitationLinkRecipients) === 0) + || (is_string($invitationLinkRecipients) && strcasecmp($recipientDomain, $invitationLinkRecipients) === 0) + || (is_array($invitationLinkRecipients) && in_array(strtolower($recipient), $invitationLinkRecipients)) + || (is_array($invitationLinkRecipients) && in_array(strtolower($recipientDomain), $invitationLinkRecipients))) { + $this->addResponseButtons($template, $l10n, $iTipMessage, $lastOccurrence); + } + } $template->addFooter(); + $message->useTemplate($template); $attachment = $this->mailer->createAttachment( @@ -447,7 +482,6 @@ class IMipPlugin extends SabreIMipPlugin { $template->setSubject('Invitation: ' . $summary); $template->addHeading($l10n->t('%1$s invited you to »%2$s«', [$inviteeName, $summary]), $l10n->t('Hello %s,', [$attendeeName])); } - } /** diff --git a/config/config.sample.php b/config/config.sample.php index 9c3cc47099..5f1eee4e94 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -1696,6 +1696,33 @@ $CONFIG = array( '/^Microsoft-WebDAV-MiniRedir/', // Windows webdav drive ), +/** +* The caldav server sends invitation emails to invitees, attaching the ICS +* file for the invitation. It also may include, in the body of the e-mail, +* invitation accept/reject web links referencing URL's that point to the nextcloud server. +* +* Although any recipient can read and reply to the ICS file via the iMip protocol, +* we must only present the web links to recipients who can access the nextcloud +* web server via their internet/intranet. +* +* When your nextcloud server is restricted behind a firewall, accessible +* only via an internal network or via vpn, you can set "dav.invitation_link_recipients" +* to the email address or email domain, or array of addresses or domains, +* of recipients who can access the server. Only those recipients will get web links. External +* users can accept/reject invitations by emailing back ICS files containing appropriate +* messages, using the iMip protocol. Many mail clients support this functionality. +* +* To suppress iMip web links entirely, set dav.invitation_link_recipients to false. +* To deliver iMip web links always, set dav.invitation_link_recipients to true. +* +* Examples: +* 'dav.invitation_link_recipients' => 'internal.example.com', +* 'dav.invitation_link_recipients' => array( 'internal.example.com', 'pat@roadwarrior.example.com' ), +* 'dav.invitation_link_recipients' => false, +* +*/ +'dav.invitation_link_recipients' => '*', // always include accept/reject server links in iMip emails + /** * By default there is on public pages a link shown that allows users to * learn about the "simple sign up" - see https://nextcloud.com/signup/