From 4470981af7cd5c2db406402775b53bc6a3b0af92 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 11 Jun 2022 03:27:52 -0600 Subject: [PATCH] Improve follow request flow, federate rejections and delete rejections from database to properly handle future follow requests from same actor --- app/FollowRequest.php | 4 +- app/Http/Controllers/AccountController.php | 8 ++- .../FollowPipeline/FollowRejectPipeline.php | 69 +++++++++++++++++++ .../ActivityPub/Verb/RejectFollow.php | 25 +++++++ 4 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 app/Jobs/FollowPipeline/FollowRejectPipeline.php create mode 100644 app/Transformer/ActivityPub/Verb/RejectFollow.php diff --git a/app/FollowRequest.php b/app/FollowRequest.php index c1b0ac755..b501a4124 100644 --- a/app/FollowRequest.php +++ b/app/FollowRequest.php @@ -32,9 +32,9 @@ class FollowRequest extends Model return $this->belongsTo(Profile::class, 'following_id', 'id'); } - public function permalink($append = null) + public function permalink($append = null, $namespace = '#accepts') { - $path = $this->target->permalink("#accepts/follows/{$this->id}{$append}"); + $path = $this->target->permalink("{$namespace}/follows/{$this->id}{$append}"); return url($path); } } diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 02921368d..e1c9bfcb3 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -30,6 +30,7 @@ use App\Services\AccountService; use App\Services\UserFilterService; use App\Services\RelationshipService; use App\Jobs\FollowPipeline\FollowAcceptPipeline; +use App\Jobs\FollowPipeline\FollowRejectPipeline; class AccountController extends Controller { @@ -406,8 +407,11 @@ class AccountController extends Controller break; case 'reject': - $followRequest->is_rejected = true; - $followRequest->save(); + if($follower->domain != null && $follower->private_key === null) { + FollowRejectPipeline::dispatch($followRequest); + } else { + $followRequest->delete(); + } break; } diff --git a/app/Jobs/FollowPipeline/FollowRejectPipeline.php b/app/Jobs/FollowPipeline/FollowRejectPipeline.php new file mode 100644 index 000000000..99d6fa65c --- /dev/null +++ b/app/Jobs/FollowPipeline/FollowRejectPipeline.php @@ -0,0 +1,69 @@ +followRequest = $followRequest; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $follow = $this->followRequest; + $actor = $follow->actor; + $target = $follow->target; + + if($actor->domain == null || $actor->inbox_url == null || !$target->private_key) { + return; + } + + $fractal = new Fractal\Manager(); + $fractal->setSerializer(new ArraySerializer()); + $resource = new Fractal\Resource\Item($follow, new RejectFollow()); + $activity = $fractal->createData($resource)->toArray(); + $url = $actor->sharedInbox ?? $actor->inbox_url; + + Helpers::sendSignedObject($target, $url, $activity); + + $follow->delete(); + + return; + } +} diff --git a/app/Transformer/ActivityPub/Verb/RejectFollow.php b/app/Transformer/ActivityPub/Verb/RejectFollow.php new file mode 100644 index 000000000..a299e0765 --- /dev/null +++ b/app/Transformer/ActivityPub/Verb/RejectFollow.php @@ -0,0 +1,25 @@ + 'https://www.w3.org/ns/activitystreams', + 'type' => 'Reject', + 'id' => $follow->permalink(null, '#rejects'), + 'actor' => $follow->target->permalink(), + 'object' => [ + 'type' => 'Follow', + 'id' => $follow->activity && isset($follow->activity['id']) ? $follow->activity['id'] : null, + 'actor' => $follow->actor->permalink(), + 'object' => $follow->target->permalink() + ] + ]; + } +}