diff --git a/CHANGELOG.md b/CHANGELOG.md index 3316868d3..3361af610 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,17 @@ ### Fixed - Fixed count bug in StatusHashtagService [#1694](https://github.com/pixelfed/pixelfed/pull/1694) +- Fixed private account bug [#1699](https://github.com/pixelfed/pixelfed/pull/1699) ### Changed - Updated EmailService, added new domains [#1690](https://github.com/pixelfed/pixelfed/pull/1690) - Updated quill.js to v1.3.7 [#1692](https://github.com/pixelfed/pixelfed/pull/1692) +- Cache ProfileController [#1700](https://github.com/pixelfed/pixelfed/pull/1700) +- Updated ComposeUI v4, made cropping optional [#1702](https://github.com/pixelfed/pixelfed/pull/1702) +- Updated DiscoverController, limit Loops to local only posts [#1703](https://github.com/pixelfed/pixelfed/pull/1703) + +## Deprecated +- Remove deprecated profile following/followers [#1697](https://github.com/pixelfed/pixelfed/pull/1697) ## [v0.10.3 (2019-09-08)](https://github.com/pixelfed/pixelfed/compare/v0.10.2...v0.10.3) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php new file mode 100644 index 000000000..4bfc890cf --- /dev/null +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -0,0 +1,80 @@ +fractal = new Fractal\Manager(); + $this->fractal->setSerializer(new ArraySerializer()); + } + public function apps(Request $request) + { + abort_if(!config('pixelfed.oauth_enabled'), 404); + + $this->validate($request, [ + 'client_name' => 'required', + 'redirect_uris' => 'required', + 'scopes' => 'nullable', + 'website' => 'nullable' + ]); + + $client = Passport::client()->forceFill([ + 'user_id' => null, + 'name' => e($request->client_name), + 'secret' => Str::random(40), + 'redirect' => $request->redirect_uris, + 'personal_access_client' => false, + 'password_client' => false, + 'revoked' => false, + ]); + + $client->save(); + + $res = [ + 'id' => $client->id, + 'name' => $client->name, + 'website' => null, + 'redirect_uri' => $client->redirect, + 'client_id' => $client->id, + 'client_secret' => $client->secret, + 'vapid_key' => null + ]; + return $res; + } + + public function accountById(Request $request, $id) + { + $profile = Profile::whereNull('status')->findOrFail($id); + $resource = new Fractal\Resource\Item($profile, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + + return response()->json($res); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/DiscoverController.php b/app/Http/Controllers/DiscoverController.php index 0024d22de..77d54dbff 100644 --- a/app/Http/Controllers/DiscoverController.php +++ b/app/Http/Controllers/DiscoverController.php @@ -78,8 +78,9 @@ class DiscoverController extends Controller abort_if(!config('exp.loops'), 403); // todo proper pagination, maybe LoopService - $res = Cache::remember('discover:loops:recent', now()->addHours(1), function() { + $res = Cache::remember('discover:loops:recent', now()->addHours(6), function() { $loops = Status::whereType('video') + ->whereNull('uri') ->whereScope('public') ->latest() ->take(18) diff --git a/app/Http/Controllers/FollowerController.php b/app/Http/Controllers/FollowerController.php index bd3f4b674..dfac38ce4 100644 --- a/app/Http/Controllers/FollowerController.php +++ b/app/Http/Controllers/FollowerController.php @@ -27,7 +27,11 @@ class FollowerController extends Controller ]); $item = (int) $request->input('item'); $this->handleFollowRequest($item); - return response()->json(200); + if($request->wantsJson()) { + return response()->json(200); + } else { + return redirect()->back(); + } } protected function handleFollowRequest($item) diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index cbc120ced..59fc4f451 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -20,80 +20,93 @@ class ProfileController extends Controller { public function show(Request $request, $username) { - $user = Profile::whereUsername($username)->firstOrFail(); - if($user->domain) { - return redirect($user->remote_url); - } - if($user->status != null) { - return $this->accountCheck($user); - } else { - return $this->buildProfile($request, $user); + $user = Profile::whereNull('domain') + ->whereNull('status') + ->whereUsername($username) + ->firstOrFail(); + if($request->wantsJson() && config('federation.activitypub.enabled')) { + return $this->showActivityPub($request, $user); } + return $this->buildProfile($request, $user); } - // TODO: refactor this mess protected function buildProfile(Request $request, $user) { $username = $user->username; $loggedIn = Auth::check(); $isPrivate = false; $isBlocked = false; + if(!$loggedIn) { + $key = 'profile:settings:' . $user->id; + $ttl = now()->addHours(6); + $settings = Cache::remember($key, $ttl, function() use($user) { + return $user->user->settings; + }); - if($user->status != null) { - return ProfileController::accountCheck($user); - } + if ($user->is_private == true) { + abort(404); + } - if ($user->remote_url) { - $settings = new \StdClass; - $settings->crawlable = false; - $settings->show_profile_follower_count = true; - $settings->show_profile_following_count = true; + $owner = false; + $is_following = false; + + $is_admin = $user->user->is_admin; + $profile = $user; + $settings = [ + 'crawlable' => $settings->crawlable, + 'following' => [ + 'count' => $settings->show_profile_following_count, + 'list' => $settings->show_profile_following + ], + 'followers' => [ + 'count' => $settings->show_profile_follower_count, + 'list' => $settings->show_profile_followers + ] + ]; + return view('profile.show', compact('profile', 'settings')); } else { - $settings = $user->user->settings; - } + $key = 'profile:settings:' . $user->id; + $ttl = now()->addHours(6); + $settings = Cache::remember($key, $ttl, function() use($user) { + return $user->user->settings; + }); - if ($request->wantsJson() && config('federation.activitypub.enabled')) { - return $this->showActivityPub($request, $user); - } + if ($user->is_private == true) { + $isPrivate = $this->privateProfileCheck($user, $loggedIn); + } - if ($user->is_private == true) { - $isPrivate = $this->privateProfileCheck($user, $loggedIn); - } - - if ($loggedIn == true) { $isBlocked = $this->blockedProfileCheck($user); + + $owner = $loggedIn && Auth::id() === $user->user_id; + $is_following = ($owner == false && Auth::check()) ? $user->followedBy(Auth::user()->profile) : false; + + if ($isPrivate == true || $isBlocked == true) { + $requested = Auth::check() ? FollowRequest::whereFollowerId(Auth::user()->profile_id) + ->whereFollowingId($user->id) + ->exists() : false; + return view('profile.private', compact('user', 'is_following', 'requested')); + } + + $is_admin = is_null($user->domain) ? $user->user->is_admin : false; + $profile = $user; + $settings = [ + 'crawlable' => $settings->crawlable, + 'following' => [ + 'count' => $settings->show_profile_following_count, + 'list' => $settings->show_profile_following + ], + 'followers' => [ + 'count' => $settings->show_profile_follower_count, + 'list' => $settings->show_profile_followers + ] + ]; + return view('profile.show', compact('profile', 'settings')); } - - $owner = $loggedIn && Auth::id() === $user->user_id; - $is_following = ($owner == false && Auth::check()) ? $user->followedBy(Auth::user()->profile) : false; - - if ($isPrivate == true || $isBlocked == true) { - $requested = Auth::check() ? FollowRequest::whereFollowerId(Auth::user()->profile_id) - ->whereFollowingId($user->id) - ->exists() : false; - return view('profile.private', compact('user', 'is_following', 'requested')); - } - - $is_admin = is_null($user->domain) ? $user->user->is_admin : false; - $profile = $user; - $settings = [ - 'crawlable' => $settings->crawlable, - 'following' => [ - 'count' => $settings->show_profile_following_count, - 'list' => $settings->show_profile_following - ], - 'followers' => [ - 'count' => $settings->show_profile_follower_count, - 'list' => $settings->show_profile_followers - ] - ]; - return view('profile.show', compact('user', 'profile', 'settings', 'owner', 'is_following', 'is_admin')); } public function permalinkRedirect(Request $request, $username) { - $user = Profile::whereUsername($username)->firstOrFail(); - $settings = User::whereUsername($username)->firstOrFail()->settings; + $user = Profile::whereNull('domain')->whereUsername($username)->firstOrFail(); if ($request->wantsJson() && config('federation.activitypub.enabled')) { return $this->showActivityPub($request, $user); @@ -136,34 +149,19 @@ class ProfileController extends Controller return false; } - public static function accountCheck(Profile $profile) - { - switch ($profile->status) { - case 'disabled': - case 'suspended': - case 'delete': - return view('profile.disabled'); - break; - - default: - # code... - break; - } - - return abort(404); - } - public function showActivityPub(Request $request, $user) { abort_if(!config('federation.activitypub.enabled'), 404); - - if($user->status != null) { - return ProfileController::accountCheck($user); - } - $fractal = new Fractal\Manager(); - $resource = new Fractal\Resource\Item($user, new ProfileTransformer); - $res = $fractal->createData($resource)->toArray(); - return response(json_encode($res['data']))->header('Content-Type', 'application/activity+json'); + abort_if($user->domain, 404); + $key = 'profile:ap:' . $user->id; + $ttl = now()->addHours(6); + + return Cache::remember($key, $ttl, function() use($user) { + $fractal = new Fractal\Manager(); + $resource = new Fractal\Resource\Item($user, new ProfileTransformer); + $res = $fractal->createData($resource)->toArray(); + return response(json_encode($res['data']))->header('Content-Type', 'application/activity+json'); + }); } public function showAtomFeed(Request $request, $user) diff --git a/app/Http/Controllers/Settings/PrivacySettings.php b/app/Http/Controllers/Settings/PrivacySettings.php index 99f7d4100..754258fc7 100644 --- a/app/Http/Controllers/Settings/PrivacySettings.php +++ b/app/Http/Controllers/Settings/PrivacySettings.php @@ -29,14 +29,14 @@ trait PrivacySettings public function privacyStore(Request $request) { - $settings = Auth::user()->settings; - $profile = Auth::user()->profile; + $settings = $request->user()->settings; + $profile = $request->user()->profile; $fields = [ 'is_private', 'crawlable', 'show_profile_follower_count', 'show_profile_following_count', - ]; + ]; foreach ($fields as $field) { $form = $request->input($field); if ($field == 'is_private') { @@ -65,7 +65,7 @@ trait PrivacySettings } $settings->save(); } - + Cache::forget('profile:settings:' . $profile->id); return redirect(route('settings.privacy'))->with('status', 'Settings successfully updated!'); } diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 968c4cfa6..6f077f832 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -4,6 +4,7 @@ namespace App\Providers; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; use Laravel\Passport\Passport; +use Gate; class AuthServiceProvider extends ServiceProvider { @@ -32,14 +33,22 @@ class AuthServiceProvider extends ServiceProvider Passport::enableImplicitGrant(); Passport::setDefaultScope([ - 'user:read', - 'user:write' + 'read', + 'write', + 'follow', + 'push' ]); Passport::tokensCan([ - 'user:read' => 'Read a user’s profile info and media', - 'user:write' => 'This scope lets an app "Change your profile information"', + 'read' => 'Full read access to your account', + 'write' => 'Full write access to your account', + 'follow' => 'Ability to follow other profiles', + 'push' => '' ]); } + + Gate::define('viewWebSocketsDashboard', function ($user = null) { + return $user->is_admin; + }); } } diff --git a/public/js/compose.js b/public/js/compose.js index 81a0800d0..d582761d2 100644 Binary files a/public/js/compose.js and b/public/js/compose.js differ diff --git a/public/js/profile.js b/public/js/profile.js index 06692e5eb..852acb1df 100644 Binary files a/public/js/profile.js and b/public/js/profile.js differ diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 6f29bece3..41f96d0db 100644 Binary files a/public/mix-manifest.json and b/public/mix-manifest.json differ diff --git a/resources/assets/js/components/ComposeModal.vue b/resources/assets/js/components/ComposeModal.vue index 3d9035bf1..99c3df1b1 100644 --- a/resources/assets/js/components/ComposeModal.vue +++ b/resources/assets/js/components/ComposeModal.vue @@ -1,6 +1,6 @@