From: Michael Date: Sat, 17 Jul 2021 20:28:46 +0000 (+0000) Subject: Move ActivityPub endpoints to an AP class X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=f62f82df75ef96b8c8c09e5a9d3c090b00d352ac;hp=6331e1e71c467e15161aab311089d66d324dbb04;p=friendica.git Move ActivityPub endpoints to an AP class --- diff --git a/src/Module/ActivityPub/Followers.php b/src/Module/ActivityPub/Followers.php new file mode 100644 index 0000000000..e1f1ccc4c1 --- /dev/null +++ b/src/Module/ActivityPub/Followers.php @@ -0,0 +1,54 @@ +. + * + */ + +namespace Friendica\Module\ActivityPub; + +use Friendica\BaseModule; +use Friendica\Model\Contact; +use Friendica\Model\User; +use Friendica\Protocol\ActivityPub; + +/** + * ActivityPub Followers + */ +class Followers extends BaseModule +{ + public static function rawContent(array $parameters = []) + { + if (empty($parameters['nickname'])) { + throw new \Friendica\Network\HTTPException\NotFoundException(); + } + + // @TODO: Replace with parameter from router + $owner = User::getOwnerDataByNick($parameters['nickname']); + if (empty($owner)) { + throw new \Friendica\Network\HTTPException\NotFoundException(); + } + + $page = $_REQUEST['page'] ?? null; + + $followers = ActivityPub\Transmitter::getContacts($owner, [Contact::FOLLOWER, Contact::FRIEND], 'followers', $page); + + header('Content-Type: application/activity+json'); + echo json_encode($followers); + exit(); + } +} diff --git a/src/Module/ActivityPub/Following.php b/src/Module/ActivityPub/Following.php new file mode 100644 index 0000000000..e9cb10be1f --- /dev/null +++ b/src/Module/ActivityPub/Following.php @@ -0,0 +1,53 @@ +. + * + */ + +namespace Friendica\Module\ActivityPub; + +use Friendica\BaseModule; +use Friendica\Model\Contact; +use Friendica\Model\User; +use Friendica\Protocol\ActivityPub; + +/** + * ActivityPub Following + */ +class Following extends BaseModule +{ + public static function rawContent(array $parameters = []) + { + if (empty($parameters['nickname'])) { + throw new \Friendica\Network\HTTPException\NotFoundException(); + } + + $owner = User::getOwnerDataByNick($parameters['nickname']); + if (empty($owner)) { + throw new \Friendica\Network\HTTPException\NotFoundException(); + } + + $page = $_REQUEST['page'] ?? null; + + $following = ActivityPub\Transmitter::getContacts($owner, [Contact::SHARING, Contact::FRIEND], 'following', $page); + + header('Content-Type: application/activity+json'); + echo json_encode($following); + exit(); + } +} diff --git a/src/Module/ActivityPub/Inbox.php b/src/Module/ActivityPub/Inbox.php new file mode 100644 index 0000000000..36940cb2de --- /dev/null +++ b/src/Module/ActivityPub/Inbox.php @@ -0,0 +1,70 @@ +. + * + */ + +namespace Friendica\Module\ActivityPub; + +use Friendica\BaseModule; +use Friendica\Core\Logger; +use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Protocol\ActivityPub; +use Friendica\Util\HTTPSignature; +use Friendica\Util\Network; + +/** + * ActivityPub Inbox + */ +class Inbox extends BaseModule +{ + public static function rawContent(array $parameters = []) + { + $postdata = Network::postdata(); + + if (empty($postdata)) { + throw new \Friendica\Network\HTTPException\BadRequestException(); + } + + if (DI::config()->get('debug', 'ap_inbox_log')) { + if (HTTPSignature::getSigner($postdata, $_SERVER)) { + $filename = 'signed-activitypub'; + } else { + $filename = 'failed-activitypub'; + } + $tempfile = tempnam(get_temppath(), $filename); + file_put_contents($tempfile, json_encode(['parameters' => $parameters, 'header' => $_SERVER, 'body' => $postdata], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); + Logger::notice('Incoming message stored', ['file' => $tempfile]); + } + + if (!empty($parameters['nickname'])) { + $user = DBA::selectFirst('user', ['uid'], ['nickname' => $parameters['nickname']]); + if (!DBA::isResult($user)) { + throw new \Friendica\Network\HTTPException\NotFoundException(); + } + $uid = $user['uid']; + } else { + $uid = 0; + } + + ActivityPub\Receiver::processInbox($postdata, $_SERVER, $uid); + + throw new \Friendica\Network\HTTPException\AcceptedException(); + } +} diff --git a/src/Module/ActivityPub/Objects.php b/src/Module/ActivityPub/Objects.php new file mode 100644 index 0000000000..f597b09059 --- /dev/null +++ b/src/Module/ActivityPub/Objects.php @@ -0,0 +1,147 @@ +. + * + */ + +namespace Friendica\Module\ActivityPub; + +use Friendica\BaseModule; +use Friendica\Core\Logger; +use Friendica\Core\System; +use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Model\Contact; +use Friendica\Model\Item; +use Friendica\Model\Post; +use Friendica\Network\HTTPException; +use Friendica\Protocol\ActivityPub; +use Friendica\Util\HTTPSignature; +use Friendica\Util\Network; +use Friendica\Util\Strings; + +/** + * ActivityPub Objects + */ +class Objects extends BaseModule +{ + public static function rawContent(array $parameters = []) + { + if (empty($parameters['guid'])) { + throw new HTTPException\BadRequestException(); + } + + if (!ActivityPub::isRequest()) { + DI::baseUrl()->redirect(str_replace('objects/', 'display/', DI::args()->getQueryString())); + } + + $itemuri = DBA::selectFirst('item-uri', ['id'], ['guid' => $parameters['guid']]); + + if (DBA::isResult($itemuri)) { + Logger::info('Provided GUID found.', ['guid' => $parameters['guid'], 'uri-id' => $itemuri['id']]); + } else { + // The item URI does not always contain the GUID. This means that we have to search the URL instead + $url = DI::baseUrl()->get() . '/' . DI::args()->getQueryString(); + $nurl = Strings::normaliseLink($url); + $ssl_url = str_replace('http://', 'https://', $nurl); + + $itemuri = DBA::selectFirst('item-uri', ['guid', 'id'], ['uri' => [$url, $nurl, $ssl_url]]); + if (DBA::isResult($itemuri)) { + Logger::info('URL found.', ['url' => $url, 'guid' => $itemuri['guid'], 'uri-id' => $itemuri['id']]); + } else { + Logger::info('URL not found.', ['url' => $url]); + throw new HTTPException\NotFoundException(); + } + } + + $item = Post::selectFirst(['id', 'uid', 'origin', 'author-link', 'changed', 'private', 'psid', 'gravity', 'deleted', 'parent-uri-id'], + ['uri-id' => $itemuri['id']], ['order' => ['origin' => true]]); + + if (!DBA::isResult($item)) { + throw new HTTPException\NotFoundException(); + } + + $validated = in_array($item['private'], [Item::PUBLIC, Item::UNLISTED]); + + if (!$validated) { + $requester = HTTPSignature::getSigner('', $_SERVER); + if (!empty($requester) && $item['origin']) { + $requester_id = Contact::getIdForURL($requester, $item['uid']); + if (!empty($requester_id)) { + $permissionSets = DI::permissionSet()->selectByContactId($requester_id, $item['uid']); + if (!empty($permissionSets)) { + $psid = array_merge($permissionSets->column('id'), + [DI::permissionSet()->getIdFromACL($item['uid'], '', '', '', '')]); + $validated = in_array($item['psid'], $psid); + } + } + } + } + + if ($validated) { + // Valid items are original post or posted from this node (including in the case of a forum) + $validated = ($item['origin'] || (parse_url($item['author-link'], PHP_URL_HOST) == parse_url(DI::baseUrl()->get(), PHP_URL_HOST))); + + if (!$validated && $item['deleted']) { + $validated = Post::exists(['origin' => true, 'uri-id' => $item['parent-uri-id']]); + } + } + + if (!$validated) { + throw new HTTPException\NotFoundException(); + } + + $etag = md5($parameters['guid'] . '-' . $item['changed']); + $last_modified = $item['changed']; + Network::checkEtagModified($etag, $last_modified); + + if (empty($parameters['activity']) && ($item['gravity'] != GRAVITY_ACTIVITY)) { + $activity = ActivityPub\Transmitter::createActivityFromItem($item['id'], true); + if (empty($activity['type'])) { + throw new HTTPException\NotFoundException(); + } + + $activity['type'] = $activity['type'] == 'Update' ? 'Create' : $activity['type']; + + // Only display "Create" activity objects here, no reshares or anything else + if (empty($activity['object']) || ($activity['type'] != 'Create')) { + throw new HTTPException\NotFoundException(); + } + + $data = ['@context' => ActivityPub::CONTEXT]; + $data = array_merge($data, $activity['object']); + } elseif (empty($parameters['activity']) || in_array($parameters['activity'], + ['Create', 'Announce', 'Update', 'Like', 'Dislike', 'Accept', 'Reject', + 'TentativeAccept', 'Follow', 'Add'])) { + $data = ActivityPub\Transmitter::createActivityFromItem($item['id']); + if (empty($data)) { + throw new HTTPException\NotFoundException(); + } + if (!empty($parameters['activity']) && ($parameters['activity'] != 'Create')) { + $data['type'] = $parameters['activity']; + $data['id'] = str_replace('/Create', '/' . $parameters['activity'], $data['id']); + } + } else { + throw new HTTPException\NotFoundException(); + } + + // Relaxed CORS header for public items + header('Access-Control-Allow-Origin: *'); + System::jsonExit($data, 'application/activity+json'); + } +} diff --git a/src/Module/ActivityPub/Outbox.php b/src/Module/ActivityPub/Outbox.php new file mode 100644 index 0000000000..fe838960d5 --- /dev/null +++ b/src/Module/ActivityPub/Outbox.php @@ -0,0 +1,53 @@ +. + * + */ + +namespace Friendica\Module\ActivityPub; + +use Friendica\BaseModule; +use Friendica\Model\User; +use Friendica\Protocol\ActivityPub; +use Friendica\Util\HTTPSignature; + +/** + * ActivityPub Outbox + */ +class Outbox extends BaseModule +{ + public static function rawContent(array $parameters = []) + { + if (empty($parameters['nickname'])) { + throw new \Friendica\Network\HTTPException\NotFoundException(); + } + + $owner = User::getOwnerDataByNick($parameters['nickname']); + if (empty($owner)) { + throw new \Friendica\Network\HTTPException\NotFoundException(); + } + + $page = $_REQUEST['page'] ?? null; + + $requester = HTTPSignature::getSigner('', $_SERVER); + $outbox = ActivityPub\Transmitter::getOutbox($owner, $page, $requester); + header('Content-Type: application/activity+json'); + echo json_encode($outbox); + exit(); + } +} diff --git a/src/Module/Followers.php b/src/Module/Followers.php deleted file mode 100644 index 932ebb47c2..0000000000 --- a/src/Module/Followers.php +++ /dev/null @@ -1,58 +0,0 @@ -. - * - */ - -namespace Friendica\Module; - -use Friendica\BaseModule; -use Friendica\DI; -use Friendica\Model\Contact; -use Friendica\Model\User; -use Friendica\Protocol\ActivityPub; - -/** - * ActivityPub Followers - */ -class Followers extends BaseModule -{ - public static function rawContent(array $parameters = []) - { - $a = DI::app(); - - // @TODO: Replace with parameter from router - if (empty($a->argv[1])) { - throw new \Friendica\Network\HTTPException\NotFoundException(); - } - - // @TODO: Replace with parameter from router - $owner = User::getOwnerDataByNick($a->argv[1]); - if (empty($owner)) { - throw new \Friendica\Network\HTTPException\NotFoundException(); - } - - $page = $_REQUEST['page'] ?? null; - - $followers = ActivityPub\Transmitter::getContacts($owner, [Contact::FOLLOWER, Contact::FRIEND], 'followers', $page); - - header('Content-Type: application/activity+json'); - echo json_encode($followers); - exit(); - } -} diff --git a/src/Module/Following.php b/src/Module/Following.php deleted file mode 100644 index 3070c5bfe6..0000000000 --- a/src/Module/Following.php +++ /dev/null @@ -1,58 +0,0 @@ -. - * - */ - -namespace Friendica\Module; - -use Friendica\BaseModule; -use Friendica\DI; -use Friendica\Model\Contact; -use Friendica\Model\User; -use Friendica\Protocol\ActivityPub; - -/** - * ActivityPub Following - */ -class Following extends BaseModule -{ - public static function rawContent(array $parameters = []) - { - $a = DI::app(); - - // @TODO: Replace with parameter from router - if (empty($a->argv[1])) { - throw new \Friendica\Network\HTTPException\NotFoundException(); - } - - // @TODO: Replace with parameter from router - $owner = User::getOwnerDataByNick($a->argv[1]); - if (empty($owner)) { - throw new \Friendica\Network\HTTPException\NotFoundException(); - } - - $page = $_REQUEST['page'] ?? null; - - $following = ActivityPub\Transmitter::getContacts($owner, [Contact::SHARING, Contact::FRIEND], 'following', $page); - - header('Content-Type: application/activity+json'); - echo json_encode($following); - exit(); - } -} diff --git a/src/Module/Inbox.php b/src/Module/Inbox.php deleted file mode 100644 index 048edb5d04..0000000000 --- a/src/Module/Inbox.php +++ /dev/null @@ -1,73 +0,0 @@ -. - * - */ - -namespace Friendica\Module; - -use Friendica\BaseModule; -use Friendica\Core\Logger; -use Friendica\Database\DBA; -use Friendica\DI; -use Friendica\Protocol\ActivityPub; -use Friendica\Util\HTTPSignature; -use Friendica\Util\Network; - -/** - * ActivityPub Inbox - */ -class Inbox extends BaseModule -{ - public static function rawContent(array $parameters = []) - { - $a = DI::app(); - - $postdata = Network::postdata(); - - if (empty($postdata)) { - throw new \Friendica\Network\HTTPException\BadRequestException(); - } - - if (DI::config()->get('debug', 'ap_inbox_log')) { - if (HTTPSignature::getSigner($postdata, $_SERVER)) { - $filename = 'signed-activitypub'; - } else { - $filename = 'failed-activitypub'; - } - $tempfile = tempnam(get_temppath(), $filename); - file_put_contents($tempfile, json_encode(['argv' => $a->argv, 'header' => $_SERVER, 'body' => $postdata], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); - Logger::log('Incoming message stored under ' . $tempfile); - } - - // @TODO: Replace with parameter from router - if (!empty($a->argv[1])) { - $user = DBA::selectFirst('user', ['uid'], ['nickname' => $a->argv[1]]); - if (!DBA::isResult($user)) { - throw new \Friendica\Network\HTTPException\NotFoundException(); - } - $uid = $user['uid']; - } else { - $uid = 0; - } - - ActivityPub\Receiver::processInbox($postdata, $_SERVER, $uid); - - throw new \Friendica\Network\HTTPException\AcceptedException(); - } -} diff --git a/src/Module/Objects.php b/src/Module/Objects.php deleted file mode 100644 index 8f1bbf2a5f..0000000000 --- a/src/Module/Objects.php +++ /dev/null @@ -1,147 +0,0 @@ -. - * - */ - -namespace Friendica\Module; - -use Friendica\BaseModule; -use Friendica\Core\Logger; -use Friendica\Core\System; -use Friendica\Database\DBA; -use Friendica\DI; -use Friendica\Model\Contact; -use Friendica\Model\Item; -use Friendica\Model\Post; -use Friendica\Network\HTTPException; -use Friendica\Protocol\ActivityPub; -use Friendica\Util\HTTPSignature; -use Friendica\Util\Network; -use Friendica\Util\Strings; - -/** - * ActivityPub Objects - */ -class Objects extends BaseModule -{ - public static function rawContent(array $parameters = []) - { - if (empty($parameters['guid'])) { - throw new HTTPException\BadRequestException(); - } - - if (!ActivityPub::isRequest()) { - DI::baseUrl()->redirect(str_replace('objects/', 'display/', DI::args()->getQueryString())); - } - - $itemuri = DBA::selectFirst('item-uri', ['id'], ['guid' => $parameters['guid']]); - - if (DBA::isResult($itemuri)) { - Logger::info('Provided GUID found.', ['guid' => $parameters['guid'], 'uri-id' => $itemuri['id']]); - } else { - // The item URI does not always contain the GUID. This means that we have to search the URL instead - $url = DI::baseUrl()->get() . '/' . DI::args()->getQueryString(); - $nurl = Strings::normaliseLink($url); - $ssl_url = str_replace('http://', 'https://', $nurl); - - $itemuri = DBA::selectFirst('item-uri', ['guid', 'id'], ['uri' => [$url, $nurl, $ssl_url]]); - if (DBA::isResult($itemuri)) { - Logger::info('URL found.', ['url' => $url, 'guid' => $itemuri['guid'], 'uri-id' => $itemuri['id']]); - } else { - Logger::info('URL not found.', ['url' => $url]); - throw new HTTPException\NotFoundException(); - } - } - - $item = Post::selectFirst(['id', 'uid', 'origin', 'author-link', 'changed', 'private', 'psid', 'gravity', 'deleted', 'parent-uri-id'], - ['uri-id' => $itemuri['id']], ['order' => ['origin' => true]]); - - if (!DBA::isResult($item)) { - throw new HTTPException\NotFoundException(); - } - - $validated = in_array($item['private'], [Item::PUBLIC, Item::UNLISTED]); - - if (!$validated) { - $requester = HTTPSignature::getSigner('', $_SERVER); - if (!empty($requester) && $item['origin']) { - $requester_id = Contact::getIdForURL($requester, $item['uid']); - if (!empty($requester_id)) { - $permissionSets = DI::permissionSet()->selectByContactId($requester_id, $item['uid']); - if (!empty($permissionSets)) { - $psid = array_merge($permissionSets->column('id'), - [DI::permissionSet()->getIdFromACL($item['uid'], '', '', '', '')]); - $validated = in_array($item['psid'], $psid); - } - } - } - } - - if ($validated) { - // Valid items are original post or posted from this node (including in the case of a forum) - $validated = ($item['origin'] || (parse_url($item['author-link'], PHP_URL_HOST) == parse_url(DI::baseUrl()->get(), PHP_URL_HOST))); - - if (!$validated && $item['deleted']) { - $validated = Post::exists(['origin' => true, 'uri-id' => $item['parent-uri-id']]); - } - } - - if (!$validated) { - throw new HTTPException\NotFoundException(); - } - - $etag = md5($parameters['guid'] . '-' . $item['changed']); - $last_modified = $item['changed']; - Network::checkEtagModified($etag, $last_modified); - - if (empty($parameters['activity']) && ($item['gravity'] != GRAVITY_ACTIVITY)) { - $activity = ActivityPub\Transmitter::createActivityFromItem($item['id'], true); - if (empty($activity['type'])) { - throw new HTTPException\NotFoundException(); - } - - $activity['type'] = $activity['type'] == 'Update' ? 'Create' : $activity['type']; - - // Only display "Create" activity objects here, no reshares or anything else - if (empty($activity['object']) || ($activity['type'] != 'Create')) { - throw new HTTPException\NotFoundException(); - } - - $data = ['@context' => ActivityPub::CONTEXT]; - $data = array_merge($data, $activity['object']); - } elseif (empty($parameters['activity']) || in_array($parameters['activity'], - ['Create', 'Announce', 'Update', 'Like', 'Dislike', 'Accept', 'Reject', - 'TentativeAccept', 'Follow', 'Add'])) { - $data = ActivityPub\Transmitter::createActivityFromItem($item['id']); - if (empty($data)) { - throw new HTTPException\NotFoundException(); - } - if (!empty($parameters['activity']) && ($parameters['activity'] != 'Create')) { - $data['type'] = $parameters['activity']; - $data['id'] = str_replace('/Create', '/' . $parameters['activity'], $data['id']); - } - } else { - throw new HTTPException\NotFoundException(); - } - - // Relaxed CORS header for public items - header('Access-Control-Allow-Origin: *'); - System::jsonExit($data, 'application/activity+json'); - } -} diff --git a/src/Module/Outbox.php b/src/Module/Outbox.php deleted file mode 100644 index 6e095b7306..0000000000 --- a/src/Module/Outbox.php +++ /dev/null @@ -1,57 +0,0 @@ -. - * - */ - -namespace Friendica\Module; - -use Friendica\BaseModule; -use Friendica\DI; -use Friendica\Model\User; -use Friendica\Protocol\ActivityPub; -use Friendica\Util\HTTPSignature; - -/** - * ActivityPub Outbox - */ -class Outbox extends BaseModule -{ - public static function rawContent(array $parameters = []) - { - $a = DI::app(); - - // @TODO: Replace with parameter from router - if (empty($a->argv[1])) { - throw new \Friendica\Network\HTTPException\NotFoundException(); - } - - $owner = User::getOwnerDataByNick($a->argv[1]); - if (empty($owner)) { - throw new \Friendica\Network\HTTPException\NotFoundException(); - } - - $page = $_REQUEST['page'] ?? null; - - $requester = HTTPSignature::getSigner('', $_SERVER); - $outbox = ActivityPub\Transmitter::getOutbox($owner, $page, $requester); - header('Content-Type: application/activity+json'); - echo json_encode($outbox); - exit(); - } -} diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index a65f855422..a65ebc8cda 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -235,26 +235,28 @@ class Transmitter */ public static function getOutbox($owner, $page = null, $requester = '') { - $public_contact = Contact::getIdForURL($owner['url']); - $condition = ['uid' => 0, 'contact-id' => $public_contact, - 'private' => [Item::PUBLIC, Item::UNLISTED]]; + $condition = ['private' => [Item::PUBLIC, Item::UNLISTED]]; if (!empty($requester)) { $requester_id = Contact::getIdForURL($requester, $owner['uid']); if (!empty($requester_id)) { $permissionSets = DI::permissionSet()->selectByContactId($requester_id, $owner['uid']); if (!empty($permissionSets)) { - $condition = ['uid' => $owner['uid'], 'origin' => true, - 'psid' => array_merge($permissionSets->column('id'), + $condition = ['psid' => array_merge($permissionSets->column('id'), [DI::permissionSet()->getIdFromACL($owner['uid'], '', '', '', '')])]; } } } $condition = array_merge($condition, - ['author-id' => $public_contact, - 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT], - 'deleted' => false, 'visible' => true]); + ['uid' => $owner['uid'], + 'author-id' => Contact::getIdForURL($owner['url'], 0, false), + 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT], + 'network' => Protocol::FEDERATED, + 'parent-network' => Protocol::FEDERATED, + 'origin' => true, + 'deleted' => false, + 'visible' => true]); $count = Post::count($condition); @@ -269,8 +271,6 @@ class Transmitter $data['type'] = 'OrderedCollectionPage'; $list = []; - $condition['parent-network'] = Protocol::NATIVE_SUPPORT; - $items = Post::select(['id'], $condition, ['limit' => [($page - 1) * 20, 20], 'order' => ['created' => true]]); while ($item = Post::fetch($items)) { $activity = self::createActivityFromItem($item['id'], true); diff --git a/static/routes.config.php b/static/routes.config.php index dfa7dad187..64a4346656 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -266,14 +266,14 @@ return [ '/status_message/{guid}' => [Module\Diaspora\Fetch::class, [R::GET]], '/reshare/{guid}' => [Module\Diaspora\Fetch::class, [R::GET]], ], - '/filed' => [Module\Search\Filed::class, [R::GET]], - '/filer[/{id:\d+}]' => [Module\Filer\SaveTag::class, [R::GET]], - '/filerm/{id:\d+}' => [Module\Filer\RemoveTag::class, [R::GET]], - '/follow_confirm' => [Module\FollowConfirm::class, [R::GET, R::POST]], - '/followers/{owner}' => [Module\Followers::class, [R::GET]], - '/following/{owner}' => [Module\Following::class, [R::GET]], - '/friendica[/json]' => [Module\Friendica::class, [R::GET]], - '/friendica/inbox' => [Module\Inbox::class, [R::GET, R::POST]], + '/filed' => [Module\Search\Filed::class, [R::GET]], + '/filer[/{id:\d+}]' => [Module\Filer\SaveTag::class, [R::GET]], + '/filerm/{id:\d+}' => [Module\Filer\RemoveTag::class, [R::GET]], + '/follow_confirm' => [Module\FollowConfirm::class, [R::GET, R::POST]], + '/followers/{nickname}' => [Module\ActivityPub\Followers::class, [R::GET]], + '/following/{nickname}' => [Module\ActivityPub\Following::class, [R::GET]], + '/friendica[/json]' => [Module\Friendica::class, [R::GET]], + '/friendica/inbox' => [Module\ActivityPub\Inbox::class, [R::GET, R::POST]], '/fsuggest/{contact:\d+}' => [Module\FriendSuggest::class, [R::GET, R::POST]], @@ -288,12 +288,12 @@ return [ '/{group:\d+}/add/{contact:\d+}' => [Module\Group::class, [R::GET, R::POST]], '/{group:\d+}/remove/{contact:\d+}' => [Module\Group::class, [R::GET, R::POST]], ], - '/hashtag' => [Module\Hashtag::class, [R::GET]], - '/help[/{doc:.+}]' => [Module\Help::class, [R::GET]], - '/home' => [Module\Home::class, [R::GET]], - '/hcard/{profile}[/{action}]' => [Module\HoverCard::class, [R::GET]], - '/inbox[/{nickname}]' => [Module\Inbox::class, [R::GET, R::POST]], - '/invite' => [Module\Invite::class, [R::GET, R::POST]], + '/hashtag' => [Module\Hashtag::class, [R::GET]], + '/help[/{doc:.+}]' => [Module\Help::class, [R::GET]], + '/home' => [Module\Home::class, [R::GET]], + '/hcard/{profile}[/{action}]' => [Module\HoverCard::class, [R::GET]], + '/inbox[/{nickname}]' => [Module\ActivityPub\Inbox::class, [R::GET, R::POST]], + '/invite' => [Module\Invite::class, [R::GET, R::POST]], '/install' => [ '[/]' => [Module\Install::class, [R::GET, R::POST]], @@ -355,10 +355,10 @@ return [ '/h2b' => [Module\Oembed::class, [R::GET]], '/{hash}' => [Module\Oembed::class, [R::GET]], ], - '/outbox/{owner}' => [Module\Outbox::class, [R::GET]], - '/owa' => [Module\Owa::class, [R::GET]], - '/openid' => [Module\Security\OpenID::class, [R::GET]], - '/opensearch' => [Module\OpenSearch::class, [R::GET]], + '/outbox/{nickname}' => [Module\ActivityPub\Outbox::class, [R::GET]], + '/owa' => [Module\Owa::class, [R::GET]], + '/openid' => [Module\Security\OpenID::class, [R::GET]], + '/opensearch' => [Module\OpenSearch::class, [R::GET]], '/parseurl' => [Module\ParseUrl::class, [R::GET]], '/permission/tooltip/{type}/{id:\d+}' => [Module\PermissionTooltip::class, [R::GET]],