Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ocs): notify of new messages and provide API endpoint to retrieve its contents #9749

Merged
merged 1 commit into from
Jul 10, 2024

Conversation

miaulalala
Copy link
Contributor

@miaulalala miaulalala commented Jun 17, 2024

To Do

  • GET Email as JSON structure
  • GET Email as RFC5322 raw email
  • GET Attachments via URL (single attachment only)
  • Event for new incoming messages
  • Tests

@miaulalala miaulalala self-assigned this Jun 17, 2024
@miaulalala miaulalala added this to the v3.8.0 milestone Jun 17, 2024
@miaulalala miaulalala marked this pull request as ready for review June 18, 2024 09:40
@miaulalala miaulalala marked this pull request as draft June 18, 2024 11:44
@miaulalala
Copy link
Contributor Author

miaulalala commented Jun 19, 2024

Wrong PR

@miaulalala miaulalala marked this pull request as ready for review June 19, 2024 15:01
Copy link
Contributor

@SebastianKrupinski SebastianKrupinski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than the one recommendation, code works.

lib/Controller/MessageApiController.php Outdated Show resolved Hide resolved
@miaulalala
Copy link
Contributor Author

@ChristophWurst shall I also expose an endpoint to download the attachments? Or is there a way to add them to the JSON without doing the base64_enocde dance? We have a download in the MessageController already that I could copy.

Copy link
Contributor

@SebastianKrupinski SebastianKrupinski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested works good.

The Json message object just didn't have the body parameter, but all other information was there.

@SebastianKrupinski
Copy link
Contributor

@ChristophWurst shall I also expose an endpoint to download the attachments? Or is there a way to add them to the JSON without doing the base64_enocde dance? We have a download in the MessageController already that I could copy.

@miaulalala i wouldn't include attachments in the get method output... That can cause a lot of traffic for something that might not be used... on that note the attachments are already in the raw message, so I don't know if the raw message should be included unless requested that way...

This was the encoded attachment in the message I pulled.

inline; name=event.ics; filename=event.ics\r\n\r\nQkVHSU46VkNBTEVOREFSDQpWRVJTSU9OOjIuMA0KUFJPRElEOi0vL1NhYnJlLy9TYWJyZSBWT2Jq\r\nZWN0IDQuNS40Ly9FTg0KQ0FMU0NBTEU6R1JFR09SSUFODQpNRVRIT0Q6Q0FOQ0VMDQpCRUdJTjpW\r\nRVZFTlQNClVJRDpkZWM2NzQzNS1iN2QwLTQ0YTMtODQxMS0zOTFjYTZmNGJiY2ENCkRUU1RBTVA6\r\nMjAyNDA2MjVUMjE1ODA2Wg0KU0VRVUVOQ0U6Mw0KU1VNTUFSWTpUZXN0aW5nIFNpbmdsZXRvbiBB\r\nbGwgRGF5IEV2ZW50DQpEVFNUQVJUO1ZBTFVFPURBVEU6MjAyNDA3MDMNCkRURU5EO1ZBTFVFPURB\r\nVEU6MjAyNDA3MDQNCk9SR0FOSVpFUjtDTj1Vc2VyIE9uZTptYWlsdG86dXNlcjFAa3NhbWFpbC5j\r\nYQ0KQVRURU5ERUU7Q049VXNlciBUd286bWFpbHRvOnVzZXIyQGtzYW1haWwuY2ENCkVORDpWRVZF\r\nTlQNCkVORDpWQ0FMRU5EQVINCg==\r\n--SM8uFlts--\r\n\r\n"

@miaulalala
Copy link
Contributor Author

JSON response:

{
    "ocs": {
        "meta": {
            "status": "ok",
            "statuscode": 200,
            "message": "OK"
        },
        "data": {
            "uid": 5396,
            "messageId": "<kjsdflkdsjflksdkjf@geopod-ismtpd-39>",
            "from": [
                {
                    "label": "FromLabel",
                    "email": "from@teefury.com"
                }
            ],
            "to": [
                {
                    "label": "fhfhf@gmx.net",
                    "email": "fhfhf@gmx.net"
                }
            ],
            "replyTo": [
                {
                    "label": "ReplyToLabel",
                    "email": "email@replyto.com"
                }
            ],
            "cc": [],
            "bcc": [],
            "subject": "Subject",
            "dateInt": 1719374564,
            "flags": {
                "seen": true,
                "flagged": false,
                "answered": false,
                "deleted": false,
                "draft": false,
                "forwarded": false,
                "hasAttachments": false,
                "mdnsent": false,
                "important": true
            },
            "hasHtmlBody": true,
            "dispositionNotificationTo": "",
            "hasDkimSignature": true,
            "unsubscribeUrl": "sjfifjsdlksdjflksdjf",
            "isOneClickUnsubscribe": true,
            "unsubscribeMailto": null,
            "scheduling": [],
            "body": "Body data here",
            "attachments": [],
            "id": 186737,
            "isSenderTrusted": false,
            "smime": {
                "isSigned": false,
                "signatureIsValid": null,
                "isEncrypted": false
            }
        }
    }
}

@st3iny
Copy link
Member

st3iny commented Jul 1, 2024

When an S/MIME encrypted message is fetched via MessageApiController::get() and the decryption fails (due to a missing key), a 404 response is returned with an empty message.

This could be improved by catching, retrying without fetching the body and adding a field bodyRawUrl field to the data response pointing to getRaw(). The HTTP status code should be 206 Partial Content.

We cannot get the body but the meta information of a message (to, cc, subject etc.) could still be interesting to an API consumer.

$client = $this->clientFactory->getClient($account);
try {
$imapMessage = $this->mailManager->getImapMessage(
$client,
$account,
$mailbox,
$message->getUid(), true
);
$json = $imapMessage->getFullMessage($id);
} catch (ServiceException $e) {
$this->logger->error('Message could not be loaded', ['exception' => $e->getMessage()]);
return new DataResponse($e, Http::STATUS_NOT_FOUND);

Fetching with $loadBody = false in line 87 will return the IMAP message without the body but will not fail on missing keys.


The thrown exception in SmimeService::decryptDataFetch() has to adjusted accordingly. Currently, a ServiceException is thrown which cannot be distinguished easily from the the decryption error.

if ($decryptionResult === null) {
throw new ServiceException('Failed to find a suitable S/MIME certificate for decryption');
}

Copy link
Member

@st3iny st3iny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S/MIME is handled correctly now.

…e its contents

Signed-off-by: Anna Larch <anna@nextcloud.com>
@miaulalala miaulalala force-pushed the feat/add-events-and-ocs-api-for-incoming-messages branch from 81c8b87 to 71dbc51 Compare July 10, 2024 12:00
@miaulalala miaulalala merged commit 1ce7b4d into main Jul 10, 2024
29 checks passed
@miaulalala miaulalala deleted the feat/add-events-and-ocs-api-for-incoming-messages branch July 10, 2024 13:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OCS Api to GET a message from a mailbox Fire events for incoming messages
4 participants