diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index a0e53a799..90810008b 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -30,6 +30,7 @@ use League\Fractal\Serializer\ArraySerializer; use League\Fractal\Pagination\IlluminatePaginatorAdapter; use App\Transformer\Api\Mastodon\v1\AccountTransformer; use App\Services\AccountService; +use App\Services\FollowerService; use App\Services\NotificationService; use App\Services\UserFilterService; use App\Services\RelationshipService; @@ -285,10 +286,27 @@ class AccountController extends Controller $followed = Follower::whereProfileId($profile->id)->whereFollowingId($pid)->first(); if($followed) { $followed->delete(); + $profile->following_count = Follower::whereProfileId($profile->id)->count(); + $profile->save(); $selfProfile = $request->user()->profile; $selfProfile->followers_count = Follower::whereFollowingId($pid)->count(); $selfProfile->save(); - AccountService::del($selfProfile->id); + FollowerService::remove($profile->id, $pid); + AccountService::del($pid); + AccountService::del($profile->id); + } + + $following = Follower::whereProfileId($pid)->whereFollowingId($profile->id)->first(); + if($following) { + $following->delete(); + $profile->followers_count = Follower::whereFollowingId($profile->id)->count(); + $profile->save(); + $selfProfile = $request->user()->profile; + $selfProfile->following_count = Follower::whereProfileId($pid)->count(); + $selfProfile->save(); + FollowerService::remove($pid, $profile->pid); + AccountService::del($pid); + AccountService::del($profile->id); } Notification::whereProfileId($pid) @@ -357,8 +375,8 @@ class AccountController extends Controller ->first(); if($filter) { - UserFilterService::unblock($pid, $filterable['id']); $filter->delete(); + UserFilterService::unblock($pid, $filterable['id']); } $res = RelationshipService::refresh($pid, $profile->id); diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 8802ee881..2ca98210d 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1095,9 +1095,39 @@ class ApiV1Controller extends Controller abort_if($count >= $maxLimit, 422, AccountController::FILTER_LIMIT_BLOCK_TEXT . $maxLimit . ' accounts'); } - Follower::whereProfileId($profile->id)->whereFollowingId($pid)->delete(); - Follower::whereProfileId($pid)->whereFollowingId($profile->id)->delete(); - Notification::whereProfileId($pid)->whereActorId($profile->id)->delete(); + $followed = Follower::whereProfileId($profile->id)->whereFollowingId($pid)->first(); + if($followed) { + $followed->delete(); + $profile->following_count = Follower::whereProfileId($profile->id)->count(); + $profile->save(); + $selfProfile = $user->profile; + $selfProfile->followers_count = Follower::whereFollowingId($pid)->count(); + $selfProfile->save(); + FollowerService::remove($profile->id, $pid); + AccountService::del($pid); + AccountService::del($profile->id); + } + + $following = Follower::whereProfileId($pid)->whereFollowingId($profile->id)->first(); + if($following) { + $following->delete(); + $profile->followers_count = Follower::whereFollowingId($profile->id)->count(); + $profile->save(); + $selfProfile = $user->profile; + $selfProfile->following_count = Follower::whereProfileId($pid)->count(); + $selfProfile->save(); + FollowerService::remove($pid, $profile->pid); + AccountService::del($pid); + AccountService::del($profile->id); + } + + Notification::whereProfileId($pid) + ->whereActorId($profile->id) + ->get() + ->map(function($n) use($pid) { + NotificationService::del($pid, $n['id']); + $n->forceDelete(); + }); $filter = UserFilter::firstOrCreate([ 'user_id' => $pid, @@ -1106,8 +1136,8 @@ class ApiV1Controller extends Controller 'filter_type' => 'block', ]); - RelationshipService::refresh($pid, $id); UserFilterService::block($pid, $id); + RelationshipService::refresh($pid, $id); $resource = new Fractal\Resource\Item($profile, new RelationshipTransformer()); $res = $this->fractal->createData($resource)->toArray(); diff --git a/app/Http/Controllers/Api/ApiV1Dot1Controller.php b/app/Http/Controllers/Api/ApiV1Dot1Controller.php index 3eb0251df..16aa3757e 100644 --- a/app/Http/Controllers/Api/ApiV1Dot1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Dot1Controller.php @@ -34,6 +34,7 @@ use App\Mail\ConfirmAppEmail; use App\Http\Resources\StatusStateless; use App\Jobs\StatusPipeline\StatusDelete; use App\Jobs\ReportPipeline\ReportNotifyAdminViaEmail; +use Illuminate\Support\Facades\RateLimiter; class ApiV1Dot1Controller extends Controller { @@ -452,7 +453,7 @@ class ApiV1Dot1Controller extends Controller public function inAppRegistrationPreFlightCheck(Request $request) { return [ - 'open' => config_cache('pixelfed.open_registration'), + 'open' => (bool) config_cache('pixelfed.open_registration'), 'iara' => config('pixelfed.allow_app_registration') ]; } @@ -466,6 +467,10 @@ class ApiV1Dot1Controller extends Controller if(config('pixelfed.bouncer.cloud_ips.ban_signups')) { abort_if(BouncerService::checkIp($request->ip()), 404); } + + $rl = RateLimiter::attempt('pf:apiv1.1:iar:'.$request->ip(), 3, function(){}, 1800); + abort_if(!$rl, 400, 'Too many requests'); + $this->validate($request, [ 'email' => [ 'required', @@ -581,6 +586,10 @@ class ApiV1Dot1Controller extends Controller if(config('pixelfed.bouncer.cloud_ips.ban_signups')) { abort_if(BouncerService::checkIp($request->ip()), 404); } + + $rl = RateLimiter::attempt('pf:apiv1.1:iarc:'.$request->ip(), 10, function(){}, 1800); + abort_if(!$rl, 400, 'Too many requests'); + $this->validate($request, [ 'user_token' => 'required', 'random_token' => 'required', diff --git a/database/migrations/2023_04_20_092740_fix_account_blocks.php b/database/migrations/2023_04_20_092740_fix_account_blocks.php new file mode 100644 index 000000000..3d07d6390 --- /dev/null +++ b/database/migrations/2023_04_20_092740_fix_account_blocks.php @@ -0,0 +1,81 @@ +whereFilterableType('App\Profile') + ->chunk(10, function($filters) { + foreach($filters as $filter) { + $actor = Profile::whereNull('status')->find($filter->user_id); + if(!$actor) { + continue; + } + $target = Profile::whereNull('status')->find($filter->filterable_id); + if(!$target) { + continue; + } + + $followed = Follower::whereProfileId($target->id)->whereFollowingId($actor->id)->first(); + if($followed) { + $followed->delete(); + $target->following_count = Follower::whereProfileId($target->id)->count(); + $target->save(); + $actor->followers_count = Follower::whereFollowingId($actor->id)->count(); + $actor->save(); + FollowerService::remove($target->id, $actor->id); + AccountService::del($actor->id); + AccountService::del($target->id); + } + + $following = Follower::whereProfileId($actor->id)->whereFollowingId($target->id)->first(); + if($following) { + $following->delete(); + $actor->followers_count = Follower::whereFollowingId($target->id)->count(); + $actor->save(); + $target->following_count = Follower::whereProfileId($actor->id)->count(); + $target->save(); + FollowerService::remove($actor->id, $target->id); + AccountService::del($actor->id); + AccountService::del($target->id); + } + + Notification::whereProfileId($actor->id) + ->whereActorId($target->id) + ->get() + ->map(function($n) use($actor) { + NotificationService::del($actor->id, $n['id']); + $n->forceDelete(); + }); + + UserFilterService::block($actor->id, $target->id); + RelationshipService::refresh($actor->id, $target->id); + } + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // + } +};