Explorar o código

Merge pull request #5881 from pixelfed/staging

Staging
daniel hai 3 meses
pai
achega
917f6759fc

+ 6 - 0
CHANGELOG.md

@@ -57,6 +57,12 @@
 - Update DM config, allow new users to send DMs by default, with a new env variable to enforce a 72h limit ([717f17cde](https://github.com/pixelfed/pixelfed/commit/717f17cde))
 - Update DM config, allow new users to send DMs by default, with a new env variable to enforce a 72h limit ([717f17cde](https://github.com/pixelfed/pixelfed/commit/717f17cde))
 - Update ApiV1Controller, add pagination to conversations endpoint with min/max/since id pagination and link header support ([244e86bad](https://github.com/pixelfed/pixelfed/commit/244e86bad))
 - Update ApiV1Controller, add pagination to conversations endpoint with min/max/since id pagination and link header support ([244e86bad](https://github.com/pixelfed/pixelfed/commit/244e86bad))
 - Update Direct message component, fix pagination ([e6ef64857](https://github.com/pixelfed/pixelfed/commit/e6ef64857))
 - Update Direct message component, fix pagination ([e6ef64857](https://github.com/pixelfed/pixelfed/commit/e6ef64857))
+- Update ActivityPub helpers, improve private account handling ([75e7a678c](https://github.com/pixelfed/pixelfed/commit/75e7a678c))
+- Update ApiV1Controller, improve follower handling ([976a1873e](https://github.com/pixelfed/pixelfed/commit/976a1873e))
+- Update Inbox, improve Accept Follower handling ([3725c689e](https://github.com/pixelfed/pixelfed/commit/3725c689e))
+- Update Inbox handler, add Reject Follow support ([fbe76e37f](https://github.com/pixelfed/pixelfed/commit/fbe76e37f))
+- Update Inbox handler, improve Undo Follow logic ([5525369fe](https://github.com/pixelfed/pixelfed/commit/5525369fe))
+- Update ApiV1Controller, send UndoFollow when cancelling a follow request on remote accounts ([2cf301181](https://github.com/pixelfed/pixelfed/commit/2cf301181))
 -  ([](https://github.com/pixelfed/pixelfed/commit/))
 -  ([](https://github.com/pixelfed/pixelfed/commit/))
 
 
 ## [v0.12.4 (2024-11-08)](https://github.com/pixelfed/pixelfed/compare/v0.12.4...dev)
 ## [v0.12.4 (2024-11-08)](https://github.com/pixelfed/pixelfed/compare/v0.12.4...dev)

+ 18 - 9
app/Http/Controllers/Api/ApiV1Controller.php

@@ -813,13 +813,13 @@ class ApiV1Controller extends Controller
         abort_unless($request->user()->tokenCan('follow'), 403);
         abort_unless($request->user()->tokenCan('follow'), 403);
 
 
         $user = $request->user();
         $user = $request->user();
+        abort_if($user->profile_id == $id, 400, 'Invalid profile');
+
         abort_if($user->has_roles && ! UserRoleService::can('can-follow', $user->id), 403, 'Invalid permissions for this action');
         abort_if($user->has_roles && ! UserRoleService::can('can-follow', $user->id), 403, 'Invalid permissions for this action');
 
 
         AccountService::setLastActive($user->id);
         AccountService::setLastActive($user->id);
 
 
-        $target = Profile::where('id', '!=', $user->profile_id)
-            ->whereNull('status')
-            ->findOrFail($id);
+        $target = Profile::whereNull('status')->findOrFail($id);
 
 
         abort_if($target && $target->moved_to_profile_id, 400, 'Cannot follow an account that has moved!');
         abort_if($target && $target->moved_to_profile_id, 400, 'Cannot follow an account that has moved!');
 
 
@@ -864,15 +864,20 @@ class ApiV1Controller extends Controller
             if ($remote == true && config('federation.activitypub.remoteFollow') == true) {
             if ($remote == true && config('federation.activitypub.remoteFollow') == true) {
                 (new FollowerController)->sendFollow($user->profile, $target);
                 (new FollowerController)->sendFollow($user->profile, $target);
             }
             }
-        } else {
-            $follower = Follower::firstOrCreate([
-                'profile_id' => $user->profile_id,
+        } elseif ($remote == true) {
+            $follow = FollowRequest::firstOrCreate([
+                'follower_id' => $user->profile_id,
                 'following_id' => $target->id,
                 'following_id' => $target->id,
             ]);
             ]);
 
 
-            if ($remote == true && config('federation.activitypub.remoteFollow') == true) {
+            if (config('federation.activitypub.remoteFollow') == true) {
                 (new FollowerController)->sendFollow($user->profile, $target);
                 (new FollowerController)->sendFollow($user->profile, $target);
             }
             }
+        } else {
+            $follower = Follower::firstOrCreate([
+                'profile_id' => $user->profile_id,
+                'following_id' => $target->id,
+            ]);
             FollowPipeline::dispatch($follower)->onQueue('high');
             FollowPipeline::dispatch($follower)->onQueue('high');
         }
         }
 
 
@@ -909,10 +914,11 @@ class ApiV1Controller extends Controller
 
 
         $user = $request->user();
         $user = $request->user();
 
 
+        abort_if($user->profile_id == $id, 400, 'Invalid profile');
+
         AccountService::setLastActive($user->id);
         AccountService::setLastActive($user->id);
 
 
-        $target = Profile::where('id', '!=', $user->profile_id)
-            ->whereNull('status')
+        $target = Profile::whereNull('status')
             ->findOrFail($id);
             ->findOrFail($id);
 
 
         $private = (bool) $target->is_private;
         $private = (bool) $target->is_private;
@@ -929,6 +935,9 @@ class ApiV1Controller extends Controller
             if ($followRequest) {
             if ($followRequest) {
                 $followRequest->delete();
                 $followRequest->delete();
                 RelationshipService::refresh($target->id, $user->profile_id);
                 RelationshipService::refresh($target->id, $user->profile_id);
+                if ($target->domain) {
+                    UnfollowPipeline::dispatch($user->profile_id, $target->id)->onQueue('high');
+                }
             }
             }
             $resource = new Fractal\Resource\Item($target, new RelationshipTransformer);
             $resource = new Fractal\Resource\Item($target, new RelationshipTransformer);
             $res = $this->fractal->createData($resource)->toArray();
             $res = $this->fractal->createData($resource)->toArray();

+ 43 - 5
app/Util/ActivityPub/Inbox.php

@@ -32,6 +32,7 @@ use App\Services\NotificationAppGatewayService;
 use App\Services\PollService;
 use App\Services\PollService;
 use App\Services\PushNotificationService;
 use App\Services\PushNotificationService;
 use App\Services\ReblogService;
 use App\Services\ReblogService;
+use App\Services\RelationshipService;
 use App\Services\UserFilterService;
 use App\Services\UserFilterService;
 use App\Status;
 use App\Status;
 use App\Story;
 use App\Story;
@@ -42,6 +43,7 @@ use App\Util\ActivityPub\Validator\Announce as AnnounceValidator;
 use App\Util\ActivityPub\Validator\Follow as FollowValidator;
 use App\Util\ActivityPub\Validator\Follow as FollowValidator;
 use App\Util\ActivityPub\Validator\Like as LikeValidator;
 use App\Util\ActivityPub\Validator\Like as LikeValidator;
 use App\Util\ActivityPub\Validator\MoveValidator;
 use App\Util\ActivityPub\Validator\MoveValidator;
+use App\Util\ActivityPub\Validator\RejectValidator;
 use App\Util\ActivityPub\Validator\UpdatePersonValidator;
 use App\Util\ActivityPub\Validator\UpdatePersonValidator;
 use Cache;
 use Cache;
 use Illuminate\Support\Facades\Bus;
 use Illuminate\Support\Facades\Bus;
@@ -120,6 +122,9 @@ class Inbox
                 break;
                 break;
 
 
             case 'Reject':
             case 'Reject':
+                if (RejectValidator::validate($this->payload) == false) {
+                    return;
+                }
                 $this->handleRejectActivity();
                 $this->handleRejectActivity();
                 break;
                 break;
 
 
@@ -245,7 +250,7 @@ class Inbox
         $cc = isset($activity['cc']) ? $activity['cc'] : [];
         $cc = isset($activity['cc']) ? $activity['cc'] : [];
 
 
         if ($activity['type'] == 'Question') {
         if ($activity['type'] == 'Question') {
-            //$this->handlePollCreate();
+            // $this->handlePollCreate();
 
 
             return;
             return;
         }
         }
@@ -614,6 +619,9 @@ class Inbox
             Cache::forget('profile:following_count:'.$target->id);
             Cache::forget('profile:following_count:'.$target->id);
             Cache::forget('profile:following_count:'.$actor->id);
             Cache::forget('profile:following_count:'.$actor->id);
         }
         }
+        RelationshipService::refresh($actor->id, $target->id);
+        AccountService::del($actor->id);
+        AccountService::del($target->id);
 
 
     }
     }
 
 
@@ -706,10 +714,20 @@ class Inbox
             'profile_id' => $actor->id,
             'profile_id' => $actor->id,
             'following_id' => $target->id,
             'following_id' => $target->id,
         ]);
         ]);
-        FollowPipeline::dispatch($follower);
-
+        FollowPipeline::dispatch($follower)->onQueue('high');
+        RelationshipService::refresh($actor->id, $target->id);
+        Cache::forget('profile:following:'.$target->id);
+        Cache::forget('profile:followers:'.$target->id);
+        Cache::forget('profile:following:'.$actor->id);
+        Cache::forget('profile:followers:'.$actor->id);
+        Cache::forget('profile:follower_count:'.$target->id);
+        Cache::forget('profile:follower_count:'.$actor->id);
+        Cache::forget('profile:following_count:'.$target->id);
+        Cache::forget('profile:following_count:'.$actor->id);
+        AccountService::del($actor->id);
+        AccountService::del($target->id);
+        RelationshipService::get($actor->id, $target->id);
         $request->delete();
         $request->delete();
-
     }
     }
 
 
     public function handleDeleteActivity()
     public function handleDeleteActivity()
@@ -843,7 +861,21 @@ class Inbox
 
 
     }
     }
 
 
-    public function handleRejectActivity() {}
+    public function handleRejectActivity()
+    {
+        $actorUrl = $this->payload['actor'];
+        $obj = $this->payload['object'];
+        $profileUrl = $obj['actor'];
+        if (! Helpers::validateUrl($actorUrl) || ! Helpers::validateLocalUrl($profileUrl)) {
+            return;
+        }
+        $actor = Helpers::profileFetch($actorUrl);
+        $profile = Helpers::profileFetch($profileUrl);
+
+        FollowRequest::whereFollowerId($profile->id)->whereFollowingId($actor->id)->forceDelete();
+        RelationshipService::refresh($actor->id, $profile->id);
+
+    }
 
 
     public function handleUndoActivity()
     public function handleUndoActivity()
     {
     {
@@ -909,6 +941,9 @@ class Inbox
                 Follower::whereProfileId($profile->id)
                 Follower::whereProfileId($profile->id)
                     ->whereFollowingId($following->id)
                     ->whereFollowingId($following->id)
                     ->delete();
                     ->delete();
+                FollowRequest::whereFollowingId($following->id)
+                    ->whereFollowerId($profile->id)
+                    ->forceDelete();
                 Notification::whereProfileId($following->id)
                 Notification::whereProfileId($following->id)
                     ->whereActorId($profile->id)
                     ->whereActorId($profile->id)
                     ->whereAction('follow')
                     ->whereAction('follow')
@@ -916,6 +951,9 @@ class Inbox
                     ->whereItemType('App\Profile')
                     ->whereItemType('App\Profile')
                     ->forceDelete();
                     ->forceDelete();
                 FollowerService::remove($profile->id, $following->id);
                 FollowerService::remove($profile->id, $following->id);
+                RelationshipService::refresh($following->id, $profile->id);
+                AccountService::del($profile->id);
+                AccountService::del($following->id);
                 break;
                 break;
 
 
             case 'Like':
             case 'Like':

+ 31 - 0
app/Util/ActivityPub/Validator/RejectValidator.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App\Util\ActivityPub\Validator;
+
+use Illuminate\Validation\Rule;
+use Validator;
+
+class RejectValidator
+{
+    public static function validate($payload)
+    {
+        $valid = Validator::make($payload, [
+            '@context' => 'required',
+            'id' => 'required|string',
+            'type' => [
+                'required',
+                Rule::in(['Reject']),
+            ],
+            'actor' => 'required|url',
+            'object.id' => 'required|url',
+            'object.actor' => 'required|url',
+            'object.object' => 'required|url',
+            'object.type' => [
+                'required',
+                Rule::in(['Follow']),
+            ],
+        ])->passes();
+
+        return $valid;
+    }
+}