]> git.mxchange.org Git - friendica.git/commitdiff
API: List handling, dummy endpoints
authorMichael <heluecht@pirati.ca>
Thu, 13 May 2021 21:15:32 +0000 (21:15 +0000)
committerMichael <heluecht@pirati.ca>
Thu, 13 May 2021 21:15:32 +0000 (21:15 +0000)
12 files changed:
src/Module/Api/Mastodon/Accounts/IdentityProofs.php [new file with mode: 0644]
src/Module/Api/Mastodon/Announcements.php [new file with mode: 0644]
src/Module/Api/Mastodon/Endorsements.php [new file with mode: 0644]
src/Module/Api/Mastodon/Lists.php
src/Module/Api/Mastodon/Markers.php [new file with mode: 0644]
src/Module/Api/Mastodon/Media.php
src/Module/Api/Mastodon/Proofs.php [new file with mode: 0644]
src/Module/Api/Mastodon/ScheduledStatuses.php [new file with mode: 0644]
src/Module/Api/Mastodon/Statuses.php
src/Module/BaseApi.php
src/Module/OAuth/Authorize.php
static/routes.config.php

diff --git a/src/Module/Api/Mastodon/Accounts/IdentityProofs.php b/src/Module/Api/Mastodon/Accounts/IdentityProofs.php
new file mode 100644 (file)
index 0000000..5a7d3a8
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Module\Api\Mastodon\Accounts;
+
+use Friendica\Core\System;
+use Friendica\Module\BaseApi;
+
+/**
+ * @see https://docs.joinmastodon.org/methods/accounts/
+ */
+class IdentityProofs extends BaseApi
+{
+       /**
+        * @param array $parameters
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        */
+       public static function rawContent(array $parameters = [])
+       {
+               self::login();
+
+               System::jsonExit([]);
+       }
+}
diff --git a/src/Module/Api/Mastodon/Announcements.php b/src/Module/Api/Mastodon/Announcements.php
new file mode 100644 (file)
index 0000000..80b25bf
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Module\Api\Mastodon;
+
+use Friendica\Core\System;
+use Friendica\Module\BaseApi;
+
+/**
+ * @see https://docs.joinmastodon.org/methods/announcements/
+ */
+class Announcements extends BaseApi
+{
+       /**
+        * @param array $parameters
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        */
+       public static function rawContent(array $parameters = [])
+       {
+               self::login();
+
+               // @todo Possibly use the message from the pageheader addon for this
+               System::jsonExit([]);
+       }
+}
diff --git a/src/Module/Api/Mastodon/Endorsements.php b/src/Module/Api/Mastodon/Endorsements.php
new file mode 100644 (file)
index 0000000..9c5e853
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Module\Api\Mastodon;
+
+use Friendica\Core\System;
+use Friendica\Module\BaseApi;
+
+/**
+ * @see https://docs.joinmastodon.org/methods/accounts/endorsements/
+ */
+class Endorsements extends BaseApi
+{
+       /**
+        * @param array $parameters
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        */
+       public static function rawContent(array $parameters = [])
+       {
+               System::jsonExit([]);
+       }
+}
index d9f9c6e5a8d7e4a96db2d65426c12b1ef96b85b8..e655edcb26d1c3dd3cfb79fbf465759211b7d357 100644 (file)
@@ -22,9 +22,9 @@
 namespace Friendica\Module\Api\Mastodon;
 
 use Friendica\Core\System;
-use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Module\BaseApi;
+use Friendica\Model\Group;
 
 /**
  * @see https://docs.joinmastodon.org/methods/timelines/lists/
@@ -33,17 +33,55 @@ class Lists extends BaseApi
 {
        public static function delete(array $parameters = [])
        {
-               self::unsupported('delete');
+               self::login();
+
+               $uid = self::getCurrentUserID();
+
+               if (empty($parameters['id'])) {
+                       DI::mstdnError()->UnprocessableEntity();
+               }
+
+               if (!Group::exists($parameters['id'], $uid)) {
+                       DI::mstdnError()->RecordNotFound();
+               }
+
+               if (!Group::remove($parameters['id'])) {
+                       DI::mstdnError()->InternalError();
+               }
+
+               System::jsonExit([]);
        }
 
        public static function post(array $parameters = [])
        {
-               self::unsupported('post');
+               self::login();
+
+               $uid   = self::getCurrentUserID();
+               $title = $_REQUEST['title'] ?? '';
+
+               if (empty($title)) {
+                       DI::mstdnError()->UnprocessableEntity();
+               }
+
+               Group::create($uid, $title);
+
+               $id = Group::getIdByName($uid, $title);
+               if (!$id) {
+                       DI::mstdnError()->InternalError();
+               }
+
+               System::jsonExit(DI::mstdnList()->createFromGroupId($id));
        }
 
        public static function put(array $parameters = [])
        {
-               self::unsupported('put');
+               $data = self::getPutData();
+
+               if (empty($data['title']) || empty($parameters['id'])) {
+                       DI::mstdnError()->UnprocessableEntity();
+               }
+
+               Group::update($parameters['id'], $data['title']);
        }
 
        /**
@@ -58,14 +96,15 @@ class Lists extends BaseApi
                if (empty($parameters['id'])) {
                        $lists = [];
 
-                       $groups = DBA::select('group', ['id'], ['uid' => $uid, 'deleted' => false]);
-                       while ($group = DBA::fetch($groups)) {
+                       $groups = Group::getByUserId($uid);
+
+                       foreach ($groups as $group) {
                                $lists[] = DI::mstdnList()->createFromGroupId($group['id']);
                        }
-                       DBA::close($groups);
                } else {
                        $id = $parameters['id'];
-                       if (!DBA::exists('group',['uid' => $uid, 'deleted' => false])) {
+
+                       if (!Group::exists($id, $uid)) {
                                DI::mstdnError()->RecordNotFound();
                        }
                        $lists = DI::mstdnList()->createFromGroupId($id);
diff --git a/src/Module/Api/Mastodon/Markers.php b/src/Module/Api/Mastodon/Markers.php
new file mode 100644 (file)
index 0000000..45ad392
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Module\Api\Mastodon;
+
+use Friendica\Core\System;
+use Friendica\Module\BaseApi;
+
+/**
+ * @see https://docs.joinmastodon.org/methods/timelines/markers/
+ */
+class Markers extends BaseApi
+{
+       public static function post(array $parameters = [])
+       {
+               self::unsupported('post');
+       }
+
+       /**
+        * @param array $parameters
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        */
+       public static function rawContent(array $parameters = [])
+       {
+               self::login();
+
+               System::jsonExit([]);
+       }
+}
index 297d7d7a3f89537a413bb05e4eca53590f4adafb..82844a6ff16fdb899027561609e4755557a67241 100644 (file)
@@ -33,6 +33,7 @@ class Media extends BaseApi
 {
        public static function put(array $parameters = [])
        {
+               $data = self::getPutData();
                self::unsupported('put');
        }
 
diff --git a/src/Module/Api/Mastodon/Proofs.php b/src/Module/Api/Mastodon/Proofs.php
new file mode 100644 (file)
index 0000000..1d09a92
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Module\Api\Mastodon;
+
+use Friendica\Core\System;
+use Friendica\Module\BaseApi;
+
+/**
+ * @see https://docs.joinmastodon.org/methods/proofs/
+ */
+class Proofs extends BaseApi
+{
+       /**
+        * @param array $parameters
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        */
+       public static function rawContent(array $parameters = [])
+       {
+               System::jsonError(404, ['error' => 'Record not found']);
+       }
+}
diff --git a/src/Module/Api/Mastodon/ScheduledStatuses.php b/src/Module/Api/Mastodon/ScheduledStatuses.php
new file mode 100644 (file)
index 0000000..28f174d
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Module\Api\Mastodon;
+
+use Friendica\Core\System;
+use Friendica\Module\BaseApi;
+
+/**
+ * @see https://docs.joinmastodon.org/methods/statuses/scheduled_statuses/
+ */
+class ScheduledStatuses extends BaseApi
+{
+       /**
+        * @param array $parameters
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        */
+       public static function rawContent(array $parameters = [])
+       {
+               System::jsonExit([]);
+       }
+}
index 900452385cf2f4c8905731ed4731715ce89a564e..afaf1598600ae13f36fc7337f9474a109e67fc65 100644 (file)
@@ -30,6 +30,12 @@ use Friendica\Module\BaseApi;
  */
 class Statuses extends BaseApi
 {
+       public static function post(array $parameters = [])
+       {
+               $data = self::getJsonPostData();
+               self::unsupported('post');
+       }
+
        public static function delete(array $parameters = [])
        {
                self::unsupported('delete');
index a53c008c62cf7e9b57e85f4208dd30f6158e9e28..f826f4ad2632f8528c51c95d1d9c3fce5439c779 100644 (file)
@@ -21,7 +21,6 @@
 
 namespace Friendica\Module;
 
-use Exception;
 use Friendica\BaseModule;
 use Friendica\Core\Logger;
 use Friendica\Core\System;
@@ -30,6 +29,7 @@ use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Network\HTTPException;
 use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Network;
 
 require_once __DIR__ . '/../../include/api.php';
 
@@ -127,6 +127,45 @@ class BaseApi extends BaseModule
                System::jsonError(501, $errorobj->toArray());
        }
 
+       /**
+        * Get post data that is transmitted as JSON
+        *
+        * @return array request data
+        */
+       public static function getJsonPostData()
+       {
+               $postdata = Network::postdata();
+               if (empty($postdata)) {
+                       return [];
+               }
+
+               return json_decode($postdata, true);
+       }
+
+       /**
+        * Get request data for put requests
+        *
+        * @return array request data
+        */
+       public static function getPutData()
+       {
+               $rawdata = Network::postdata();
+               if (empty($rawdata)) {
+                       return [];
+               }
+
+               $putdata = [];
+
+               foreach (explode('&', $rawdata) as $value) {
+                       $data = explode('=', $value);
+                       if (count($data) == 2) {
+                               $putdata[$data[0]] = urldecode($data[1]);
+                       }
+               }
+
+               return $putdata;
+       }
+
        /**
         * Log in user via OAuth1 or Simple HTTP Auth.
         *
index 57efe70c6387409bf16c780a333321c7351c4ec2..3834c0cd5f5dc09d5b602d38bd8176c99b8ba2f8 100644 (file)
@@ -85,6 +85,6 @@ class Authorize extends BaseApi
                        DI::mstdnError()->UnprocessableEntity();
                }
 
-               DI::app()->redirect($application['redirect_uri'] . '?' . http_build_query(['code' => $token['code'], 'state' => $state]));
+               DI::app()->redirect($application['redirect_uri'] . (strpos($application['redirect_uri'], '?') ? '&' : '?') . http_build_query(['code' => $token['code'], 'state' => $state]));
        }
 }
index 9d8e1fda4277b8783cb34dc6a972f9f9a2e10ed7..3a19ff37972bb93c669e7ac01de53ad09bbb68ce 100644 (file)
@@ -57,52 +57,52 @@ return [
 
        '/api' => [
                '/v1' => [
-                       '/accounts'                          => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not implemented
+                       '/accounts'                          => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not supported
                        '/accounts/{id:\d+}'                 => [Module\Api\Mastodon\Accounts::class,                 [R::GET         ]],
                        '/accounts/{id:\d+}/statuses'        => [Module\Api\Mastodon\Accounts\Statuses::class,        [R::GET         ]],
                        '/accounts/{id:\d+}/followers'       => [Module\Api\Mastodon\Accounts\Followers::class,       [R::GET         ]],
                        '/accounts/{id:\d+}/following'       => [Module\Api\Mastodon\Accounts\Following::class,       [R::GET         ]],
                        '/accounts/{id:\d+}/lists'           => [Module\Api\Mastodon\Accounts\Lists::class,           [R::GET         ]],
-                       '/accounts/{id:\d+}/identity_proofs' => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
-                       '/accounts/{id:\d+}/follow'          => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/accounts/{id:\d+}/unfollow'        => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/accounts/{id:\d+}/block'           => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/accounts/{id:\d+}/unblock'         => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/accounts/{id:\d+}/mute'            => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/accounts/{id:\d+}/unmute'          => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/accounts/{id:\d+}/pin'             => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not implemented
-                       '/accounts/{id:\d+}/unpin'           => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not implemented
-                       '/accounts/{id:\d+}/note'            => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
+                       '/accounts/{id:\d+}/identity_proofs' => [Module\Api\Mastodon\Accounts\IdentityProofs::class,  [R::GET         ]], // Dummy, not supported
+                       '/accounts/{id:\d+}/follow'          => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/accounts/{id:\d+}/unfollow'        => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/accounts/{id:\d+}/block'           => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/accounts/{id:\d+}/unblock'         => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/accounts/{id:\d+}/mute'            => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/accounts/{id:\d+}/unmute'          => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/accounts/{id:\d+}/pin'             => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not supported
+                       '/accounts/{id:\d+}/unpin'           => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not supported
+                       '/accounts/{id:\d+}/note'            => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
                        '/accounts/relationships'            => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // @todo
                        '/accounts/search'                   => [Module\Api\Mastodon\Accounts\Search::class,          [R::GET         ]],
                        '/accounts/verify_credentials'       => [Module\Api\Mastodon\Accounts\VerifyCredentials::class, [R::GET       ]],
-                       '/accounts/update_credentials'       => [Module\Api\Mastodon\Unimplemented::class,            [R::PATCH       ]],
-                       '/admin/accounts'                    => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
-                       '/admin/accounts/{id:\d+}'           => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
-                       '/admin/accounts/{id:\d+}/{action}'  => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not implemented
-                       '/admin/reports'                     => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
-                       '/admin/reports/{id:\d+}'            => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
-                       '/admin/reports/{id:\d+}/{action}'   => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not implemented
-                       '/announcements'                     => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
-                       '/announcements/{id:\d+}/dismiss'    => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not implemented
-                       '/announcements/{id:\d+}/reactions/{name}' => [Module\Api\Mastodon\Unimplemented::class,      [R::PUT, R::DELETE]], // not implemented
+                       '/accounts/update_credentials'       => [Module\Api\Mastodon\Unimplemented::class,            [R::PATCH       ]], // @todo
+                       '/admin/accounts'                    => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not supported
+                       '/admin/accounts/{id:\d+}'           => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not supported
+                       '/admin/accounts/{id:\d+}/{action}'  => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not supported
+                       '/admin/reports'                     => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not supported
+                       '/admin/reports/{id:\d+}'            => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not supported
+                       '/admin/reports/{id:\d+}/{action}'   => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not supported
+                       '/announcements'                     => [Module\Api\Mastodon\Announcements::class,            [R::GET         ]], // Dummy, not supported
+                       '/announcements/{id:\d+}/dismiss'    => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not supported
+                       '/announcements/{id:\d+}/reactions/{name}' => [Module\Api\Mastodon\Unimplemented::class,      [R::PUT, R::DELETE]], // not supported
                        '/apps'                              => [Module\Api\Mastodon\Apps::class,                     [        R::POST]],
-                       '/apps/verify_credentials'           => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]],
+                       '/apps/verify_credentials'           => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // @todo
                        '/blocks'                            => [Module\Api\Mastodon\Blocks::class,                   [R::GET         ]],
                        '/bookmarks'                         => [Module\Api\Mastodon\Bookmarks::class,                [R::GET         ]],
                        '/conversations'                     => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
                        '/conversations/{id:\d+}'            => [Module\Api\Mastodon\Unimplemented::class,            [R::DELETE      ]], // not implemented
                        '/conversations/{id:\d+}/read'       => [Module\Api\Mastodon\Unimplemented::class,            [R::POST        ]], // not implemented
                        '/custom_emojis'                     => [Module\Api\Mastodon\CustomEmojis::class,             [R::GET         ]],
-                       '/domain_blocks'                     => [Module\Api\Mastodon\Unimplemented::class,            [R::GET, R::POST, R::DELETE]], // not implemented
+                       '/domain_blocks'                     => [Module\Api\Mastodon\Unimplemented::class,            [R::GET, R::POST, R::DELETE]], // not supported
                        '/directory'                         => [Module\Api\Mastodon\Directory::class,                [R::GET         ]],
-                       '/endorsements'                      => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
+                       '/endorsements'                      => [Module\Api\Mastodon\Endorsements::class,             [R::GET         ]], // Dummy, not supported
                        '/favourites'                        => [Module\Api\Mastodon\Favourited::class,               [R::GET         ]],
-                       '/featured_tags'                     => [Module\Api\Mastodon\Unimplemented::class,            [R::GET, R::POST]], // not implemented
-                       '/featured_tags/{id:\d+}'            => [Module\Api\Mastodon\Unimplemented::class,            [R::DELETE      ]], // not implemented
-                       '/featured_tags/suggestions'         => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
-                       '/filters'                           => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
-                       '/filters/{id:\d+}'                  => [Module\Api\Mastodon\Unimplemented::class,            [R::GET, R::POST, R::PUT, R::DELETE]], // not implemented
+                       '/featured_tags'                     => [Module\Api\Mastodon\Unimplemented::class,            [R::GET, R::POST]], // not supported
+                       '/featured_tags/{id:\d+}'            => [Module\Api\Mastodon\Unimplemented::class,            [R::DELETE      ]], // not supported
+                       '/featured_tags/suggestions'         => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not supported
+                       '/filters'                           => [Module\Api\Mastodon\Filters::class,                  [R::GET         ]], // Dummy, not supported
+                       '/filters/{id:\d+}'                  => [Module\Api\Mastodon\Unimplemented::class,            [R::GET, R::POST, R::PUT, R::DELETE]], // not supported
                        '/follow_requests'                   => [Module\Api\Mastodon\FollowRequests::class,           [R::GET         ]],
                        '/follow_requests/{id:\d+}/{action}' => [Module\Api\Mastodon\FollowRequests::class,           [        R::POST]],
                        '/instance'                          => [Module\Api\Mastodon\Instance::class,                 [R::GET         ]],
@@ -111,35 +111,35 @@ return [
                        '/lists'                             => [Module\Api\Mastodon\Lists::class,                    [R::GET, R::POST]],
                        '/lists/{id:\d+}'                    => [Module\Api\Mastodon\Lists::class,                    [R::GET, R::PUT, R::DELETE]],
                        '/lists/{id:\d+}/accounts'           => [Module\Api\Mastodon\Lists\Accounts::class,           [R::GET, R::POST, R::DELETE]],
-                       '/markers'                           => [Module\Api\Mastodon\Unimplemented::class,            [R::GET, R::POST]], // not implemented
-                       '/media'                             => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/media/{id:\d+}'                    => [Module\Api\Mastodon\Media::class,                    [R::GET, R::PUT]],
+                       '/markers'                           => [Module\Api\Mastodon\Markers::class,                  [R::GET, R::POST]], // Dummy, not supported
+                       '/media'                             => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/media/{id:\d+}'                    => [Module\Api\Mastodon\Media::class,                    [R::GET, R::PUT ]],
                        '/mutes'                             => [Module\Api\Mastodon\Mutes::class,                    [R::GET         ]],
                        '/notifications'                     => [Module\Api\Mastodon\Notifications::class,            [R::GET         ]],
                        '/notifications/{id:\d+}'            => [Module\Api\Mastodon\Notifications::class,            [R::GET         ]],
-                       '/notifications/clear'               => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/notifications/{id:\d+}/dismiss'    => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/polls/{id:\d+}'                    => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
-                       '/polls/{id:\d+}/votes'              => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not implemented
+                       '/notifications/clear'               => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/notifications/{id:\d+}/dismiss'    => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/polls/{id:\d+}'                    => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not supported
+                       '/polls/{id:\d+}/votes'              => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not supported
                        '/preferences'                       => [Module\Api\Mastodon\Preferences::class,              [R::GET         ]],
-                       '/reports'                           => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not implemented
-                       '/scheduled_statuses'                => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
-                       '/scheduled_statuses/{id:\d+}'       => [Module\Api\Mastodon\Unimplemented::class,            [R::GET, R::PUT, R::DELETE]], // not implemented
-                       '/statuses'                          => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
+                       '/reports'                           => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // not supported
+                       '/scheduled_statuses'                => [Module\Api\Mastodon\ScheduledStatuses::class,        [R::GET         ]], // Dummy, not supported
+                       '/scheduled_statuses/{id:\d+}'       => [Module\Api\Mastodon\Unimplemented::class,            [R::GET, R::PUT, R::DELETE]], // not supported
+                       '/statuses'                          => [Module\Api\Mastodon\Statuses::class,                 [        R::POST]],
                        '/statuses/{id:\d+}'                 => [Module\Api\Mastodon\Statuses::class,                 [R::GET, R::DELETE]],
                        '/statuses/{id:\d+}/context'         => [Module\Api\Mastodon\Statuses\Context::class,         [R::GET         ]],
                        '/statuses/{id:\d+}/reblogged_by'    => [Module\Api\Mastodon\Statuses\RebloggedBy::class,     [R::GET         ]],
                        '/statuses/{id:\d+}/favourited_by'   => [Module\Api\Mastodon\Statuses\FavouritedBy::class,    [R::GET         ]],
-                       '/statuses/{id:\d+}/favourite'       => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/statuses/{id:\d+}/unfavourite'     => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/statuses/{id:\d+}/reblog'          => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/statuses/{id:\d+}/unreblog'        => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/statuses/{id:\d+}/bookmark'        => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/statuses/{id:\d+}/unbookmark'      => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/statuses/{id:\d+}/mute'            => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/statuses/{id:\d+}/unmute'          => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/statuses/{id:\d+}/pin'             => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-                       '/statuses/{id:\d+}/unpin'           => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
+                       '/statuses/{id:\d+}/favourite'       => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/statuses/{id:\d+}/unfavourite'     => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/statuses/{id:\d+}/reblog'          => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/statuses/{id:\d+}/unreblog'        => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/statuses/{id:\d+}/bookmark'        => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/statuses/{id:\d+}/unbookmark'      => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/statuses/{id:\d+}/mute'            => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/statuses/{id:\d+}/unmute'          => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/statuses/{id:\d+}/pin'             => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
+                       '/statuses/{id:\d+}/unpin'           => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]], // @todo
                        '/suggestions'                       => [Module\Api\Mastodon\Suggestions::class,              [R::GET         ]],
                        '/suggestions/{id:\d+}'              => [Module\Api\Mastodon\Unimplemented::class,            [R::DELETE      ]], // not implemented
                        '/timelines/home'                    => [Module\Api\Mastodon\Timelines\Home::class,           [R::GET         ]],
@@ -152,14 +152,15 @@ return [
                        '/search'                            => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // @todo
                ],
                '/friendica' => [
-                       '/profile/show'                      => [Module\Api\Friendica\Profile\Show::class , [R::GET         ]],
-                       '/events'                            => [Module\Api\Friendica\Events\Index::class , [R::GET         ]],
+                       '/profile/show'                      => [Module\Api\Friendica\Profile\Show::class, [R::GET         ]],
+                       '/events'                            => [Module\Api\Friendica\Events\Index::class, [R::GET         ]],
                ],
-               '/followers/ids'                         => [Module\Api\Twitter\FollowersIds::class   , [R::GET         ]],
-               '/followers/list'                        => [Module\Api\Twitter\FollowersList::class  , [R::GET         ]],
-               '/friends/ids'                           => [Module\Api\Twitter\FriendsIds::class     , [R::GET         ]],
-               '/friends/list'                          => [Module\Api\Twitter\FriendsList::class    , [R::GET         ]],
-               '/oembed'                                => [Module\Api\Mastodon\Unimplemented::class,  [R::GET         ]],
+               '/followers/ids'                         => [Module\Api\Twitter\FollowersIds::class,   [R::GET         ]],
+               '/followers/list'                        => [Module\Api\Twitter\FollowersList::class,  [R::GET         ]],
+               '/friends/ids'                           => [Module\Api\Twitter\FriendsIds::class,     [R::GET         ]],
+               '/friends/list'                          => [Module\Api\Twitter\FriendsList::class,    [R::GET         ]],
+               '/oembed'                                => [Module\Api\Mastodon\Unimplemented::class, [R::GET         ]],
+               '/proofs'                                => [Module\Api\Mastodon\Proofs::class,        [R::GET         ]], // Dummy, not supported
        ],
 
        '/admin'               => [
@@ -363,8 +364,6 @@ return [
        '/pretheme'          => [Module\ThemeDetails::class, [R::GET]],
        '/probe'             => [Module\Debug\Probe::class,  [R::GET]],
 
-       '/proofs'            => [Module\Api\Mastodon\Unimplemented::class, [R::GET]],
-
        '/profile/{nickname}' => $profileRoutes,
        '/u/{nickname}'       => $profileRoutes,
        '/~{nickname}'        => $profileRoutes,