diff --git a/src/Socialbox/Classes/StandardMethods/EncryptionChannel/EncryptionChannelReceive.php b/src/Socialbox/Classes/StandardMethods/EncryptionChannel/EncryptionChannelReceive.php index fa0db4e..3989e67 100644 --- a/src/Socialbox/Classes/StandardMethods/EncryptionChannel/EncryptionChannelReceive.php +++ b/src/Socialbox/Classes/StandardMethods/EncryptionChannel/EncryptionChannelReceive.php @@ -2,18 +2,20 @@ namespace Socialbox\Classes\StandardMethods\EncryptionChannel; + use Exception; use Socialbox\Abstracts\Method; - use Socialbox\Classes\Validator; + use Socialbox\Classes\Logger; use Socialbox\Enums\StandardError; use Socialbox\Enums\Status\EncryptionChannelStatus; use Socialbox\Exceptions\DatabaseOperationException; - use Socialbox\Exceptions\Standard\InvalidRpcArgumentException; + use Socialbox\Exceptions\RpcException; use Socialbox\Exceptions\Standard\MissingRpcArgumentException; use Socialbox\Exceptions\Standard\StandardRpcException; use Socialbox\Interfaces\SerializableInterface; use Socialbox\Managers\EncryptionChannelManager; use Socialbox\Objects\ClientRequest; use Socialbox\Objects\RpcRequest; + use Socialbox\Socialbox; class EncryptionChannelReceive extends Method { @@ -27,10 +29,6 @@ { throw new MissingRpcArgumentException('channel_uuid'); } - elseif(!Validator::validateUuid($rpcRequest->getParameter('channel_uuid'))) - { - throw new InvalidRpcArgumentException('channel_uuid', 'The given channel uuid is not a valid UUID V4'); - } try { @@ -82,10 +80,46 @@ $messages = EncryptionChannelManager::receiveData( $rpcRequest->getParameter('channel_uuid'), $encryptionChannel->determineRecipient($requestingPeer->getAddress(), true) ); + $messageUuids = array_map(fn($message) => $message->getUuid(), $messages); if($acknowledge) { - EncryptionChannelManager::acknowledgeMessagesBatch($rpcRequest->getParameter('channel_uuid'), array_map(fn($message) => $message->getUuid(), $messages)); + EncryptionChannelManager::acknowledgeMessagesBatch( + channelUuid: $rpcRequest->getParameter('channel_uuid'), + messageUuids: $messageUuids, + ); + + $externalPeer = $encryptionChannel->getExternalPeer(); + if($externalPeer !== null) + { + try + { + $rpcClient = Socialbox::getExternalSession($externalPeer->getDomain()); + $rpcClient->encryptionChannelAcknowledgeMessages( + channelUuid: (string)$rpcRequest->getParameter('channel_uuid'), + messageUuids: $messageUuids, + identifiedAs: $requestingPeer->getAddress() + ); + } + catch(Exception $e) + { + try + { + EncryptionChannelManager::rejectMessage($rpcRequest->getParameter('channel_uuid'), $rpcRequest->getParameter('message_uuid'), true); + } + catch (DatabaseOperationException $e) + { + Logger::getLogger()->error('Error rejecting message as server', $e); + } + + if($e instanceof RpcException) + { + throw StandardRpcException::fromRpcException($e); + } + + throw new StandardRpcException('Failed to acknowledge the message with the external server', StandardError::INTERNAL_SERVER_ERROR, $e); + } + } } } catch(DatabaseOperationException $e) diff --git a/src/Socialbox/Managers/EncryptionChannelManager.php b/src/Socialbox/Managers/EncryptionChannelManager.php index ebf10bc..f5249a8 100644 --- a/src/Socialbox/Managers/EncryptionChannelManager.php +++ b/src/Socialbox/Managers/EncryptionChannelManager.php @@ -604,23 +604,42 @@ * @return EncryptionChannelMessageRecord[] An array of message objects returned * @throws DatabaseOperationException Thrown if there was a database operation error */ - public static function receiveData(string $channelUuid, EncryptionMessageRecipient|string $recipient): array + public static function receiveData(string $channelUuid, EncryptionMessageRecipient|string $recipient, int $limit=100): array { if(!Validator::validateUuid($channelUuid)) { throw new InvalidArgumentException('The given Channel UUID is not a valid V4 UUID'); } + elseif(is_string($recipient)) + { + $recipient = EncryptionMessageRecipient::tryFrom($recipient); + if($recipient === null) + { + throw new InvalidArgumentException('The given recipient is not a valid EncryptionMessageRecipient'); + } + } + if($recipient instanceof EncryptionMessageRecipient) { $recipient = $recipient->value; } + else + { + throw new InvalidArgumentException('The given recipient is not a valid EncryptionMessageRecipient'); + } + + if($limit < 1) + { + throw new InvalidArgumentException('The limit cannot be less than 1'); + } try { - $stmt = Database::getConnection()->prepare("SELECT * FROM encryption_channels_com WHERE channel_uuid=:channel_uuid AND recipient=:recipient AND status='SENT' ORDER BY timestamp LIMIT 100"); + $stmt = Database::getConnection()->prepare("SELECT * FROM encryption_channels_com WHERE channel_uuid=:channel_uuid AND recipient=:recipient AND status='SENT' ORDER BY timestamp LIMIT :limit"); $stmt->bindParam(':channel_uuid', $channelUuid); $stmt->bindParam(':recipient', $recipient); + $stmt->bindParam(':limit', $limit); $stmt->execute(); $results = $stmt->fetchAll(); @@ -690,6 +709,14 @@ throw new InvalidArgumentException('The given Message UUIDs array is empty'); } + foreach($messageUuids as $messageUuid) + { + if(!Validator::validateUuid($messageUuid)) + { + throw new InvalidArgumentException('The given Message UUID is not a valid V4 uuid'); + } + } + $placeholders = implode(',', array_fill(0, count($messageUuids), '?')); $query = "UPDATE encryption_channels_com SET status='RECEIVED' WHERE channel_uuid=:channel_uuid AND uuid IN ($placeholders)";