From 87b98b82495e254e7d1ecf84354648d95b8c9b11 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 14 May 2019 17:50:45 +0000 Subject: [PATCH] Sending direct messages via AP does work now - receiving is pending --- src/Protocol/ActivityPub.php | 4 +- src/Protocol/ActivityPub/Transmitter.php | 94 ++++++++++++++++++++++++ src/Util/JsonLD.php | 3 +- src/Worker/APDelivery.php | 4 + src/Worker/Notifier.php | 12 ++- 5 files changed, 113 insertions(+), 4 deletions(-) diff --git a/src/Protocol/ActivityPub.php b/src/Protocol/ActivityPub.php index 22073a502..fa63c44d5 100644 --- a/src/Protocol/ActivityPub.php +++ b/src/Protocol/ActivityPub.php @@ -44,8 +44,10 @@ class ActivityPub ['vcard' => 'http://www.w3.org/2006/vcard/ns#', 'dfrn' => 'http://purl.org/macgirvin/dfrn/1.0/', 'diaspora' => 'https://diasporafoundation.org/ns/', + 'litepub' => 'http://litepub.social/ns#', 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', - 'sensitive' => 'as:sensitive', 'Hashtag' => 'as:Hashtag']]; + 'sensitive' => 'as:sensitive', 'Hashtag' => 'as:Hashtag', + 'directMessage' => 'litepub:directMessage']]; const ACCOUNT_TYPES = ['Person', 'Organization', 'Service', 'Group', 'Application']; /** * Checks if the web request is done for the AP protocol diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index 0d024d26f..1b418a7a5 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -631,6 +631,100 @@ class Transmitter return $inboxes; } + /** + * Creates an array in the structure of the item table for a given mail id + * + * @param integer $mail_id + * + * @return array + * @throws \Exception + */ + public static function ItemArrayFromMail($mail_id) + { + $mail = DBA::selectFirst('mail', [], ['id' => $mail_id]); + + $reply = DBA::selectFirst('mail', ['uri'], ['parent-uri' => $mail['parent-uri'], 'reply' => false]); + + $mail['author-link'] = $mail['owner-link'] = $mail['from-url']; + $mail['allow_cid'] = '<'.$mail['contact-id'].'>'; + $mail['allow_gid'] = ''; + $mail['deny_cid'] = ''; + $mail['deny_gid'] = ''; + $mail['private'] = true; + $mail['deleted'] = false; + $mail['edited'] = $mail['created']; + $mail['plink'] = $mail['uri']; + $mail['thr-parent'] = $reply['uri']; + $mail['gravity'] = ($mail['reply'] ? GRAVITY_COMMENT: GRAVITY_PARENT); + + $mail['event-type'] = ''; + $mail['attach'] = ''; + + $mail['parent'] = 0; + + return $mail; + } + + /** + * Creates an activity array for a given mail id + * + * @param integer $mail_id + * @param boolean $object_mode Is the activity item is used inside another object? + * + * @return array of activity + * @throws \Exception + */ + public static function createActivityFromMail($mail_id, $object_mode = false) + { + $mail = self::ItemArrayFromMail($mail_id); + $object = self::createNote($mail); + + $object['to'] = $object['cc']; + unset($object['cc']); + + $object['tag'] = [['type' => 'Mention', 'href' => $object['to'][0], 'name' => 'test']]; + + if (!$object_mode) { + $data = ['@context' => ActivityPub::CONTEXT]; + } else { + $data = []; + } + + $data['id'] = $mail['uri'] . '#Create'; + $data['type'] = 'Create'; + $data['actor'] = $mail['author-link']; + $data['published'] = DateTimeFormat::utc($mail['created'] . '+00:00', DateTimeFormat::ATOM); + $data['instrument'] = self::getService(); + $data = array_merge($data, self::createPermissionBlockForItem($mail, true)); + + if (empty($data['to']) && !empty($data['cc'])) { + $data['to'] = $data['cc']; + } + + if (empty($data['to']) && !empty($data['bcc'])) { + $data['to'] = $data['bcc']; + } + + unset($data['cc']); + unset($data['bcc']); + + $object['to'] = $data['to']; + unset($object['cc']); + unset($object['bcc']); + + $data['directMessage'] = true; + + $data['object'] = $object; + + $owner = User::getOwnerDataById($mail['uid']); + + if (!$object_mode && !empty($owner)) { + return LDSignature::sign($data, $owner); + } else { + return $data; + } + } + /** * Returns the activity type of a given item * diff --git a/src/Util/JsonLD.php b/src/Util/JsonLD.php index 9566c424a..69973f4fe 100644 --- a/src/Util/JsonLD.php +++ b/src/Util/JsonLD.php @@ -96,7 +96,8 @@ class JsonLD 'diaspora' => (object)['@id' => 'https://diasporafoundation.org/ns/', '@type' => '@id'], 'ostatus' => (object)['@id' => 'http://ostatus.org#', '@type' => '@id'], 'dc' => (object)['@id' => 'http://purl.org/dc/terms/', '@type' => '@id'], - 'toot' => (object)['@id' => 'http://joinmastodon.org/ns#', '@type' => '@id']]; + 'toot' => (object)['@id' => 'http://joinmastodon.org/ns#', '@type' => '@id'], + 'litepub' => (object)['@id' => 'http://litepub.social/ns#', '@type' => '@id']]; // Preparation for adding possibly missing content to the context if (!empty($json['@context']) && is_string($json['@context'])) { diff --git a/src/Worker/APDelivery.php b/src/Worker/APDelivery.php index 2048b97d0..25c1dfb71 100644 --- a/src/Worker/APDelivery.php +++ b/src/Worker/APDelivery.php @@ -30,6 +30,10 @@ class APDelivery extends BaseObject $success = true; if ($cmd == Delivery::MAIL) { + $data = ActivityPub\Transmitter::createActivityFromMail($target_id); + if (!empty($data)) { + $success = HTTPSignature::transmit($data, $inbox, $uid); + } } elseif ($cmd == Delivery::SUGGESTION) { $success = ActivityPub\Transmitter::sendContactSuggestion($uid, $inbox, $target_id); } elseif ($cmd == Delivery::RELOCATION) { diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php index 1ce4ff244..77aa4d564 100644 --- a/src/Worker/Notifier.php +++ b/src/Worker/Notifier.php @@ -76,6 +76,14 @@ class Notifier } $uid = $message['uid']; $recipients[] = $message['contact-id']; + + $mail = ActivityPub\Transmitter::ItemArrayFromMail($target_id); + $inboxes = ActivityPub\Transmitter::fetchTargetInboxes($mail, §uid, true); + foreach ($inboxes as $inbox) { + Logger::info('Delivery via ActivityPub', ['cmd' => $cmd, 'id' => $target_id, 'inbox' => $inbox]); + Worker::add(['priority' => PRIORITY_HIGH, 'created' => $a->queue['created'], 'dont_fork' => true], + 'APDelivery', $cmd, $target_id, $inbox, $uid); + } } elseif ($cmd == Delivery::SUGGESTION) { $suggest = DBA::selectFirst('fsuggest', ['uid', 'cid'], ['id' => $target_id]); if (!DBA::isResult($suggest)) { @@ -593,7 +601,7 @@ class Notifier $inboxes = ActivityPub\Transmitter::fetchTargetInboxesforUser(0); foreach ($inboxes as $inbox) { - Logger::log('Account removal for user ' . $self_user_id . ' to ' . $inbox .' via ActivityPub', Logger::DEBUG); + Logger::info('Account removal via ActivityPub', ['uid' => $self_user_id, 'inbox' => $inbox]); Worker::add(['priority' => PRIORITY_NEGLIGIBLE, 'created' => $created, 'dont_fork' => true], 'APDelivery', Delivery::REMOVAL, '', $inbox, $self_user_id); } @@ -642,7 +650,7 @@ class Notifier ActivityPub\Transmitter::createCachedActivityFromItem($target_item['id'], true); foreach ($inboxes as $inbox) { - Logger::log('Deliver ' . $target_item['id'] .' to ' . $inbox .' via ActivityPub', Logger::DEBUG); + Logger::info('Delivery via ActivityPub', ['cmd' => $cmd, 'id' => $target_item['id'], 'inbox' => $inbox]); Worker::add(['priority' => $priority, 'created' => $created, 'dont_fork' => true], 'APDelivery', $cmd, $target_item['id'], $inbox, $uid);