]> git.mxchange.org Git - friendica.git/blobdiff - src/Protocol/ActivityPub/Receiver.php
Logging for an exception when processing activities
[friendica.git] / src / Protocol / ActivityPub / Receiver.php
index f246a9f94b13d3c316cf030ab7bd2c5d10981338..db4196abc4a5e85de0b3b00253e0b8f885c224b8 100644 (file)
@@ -73,6 +73,7 @@ class Receiver
        const TARGET_FOLLOWER = 5;
        const TARGET_ANSWER = 6;
        const TARGET_GLOBAL = 7;
+       const TARGET_AUDIENCE = 8;
 
        const COMPLETION_NONE     = 0;
        const COMPLETION_ANNOUNCE = 1;
@@ -248,7 +249,7 @@ class Receiver
         * Fetches the object type for a given object id
         *
         * @param array   $activity
-        * @param string  $object_id Object ID of the the provided object
+        * @param string  $object_id Object ID of the provided object
         * @param integer $uid       User ID
         *
         * @return string with object type or NULL
@@ -395,15 +396,22 @@ class Receiver
 
                // Fetch the activity on Lemmy "Announce" messages (announces of activities)
                if (($type == 'as:Announce') && in_array($object_type, array_merge(self::ACTIVITY_TYPES, ['as:Delete', 'as:Undo', 'as:Update']))) {
-                       Logger::debug('Fetch announced activity', ['object' => $object_id]);
+                       Logger::debug('Fetch announced activity', ['object' => $object_id, 'uid' => $fetch_uid]);
                        $data = Processor::fetchCachedActivity($object_id, $fetch_uid);
                        if (!empty($data)) {
                                $type = $object_type;
-                               $activity = JsonLD::compact($data);
+                               $announced_activity = JsonLD::compact($data);
 
                                // Some variables need to be refetched since the activity changed
-                               $actor = JsonLD::fetchElement($activity, 'as:actor', '@id');
-                               $object_id = JsonLD::fetchElement($activity, 'as:object', '@id');
+                               $actor = JsonLD::fetchElement($announced_activity, 'as:actor', '@id');
+                               $announced_id = JsonLD::fetchElement($announced_activity, 'as:object', '@id');
+                               if (empty($announced_id)) {
+                                       Logger::warning('No object id in announced activity', ['id' => $object_id, 'activity' => $activity, 'announced' => $announced_activity]);
+                                       return [];
+                               } else {
+                                       $activity  = $announced_activity;
+                                       $object_id = $announced_id;
+                               }
                                $object_type = self::fetchObjectType($activity, $object_id, $fetch_uid);
                        }
                }
@@ -487,7 +495,7 @@ class Receiver
                        $object_data['object_type'] = $object_type;
                }
 
-               foreach (['as:to', 'as:cc', 'as:bto', 'as:bcc'] as $element) {
+               foreach (['as:to', 'as:cc', 'as:bto', 'as:bcc', 'as:audience', 'as:attributedTo'] as $element) {
                        if ((empty($object_data['receiver_urls'][$element]) || in_array($element, ['as:bto', 'as:bcc'])) && !empty($urls[$element])) {
                                $object_data['receiver_urls'][$element] = array_unique(array_merge($object_data['receiver_urls'][$element] ?? [], $urls[$element]));
                        }
@@ -630,7 +638,7 @@ class Receiver
                        $object_data['object_activity'] = $activity;
                }
 
-               if (($type == 'as:Create') && $trust_source) {
+               if (($type == 'as:Create') && $trust_source && !in_array($completion, [self::COMPLETION_MANUAL, self::COMPLETION_ANNOUNCE])) {
                        if (self::hasArrived($object_data['object_id'])) {
                                Logger::info('The activity already arrived.', ['id' => $object_data['object_id']]);
                                return true;
@@ -641,6 +649,8 @@ class Receiver
                                Logger::info('The activity is already added.', ['id' => $object_data['object_id']]);
                                return true;
                        }
+               } elseif (($type == 'as:Create') && $trust_source && !self::hasArrived($object_data['object_id'])) {
+                       self::addArrivedId($object_data['object_id']);
                }
 
                $decouple = DI::config()->get('system', 'decoupled_receiver') && !in_array($completion, [self::COMPLETION_MANUAL, self::COMPLETION_ANNOUNCE]);
@@ -1030,7 +1040,7 @@ class Receiver
        {
                $urls = [];
 
-               foreach (['as:to', 'as:cc', 'as:bto', 'as:bcc'] as $element) {
+               foreach (['as:to', 'as:cc', 'as:bto', 'as:bcc', 'as:audience', 'as:attributedTo'] as $element) {
                        $receiver_list = JsonLD::fetchElementArray($activity, $element, '@id');
                        if (empty($receiver_list)) {
                                continue;
@@ -1067,7 +1077,7 @@ class Receiver
        {
                $reply = $receivers = $profile = [];
 
-               // When it is an answer, we inherite the receivers from the parent
+               // When it is an answer, we inherit the receivers from the parent
                $replyto = JsonLD::fetchElement($activity, 'as:inReplyTo', '@id');
                if (!empty($replyto)) {
                        $reply = [$replyto];
@@ -1102,7 +1112,7 @@ class Receiver
                // We have to prevent false follower assumptions upon thread completions
                $follower_target = empty($activity['thread-completion']) ? self::TARGET_FOLLOWER : self::TARGET_UNKNOWN;
 
-               foreach (['as:to', 'as:cc', 'as:bto', 'as:bcc'] as $element) {
+               foreach (['as:to', 'as:cc', 'as:bto', 'as:bcc','as:audience'] as $element) {
                        $receiver_list = JsonLD::fetchElementArray($activity, $element, '@id');
                        if (empty($receiver_list)) {
                                continue;
@@ -1163,6 +1173,9 @@ class Receiver
                                                case 'as:bcc':
                                                        $type = self::TARGET_BCC;
                                                        break;
+                                               case 'as:audience':
+                                                       $type = self::TARGET_AUDIENCE;
+                                                       break;
                                        }
 
                                        $receivers[$contact['uid']] = ['uid' => $contact['uid'], 'type' => $type];
@@ -1181,7 +1194,7 @@ class Receiver
                self::switchContacts($receivers, $actor);
 
                // "birdsitelive" is a service that mirrors tweets into the fediverse
-               // These posts can be fetched without authentification, but are not marked as public
+               // These posts can be fetched without authentication, but are not marked as public
                // We treat them as unlisted posts to be able to handle them.
                if (empty($receivers) && $fetch_unlisted && Contact::isPlatform($actor, 'birdsitelive')) {
                        $receivers[0]  = ['uid' => 0, 'type' => self::TARGET_GLOBAL];
@@ -1370,9 +1383,9 @@ class Receiver
        }
 
        /**
-        * Fetches the object data from external ressources if needed
+        * Fetches the object data from external resources if needed
         *
-        * @param string  $object_id    Object ID of the the provided object
+        * @param string  $object_id    Object ID of the provided object
         * @param array   $object       The provided object array
         * @param boolean $trust_source Do we trust the provided object?
         * @param integer $uid          User ID for the signature that we use to fetch data
@@ -1636,7 +1649,7 @@ class Receiver
                                                'type' => str_replace('as:', '', JsonLD::fetchElement($attachment, '@type')),
                                                'mediaType' => JsonLD::fetchElement($attachment, 'as:mediaType', '@value'),
                                                'name' => JsonLD::fetchElement($attachment, 'as:name', '@value'),
-                                               'url' => JsonLD::fetchElement($attachment, 'as:url', '@id'),
+                                               'url' => JsonLD::fetchElement($attachment, 'as:url', '@id') ?? JsonLD::fetchElement($attachment, 'as:href', '@id'),
                                                'height' => JsonLD::fetchElement($attachment, 'as:height', '@value'),
                                                'width' => JsonLD::fetchElement($attachment, 'as:width', '@value'),
                                                'image' => JsonLD::fetchElement($attachment, 'as:image', '@id')