diff --git a/Project/Sources/Classes/Office365Mail.4dm b/Project/Sources/Classes/Office365Mail.4dm index 75cb8316..fd7469fc 100644 --- a/Project/Sources/Classes/Office365Mail.4dm +++ b/Project/Sources/Classes/Office365Mail.4dm @@ -31,10 +31,11 @@ Class constructor($inProvider : cs.OAuth2Provider; $inParameters : Object) // ---------------------------------------------------- -Function _postJSONMessage($inURL : Text; $inMail : Object; $bSkipMessageEncapsulation : Boolean; $inHeaders : Object) : Object +Function _postJSONMessage($inFunction : Text; $inURL : Text; $inMail : Object; $bSkipMessageEncapsulation : Boolean; $inHeaders : Object) : Object /** * @function _postJSONMessage * @private + * @param {Text} $inFunction - Caller name for error reporting (e.g. `"office365.mail.send"`) * @param {Text} $inURL - Target Graph API endpoint URL * @param {Object} $inMail - Mail object in Microsoft Graph JSON format * @param {Boolean} $bSkipMessageEncapsulation - When `True`, sends `$inMail` as-is; @@ -54,6 +55,10 @@ Function _postJSONMessage($inURL : Text; $inMail : Object; $bSkipMessageEncapsul End if $headers["Content-Type"]:="application/json" + If (Not(This._validateGraphMessageProperties($inMail; $inFunction))) + return This._returnStatus() + End if + var $message : Object var $messageCopy : Object:=This._copyGraphMessage($inMail) If (Not(OB Is defined($inMail; "message")) && Not($bSkipMessageEncapsulation)) @@ -149,7 +154,7 @@ Function _postMessage($inFunction : Text; $inURL : Text; $inMail : Variant; $bSk $status:=This._postMailMIMEMessage($inURL; $inMail) : ((This.mailType="Microsoft") && (Value type($inMail)=Is object)) - $status:=This._postJSONMessage($inURL; $inMail; $bSkipMessageEncapsulation; $inHeader) + $status:=This._postJSONMessage($inFunction; $inURL; $inMail; $bSkipMessageEncapsulation; $inHeader) Else Super._throwError(10; {which: 1; function: $inFunction}) @@ -542,6 +547,10 @@ Function update($inMailId : Text; $inMail : Object) : Object If ((Type($inMail)=Is object) && (Type($inMailId)=Is text) && (Length(String($inMailId))>0)) + If (Not(This._validateGraphMessageProperties($inMail; "office365.mail.update"))) + return This._returnStatus() + End if + var $response : Object var $URL : Text:=Super._getURL() diff --git a/Project/Sources/Classes/_GraphAPI.4dm b/Project/Sources/Classes/_GraphAPI.4dm index 7e6cc751..fa92b13f 100644 --- a/Project/Sources/Classes/_GraphAPI.4dm +++ b/Project/Sources/Classes/_GraphAPI.4dm @@ -76,6 +76,94 @@ Function _copyGraphMessage($inMessage : Object) : Object // ---------------------------------------------------- +Function _validateGraphMessageProperties($inPayload : Object; $inFunction : Text) : Boolean +/** + * @function _validateGraphMessageProperties + * @private + * @param {Object} $inPayload - Graph message object or request envelope (`{message: ...}`) + * @param {Text} $inFunction - Caller function name for error reporting + * @returns {Boolean} `True` when all properties are supported; otherwise `False` + * @description Validates mail payload keys before sending to Microsoft Graph. + * Adds an error to the stack for each unsupported property (for example `attachment` + * instead of `attachments`). + */ + + var $isValid : Boolean:=True + + If (($inPayload#Null) && (Value type($inPayload)=Is object)) + + var $message : Object + var $allowedPayloadKeys : Object:={message: True; saveToSentItems: True; comment: True} + If (OB Is defined($inPayload; "message") && (Value type($inPayload.message)=Is object)) + $message:=$inPayload.message + + var $payloadKey : Text + For each ($payloadKey; OB Keys($inPayload)) + If (Not(OB Is defined($allowedPayloadKeys; $payloadKey))) + This._pushError(12; {function: $inFunction; message: "Unsupported property \""+$payloadKey+"\" in mail payload."}) + $isValid:=False + End if + End for each + Else + $message:=$inPayload + End if + + var $messageKey : Text + For each ($messageKey; OB Keys($message)) + var $isAllowed : Boolean:=False + Case of + : ($messageKey="attachments") + : ($messageKey="bccRecipients") + : ($messageKey="body") + : ($messageKey="bodyPreview") + : ($messageKey="categories") + : ($messageKey="ccRecipients") + : ($messageKey="changeKey") + : ($messageKey="conversationId") + : ($messageKey="conversationIndex") + : ($messageKey="createdDateTime") + : ($messageKey="extensions") + : ($messageKey="flag") + : ($messageKey="from") + : ($messageKey="hasAttachments") + : ($messageKey="id") + : ($messageKey="importance") + : ($messageKey="inferenceClassification") + : ($messageKey="internetMessageHeaders") + : ($messageKey="internetMessageId") + : ($messageKey="isDeliveryReceiptRequested") + : ($messageKey="isDraft") + : ($messageKey="isRead") + : ($messageKey="isReadReceiptRequested") + : ($messageKey="lastModifiedDateTime") + : ($messageKey="multiValueExtendedProperties") + : ($messageKey="parentFolderId") + : ($messageKey="receivedDateTime") + : ($messageKey="replyTo") + : ($messageKey="sender") + : ($messageKey="sentDateTime") + : ($messageKey="singleValueExtendedProperties") + : ($messageKey="subject") + : ($messageKey="toRecipients") + : ($messageKey="uniqueBody") + : ($messageKey="webLink") + $isAllowed:=True + End case + + If (Not($isAllowed)) + This._pushError(12; {function: $inFunction; message: "Unsupported property \""+$messageKey+"\" in mail object."}) + $isValid:=False + End if + End for each + + End if + + return $isValid + + + // ---------------------------------------------------- + + Function _loadFromObject($inObject : Object) /** * @function _loadFromObject