diff --git a/src/Model/Item.php b/src/Model/Item.php index 47af3d5a69..badf9281bb 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -3744,6 +3744,36 @@ class Item return 0; } + /** + * Return the URI for a link to the post + * + * @param string $uri URI or link to post + * + * @return string URI + */ + public static function getURIByLink(string $uri) + { + $ssl_uri = str_replace('http://', 'https://', $uri); + $uris = [$uri, $ssl_uri, Strings::normaliseLink($uri)]; + + $item = DBA::selectFirst('item', ['uri'], ['uri' => $uris]); + if (DBA::isResult($item)) { + return $item['uri']; + } + + $itemcontent = DBA::selectFirst('item-content', ['uri-id'], ['plink' => $uris]); + if (!DBA::isResult($itemcontent)) { + return ''; + } + + $itemuri = DBA::selectFirst('item-uri', ['uri'], ['id' => $itemcontent['uri-id']]); + if (DBA::isResult($itemuri)) { + return $itemuri['uri']; + } + + return ''; + } + /** * Fetches item for given URI or plink * diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 9267943d5e..3bc7ff4a73 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -181,7 +181,7 @@ class Processor } if (empty($activity['directmessage']) && ($activity['id'] != $activity['reply-to-id']) && !Item::exists(['uri' => $activity['reply-to-id']])) { - Logger::log('Parent ' . $activity['reply-to-id'] . ' not found. Try to refetch it.'); + Logger::notice('Parent not found. Try to refetch it.', ['parent' => $activity['reply-to-id']]); self::fetchMissingActivity($activity['reply-to-id'], $activity); } diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index b15ce2bc13..0ef1791413 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -503,6 +503,10 @@ class Receiver // When it is an answer, we inherite the receivers from the parent $replyto = JsonLD::fetchElement($activity, 'as:inReplyTo', '@id'); if (!empty($replyto)) { + // Fix possibly wrong item URI (could be an answer to a plink uri) + $fixedReplyTo = Item::getURIByLink($replyto); + $replyto = $fixedReplyTo ?: $replyto; + $parents = Item::select(['uid'], ['uri' => $replyto]); while ($parent = Item::fetch($parents)) { $receivers['uid:' . $parent['uid']] = $parent['uid']; @@ -723,6 +727,15 @@ class Receiver $object_data['service'] = JsonLD::fetchElement($activity, 'as:instrument', 'as:name', '@type', 'as:Service'); $object_data['service'] = JsonLD::fetchElement($object_data, 'service', '@value'); + if (!empty($object_data['object_id'])) { + // Some systems (e.g. GNU Social) don't reply to the "id" field but the "uri" field. + $objectId = Item::getURIByLink($object_data['object_id']); + if (!empty($objectId) && ($object_data['object_id'] != $objectId)) { + Logger::notice('Fix wrong object-id', ['received' => $object_data['object_id'], 'correct' => $objectId]); + $object_data['object_id'] = $objectId; + } + } + return $object_data; } @@ -932,6 +945,13 @@ class Receiver // An empty "id" field is translated to "./" by the compactor, so we have to check for this content if (empty($object_data['reply-to-id']) || ($object_data['reply-to-id'] == './')) { $object_data['reply-to-id'] = $object_data['id']; + } else { + // Some systems (e.g. GNU Social) don't reply to the "id" field but the "uri" field. + $replyToId = Item::getURIByLink($object_data['reply-to-id']); + if (!empty($replyToId) && ($object_data['reply-to-id'] != $replyToId)) { + Logger::notice('Fix wrong reply-to', ['received' => $object_data['reply-to-id'], 'correct' => $replyToId]); + $object_data['reply-to-id'] = $replyToId; + } } $object_data['published'] = JsonLD::fetchElement($object, 'as:published', '@value');