From 4646f70786dbc6238ae352d79a464e76923e27fc Mon Sep 17 00:00:00 2001 From: Shlee Date: Sat, 31 Jan 2026 15:23:07 +1030 Subject: [PATCH 1/6] Update ActivityPubService.php --- app/Services/ActivityPubService.php | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/app/Services/ActivityPubService.php b/app/Services/ActivityPubService.php index 61866c43d..aa5673f18 100644 --- a/app/Services/ActivityPubService.php +++ b/app/Services/ActivityPubService.php @@ -10,7 +10,7 @@ class ActivityPubService { - public function get($url, $params = [], $signed = true, $validateUrl = true, $validateContentType = true) + public function get($url, $params = [], $signed = true, $validateUrl = true, $validateContentType = true, $bypassCache = false) { if ($validateUrl) { $valid = app(SanitizeService::class)->url($url, true); @@ -21,9 +21,11 @@ public function get($url, $params = [], $signed = true, $validateUrl = true, $va $cacheKey = 'activitypub-fetch:'.sha1($url.json_encode($params)); - $cached = Cache::get($cacheKey); - if ($cached !== null) { - return $cached; + if (! $bypassCache) { + $cached = Cache::get($cacheKey); + if ($cached !== null) { + return $cached; + } } $lock = Cache::lock('activitypub-fetch_lock:'.sha1($url.json_encode($params)), 10); @@ -31,17 +33,19 @@ public function get($url, $params = [], $signed = true, $validateUrl = true, $va try { $lock->block(10); - $cached = Cache::get($cacheKey); - if ($cached !== null) { - return $cached; + if (! $bypassCache) { + $cached = Cache::get($cacheKey); + if ($cached !== null) { + return $cached; + } } $result = $this->fetchActivityPub($url, $params, $signed, $validateContentType); - if ($result !== false) { - Cache::put($cacheKey, $result, 14400); + if ($result !== false && $result !== null) { + Cache::put($cacheKey, $result, 14400); // Cache successful results for 4 hours } else { - Cache::put($cacheKey, null, 14400); + Cache::put($cacheKey, null, 300); // Cache failures for only 5 minutes } return $result; From 542fe11c224a99646f3d9418856cb3d9b6ecd34f Mon Sep 17 00:00:00 2001 From: Shlee Date: Sat, 31 Jan 2026 15:33:04 +1030 Subject: [PATCH 2/6] Update QuoteRequestHandler.php --- .../Handlers/QuoteRequestHandler.php | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/app/Federation/Handlers/QuoteRequestHandler.php b/app/Federation/Handlers/QuoteRequestHandler.php index 7c0c19d27..0303138f4 100644 --- a/app/Federation/Handlers/QuoteRequestHandler.php +++ b/app/Federation/Handlers/QuoteRequestHandler.php @@ -3,6 +3,7 @@ namespace App\Federation\Handlers; use App\Federation\ActivityBuilders\QuoteRequestActivityBuilder; +use App\Jobs\Federation\DiscoverInstance; use App\Models\Comment; use App\Models\CommentReply; use App\Models\Profile; @@ -25,6 +26,11 @@ class QuoteRequestHandler */ public function handle(array $activity, Profile $actor, ?Profile $target = null): void { + // Ensure we discover the instance if this is a new remote actor + if (! $actor->local && $actor->uri) { + DiscoverInstance::dispatch($actor->uri)->onQueue('activitypub-in'); + } + $quotedObjectUrl = $activity['object']; $quotePostUrl = is_array($activity['instrument']) ? ($activity['instrument']['id'] ?? null) @@ -160,6 +166,39 @@ protected function approveQuoteRequest( string $quotePostUrl, Profile $quoterProfile ): void { + // Ensure the quoter profile has an inbox URL for delivery + if (! $quoterProfile->inbox_url) { + if (config('logging.dev_log')) { + Log::warning('QuoteRequest handler: Cannot approve - quoter has no inbox_url', [ + 'quoter_id' => $quoterProfile->id, + 'quoter_uri' => $quoterProfile->uri, + 'quote_post_url' => $quotePostUrl, + ]); + } + + // Try to re-fetch the actor data to get the inbox URL (bypass cache) + $actorData = app(\App\Services\ActivityPubService::class)->get( $quoterProfile->uri, [], true, true, true, true ); + + if ($actorData && isset($actorData['inbox'])) { + $quoterProfile->inbox_url = $actorData['inbox']; + $quoterProfile->shared_inbox_url = data_get($actorData, 'endpoints.sharedInbox'); + $quoterProfile->save(); + + // Discover the instance since we're seeing it for the first time + DiscoverInstance::dispatch($quoterProfile->uri)->onQueue('activitypub-in'); + + } else { + if (config('logging.dev_log')) { + Log::error('QuoteRequest handler: Failed to fetch inbox_url for quoter', [ + 'quoter_id' => $quoterProfile->id, + 'quoter_uri' => $quoterProfile->uri, + ]); + } + + return; + } + } + $existing = QuoteAuthorization::where('quote_post_url', $quotePostUrl) ->where('quotable_type', get_class($quotable)) ->where('quotable_id', $quotable->id) @@ -212,6 +251,50 @@ protected function approveQuoteRequest( */ protected function rejectQuoteRequest(array $activity, $quotable, Profile $quoterProfile): void { + // Ensure the quoter profile has an inbox URL for delivery + if (! $quoterProfile->inbox_url) { + if (config('logging.dev_log')) { + Log::warning('QuoteRequest handler: Cannot reject - quoter has no inbox_url', [ + 'quoter_id' => $quoterProfile->id, + 'quoter_uri' => $quoterProfile->uri, + ]); + } + + // Try to re-fetch the actor data to get the inbox URL (bypass cache) + $actorData = app(\App\Services\ActivityPubService::class)->get( + $quoterProfile->uri, + [], + true, + true, + true, + true // bypassCache + ); + if ($actorData && isset($actorData['inbox'])) { + $quoterProfile->inbox_url = $actorData['inbox']; + $quoterProfile->shared_inbox_url = data_get($actorData, 'endpoints.sharedInbox'); + $quoterProfile->save(); + + // Discover the instance since we're seeing it for the first time + DiscoverInstance::dispatch($quoterProfile->uri)->onQueue('activitypub-in'); + + if (config('logging.dev_log')) { + Log::info('QuoteRequest handler: Re-fetched inbox_url for quoter (reject)', [ + 'quoter_id' => $quoterProfile->id, + 'inbox_url' => $quoterProfile->inbox_url, + ]); + } + } else { + if (config('logging.dev_log')) { + Log::error('QuoteRequest handler: Failed to fetch inbox_url for quoter (reject)', [ + 'quoter_id' => $quoterProfile->id, + 'quoter_uri' => $quoterProfile->uri, + ]); + } + + return; + } + } + $reject = QuoteRequestActivityBuilder::buildReject( $activity, $quotable->profile From 59f0d1af8d8eacd4dce2cbd1def69a8ccb740ae1 Mon Sep 17 00:00:00 2001 From: Shlee Date: Sat, 31 Jan 2026 15:37:53 +1030 Subject: [PATCH 3/6] Update QuoteRequestHandler.php --- app/Federation/Handlers/QuoteRequestHandler.php | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/app/Federation/Handlers/QuoteRequestHandler.php b/app/Federation/Handlers/QuoteRequestHandler.php index 0303138f4..ea2dee731 100644 --- a/app/Federation/Handlers/QuoteRequestHandler.php +++ b/app/Federation/Handlers/QuoteRequestHandler.php @@ -261,14 +261,7 @@ protected function rejectQuoteRequest(array $activity, $quotable, Profile $quote } // Try to re-fetch the actor data to get the inbox URL (bypass cache) - $actorData = app(\App\Services\ActivityPubService::class)->get( - $quoterProfile->uri, - [], - true, - true, - true, - true // bypassCache - ); + $actorData = app(\App\Services\ActivityPubService::class)->get( $quoterProfile->uri, [], true, true, true, true ); if ($actorData && isset($actorData['inbox'])) { $quoterProfile->inbox_url = $actorData['inbox']; $quoterProfile->shared_inbox_url = data_get($actorData, 'endpoints.sharedInbox'); @@ -277,12 +270,6 @@ protected function rejectQuoteRequest(array $activity, $quotable, Profile $quote // Discover the instance since we're seeing it for the first time DiscoverInstance::dispatch($quoterProfile->uri)->onQueue('activitypub-in'); - if (config('logging.dev_log')) { - Log::info('QuoteRequest handler: Re-fetched inbox_url for quoter (reject)', [ - 'quoter_id' => $quoterProfile->id, - 'inbox_url' => $quoterProfile->inbox_url, - ]); - } } else { if (config('logging.dev_log')) { Log::error('QuoteRequest handler: Failed to fetch inbox_url for quoter (reject)', [ From 3553eb44119dc4fae8ec39029b926b2be7558aea Mon Sep 17 00:00:00 2001 From: Shlee Date: Sat, 31 Jan 2026 15:41:36 +1030 Subject: [PATCH 4/6] Update QuoteRequestHandler.php --- app/Federation/Handlers/QuoteRequestHandler.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/app/Federation/Handlers/QuoteRequestHandler.php b/app/Federation/Handlers/QuoteRequestHandler.php index ea2dee731..79d80127f 100644 --- a/app/Federation/Handlers/QuoteRequestHandler.php +++ b/app/Federation/Handlers/QuoteRequestHandler.php @@ -168,14 +168,6 @@ protected function approveQuoteRequest( ): void { // Ensure the quoter profile has an inbox URL for delivery if (! $quoterProfile->inbox_url) { - if (config('logging.dev_log')) { - Log::warning('QuoteRequest handler: Cannot approve - quoter has no inbox_url', [ - 'quoter_id' => $quoterProfile->id, - 'quoter_uri' => $quoterProfile->uri, - 'quote_post_url' => $quotePostUrl, - ]); - } - // Try to re-fetch the actor data to get the inbox URL (bypass cache) $actorData = app(\App\Services\ActivityPubService::class)->get( $quoterProfile->uri, [], true, true, true, true ); @@ -194,7 +186,6 @@ protected function approveQuoteRequest( 'quoter_uri' => $quoterProfile->uri, ]); } - return; } } @@ -211,7 +202,6 @@ protected function approveQuoteRequest( 'quote_post_url' => $quotePostUrl, ]); } - return; } From 8cd02393f831b5117191168520b1421c7a619079 Mon Sep 17 00:00:00 2001 From: Shlee Date: Sat, 31 Jan 2026 15:42:48 +1030 Subject: [PATCH 5/6] Update QuoteRequestHandler.php --- app/Federation/Handlers/QuoteRequestHandler.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/Federation/Handlers/QuoteRequestHandler.php b/app/Federation/Handlers/QuoteRequestHandler.php index 79d80127f..2598b0c6b 100644 --- a/app/Federation/Handlers/QuoteRequestHandler.php +++ b/app/Federation/Handlers/QuoteRequestHandler.php @@ -243,13 +243,6 @@ protected function rejectQuoteRequest(array $activity, $quotable, Profile $quote { // Ensure the quoter profile has an inbox URL for delivery if (! $quoterProfile->inbox_url) { - if (config('logging.dev_log')) { - Log::warning('QuoteRequest handler: Cannot reject - quoter has no inbox_url', [ - 'quoter_id' => $quoterProfile->id, - 'quoter_uri' => $quoterProfile->uri, - ]); - } - // Try to re-fetch the actor data to get the inbox URL (bypass cache) $actorData = app(\App\Services\ActivityPubService::class)->get( $quoterProfile->uri, [], true, true, true, true ); if ($actorData && isset($actorData['inbox'])) { From 64f5ac4efa4cdd767d52e646190760b51fa6e6d1 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 31 Jan 2026 17:33:43 +1030 Subject: [PATCH 6/6] pint --- app/Federation/Handlers/QuoteRequestHandler.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/Federation/Handlers/QuoteRequestHandler.php b/app/Federation/Handlers/QuoteRequestHandler.php index 2598b0c6b..75c3a680a 100644 --- a/app/Federation/Handlers/QuoteRequestHandler.php +++ b/app/Federation/Handlers/QuoteRequestHandler.php @@ -169,7 +169,7 @@ protected function approveQuoteRequest( // Ensure the quoter profile has an inbox URL for delivery if (! $quoterProfile->inbox_url) { // Try to re-fetch the actor data to get the inbox URL (bypass cache) - $actorData = app(\App\Services\ActivityPubService::class)->get( $quoterProfile->uri, [], true, true, true, true ); + $actorData = app(\App\Services\ActivityPubService::class)->get($quoterProfile->uri, [], true, true, true, true); if ($actorData && isset($actorData['inbox'])) { $quoterProfile->inbox_url = $actorData['inbox']; @@ -186,6 +186,7 @@ protected function approveQuoteRequest( 'quoter_uri' => $quoterProfile->uri, ]); } + return; } } @@ -202,6 +203,7 @@ protected function approveQuoteRequest( 'quote_post_url' => $quotePostUrl, ]); } + return; } @@ -244,7 +246,7 @@ protected function rejectQuoteRequest(array $activity, $quotable, Profile $quote // Ensure the quoter profile has an inbox URL for delivery if (! $quoterProfile->inbox_url) { // Try to re-fetch the actor data to get the inbox URL (bypass cache) - $actorData = app(\App\Services\ActivityPubService::class)->get( $quoterProfile->uri, [], true, true, true, true ); + $actorData = app(\App\Services\ActivityPubService::class)->get($quoterProfile->uri, [], true, true, true, true); if ($actorData && isset($actorData['inbox'])) { $quoterProfile->inbox_url = $actorData['inbox']; $quoterProfile->shared_inbox_url = data_get($actorData, 'endpoints.sharedInbox');