From 8f0f6e6aacd0c373ad8109c2136fae3b92f6049d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AB=8F=E8=A8=AA=E5=AD=90?= Date: Sun, 25 May 2025 22:12:35 +0900 Subject: [PATCH 1/3] fix(settings): change Mastodon only URI to webfinger MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 諏訪子 --- AUTHORS | 1 + lib/private/Accounts/AccountManager.php | 4 ++-- tests/lib/Accounts/AccountManagerTest.php | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index d6c8f3f6f0032..a15a5cd061eab 100644 --- a/AUTHORS +++ b/AUTHORS @@ -619,6 +619,7 @@ - szaimen - tbartenstein - tbelau666 + - TechnicalSuwako - tgrant - timm2k - tux-rampage diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php index d69e72a29de4a..a35db05130350 100644 --- a/lib/private/Accounts/AccountManager.php +++ b/lib/private/Accounts/AccountManager.php @@ -736,7 +736,7 @@ private function sanitizePropertyFediverse(IAccountProperty $property): void { try { // try the public account lookup API of mastodon - $response = $client->get("https://{$instance}/api/v1/accounts/lookup?acct={$username}@{$instance}"); + $response = $client->get("https://{$instance}/.well-known/webfinger?resource=acct:{$username}@{$instance}"); // should be a json response with account information $data = $response->getBody(); if (is_resource($data)) { @@ -745,7 +745,7 @@ private function sanitizePropertyFediverse(IAccountProperty $property): void { $decoded = json_decode($data, true); // ensure the username is the same the user passed // in this case we can assume this is a valid fediverse server and account - if (!is_array($decoded) || ($decoded['username'] ?? '') !== $username) { + if (!is_array($decoded) || ($decoded['subject'] ?? '') !== "acct:{$username}@{$instance}") { throw new InvalidArgumentException(); } } catch (InvalidArgumentException) { diff --git a/tests/lib/Accounts/AccountManagerTest.php b/tests/lib/Accounts/AccountManagerTest.php index fab3aaf5fdd2b..ec391e0421007 100644 --- a/tests/lib/Accounts/AccountManagerTest.php +++ b/tests/lib/Accounts/AccountManagerTest.php @@ -839,12 +839,12 @@ public function testSanitizingFediverseServer(string $input, ?string $output, bo ->willReturn($serverResponse); $client->expects(self::once()) ->method('get') - ->with('https://example.com/api/v1/accounts/lookup?acct=foo@example.com') + ->with('https://example.com/.well-known/webfinger?resource=acct:foo@example.com') ->willReturn($response); } else { $client->expects(self::once()) ->method('get') - ->with('https://example.com/api/v1/accounts/lookup?acct=foo@example.com') + ->with('https://example.com/.well-known/webfinger?resource=acct:foo@example.com') ->willThrowException(new \Exception('404')); } From 645b98961907786f173f59dd3f2153955fcf8593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AB=8F=E8=A8=AA=E5=AD=90?= Date: Mon, 26 May 2025 09:58:50 +0900 Subject: [PATCH 2/3] fix(settings): add link check in webfinger MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 諏訪子 --- lib/private/Accounts/AccountManager.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php index a35db05130350..c40e612a3b571 100644 --- a/lib/private/Accounts/AccountManager.php +++ b/lib/private/Accounts/AccountManager.php @@ -748,6 +748,23 @@ private function sanitizePropertyFediverse(IAccountProperty $property): void { if (!is_array($decoded) || ($decoded['subject'] ?? '') !== "acct:{$username}@{$instance}") { throw new InvalidArgumentException(); } + // check for activitypub link + if (is_array($decoded['links']) && isset($decoded['links'])) { + $found = false; + foreach ($decoded['links'] as $link) { + // have application/activity+json or application/ld+json + if (isset($link['type']) && ( + $link['type'] === 'application/activity+json' || + $link['type'] === 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' + )) { + $found = true; + break; + } + } + if (!$found) { + throw new InvalidArgumentException(); + } + } } catch (InvalidArgumentException) { throw new InvalidArgumentException(self::PROPERTY_FEDIVERSE); } catch (\Exception $error) { From df78886ae70bc58de859ddda2910b8b51d179491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AB=8F=E8=A8=AA=E5=AD=90?= Date: Tue, 27 May 2025 18:40:27 +0900 Subject: [PATCH 3/3] fix(settings): fix test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 諏訪子 --- tests/lib/Accounts/AccountManagerTest.php | 31 ++++++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/tests/lib/Accounts/AccountManagerTest.php b/tests/lib/Accounts/AccountManagerTest.php index ec391e0421007..06a4ab38afc0d 100644 --- a/tests/lib/Accounts/AccountManagerTest.php +++ b/tests/lib/Accounts/AccountManagerTest.php @@ -792,20 +792,41 @@ public static function dataSanitizeFediverseServer(): array { '@foo@example.com', 'foo@example.com', true, - json_encode(['username' => 'foo']), + json_encode([ + 'subject' => 'acct:foo@example.com', + 'links' => [ + [ + 'rel' => 'self', + 'type' => 'application/activity+json', + 'href' => 'https://example.com/users/foo', + ], + ], + ]), ], 'valid response - no at' => [ 'foo@example.com', 'foo@example.com', true, - json_encode(['username' => 'foo']), + json_encode([ + 'subject' => 'acct:foo@example.com', + 'links' => [ + [ + 'rel' => 'self', + 'type' => 'application/activity+json', + 'href' => 'https://example.com/users/foo', + ], + ], + ]), ], // failures 'invalid response' => [ '@foo@example.com', null, true, - json_encode(['not found']), + json_encode([ + 'subject' => 'acct:foo@example.com', + 'links' => [], + ]), ], 'no response' => [ '@foo@example.com', @@ -817,7 +838,9 @@ public static function dataSanitizeFediverseServer(): array { '@foo@example.com', null, true, - json_encode(['username' => 'foo@other.example.com']), + json_encode([ + 'links' => [], + ]), ], ]; }