aboutsummaryrefslogtreecommitdiffstats
path: root/lib/public
diff options
context:
space:
mode:
authorSebastianKrupinski <krupinskis05@gmail.com>2024-05-16 19:06:34 -0400
committerSebastianKrupinski <krupinskis05@gmail.com>2024-07-23 16:20:36 -0400
commitfc0b694d379efefc50ba46262bd448abd29da6ed (patch)
treee49d558e18465da8156b1705f682364e1f8e6950 /lib/public
parentf9d4becf60da69f272f6c5700bbdf5cb99761bc4 (diff)
downloadnextcloud-server-fc0b694d379efefc50ba46262bd448abd29da6ed.tar.gz
nextcloud-server-fc0b694d379efefc50ba46262bd448abd29da6ed.zip
feat: mail provider backend
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
Diffstat (limited to 'lib/public')
-rw-r--r--lib/public/AppFramework/Bootstrap/IRegistrationContext.php11
-rw-r--r--lib/public/Mail/Provider/Address.php85
-rw-r--r--lib/public/Mail/Provider/Attachment.php139
-rw-r--r--lib/public/Mail/Provider/Exception/Exception.php18
-rw-r--r--lib/public/Mail/Provider/Exception/SendException.php18
-rw-r--r--lib/public/Mail/Provider/IAddress.php61
-rw-r--r--lib/public/Mail/Provider/IAttachment.php101
-rw-r--r--lib/public/Mail/Provider/IManager.php106
-rw-r--r--lib/public/Mail/Provider/IMessage.php232
-rw-r--r--lib/public/Mail/Provider/IMessageSend.php31
-rw-r--r--lib/public/Mail/Provider/IProvider.php94
-rw-r--r--lib/public/Mail/Provider/IService.php119
-rw-r--r--lib/public/Mail/Provider/Message.php338
13 files changed, 1353 insertions, 0 deletions
diff --git a/lib/public/AppFramework/Bootstrap/IRegistrationContext.php b/lib/public/AppFramework/Bootstrap/IRegistrationContext.php
index b86f7bcd76d..57e76f268d9 100644
--- a/lib/public/AppFramework/Bootstrap/IRegistrationContext.php
+++ b/lib/public/AppFramework/Bootstrap/IRegistrationContext.php
@@ -17,6 +17,7 @@ use OCP\Collaboration\Reference\IReferenceProvider;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Template\ICustomTemplateProvider;
use OCP\IContainer;
+use OCP\Mail\Provider\IProvider as IMailProvider;
use OCP\Notification\INotifier;
use OCP\Preview\IProviderV2;
use OCP\SpeechToText\ISpeechToTextProvider;
@@ -412,4 +413,14 @@ interface IRegistrationContext {
* @since 30.0.0
*/
public function registerTaskProcessingTaskType(string $taskProcessingTaskTypeClass): void;
+
+ /**
+ * Register a mail provider
+ *
+ * @param string $class
+ * @psalm-param class-string<IMailProvider> $class
+ * @since 30.0.0
+ */
+ public function registerMailProvider(string $class): void;
+
}
diff --git a/lib/public/Mail/Provider/Address.php b/lib/public/Mail/Provider/Address.php
new file mode 100644
index 00000000000..9cd2859a8a5
--- /dev/null
+++ b/lib/public/Mail/Provider/Address.php
@@ -0,0 +1,85 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Address Object
+ *
+ * This object is used to define the address and label of a email address
+ *
+ * @since 30.0.0
+ *
+ */
+class Address implements \OCP\Mail\Provider\IAddress {
+
+ /**
+ * initialize the mail address object
+ *
+ * @since 30.0.0
+ *
+ * @param string|null $address mail address (e.g test@example.com)
+ * @param string|null $label mail address label/name
+ */
+ public function __construct(
+ protected ?string $address = null,
+ protected ?string $label = null
+ ) {
+ }
+
+ /**
+ * sets the mail address
+ *
+ * @since 30.0.0
+ *
+ * @param string $value mail address (e.g. test@example.com)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setAddress(string $value): self {
+ $this->address = $value;
+ return $this;
+ }
+
+ /**
+ * gets the mail address
+ *
+ * @since 30.0.0
+ *
+ * @return string|null returns the mail address or null if one is not set
+ */
+ public function getAddress(): string | null {
+ return $this->address;
+ }
+
+ /**
+ * sets the mail address label/name
+ *
+ * @since 30.0.0
+ *
+ * @param string $value mail address label/name
+ *
+ * @return self return this object for command chaining
+ */
+ public function setLabel(string $value): self {
+ $this->label = $value;
+ return $this;
+ }
+
+ /**
+ * gets the mail address label/name
+ *
+ * @since 30.0.0
+ *
+ * @return string|null returns the mail address label/name or null if one is not set
+ */
+ public function getLabel(): string | null {
+ return $this->label;
+ }
+
+}
diff --git a/lib/public/Mail/Provider/Attachment.php b/lib/public/Mail/Provider/Attachment.php
new file mode 100644
index 00000000000..d7790a3bbc6
--- /dev/null
+++ b/lib/public/Mail/Provider/Attachment.php
@@ -0,0 +1,139 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Attachment Object
+ *
+ * This object is used to define the parameters of a mail attachment
+ *
+ * @since 30.0.0
+ *
+ */
+class Attachment implements \OCP\Mail\Provider\IAttachment {
+
+ /**
+ * initialize the mail attachment object
+ *
+ * @since 30.0.0
+ *
+ * @param string|null $contents binary contents of file
+ * @param string|null $name file name (e.g example.txt)
+ * @param string|null $type mime type (e.g. text/plain)
+ * @param bool $embedded embedded status of the attachment, default is false
+ */
+ public function __construct(
+ protected ?string $contents,
+ protected ?string $name,
+ protected ?string $type,
+ protected bool $embedded = false
+ ) {
+ }
+
+ /**
+ * sets the attachment file name
+ *
+ * @since 30.0.0
+ *
+ * @param string $value file name (e.g example.txt)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setName(string $value): self {
+ $this->name = $value;
+ return $this;
+ }
+
+ /**
+ * gets the attachment file name
+ *
+ * @since 30.0.0
+ *
+ * @return string | null returns the attachment file name or null if not set
+ */
+ public function getName(): string | null {
+ return $this->name;
+ }
+
+ /**
+ * sets the attachment mime type
+ *
+ * @since 30.0.0
+ *
+ * @param string $value mime type (e.g. text/plain)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setType(string $value): self {
+ $this->type = $value;
+ return $this;
+ }
+
+ /**
+ * gets the attachment mime type
+ *
+ * @since 30.0.0
+ *
+ * @return string | null returns the attachment mime type or null if not set
+ */
+ public function getType(): string | null {
+ return $this->type;
+ }
+
+ /**
+ * sets the attachment contents (actual data)
+ *
+ * @since 30.0.0
+ *
+ * @param string $value binary contents of file
+ *
+ * @return self return this object for command chaining
+ */
+ public function setContents(string $value): self {
+ $this->contents = $value;
+ return $this;
+ }
+
+ /**
+ * gets the attachment contents (actual data)
+ *
+ * @since 30.0.0
+ *
+ * @return string | null returns the attachment contents or null if not set
+ */
+ public function getContents(): string | null {
+ return $this->contents;
+ }
+
+ /**
+ * sets the embedded status of the attachment
+ *
+ * @since 30.0.0
+ *
+ * @param bool $value true - embedded / false - not embedded
+ *
+ * @return self return this object for command chaining
+ */
+ public function setEmbedded(bool $value): self {
+ $this->embedded = $value;
+ return $this;
+ }
+
+ /**
+ * gets the embedded status of the attachment
+ *
+ * @since 30.0.0
+ *
+ * @return bool embedded status of the attachment
+ */
+ public function getEmbedded(): bool {
+ return $this->embedded;
+ }
+
+}
diff --git a/lib/public/Mail/Provider/Exception/Exception.php b/lib/public/Mail/Provider/Exception/Exception.php
new file mode 100644
index 00000000000..7514c72a869
--- /dev/null
+++ b/lib/public/Mail/Provider/Exception/Exception.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider\Exception;
+
+/**
+ * Mail Provider Base Exception
+ *
+ * @since 30.0.0
+ */
+class Exception extends \Exception {
+
+}
diff --git a/lib/public/Mail/Provider/Exception/SendException.php b/lib/public/Mail/Provider/Exception/SendException.php
new file mode 100644
index 00000000000..fba0903cbb3
--- /dev/null
+++ b/lib/public/Mail/Provider/Exception/SendException.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider\Exception;
+
+/**
+ * Mail Provider Send Exception
+ *
+ * @since 30.0.0
+ */
+class SendException extends Exception {
+
+}
diff --git a/lib/public/Mail/Provider/IAddress.php b/lib/public/Mail/Provider/IAddress.php
new file mode 100644
index 00000000000..b980f31150b
--- /dev/null
+++ b/lib/public/Mail/Provider/IAddress.php
@@ -0,0 +1,61 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Address Interface
+ *
+ * This interface is a base requirement of methods and functionality used to construct a mail address object
+ *
+ * @since 30.0.0
+ *
+ */
+interface IAddress {
+
+ /**
+ * sets the mail address
+ *
+ * @since 30.0.0
+ *
+ * @param string $value mail address (test@example.com)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setAddress(string $value): self;
+
+ /**
+ * gets the mail address
+ *
+ * @since 30.0.0
+ *
+ * @return string returns the mail address
+ */
+ public function getAddress(): string | null;
+
+ /**
+ * sets the mail address label/name
+ *
+ * @since 30.0.0
+ *
+ * @param string $value mail address label/name
+ *
+ * @return self return this object for command chaining
+ */
+ public function setLabel(string $value): self;
+
+ /**
+ * gets the mail address label/name
+ *
+ * @since 30.0.0
+ *
+ * @return string returns the mail address label/name
+ */
+ public function getLabel(): string | null;
+
+}
diff --git a/lib/public/Mail/Provider/IAttachment.php b/lib/public/Mail/Provider/IAttachment.php
new file mode 100644
index 00000000000..b5bdffc0e81
--- /dev/null
+++ b/lib/public/Mail/Provider/IAttachment.php
@@ -0,0 +1,101 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Attachment Interface
+ *
+ * This interface is used for defining individual attachments that are attached to a message
+ *
+ * @since 30.0.0
+ *
+ */
+interface IAttachment {
+
+ /**
+ * sets the attachment file name
+ *
+ * @since 30.0.0
+ *
+ * @param string $value file name (e.g example.txt)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setName(string $value): self;
+
+ /**
+ * gets the attachment file name
+ *
+ * @since 30.0.0
+ *
+ * @return string | null returns the attachment file name or null if one is not set
+ */
+ public function getName(): string | null;
+
+ /**
+ * sets the attachment mime type
+ *
+ * @since 30.0.0
+ *
+ * @param string $value mime type (e.g. text/plain)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setType(string $value): self;
+
+ /**
+ * gets the attachment mime type
+ *
+ * @since 30.0.0
+ *
+ * @return string | null returns the attachment mime type or null if not set
+ */
+ public function getType(): string | null;
+
+ /**
+ * sets the attachment contents (actual data)
+ *
+ * @since 30.0.0
+ *
+ * @param string $value binary contents of file
+ *
+ * @return self return this object for command chaining
+ */
+ public function setContents(string $value): self;
+
+ /**
+ * gets the attachment contents (actual data)
+ *
+ * @since 30.0.0
+ *
+ * @return string | null returns the attachment contents or null if not set
+ */
+ public function getContents(): string | null;
+
+ /**
+ * sets the embedded status of the attachment
+ *
+ * @since 30.0.0
+ *
+ * @param bool $value true - embedded / false - not embedded
+ *
+ * @return self return this object for command chaining
+ */
+ public function setEmbedded(bool $value): self;
+
+ /**
+ * gets the embedded status of the attachment
+ *
+ * @since 30.0.0
+ *
+ * @return bool embedded status of the attachment
+ */
+ public function getEmbedded(): bool;
+
+}
diff --git a/lib/public/Mail/Provider/IManager.php b/lib/public/Mail/Provider/IManager.php
new file mode 100644
index 00000000000..4c06cfff87c
--- /dev/null
+++ b/lib/public/Mail/Provider/IManager.php
@@ -0,0 +1,106 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Provider Manager Interface
+ *
+ * This interface is a base requirement of methods and functionality used to construct a mail provider manager object
+ *
+ * @since 30.0.0
+ *
+ */
+interface IManager {
+
+ /**
+ * determine if any mail providers are registered
+ *
+ * @since 30.0.0
+ *
+ * @return bool
+ */
+ public function has(): bool;
+
+ /**
+ * retrieve a count of how many mail providers are registered
+ *
+ * @since 30.0.0
+ *
+ * @return int
+ */
+ public function count(): int;
+
+ /**
+ * retrieve which mail providers are registered
+ *
+ * @since 30.0.0
+ *
+ * @return array<string,String> collection of provider id and label ['jmap' => 'JMap Connector']
+ */
+ public function types(): array;
+
+ /**
+ * retrieve all registered mail providers
+ *
+ * @since 30.0.0
+ *
+ * @return array<string,IProvider> collection of provider id and object ['jmap' => IProviderObject]
+ */
+ public function providers(): array;
+
+ /**
+ * retrieve a provider with a specific id
+ *
+ * @since 30.0.0
+ *
+ * @param string $providerId provider id
+ *
+ * @return IProvider|null
+ */
+ public function findProviderById(string $providerId): IProvider | null;
+
+ /**
+ * retrieve all services for all registered mail providers
+ *
+ * @since 30.0.0
+ *
+ * @param string $userId user id
+ *
+ * @return array<string,array<string,IService>> collection of provider id, service id and object ['jmap' => ['Service1' => IServiceObject]]
+ */
+ public function services(string $userId): array;
+
+ /**
+ * retrieve a service with a specific id
+ *
+ * @since 30.0.0
+ *
+ * @param string $userId user id
+ * @param string $serviceId service id
+ * @param string $providerId provider id
+ *
+ * @return IService|null returns service object or null if none found
+ */
+ public function findServiceById(string $userId, string $serviceId, ?string $providerId = null): IService | null;
+
+ /**
+ * retrieve a service for a specific mail address
+ * returns first service with specific primary address
+ *
+ * @since 30.0.0
+ *
+ * @param string $userId user id
+ * @param string $address mail address (e.g. test@example.com)
+ * @param string $providerId provider id
+ *
+ * @return IService|null returns service object or null if none found
+ */
+ public function findServiceByAddress(string $userId, string $address, ?string $providerId = null): IService | null;
+
+}
diff --git a/lib/public/Mail/Provider/IMessage.php b/lib/public/Mail/Provider/IMessage.php
new file mode 100644
index 00000000000..71021981362
--- /dev/null
+++ b/lib/public/Mail/Provider/IMessage.php
@@ -0,0 +1,232 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Message Interface
+ *
+ * This interface is a base requirement of methods and functionality used to construct a mail message object
+ *
+ * @since 30.0.0
+ *
+ */
+interface IMessage {
+
+ /**
+ * arbitrary unique text string identifying this message
+ *
+ * @since 30.0.0
+ *
+ * @return string id of this message
+ */
+ public function id(): string;
+
+ /**
+ * sets the sender of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress $value sender's mail address object
+ *
+ * @return self return this object for command chaining
+ */
+ public function setFrom(IAddress $value): self;
+
+ /**
+ * gets the sender of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress|null sender's mail address object
+ */
+ public function getFrom(): IAddress | null;
+
+ /**
+ * sets the sender's reply to address of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress $value senders's reply to mail address object
+ *
+ * @return self return this object for command chaining
+ */
+ public function setReplyTo(IAddress $value): self;
+
+ /**
+ * gets the sender's reply to address of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress|null sender's reply to mail address object
+ */
+ public function getReplyTo(): IAddress | null;
+
+ /**
+ * sets the recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of or one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setTo(IAddress ...$value): self;
+
+ /**
+ * gets the recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param array<int,IAddress> collection of all recipient mail address objects
+ */
+ public function getTo(): array;
+
+ /**
+ * sets the copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of or one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setCc(IAddress ...$value): self;
+
+ /**
+ * gets the copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param array<int,IAddress> collection of all copied recipient mail address objects
+ */
+ public function getCc(): array;
+
+ /**
+ * sets the blind copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of or one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBcc(IAddress ...$value): self;
+
+ /**
+ * gets the blind copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param array<int,IAddress> collection of all blind copied recipient mail address objects
+ */
+ public function getBcc(): array;
+
+ /**
+ * sets the subject of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value subject of mail message
+ *
+ * @return self return this object for command chaining
+ */
+ public function setSubject(string $value): self;
+
+ /**
+ * gets the subject of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string|null subject of message or null if one is not set
+ */
+ public function getSubject(): string | null;
+
+ /**
+ * sets the plain text or html body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value text or html body of message
+ * @param bool $html html flag - true for html
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBody(string $value, bool $html): self;
+
+ /**
+ * gets either the html or plain text body of this message
+ *
+ * html body will be returned over plain text if html body exists
+ *
+ * @since 30.0.0
+ *
+ * @param string|null html/plain body of this message or null if one is not set
+ */
+ public function getBody(): string | null;
+
+ /**
+ * sets the html body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value html body of message
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBodyHtml(string $value): self;
+
+ /**
+ * gets the html body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string|null html body of this message or null if one is not set
+ */
+ public function getBodyHtml(): string | null;
+
+ /**
+ * sets the plain text body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value plain text body of message
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBodyPlain(string $value): self;
+
+ /**
+ * gets the plain text body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string|null plain text body of this message or null if one is not set
+ */
+ public function getBodyPlain(): string | null;
+
+ /**
+ * sets the attachments of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAttachment ...$value collection of or one or more mail attachment objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setAttachments(IAttachment ...$value): self;
+
+ /**
+ * gets the attachments of this message
+ *
+ * @since 30.0.0
+ *
+ * @return array<int,IAttachment> collection of all mail attachment objects
+ */
+ public function getAttachments(): array;
+}
diff --git a/lib/public/Mail/Provider/IMessageSend.php b/lib/public/Mail/Provider/IMessageSend.php
new file mode 100644
index 00000000000..e68f18cf95c
--- /dev/null
+++ b/lib/public/Mail/Provider/IMessageSend.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Message Send Interface
+ *
+ * This interface is the required set of methods and functionality used to extend IService with message sending functionality
+ *
+ * @since 30.0.0
+ *
+ */
+interface IMessageSend {
+
+ /**
+ * send an outbound message
+ *
+ * @since 30.0.0
+ *
+ * @param IMessage $message mail message object with all required parameters to send a message
+ * @param array $options array of options reserved for future use
+ */
+ public function sendMessage(IMessage $message, array $option = []): void;
+
+}
diff --git a/lib/public/Mail/Provider/IProvider.php b/lib/public/Mail/Provider/IProvider.php
new file mode 100644
index 00000000000..47d6002f9b0
--- /dev/null
+++ b/lib/public/Mail/Provider/IProvider.php
@@ -0,0 +1,94 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Provider Interface
+ *
+ * This interface is a base requirement of methods and functionality used to construct a mail provider object
+ *
+ * @since 30.0.0
+ *
+ */
+interface IProvider {
+
+ /**
+ * arbitrary unique text string identifying this provider
+ *
+ * @since 30.0.0
+ *
+ * @return string id of this provider (e.g. UUID or 'IMAP/SMTP' or anything else)
+ */
+ public function id(): string;
+
+ /**
+ * localized human friendly name of this provider
+ *
+ * @since 30.0.0
+ *
+ * @return string label/name of this provider (e.g. Plain Old IMAP/SMTP)
+ */
+ public function label(): string;
+
+ /**
+ * determine if any services are configured for a specific user
+ *
+ * @since 30.0.0
+ *
+ * @param string $userId user id
+ *
+ * @return bool true if any services are configure for the user
+ */
+ public function hasServices(string $userId): bool;
+
+ /**
+ * retrieve collection of services for a specific user
+ *
+ * @param string $userId user id
+ *
+ * @since 30.0.0
+ *
+ * @return array<string,IService> collection of service id and object ['1' => IServiceObject]
+ */
+ public function listServices(string $userId): array;
+
+ /**
+ * retrieve a service with a specific id
+ *
+ * @since 30.0.0
+ *
+ * @param string $userId user id
+ * @param string $serviceId service id
+ *
+ * @return IService|null returns service object or null if none found
+ */
+ public function findServiceById(string $userId, string $serviceId): IService | null;
+
+ /**
+ * retrieve a service for a specific mail address
+ *
+ * @since 30.0.0
+ *
+ * @param string $userId user id
+ * @param string $address mail address (e.g. test@example.com)
+ *
+ * @return IService|null returns service object or null if none found
+ */
+ public function findServiceByAddress(string $userId, string $address): IService | null;
+
+ /**
+ * construct a new empty service object
+ *
+ * @since 30.0.0
+ *
+ * @return IService blank service object
+ */
+ public function initiateService(): IService;
+
+}
diff --git a/lib/public/Mail/Provider/IService.php b/lib/public/Mail/Provider/IService.php
new file mode 100644
index 00000000000..a8fd73749bb
--- /dev/null
+++ b/lib/public/Mail/Provider/IService.php
@@ -0,0 +1,119 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Service Interface
+ *
+ * This interface is a base requirement of methods and functionality used to construct a mail service object
+ *
+ * @since 30.0.0
+ *
+ */
+interface IService {
+
+ /**
+ * arbitrary unique text string identifying this service
+ *
+ * @since 30.0.0
+ *
+ * @return string id of this service (e.g. 1 or service1 or anything else)
+ */
+ public function id(): string;
+
+ /**
+ * checks if a service is able of performing an specific action
+ *
+ * @since 4.0.0
+ *
+ * @param string $value required ability e.g. 'MessageSend'
+ *
+ * @return bool true/false if ability is supplied and found in collection
+ */
+ public function capable(string $value): bool;
+
+ /**
+ * retrieves a collection of what actions a service can perfrom
+ *
+ * @since 4.0.0
+ *
+ * @return array collection of abilities otherwise empty collection
+ */
+ public function capabilities(): array;
+
+ /**
+ * gets the localized human frendly name of this service
+ *
+ * @since 30.0.0
+ *
+ * @return string label/name of service (e.g. ACME Company Mail Service)
+ */
+ public function getLabel(): string;
+
+ /**
+ * sets the localized human frendly name of this service
+ *
+ * @since 30.0.0
+ *
+ * @param string $value label/name of service (e.g. ACME Company Mail Service)
+ *
+ * @return self return this object for command chaining
+ */
+ public function setLabel(string $value): self;
+
+ /**
+ * gets the primary mailing address for this service
+ *
+ * @since 30.0.0
+ *
+ * @return IAddress mail address object
+ */
+ public function getPrimaryAddress(): IAddress;
+
+ /**
+ * sets the primary mailing address for this service
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress $value mail address object
+ *
+ * @return self return this object for command chaining
+ */
+ public function setPrimaryAddress(IAddress $value): self;
+
+ /**
+ * gets the secondary mailing addresses (aliases) collection for this service
+ *
+ * @since 30.0.0
+ *
+ * @return array<int, IAddress> collection of mail address objects
+ */
+ public function getSecondaryAddresses(): array;
+
+ /**
+ * sets the secondary mailing addresses (aliases) for this service
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setSecondaryAddresses(IAddress ...$value): self;
+
+ /**
+ * construct a new empty message object
+ *
+ * @since 30.0.0
+ *
+ * @return IMessage blank message object
+ */
+ public function initiateMessage(): IMessage;
+
+}
diff --git a/lib/public/Mail/Provider/Message.php b/lib/public/Mail/Provider/Message.php
new file mode 100644
index 00000000000..58638963640
--- /dev/null
+++ b/lib/public/Mail/Provider/Message.php
@@ -0,0 +1,338 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Mail\Provider;
+
+/**
+ * Mail Message Object
+ *
+ * This object is used to define a mail message that can be used to transfer data to a provider
+ *
+ * @since 30.0.0
+ *
+ */
+class Message implements \OCP\Mail\Provider\IMessage {
+
+ /**
+ * initialize the mail message object
+ *
+ * @since 30.0.0
+ *
+ * @param array $data message data array
+ */
+ public function __construct(
+ protected array $data = [],
+ ) {
+ }
+
+ /**
+ * arbitrary unique text string identifying this message
+ *
+ * @since 30.0.0
+ *
+ * @return string id of this message
+ */
+ public function id(): string {
+ // return id of message
+ return (isset($this->data['id'])) ? $this->data['id'] : '';
+ }
+
+ /**
+ * sets the sender of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress $value sender's mail address object
+ *
+ * @return self return this object for command chaining
+ */
+ public function setFrom(IAddress $value): self {
+ // create or update field in data store with value
+ $this->data['from'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the sender of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress|null sender's mail address object
+ */
+ public function getFrom(): IAddress | null {
+ // evaluate if data store field exists and return value(s) or null otherwise
+ return (isset($this->data['from'])) ? $this->data['from'] : null;
+ }
+
+ /**
+ * sets the sender's reply to address of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress $value senders's reply to mail address object
+ *
+ * @return self return this object for command chaining
+ */
+ public function setReplyTo(IAddress $value): self {
+ // create or update field in data store with value
+ $this->data['replyTo'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the sender's reply to address of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress|null sender's reply to mail address object
+ */
+ public function getReplyTo(): IAddress | null {
+ // evaluate if data store field exists and return value(s) or null otherwise
+ return (isset($this->data['replyTo'])) ? $this->data['replyTo'] : null;
+ }
+
+ /**
+ * sets the recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of or one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setTo(IAddress ...$value): self {
+ // create or update field in data store with value
+ $this->data['to'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param array<int,IAddress> collection of all recipient mail address objects
+ */
+ public function getTo(): array {
+ // evaluate if data store field exists and return value(s) or empty collection
+ return (isset($this->data['to'])) ? $this->data['to'] : [];
+ }
+
+ /**
+ * sets the copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of or one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setCc(IAddress ...$value): self {
+ // create or update field in data store with value
+ $this->data['cc'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param array<int,IAddress> collection of all copied recipient mail address objects
+ */
+ public function getCc(): array {
+ // evaluate if data store field exists and return value(s) or empty collection
+ return (isset($this->data['cc'])) ? $this->data['cc'] : [];
+ }
+
+ /**
+ * sets the blind copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAddress ...$value collection of or one or more mail address objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBcc(IAddress ...$value): self {
+ // create or update field in data store with value
+ $this->data['bcc'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the blind copy to recipient(s) of this message
+ *
+ * @since 30.0.0
+ *
+ * @param array<int,IAddress> collection of all blind copied recipient mail address objects
+ */
+ public function getBcc(): array {
+ // evaluate if data store field exists and return value(s) or empty collection
+ return (isset($this->data['bcc'])) ? $this->data['bcc'] : [];
+ }
+
+ /**
+ * sets the subject of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value subject of mail message
+ *
+ * @return self return this object for command chaining
+ */
+ public function setSubject(string $value): self {
+ // create or update field in data store with value
+ $this->data['subject'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the subject of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string|null subject of message or null if one is not set
+ */
+ public function getSubject(): string | null {
+ // evaluate if data store field exists and return value(s) or null otherwise
+ return (isset($this->data['subject'])) ? $this->data['subject'] : null;
+ }
+
+ /**
+ * sets the plain text or html body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value text or html body of message
+ * @param bool $html html flag - true for html
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBody(string $value, bool $html = false): self {
+ // evaluate html flag and create or update appropriate field in data store with value
+ if ($html) {
+ $this->data['bodyHtml'] = $value;
+ } else {
+ $this->data['bodyPlain'] = $value;
+ }
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets either the html or plain text body of this message
+ *
+ * html body will be returned over plain text if html body exists
+ *
+ * @since 30.0.0
+ *
+ * @param string|null html/plain body of this message or null if one is not set
+ */
+ public function getBody(): string | null {
+ // evaluate if data store field(s) exists and return value
+ if (isset($this->data['bodyHtml'])) {
+ return $this->data['bodyHtml'];
+ } elseif (isset($this->data['bodyPlain'])) {
+ return $this->data['bodyPlain'];
+ }
+ // return null if data fields did not exist in data store
+ return null;
+ }
+
+ /**
+ * sets the html body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value html body of message
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBodyHtml(string $value): self {
+ // create or update field in data store with value
+ $this->data['bodyHtml'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the html body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string|null html body of this message or null if one is not set
+ */
+ public function getBodyHtml(): string | null {
+ // evaluate if data store field exists and return value(s) or null otherwise
+ return (isset($this->data['bodyHtml'])) ? $this->data['bodyHtml'] : null;
+ }
+
+ /**
+ * sets the plain text body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string $value plain text body of message
+ *
+ * @return self return this object for command chaining
+ */
+ public function setBodyPlain(string $value): self {
+ // create or update field in data store with value
+ $this->data['bodyPlain'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the plain text body of this message
+ *
+ * @since 30.0.0
+ *
+ * @param string|null plain text body of this message or null if one is not set
+ */
+ public function getBodyPlain(): string | null {
+ // evaluate if data store field exists and return value(s) or null otherwise
+ return (isset($this->data['bodyPlain'])) ? $this->data['bodyPlain'] : null;
+ }
+
+ /**
+ * sets the attachments of this message
+ *
+ * @since 30.0.0
+ *
+ * @param IAttachment ...$value collection of or one or more mail attachment objects
+ *
+ * @return self return this object for command chaining
+ */
+ public function setAttachments(IAttachment ...$value): self {
+ // create or update field in data store with value
+ $this->data['attachments'] = $value;
+ // return this object for command chaining
+ return $this;
+ }
+
+ /**
+ * gets the attachments of this message
+ *
+ * @since 30.0.0
+ *
+ * @return array<int,IAttachment> collection of all mail attachment objects
+ */
+ public function getAttachments(): array {
+ // evaluate if data store field exists and return value(s) or null otherwise
+ return (isset($this->data['attachments'])) ? $this->data['attachments'] : [];
+ }
+
+}