diff --git a/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php b/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php index 3ff3ed0c5697a..754812461ccfd 100644 --- a/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php +++ b/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php @@ -244,13 +244,37 @@ public function schedule(Message $iTipMessage) { $template->addFooter(); $message->useTemplate($template); - $attachment = $this->mailer->createAttachment( - $iTipMessage->message->serialize(), - 'event.ics',// TODO(leon): Make file name unique, e.g. add event id - 'text/calendar; method=' . $iTipMessage->method - ); - $message->attach($attachment); - + # We choose to work like thinderbird Lightning. + # using a plain text text/calendar ics. + # This plain text text/calendar part is needed for + # Microsoft Outlook versions <=2010 to work. + + # The attachment base64 text/calendar part is removed from the code + #$attachment = $this->mailer->createAttachment( + # $iTipMessage->message->serialize(), + # 'event.ics',// TODO(leon): Make file name unique, e.g. add event id + # 'text/calendar; method=' . $iTipMessage->method + #); + #$message->attach($attachment); + + # The plain text text/calendar part is added to the code, but we need + # to do something more. Outlook (2010 and 2016 tested) has problems with canceled messages + # that contain Time Zone Identifications. + # We get an 'not-supported-calendar-message.ics' and the cancellation is not recognized. + # We remove the TZID from the iTipMessage and the problem is solved. + # It is a workaround, and probably not a structural solution. + # See: https://stackoverflow.com/questions/48550054/icalendar-appointment-is-a-not-supported-calendar-message-ics + + $itip_msg = $iTipMessage->message->serialize(); + if (strpos($itip_msg, 'METHOD:CANCEL') !== false) { + $itip_msg = preg_replace('/[;]TZID=[^:]+/', '', $itip_msg); + } + $message->addPart( + $itip_msg, + 'text/calendar; method=' . $iTipMessage->method, + 'UTF-8' + ); + try { $failed = $this->mailer->send($message); $iTipMessage->scheduleStatus = '1.1; Scheduling message is sent via iMip'; diff --git a/apps/oauth2/lib/Controller/LoginRedirectorController.php b/apps/oauth2/lib/Controller/LoginRedirectorController.php index 8e8cff1b1a56f..25154cbd4dcf4 100644 --- a/apps/oauth2/lib/Controller/LoginRedirectorController.php +++ b/apps/oauth2/lib/Controller/LoginRedirectorController.php @@ -1,4 +1,5 @@ * @@ -50,7 +51,7 @@ class LoginRedirectorController extends Controller { * @param ISession $session * @param IL10N $l */ - public function __construct($appName, + public function __construct(string $appName, IRequest $request, IURLGenerator $urlGenerator, ClientMapper $clientMapper, @@ -75,7 +76,7 @@ public function __construct($appName, */ public function authorize($client_id, $state, - $response_type) { + $response_type): Response { try { $client = $this->clientMapper->getByIdentifier($client_id); } catch (ClientNotFoundException $e) { diff --git a/apps/oauth2/lib/Controller/OauthApiController.php b/apps/oauth2/lib/Controller/OauthApiController.php index 73fed3654d574..b05d3781e5c16 100644 --- a/apps/oauth2/lib/Controller/OauthApiController.php +++ b/apps/oauth2/lib/Controller/OauthApiController.php @@ -1,4 +1,5 @@ * @@ -53,18 +54,7 @@ class OauthApiController extends Controller { /** @var Throttler */ private $throttler; - /** - * @param string $appName - * @param IRequest $request - * @param ICrypto $crypto - * @param AccessTokenMapper $accessTokenMapper - * @param ClientMapper $clientMapper - * @param TokenProvider $tokenProvider - * @param ISecureRandom $secureRandom - * @param ITimeFactory $time - * @param Throttler $throttler - */ - public function __construct($appName, + public function __construct(string $appName, IRequest $request, ICrypto $crypto, AccessTokenMapper $accessTokenMapper, @@ -94,7 +84,7 @@ public function __construct($appName, * @param string $client_secret * @return JSONResponse */ - public function getToken($grant_type, $code, $refresh_token, $client_id, $client_secret) { + public function getToken($grant_type, $code, $refresh_token, $client_id, $client_secret): JSONResponse { // We only handle two types if ($grant_type !== 'authorization_code' && $grant_type !== 'refresh_token') { diff --git a/apps/oauth2/lib/Exceptions/AccessTokenNotFoundException.php b/apps/oauth2/lib/Exceptions/AccessTokenNotFoundException.php index a1eb632a9eb56..c6b020b8f7e36 100644 --- a/apps/oauth2/lib/Exceptions/AccessTokenNotFoundException.php +++ b/apps/oauth2/lib/Exceptions/AccessTokenNotFoundException.php @@ -1,4 +1,5 @@ * diff --git a/apps/oauth2/lib/Exceptions/ClientNotFoundException.php b/apps/oauth2/lib/Exceptions/ClientNotFoundException.php index b2395c7bc9e29..9655ad508d29d 100644 --- a/apps/oauth2/lib/Exceptions/ClientNotFoundException.php +++ b/apps/oauth2/lib/Exceptions/ClientNotFoundException.php @@ -1,4 +1,5 @@ * diff --git a/apps/oauth2/lib/Migration/SetTokenExpiration.php b/apps/oauth2/lib/Migration/SetTokenExpiration.php index 54add100fa770..f55c1a41c6f04 100644 --- a/apps/oauth2/lib/Migration/SetTokenExpiration.php +++ b/apps/oauth2/lib/Migration/SetTokenExpiration.php @@ -1,4 +1,5 @@ * @@ -50,7 +51,7 @@ public function __construct(IDBConnection $connection, $this->tokenProvider = $tokenProvider; } - public function getName() { + public function getName(): string { return 'Update OAuth token expiration times'; } diff --git a/lib/private/Mail/Message.php b/lib/private/Mail/Message.php index 8a13e2c108cc7..770b6fc190ede 100644 --- a/lib/private/Mail/Message.php +++ b/lib/private/Mail/Message.php @@ -57,6 +57,26 @@ public function attach(IAttachment $attachment): IMessage { $this->swiftMessage->attach($attachment->getSwiftAttachment()); return $this; } + + /** + * @param $body: body of the mime part + * @param $content-type = null: Mime Content-Type (e.g. text/plain or text/calendar) + * @param $charset = null: Character Set (e.g. UTF-8) + * @return $this + * @since 14.0.4 + */ + public function addPart($data, $content_type = null, $charset = null): IMessage { + # To be sure this works with iCalendar messages, we encode with 8bit instead of + # quoted-printable encoding. We save the current encoder, replace the current + # encoder with an 8bit encoder and after we've finished, we reset the encoder + # to the previous one. + $encoder = $this->swiftMessage->getEncoder(); + $eightbit_encoder = new \Swift_Mime_ContentEncoder_PlainContentEncoder("8bit"); + $this->swiftMessage->setEncoder($eightbit_encoder); + $this->swiftMessage->addPart($data, $content_type, $charset); + $this->swiftMessage->setEncoder($encoder); + return $this; + } /** * SwiftMailer does currently not work with IDN domains, this function therefore converts the domains diff --git a/lib/public/Mail/IMessage.php b/lib/public/Mail/IMessage.php index 638fd9d103fc7..57d7a261b5580 100644 --- a/lib/public/Mail/IMessage.php +++ b/lib/public/Mail/IMessage.php @@ -38,7 +38,16 @@ interface IMessage { * @since 13.0.0 */ public function attach(IAttachment $attachment): IMessage; - + + /** + * @param $body: body of the mime part + * @param $content-type = null: Mime Content-Type (e.g. text/plain or text/calendar) + * @param $charset = null: Character Set (e.g. UTF-8) + * @return IMessage + * @since 14.0.4 + */ + public function addPart($body, $content_type = null, $charset = null): IMessage; + /** * Set the from address of this message. *