diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 7344b2fc..79c5a08f 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -411,34 +411,40 @@ class ApiV1Controller extends Controller public function accountFollowersById(Request $request, $id) { abort_if(!$request->user(), 403); + $account = AccountService::get($id); + abort_if(!$account, 404); + $pid = $request->user()->profile_id; - $user = $request->user(); - $profile = Profile::whereNull('status')->findOrFail($id); - $limit = $request->input('limit') ?? 40; - - if($profile->domain) { - $res = []; - } else { - if($profile->id == $user->profile_id) { - $followers = $profile->followers()->paginate($limit); - $resource = new Fractal\Resource\Collection($followers, new AccountTransformer()); - $res = $this->fractal->createData($resource)->toArray(); - } else { - if($profile->is_private) { - abort_if(!$profile->followedBy($user->profile), 403); - } - $settings = $profile->user->settings; - if( in_array($user->profile_id, $profile->blockedIds()->toArray()) || - $settings->show_profile_followers == false - ) { - $res = []; - } else { - $followers = $profile->followers()->paginate($limit); - $resource = new Fractal\Resource\Collection($followers, new AccountTransformer()); - $res = $this->fractal->createData($resource)->toArray(); + if($pid != $account['id']) { + if($account['locked']) { + if(FollowerService::follows($pid, $account['id'])) { + return []; } } + + if(AccountService::hiddenFollowers($id)) { + return []; + } + + if($request->has('page') && $request->page >= 5) { + return []; + } } + + $res = DB::table('followers') + ->select('id', 'profile_id', 'following_id') + ->whereFollowingId($account['id']) + ->orderByDesc('id') + ->simplePaginate(10) + ->map(function($follower) { + return AccountService::getMastodon($follower->profile_id); + }) + ->filter(function($account) { + return $account && isset($account['id']); + }) + ->values() + ->toArray(); + return response()->json($res); } @@ -451,36 +457,40 @@ class ApiV1Controller extends Controller */ public function accountFollowingById(Request $request, $id) { - abort_if(!$request->user(), 403); + abort_if(!$request->user(), 403); + $account = AccountService::get($id); + abort_if(!$account, 404); + $pid = $request->user()->profile_id; - $user = $request->user(); - $profile = Profile::whereNull('status')->findOrFail($id); - $limit = $request->input('limit') ?? 40; + if($pid != $account['id']) { + if($account['locked']) { + if(FollowerService::follows($pid, $account['id'])) { + return []; + } + } - if($profile->domain) { - $res = []; - } else { - if($profile->id == $user->profile_id) { - $following = $profile->following()->paginate($limit); - $resource = new Fractal\Resource\Collection($following, new AccountTransformer()); - $res = $this->fractal->createData($resource)->toArray(); - } else { - if($profile->is_private) { - abort_if(!$profile->followedBy($user->profile), 403); - } - $settings = $profile->user->settings; - if( in_array($user->profile_id, $profile->blockedIds()->toArray()) || - $settings->show_profile_following == false - ) { - $res = []; - } else { - $following = $profile->following()->paginate($limit); - $resource = new Fractal\Resource\Collection($following, new AccountTransformer()); - $res = $this->fractal->createData($resource)->toArray(); - } + if(AccountService::hiddenFollowing($id)) { + return []; + } + + if($request->has('page') && $request->page >= 5) { + return []; } } + $res = DB::table('followers') + ->select('id', 'profile_id', 'following_id') + ->whereProfileId($account['id']) + ->orderByDesc('id') + ->simplePaginate(10) + ->map(function($follower) { + return AccountService::get($follower->following_id); + }) + ->filter(function($account) { + return $account && isset($account['id']); + }) + ->values() + ->toArray(); return response()->json($res); } diff --git a/app/Http/Controllers/PublicApiController.php b/app/Http/Controllers/PublicApiController.php index 5c25977a..5c1921be 100644 --- a/app/Http/Controllers/PublicApiController.php +++ b/app/Http/Controllers/PublicApiController.php @@ -15,7 +15,7 @@ use App\{ StatusView, UserFilter }; -use Auth, Cache; +use Auth, Cache, DB; use Illuminate\Support\Facades\Redis; use Carbon\Carbon; use League\Fractal; @@ -651,70 +651,82 @@ class PublicApiController extends Controller public function accountFollowers(Request $request, $id) { - abort_unless(Auth::check(), 403); - $profile = Profile::with('user')->whereNull('status')->findOrFail($id); - $owner = Auth::id() == $profile->user_id; + abort_if(!$request->user(), 403); + $account = AccountService::get($id); + abort_if(!$account, 404); + $pid = $request->user()->profile_id; - if(Auth::id() != $profile->user_id && $profile->is_private) { - return response()->json([]); - } - if(!$profile->domain && !$profile->user->settings->show_profile_followers) { - return response()->json([]); - } - if(!$owner && $request->page > 5) { - return []; - } + if($pid != $account['id']) { + if($account['locked']) { + if(FollowerService::follows($pid, $account['id'])) { + return []; + } + } - $res = Follower::select('id', 'profile_id', 'following_id') - ->whereFollowingId($profile->id) - ->orderByDesc('id') - ->simplePaginate(10) - ->map(function($follower) { - return ProfileService::get($follower['profile_id']); - }) - ->toArray(); + if(AccountService::hiddenFollowers($id)) { + return []; + } - return response()->json($res); + if($request->has('page') && $request->page >= 5) { + return []; + } + } + + $res = DB::table('followers') + ->select('id', 'profile_id', 'following_id') + ->whereFollowingId($account['id']) + ->orderByDesc('id') + ->simplePaginate(10) + ->map(function($follower) { + return AccountService::get($follower->profile_id); + }) + ->filter(function($account) { + return $account && isset($account['id']); + }) + ->values() + ->toArray(); + + return response()->json($res); } public function accountFollowing(Request $request, $id) { - abort_unless(Auth::check(), 403); + abort_if(!$request->user(), 403); + $account = AccountService::get($id); + abort_if(!$account, 404); + $pid = $request->user()->profile_id; - $profile = Profile::with('user') - ->whereNull('status') - ->findOrFail($id); + if($pid != $account['id']) { + if($account['locked']) { + if(FollowerService::follows($pid, $account['id'])) { + return []; + } + } - // filter by username - $search = $request->input('fbu'); - $owner = Auth::id() == $profile->user_id; - $filter = ($owner == true) && ($search != null); + if(AccountService::hiddenFollowing($id)) { + return []; + } - abort_if($owner == false && $profile->is_private == true && !$profile->followedBy(Auth::user()->profile), 404); + if($request->has('page') && $request->page >= 5) { + return []; + } + } - if(!$profile->domain) { - abort_if($profile->user->settings->show_profile_following == false && $owner == false, 404); - } + $res = DB::table('followers') + ->select('id', 'profile_id', 'following_id') + ->whereProfileId($account['id']) + ->orderByDesc('id') + ->simplePaginate(10) + ->map(function($follower) { + return AccountService::get($follower->following_id); + }) + ->filter(function($account) { + return $account && isset($account['id']); + }) + ->values() + ->toArray(); - if(!$owner && $request->page > 5) { - return []; - } - - if($search) { - abort_if(!$owner, 404); - $following = $profile->following() - ->where('profiles.username', 'like', '%'.$search.'%') - ->orderByDesc('followers.created_at') - ->paginate(10); - } else { - $following = $profile->following() - ->orderByDesc('followers.created_at') - ->paginate(10); - } - $resource = new Fractal\Resource\Collection($following, new AccountTransformer()); - $res = $this->fractal->createData($resource)->toArray(); - - return response()->json($res); + return response()->json($res); } public function accountStatuses(Request $request, $id) diff --git a/app/Http/Controllers/Settings/PrivacySettings.php b/app/Http/Controllers/Settings/PrivacySettings.php index 30bc4090..e4553615 100644 --- a/app/Http/Controllers/Settings/PrivacySettings.php +++ b/app/Http/Controllers/Settings/PrivacySettings.php @@ -77,6 +77,8 @@ trait PrivacySettings Cache::forget('profile:follower_count:' . $profile->id); Cache::forget('profile:following_count:' . $profile->id); Cache::forget('profile:embed:' . $profile->id); + Cache::forget('pf:acct:settings:hidden-followers:' . $profile->id); + Cache::forget('pf:acct:settings:hidden-following:' . $profile->id); return redirect(route('settings.privacy'))->with('status', 'Settings successfully updated!'); } @@ -225,4 +227,4 @@ trait PrivacySettings Cache::forget('profiles:private'); return [200]; } -} \ No newline at end of file +} diff --git a/app/Services/AccountService.php b/app/Services/AccountService.php index 62996a83..3813f70f 100644 --- a/app/Services/AccountService.php +++ b/app/Services/AccountService.php @@ -5,6 +5,7 @@ namespace App\Services; use Cache; use App\Profile; use App\Status; +use App\User; use App\UserSetting; use App\Transformer\Api\AccountTransformer; use League\Fractal; @@ -174,4 +175,44 @@ class AccountService return (string) $profile->id; }); } + + public static function hiddenFollowers($id) + { + $account = self::get($id, true); + if(!$account || !isset($account['local']) || $account['local'] == false) { + return false; + } + + return Cache::remember('pf:acct:settings:hidden-followers:' . $id, 43200, function() use($id) { + $user = User::whereProfileId($id)->first(); + if(!$user) { + return false; + } + $settings = UserSetting::whereUserId($user->id)->first(); + if($settings) { + return $settings->show_profile_follower_count == false; + } + return false; + }); + } + + public static function hiddenFollowing($id) + { + $account = self::get($id, true); + if(!$account || !isset($account['local']) || $account['local'] == false) { + return false; + } + + return Cache::remember('pf:acct:settings:hidden-following:' . $id, 43200, function() use($id) { + $user = User::whereProfileId($id)->first(); + if(!$user) { + return false; + } + $settings = UserSetting::whereUserId($user->id)->first(); + if($settings) { + return $settings->show_profile_following_count == false; + } + return false; + }); + } }