diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index c1443bc331..ed1ac43c76 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -469,6 +469,21 @@ class Transmitter return $permissions; } + /** + * Check if the given item id is from ActivityPub + * + * @param integer $item_id + * @return boolean "true" if the post is from ActivityPub + */ + private static function isAPPost(int $item_id) + { + if (empty($item_id)) { + return false; + } + + return Item::exists(['id' => $item_id, 'network' => Protocol::ACTIVITYPUB]); + } + /** * Creates an array of permissions from an item thread * @@ -501,7 +516,7 @@ class Transmitter $always_bcc = true; } - if (self::isAnnounce($item) || DI::config()->get('debug', 'total_ap_delivery')) { + if (self::isAnnounce($item) || DI::config()->get('debug', 'total_ap_delivery') || self::isAPPost($last_id)) { // Will be activated in a later step $networks = Protocol::FEDERATED; } else { @@ -680,12 +695,13 @@ class Transmitter * * @param integer $uid User ID * @param boolean $personal fetch personal inboxes + * @param boolean $all_ap Retrieve all AP enabled inboxes * * @return array of follower inboxes * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function fetchTargetInboxesforUser($uid, $personal = false) + public static function fetchTargetInboxesforUser($uid, $personal = false, bool $all_ap = false) { $inboxes = []; @@ -698,7 +714,7 @@ class Transmitter } } - if (DI::config()->get('debug', 'total_ap_delivery')) { + if (DI::config()->get('debug', 'total_ap_delivery') || $all_ap) { // Will be activated in a later step $networks = Protocol::FEDERATED; } else { @@ -793,7 +809,7 @@ class Transmitter } if ($item_profile && ($receiver == $item_profile['followers']) && ($uid == $profile_uid)) { - $inboxes = array_merge($inboxes, self::fetchTargetInboxesforUser($uid, $personal)); + $inboxes = array_merge($inboxes, self::fetchTargetInboxesforUser($uid, $personal, self::isAPPost($last_id))); } else { if (Contact::isLocal($receiver)) { continue; @@ -1033,33 +1049,31 @@ class Transmitter return false; } - if (empty($type)) { - $condition = ['item-uri' => $item['uri'], 'protocol' => Conversation::PARCEL_ACTIVITYPUB]; - $conversation = DBA::selectFirst('conversation', ['source'], $condition); - if (DBA::isResult($conversation)) { - $data = json_decode($conversation['source'], true); - if (!empty($data['type'])) { - if (in_array($data['type'], ['Create', 'Update'])) { - if ($object_mode) { - unset($data['@context']); - unset($data['signature']); - } - Logger::info('Return stored conversation', ['item' => $item_id]); - return $data; - } elseif (in_array('as:' . $data['type'], Receiver::CONTENT_TYPES)) { - if (!empty($data['@context'])) { - $context = $data['@context']; - unset($data['@context']); - } - unset($data['actor']); - $object = $data; + $condition = ['item-uri' => $item['uri'], 'protocol' => Conversation::PARCEL_ACTIVITYPUB]; + $conversation = DBA::selectFirst('conversation', ['source'], $condition); + if (!$item['origin'] && DBA::isResult($conversation)) { + $data = json_decode($conversation['source'], true); + if (!empty($data['type'])) { + if (in_array($data['type'], ['Create', 'Update'])) { + if ($object_mode) { + unset($data['@context']); + unset($data['signature']); } + Logger::info('Return stored conversation', ['item' => $item_id]); + return $data; + } elseif (in_array('as:' . $data['type'], Receiver::CONTENT_TYPES)) { + if (!empty($data['@context'])) { + $context = $data['@context']; + unset($data['@context']); + } + unset($data['actor']); + $object = $data; } } - - $type = self::getTypeOfItem($item); } + $type = self::getTypeOfItem($item); + if (!$object_mode) { $data = ['@context' => $context ?? ActivityPub::CONTEXT]; diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 7ab41eb52b..54a8d1c1ba 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -3031,7 +3031,18 @@ class Diaspora $owner['uprvkey'] = $owner['prvkey']; } - $envelope = self::buildMessage($msg, $owner, $contact, $owner['uprvkey'], $contact['pubkey'], $public_batch); + // When sending content to Friendica contacts using the Diaspora protocol + // we have to fetch the public key from the fcontact. + // This is due to the fact that legacy DFRN had unique keys for every contact. + $pubkey = $contact['pubkey']; + if (!empty($contact['addr'])) { + $fcontact = FContact::getByURL($contact['addr']); + if (!empty($fcontact)) { + $pubkey = $fcontact['pubkey']; + } + } + + $envelope = self::buildMessage($msg, $owner, $contact, $owner['uprvkey'], $pubkey, $public_batch); $return_code = self::transmit($owner, $contact, $envelope, $public_batch, $guid); diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php index 8a84f34a2f..1d1e8702b2 100644 --- a/src/Worker/Delivery.php +++ b/src/Worker/Delivery.php @@ -141,13 +141,7 @@ class Delivery } } - // When commenting too fast after delivery, a post wasn't recognized as top level post. - // The count then showed more than one entry. The additional check should help. - // The check for the "count" should be superfluous, but I'm not totally sure by now, so we keep it. - if ((($parent['id'] == $target_id) || (count($items) == 1)) && ($parent['uri'] === $parent['parent-uri'])) { - Logger::log('Top level post'); - $top_level = true; - } + $top_level = $target_item['gravity'] == GRAVITY_PARENT; // This is IMPORTANT!!!! @@ -211,7 +205,8 @@ class Delivery // Transmit via Diaspora if the thread had started as Diaspora post. // Also transmit via Diaspora if this is a direct answer to a Diaspora comment. // This is done since the uri wouldn't match (Diaspora doesn't transmit it) - if (!empty($parent) && !empty($thr_parent) && in_array(Protocol::DIASPORA, [$parent['network'], $thr_parent['network']])) { + // Also transmit relayed posts from Diaspora contacts via Diaspora. + if (!empty($parent) && !empty($thr_parent) && in_array(Protocol::DIASPORA, [$parent['network'], $thr_parent['network'], $target_item['network']])) { $contact['network'] = Protocol::DIASPORA; } diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php index 7359ad1d47..3be00359e5 100644 --- a/src/Worker/Notifier.php +++ b/src/Worker/Notifier.php @@ -133,10 +133,7 @@ class Notifier } } - if ((count($items) == 1) && ($items[0]['id'] === $target_item['id']) && ($items[0]['uri'] === $items[0]['parent-uri'])) { - Logger::info('Top level post', ['target' => $target_id]); - $top_level = true; - } + $top_level = $target_item['gravity'] == GRAVITY_PARENT; } $owner = User::getOwnerDataById($uid); @@ -774,11 +771,16 @@ class Notifier return 0; } - // Also don't deliver when the direct thread parent was delivered via Diaspora + // Also don't deliver when the direct thread parent was delivered via Diaspora if ($thr_parent['network'] == Protocol::DIASPORA) { return 0; } + // Posts from Diaspora contacts are transmitted via Diaspora + if ($target_item['network'] == Protocol::DIASPORA) { + return 0; + } + $inboxes = []; $relay_inboxes = [];