From 995d604ea012b74102970aefb532fd1802c621fa Mon Sep 17 00:00:00 2001 From: trwnh Date: Tue, 24 Sep 2019 14:33:29 -0500 Subject: [PATCH 01/93] copy activity id instead of guessing blindly see #1710 --- app/Util/ActivityPub/Inbox.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Util/ActivityPub/Inbox.php b/app/Util/ActivityPub/Inbox.php index 52205bb7d..fdd39d61b 100644 --- a/app/Util/ActivityPub/Inbox.php +++ b/app/Util/ActivityPub/Inbox.php @@ -197,7 +197,7 @@ class Inbox 'type' => 'Accept', 'actor' => $target->permalink(), 'object' => [ - 'id' => $actor->permalink('#follows/' . $follower->id), + 'id' => $this->payload['id'], 'actor' => $actor->permalink(), 'type' => 'Follow', 'object' => $target->permalink() From 782a7ccb7815db39b00962d292c0662a36b7f0a5 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 18:24:32 -0600 Subject: [PATCH 02/93] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e865b260..6991445f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### Fixed ### Changed +- Updated Inbox Accept.Follow to use id of remote object [#1715](https://github.com/pixelfed/pixelfed/pull/1715) ## [v0.10.5 (2019-09-24)](https://github.com/pixelfed/pixelfed/compare/v0.10.4...v0.10.5) From cd365ab30154521744c489430801f83dbf02eade Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 19:45:16 -0600 Subject: [PATCH 03/93] Update developer settings, fix vue bug --- resources/views/settings/applications.blade.php | 5 ----- resources/views/settings/developers.blade.php | 5 ----- 2 files changed, 10 deletions(-) diff --git a/resources/views/settings/applications.blade.php b/resources/views/settings/applications.blade.php index be40dfdf7..912b108b6 100644 --- a/resources/views/settings/applications.blade.php +++ b/resources/views/settings/applications.blade.php @@ -16,9 +16,4 @@ @push('scripts') - @endpush \ No newline at end of file diff --git a/resources/views/settings/developers.blade.php b/resources/views/settings/developers.blade.php index 14f80094e..ade660d77 100644 --- a/resources/views/settings/developers.blade.php +++ b/resources/views/settings/developers.blade.php @@ -16,9 +16,4 @@ @push('scripts') - @endpush \ No newline at end of file From 6afd69702a4bad46a273f5bfc5300e3f95ad349b Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 19:47:45 -0600 Subject: [PATCH 04/93] Add /api/v1/accounts/update_credentials endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 68 ++++++++++++++++++++ routes/web.php | 2 + 2 files changed, 70 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 3cc31514e..fbb5328ac 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -78,6 +78,56 @@ class ApiV1Controller extends Controller return response()->json($res); } + public function accountUpdateCredentials(Request, $request) + { + abort_if(!$request->user(), 403); + + $this->validate($request, [ + 'display_name' => 'nullable|string', + 'note' => 'nullable|string', + 'locked' => 'nullable|boolean', + // 'source.privacy' => 'nullable|in:unlisted,public,private', + // 'source.sensitive' => 'nullable|boolean' + ]); + + $user = $request->user(); + $profile = $user->profile; + + $displayName = $request->input('display_name'); + $note = $request->input('note'); + $locked = $request->input('locked'); + // $privacy = $request->input('source.privacy'); + // $sensitive = $request->input('source.sensitive'); + + $changes = false; + + if($displayName !== $user->name) { + $user->name = $displayName; + $profile->name = $displayName; + $changes = true; + } + + if($note !== $profile->bio) { + $profile->bio = e($note); + $changes = true; + } + + if(!is_null($locked)) { + $profile->is_private = $locked; + $changes = true; + } + + if($changes) { + $user->save(); + $profile->save() + } + + $resource = new Fractal\Resource\Item($profile, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); @@ -125,4 +175,22 @@ class ApiV1Controller extends Controller return response()->json($res); } + + public function createStatus(Request $request) + { + abort_if(!$request->user(), 403); + + $this->validate($request, [ + 'status' => 'string', + 'media_ids' => 'array', + 'media_ids.*' => 'integer|min:1', + 'sensitive' => 'nullable|boolean', + 'visibility' => 'string|in:private,unlisted,public', + 'in_reply_to_id' => 'integer' + ]); + + if(!$request->filled('media_ids') && !$request->filled('in_reply_to_id')) { + abort(403, 'Empty statuses are not allowed'); + } + } } \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 5f8d730fe..fc881e047 100644 --- a/routes/web.php +++ b/routes/web.php @@ -78,6 +78,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::group(['prefix' => 'v1'], function () { Route::get('accounts/verify_credentials', 'ApiController@verifyCredentials')->middleware('auth:api'); + Route::patch('accounts/update_credentials', 'Api\ApiV1Controller@accountUpdateCredentials')->middleware('auth:api'); Route::get('accounts/relationships', 'PublicApiController@relationships')->middleware('auth:api'); Route::get('accounts/{id}/statuses', 'PublicApiController@accountStatuses')->middleware('auth:api'); Route::get('accounts/{id}/following', 'PublicApiController@accountFollowing')->middleware('auth:api'); @@ -91,6 +92,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('notifications', 'ApiController@notifications')->middleware('auth:api'); Route::get('timelines/public', 'PublicApiController@publicTimelineApi'); Route::get('timelines/home', 'PublicApiController@homeTimelineApi')->middleware('auth:api'); + Route::post('status', 'Api\ApiV1Controller@createStatus')->middleware('auth:api'); }); Route::group(['prefix' => 'v2'], function() { Route::get('config', 'ApiController@siteConfiguration'); From 41c91cba43eec6acceb3972cd590e8ca2ee6320d Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 20:05:40 -0600 Subject: [PATCH 05/93] Add /api/v1/accounts/{id}/followers endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 37 ++++++++++++++++++++ routes/web.php | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index fbb5328ac..3f8630bee 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -34,6 +34,7 @@ class ApiV1Controller extends Controller $this->fractal = new Fractal\Manager(); $this->fractal->setSerializer(new ArraySerializer()); } + public function apps(Request $request) { abort_if(!config('pixelfed.oauth_enabled'), 404); @@ -69,6 +70,13 @@ class ApiV1Controller extends Controller return $res; } + /** + * GET /api/v1/accounts/{id} + * + * @param integer $id + * + * @return \App\Transformer\Api\AccountTransformer + */ public function accountById(Request $request, $id) { $profile = Profile::whereNull('status')->findOrFail($id); @@ -78,6 +86,11 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * PATCH /api/v1/accounts/update_credentials + * + * @return \App\Transformer\Api\AccountTransformer + */ public function accountUpdateCredentials(Request, $request) { abort_if(!$request->user(), 403); @@ -128,6 +141,30 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/accounts/{id}/followers + * + * @param integer $id + * + * @return \App\Transformer\Api\AccountTransformer + */ + public function accountFollowersById(Request $request, $id) + { + abort_if(!$request->user(), 403); + $profile = Profile::whereNull('status')->findOrFail($id); + + $settings = $profile->user->settings; + if($settings->show_profile_followers == true) { + $limit = $request->input('limit') ?? 40; + $followers = $profile->followers()->paginate($limit); + $resource = new Fractal\Resource\Collection($followers, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + } else { + $res = []; + } + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index fc881e047..d20bae191 100644 --- a/routes/web.php +++ b/routes/web.php @@ -82,7 +82,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('accounts/relationships', 'PublicApiController@relationships')->middleware('auth:api'); Route::get('accounts/{id}/statuses', 'PublicApiController@accountStatuses')->middleware('auth:api'); Route::get('accounts/{id}/following', 'PublicApiController@accountFollowing')->middleware('auth:api'); - Route::get('accounts/{id}/followers', 'PublicApiController@accountFollowers')->middleware('auth:api'); + Route::get('accounts/{id}/followers', 'Api\ApiV1Controller@accountFollowersById')->middleware('auth:api'); // Route::get('accounts/{id}', 'PublicApiController@account'); Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware('auth:api'); From 607eb51b4e44c1ce2188b80a666c343d3751329b Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 20:08:44 -0600 Subject: [PATCH 06/93] Add /api/v1/accounts/{id}/following endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 24 ++++++++++++++++++++ routes/web.php | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 3f8630bee..a1a3fc60d 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -165,6 +165,30 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/accounts/{id}/following + * + * @param integer $id + * + * @return \App\Transformer\Api\AccountTransformer + */ + public function accountFollowingById(Request $request, $id) + { + abort_if(!$request->user(), 403); + $profile = Profile::whereNull('status')->findOrFail($id); + + $settings = $profile->user->settings; + if($settings->show_profile_following == true) { + $limit = $request->input('limit') ?? 40; + $following = $profile->following()->paginate($limit); + $resource = new Fractal\Resource\Collection($following, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + } else { + $res = []; + } + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index d20bae191..1d461670a 100644 --- a/routes/web.php +++ b/routes/web.php @@ -81,7 +81,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::patch('accounts/update_credentials', 'Api\ApiV1Controller@accountUpdateCredentials')->middleware('auth:api'); Route::get('accounts/relationships', 'PublicApiController@relationships')->middleware('auth:api'); Route::get('accounts/{id}/statuses', 'PublicApiController@accountStatuses')->middleware('auth:api'); - Route::get('accounts/{id}/following', 'PublicApiController@accountFollowing')->middleware('auth:api'); + Route::get('accounts/{id}/following', 'Api\ApiV1Controller@accountFollowingById')->middleware('auth:api'); Route::get('accounts/{id}/followers', 'Api\ApiV1Controller@accountFollowersById')->middleware('auth:api'); // Route::get('accounts/{id}', 'PublicApiController@account'); Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); From 8ce6c1f2d2a7c31cc8cabcb3357542905996e1a9 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 20:35:07 -0600 Subject: [PATCH 07/93] Add /api/v1/accounts/{id}/statuses endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 80 ++++++++++++++++++++ routes/web.php | 2 +- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index a1a3fc60d..c33bacbfb 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -9,6 +9,7 @@ use App\Jobs\StatusPipeline\StatusDelete; use Laravel\Passport\Passport; use Auth, Cache, DB; use App\{ + Follower, Like, Media, Profile, @@ -189,6 +190,85 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/accounts/{id}/statuses + * + * @param integer $id + * + * @return \App\Transformer\Api\StatusTransformer + */ + public function accountStatusesById(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $this->validate($request, [ + 'only_media' => 'nullable', + 'pinned' => 'nullable', + 'exclude_replies' => 'nullable', + 'max_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, + 'since_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, + 'min_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, + 'limit' => 'nullable|integer|min:1|max:40' + ]); + + $profile = Profile::whereNull('status')->findOrFail($id); + + $limit = $request->limit ?? 20; + $max_id = $request->max_id; + $min_id = $request->min_id; + $pid = $request->user()->profile_id; + $scope = $request->only_media == true ? + ['photo', 'photo:album', 'video', 'video:album'] : + ['photo', 'photo:album', 'video', 'video:album', 'share', 'reply']; + + if($pid == $profile->id) { + $visibility = ['public', 'unlisted', 'private']; + } else if($profile->is_private) { + $following = Cache::remember('profile:following:'.$pid, now()->addMinutes(1440), function() use($pid) { + $following = Follower::whereProfileId($pid)->pluck('following_id'); + return $following->push($pid)->toArray(); + }); + $visibility = true == in_array($profile->id, $following) ? ['public', 'unlisted', 'private'] : []; + } else { + $following = Cache::remember('profile:following:'.$pid, now()->addMinutes(1440), function() use($pid) { + $following = Follower::whereProfileId($pid)->pluck('following_id'); + return $following->push($pid)->toArray(); + }); + $visibility = true == in_array($profile->id, $following) ? ['public', 'unlisted', 'private'] : ['public', 'unlisted']; + + } + + $dir = $min_id ? '>' : '<'; + $id = $min_id ?? $max_id; + $timeline = Status::select( + 'id', + 'uri', + 'caption', + 'rendered', + 'profile_id', + 'type', + 'in_reply_to_id', + 'reblog_of_id', + 'is_nsfw', + 'scope', + 'local', + 'created_at', + 'updated_at' + )->whereProfileId($profile->id) + ->whereIn('type', $scope) + ->whereLocal(true) + ->whereNull('uri') + ->where('id', $dir, $id) + ->whereIn('visibility', $visibility) + ->latest() + ->limit($limit) + ->get(); + + $resource = new Fractal\Resource\Collection($timeline, new StatusTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 1d461670a..1e5023d9d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -80,7 +80,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('accounts/verify_credentials', 'ApiController@verifyCredentials')->middleware('auth:api'); Route::patch('accounts/update_credentials', 'Api\ApiV1Controller@accountUpdateCredentials')->middleware('auth:api'); Route::get('accounts/relationships', 'PublicApiController@relationships')->middleware('auth:api'); - Route::get('accounts/{id}/statuses', 'PublicApiController@accountStatuses')->middleware('auth:api'); + Route::get('accounts/{id}/statuses', 'Api\ApiV1Controller@accountStatusesById')->middleware('auth:api'); Route::get('accounts/{id}/following', 'Api\ApiV1Controller@accountFollowingById')->middleware('auth:api'); Route::get('accounts/{id}/followers', 'Api\ApiV1Controller@accountFollowersById')->middleware('auth:api'); // Route::get('accounts/{id}', 'PublicApiController@account'); From 284cd84c85262dfb6878cab7fd83a8e8f3d4c265 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 20:39:06 -0600 Subject: [PATCH 08/93] Update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6991445f9..e328ea767 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,13 @@ ## [Unreleased](https://github.com/pixelfed/pixelfed/compare/v0.10.5...dev) ### Added +- Added ```/api/v1/accounts/update_credentials``` endpoint [6afd6970](https://github.com/pixelfed/pixelfed/commit/6afd6970) +- Added ```/api/v1/accounts/{id}/followers``` endpoint [41c91cba](https://github.com/pixelfed/pixelfed/commit/41c91cba) +- Added ```/api/v1/accounts/{id}/following``` endpoint [607eb51b](https://github.com/pixelfed/pixelfed/commit/607eb51b) +- Added ```/api/v1/accounts/{id}/statuses``` endpoint [8ce6c1f2](https://github.com/pixelfed/pixelfed/commit/8ce6c1f2) ### Fixed +- Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) ### Changed - Updated Inbox Accept.Follow to use id of remote object [#1715](https://github.com/pixelfed/pixelfed/pull/1715) From b66cf9cdc2a1b882220b6a4112942782690fb603 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 20:45:36 -0600 Subject: [PATCH 09/93] Update StatusTransformer, make spoiler_text non-nullable --- app/Transformer/Api/StatusTransformer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Transformer/Api/StatusTransformer.php b/app/Transformer/Api/StatusTransformer.php index 27f3f555f..5b251501e 100644 --- a/app/Transformer/Api/StatusTransformer.php +++ b/app/Transformer/Api/StatusTransformer.php @@ -31,7 +31,7 @@ class StatusTransformer extends Fractal\TransformerAbstract 'favourited' => $status->liked(), 'muted' => null, 'sensitive' => (bool) $status->is_nsfw, - 'spoiler_text' => $status->cw_summary, + 'spoiler_text' => $status->cw_summary ?? '', 'visibility' => $status->visibility ?? $status->scope, 'application' => [ 'name' => 'web', From 5b15f6f3b254e7c899c2af70703a881a6ba9f1d2 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 20:47:25 -0600 Subject: [PATCH 10/93] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e328ea767..78ec1daf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ### Changed - Updated Inbox Accept.Follow to use id of remote object [#1715](https://github.com/pixelfed/pixelfed/pull/1715) +- Update StatusTransformer, make spoiler_text non-nullable [b66cf9cd](https://github.com/pixelfed/pixelfed/commit/b66cf9cd) ## [v0.10.5 (2019-09-24)](https://github.com/pixelfed/pixelfed/compare/v0.10.4...v0.10.5) From 05968fa135eda9c2905dc984009a42e4b5ed4575 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 20:59:39 -0600 Subject: [PATCH 11/93] Fix typo in ApiV1Controller --- app/Http/Controllers/Api/ApiV1Controller.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index c33bacbfb..26046518c 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -92,7 +92,7 @@ class ApiV1Controller extends Controller * * @return \App\Transformer\Api\AccountTransformer */ - public function accountUpdateCredentials(Request, $request) + public function accountUpdateCredentials(Request $request) { abort_if(!$request->user(), 403); @@ -252,6 +252,7 @@ class ApiV1Controller extends Controller 'is_nsfw', 'scope', 'local', + 'place_id', 'created_at', 'updated_at' )->whereProfileId($profile->id) From bd3f95415ec662dd60242cbceda01938f720a152 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 21:01:01 -0600 Subject: [PATCH 12/93] Fix typo in ApiV1Controller --- app/Http/Controllers/Api/ApiV1Controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 26046518c..741315fe4 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -133,7 +133,7 @@ class ApiV1Controller extends Controller if($changes) { $user->save(); - $profile->save() + $profile->save(); } $resource = new Fractal\Resource\Item($profile, new AccountTransformer()); From 6237897def2b3bb6c8f0808790698ae161b42d55 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 21:20:53 -0600 Subject: [PATCH 13/93] Update FollowerController, make follow and unfollow methods public --- app/Http/Controllers/FollowerController.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/FollowerController.php b/app/Http/Controllers/FollowerController.php index 97a3700d2..b3b6b2e4a 100644 --- a/app/Http/Controllers/FollowerController.php +++ b/app/Http/Controllers/FollowerController.php @@ -109,7 +109,7 @@ class FollowerController extends Controller Cache::forget('user:account:id:'.$user->user_id); } - protected function sendFollow($user, $target) + public function sendFollow($user, $target) { if($target->domain == null || $user->domain != null) { return; @@ -117,7 +117,7 @@ class FollowerController extends Controller $payload = [ '@context' => 'https://www.w3.org/ns/activitystreams', - 'id' => $user->permalink('#follow/'.$target->id.''), + 'id' => $user->permalink('#follow/'.$target->id), 'type' => 'Follow', 'actor' => $user->permalink(), 'object' => $target->permalink() @@ -128,7 +128,7 @@ class FollowerController extends Controller Helpers::sendSignedObject($user, $inbox, $payload); } - protected function sendUndoFollow($user, $target) + public function sendUndoFollow($user, $target) { if($target->domain == null || $user->domain != null) { return; From f383902662f3b157f87d70ec05d6bbba28b2ceba Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 21:37:25 -0600 Subject: [PATCH 14/93] Add /api/v1/accounts/{id}/follow endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 163 +++++++++++++++---- routes/web.php | 1 + 2 files changed, 136 insertions(+), 28 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 741315fe4..ab3a02fe0 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -6,14 +6,17 @@ use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Illuminate\Support\Str; use App\Jobs\StatusPipeline\StatusDelete; +use App\Jobs\FollowPipeline\FollowPipeline; use Laravel\Passport\Passport; use Auth, Cache, DB; use App\{ Follower, + FollowRequest, Like, Media, Profile, - Status + Status, + UserFilter, }; use League\Fractal; use App\Transformer\Api\{ @@ -21,6 +24,7 @@ use App\Transformer\Api\{ RelationshipTransformer, StatusTransformer, }; +use App\Http\Controllers\FollowerController; use League\Fractal\Serializer\ArraySerializer; use League\Fractal\Pagination\IlluminatePaginatorAdapter; @@ -235,41 +239,144 @@ class ApiV1Controller extends Controller return $following->push($pid)->toArray(); }); $visibility = true == in_array($profile->id, $following) ? ['public', 'unlisted', 'private'] : ['public', 'unlisted']; - } - $dir = $min_id ? '>' : '<'; - $id = $min_id ?? $max_id; - $timeline = Status::select( - 'id', - 'uri', - 'caption', - 'rendered', - 'profile_id', - 'type', - 'in_reply_to_id', - 'reblog_of_id', - 'is_nsfw', - 'scope', - 'local', - 'place_id', - 'created_at', - 'updated_at' - )->whereProfileId($profile->id) - ->whereIn('type', $scope) - ->whereLocal(true) - ->whereNull('uri') - ->where('id', $dir, $id) - ->whereIn('visibility', $visibility) - ->latest() - ->limit($limit) - ->get(); + if($min_id || $max_id) { + $dir = $min_id ? '>' : '<'; + $id = $min_id ?? $max_id; + $timeline = Status::select( + 'id', + 'uri', + 'caption', + 'rendered', + 'profile_id', + 'type', + 'in_reply_to_id', + 'reblog_of_id', + 'is_nsfw', + 'scope', + 'local', + 'place_id', + 'created_at', + 'updated_at' + )->whereProfileId($profile->id) + ->whereIn('type', $scope) + ->where('id', $dir, $id) + ->whereIn('visibility', $visibility) + ->latest() + ->limit($limit) + ->get(); + } else { + $timeline = Status::select( + 'id', + 'uri', + 'caption', + 'rendered', + 'profile_id', + 'type', + 'in_reply_to_id', + 'reblog_of_id', + 'is_nsfw', + 'scope', + 'local', + 'place_id', + 'created_at', + 'updated_at' + )->whereProfileId($profile->id) + ->whereIn('type', $scope) + ->whereIn('visibility', $visibility) + ->latest() + ->limit($limit) + ->get(); + } $resource = new Fractal\Resource\Collection($timeline, new StatusTransformer()); $res = $this->fractal->createData($resource)->toArray(); return response()->json($res); } + /** + * POST /api/v1/accounts/{id}/follow + * + * @param integer $id + * + * @return \App\Transformer\Api\RelationshipTransformer + */ + public function accountFollowById(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $user = $request->user(); + + $target = Profile::where('id', '!=', $user->id) + ->whereNull('status') + ->findOrFail($item); + + $private = (bool) $target->is_private; + $remote = (bool) $target->domain; + $blocked = UserFilter::whereUserId($target->id) + ->whereFilterType('block') + ->whereFilterableId($user->id) + ->whereFilterableType('App\Profile') + ->exists(); + + if($blocked == true) { + abort(400, 'You cannot follow this user.'); + } + + $isFollowing = Follower::whereProfileId($user->id) + ->whereFollowingId($target->id) + ->exists(); + + // Following already, return empty response + if($isFollowing == true) { + return response()->json([]); + } + + // Rate limits, max 7500 followers per account + if($user->following()->count() >= Follower::MAX_FOLLOWING) { + abort(400, 'You cannot follow more than ' . Follower::MAX_FOLLOWING . ' accounts'); + } + + // Rate limits, follow 30 accounts per hour max + if($user->following()->where('followers.created_at', '>', now()->subHour())->count() >= Follower::FOLLOW_PER_HOUR) { + abort(400, 'You can only follow ' . Follower::FOLLOW_PER_HOUR . ' users per hour'); + } + + if($private == true) { + $follow = FollowRequest::firstOrCreate([ + 'follower_id' => $user->id, + 'following_id' => $target->id + ]); + if($remote == true && config('federation.activitypub.remoteFollow') == true) { + (new FollowerController())->sendFollow($user, $target); + } + } else { + $follower = new Follower(); + $follower->profile_id = $user->id; + $follower->following_id = $target->id; + $follower->save(); + + if($remote == true && config('federation.activitypub.remoteFollow') == true) { + (new FollowerController())->sendFollow($user, $target); + } + FollowPipeline::dispatch($follower); + } + + Cache::forget('profile:following:'.$target->id); + Cache::forget('profile:followers:'.$target->id); + Cache::forget('profile:following:'.$user->id); + Cache::forget('profile:followers:'.$user->id); + Cache::forget('api:local:exp:rec:'.$user->id); + Cache::forget('user:account:id:'.$target->user_id); + Cache::forget('user:account:id:'.$user->user_id); + + $resource = new Fractal\Resource\Item($target, new RelationshipTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 1e5023d9d..6b745c9a1 100644 --- a/routes/web.php +++ b/routes/web.php @@ -83,6 +83,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('accounts/{id}/statuses', 'Api\ApiV1Controller@accountStatusesById')->middleware('auth:api'); Route::get('accounts/{id}/following', 'Api\ApiV1Controller@accountFollowingById')->middleware('auth:api'); Route::get('accounts/{id}/followers', 'Api\ApiV1Controller@accountFollowersById')->middleware('auth:api'); + Route::post('accounts/{id}/follow', 'Api\ApiV1Controller@accountFollowById')->middleware('auth:api'); // Route::get('accounts/{id}', 'PublicApiController@account'); Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware('auth:api'); From c09f94b3e43f6d7ef551ef8e9f96e68df45ed011 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 21:38:33 -0600 Subject: [PATCH 15/93] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78ec1daf6..dd04895f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Added ```/api/v1/accounts/{id}/followers``` endpoint [41c91cba](https://github.com/pixelfed/pixelfed/commit/41c91cba) - Added ```/api/v1/accounts/{id}/following``` endpoint [607eb51b](https://github.com/pixelfed/pixelfed/commit/607eb51b) - Added ```/api/v1/accounts/{id}/statuses``` endpoint [8ce6c1f2](https://github.com/pixelfed/pixelfed/commit/8ce6c1f2) +- Added ```/api/v1/accounts/{id}/follow``` endpoint [f3839026](https://github.com/pixelfed/pixelfed/commit/f3839026) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) @@ -14,6 +15,7 @@ ### Changed - Updated Inbox Accept.Follow to use id of remote object [#1715](https://github.com/pixelfed/pixelfed/pull/1715) - Update StatusTransformer, make spoiler_text non-nullable [b66cf9cd](https://github.com/pixelfed/pixelfed/commit/b66cf9cd) +- Update FollowerController, make follow and unfollow methods public [6237897d](https://github.com/pixelfed/pixelfed/commit/6237897d) ## [v0.10.5 (2019-09-24)](https://github.com/pixelfed/pixelfed/compare/v0.10.4...v0.10.5) From fadc96b2d687e3988980167ffea6d96ae9ef1fe5 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 22:58:29 -0600 Subject: [PATCH 16/93] Add /api/v1/accounts/{id}/unfollow endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 69 +++++++++++++++++++- routes/web.php | 1 + 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index ab3a02fe0..916474f0e 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -328,9 +328,12 @@ class ApiV1Controller extends Controller ->whereFollowingId($target->id) ->exists(); - // Following already, return empty response + // Following already, return empty relationship if($isFollowing == true) { - return response()->json([]); + $resource = new Fractal\Resource\Item($target, new RelationshipTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + + return response()->json($res); } // Rate limits, max 7500 followers per account @@ -377,6 +380,68 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * POST /api/v1/accounts/{id}/unfollow + * + * @param integer $id + * + * @return \App\Transformer\Api\RelationshipTransformer + */ + public function accountUnfollowById(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $user = $request->user(); + + $target = Profile::where('id', '!=', $user->id) + ->whereNull('status') + ->findOrFail($item); + + $private = (bool) $target->is_private; + $remote = (bool) $target->domain; + + $isFollowing = Follower::whereProfileId($user->id) + ->whereFollowingId($target->id) + ->exists(); + + if($isFollowing == false) { + $resource = new Fractal\Resource\Item($target, new RelationshipTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + + return response()->json($res); + } + + // Rate limits, follow 30 accounts per hour max + if($user->following()->where('followers.updated_at', '>', now()->subHour())->count() >= Follower::FOLLOW_PER_HOUR) { + abort(400, 'You can only follow or unfollow ' . Follower::FOLLOW_PER_HOUR . ' users per hour'); + } + + FollowRequest::whereFollowerId($user->id) + ->whereFollowingId($target->id) + ->delete(); + + Follower::whereProfileId($user->id) + ->whereFollowingId($target->id) + ->delete(); + + if($remote == true && config('federation.activitypub.remoteFollow') == true) { + (new FollowerController())->sendUndoFollow($user, $target); + } + + Cache::forget('profile:following:'.$target->id); + Cache::forget('profile:followers:'.$target->id); + Cache::forget('profile:following:'.$user->id); + Cache::forget('profile:followers:'.$user->id); + Cache::forget('api:local:exp:rec:'.$user->id); + Cache::forget('user:account:id:'.$target->user_id); + Cache::forget('user:account:id:'.$user->user_id); + + $resource = new Fractal\Resource\Item($target, new RelationshipTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 6b745c9a1..c225f170d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -84,6 +84,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('accounts/{id}/following', 'Api\ApiV1Controller@accountFollowingById')->middleware('auth:api'); Route::get('accounts/{id}/followers', 'Api\ApiV1Controller@accountFollowersById')->middleware('auth:api'); Route::post('accounts/{id}/follow', 'Api\ApiV1Controller@accountFollowById')->middleware('auth:api'); + Route::post('accounts/{id}/unfollow', 'Api\ApiV1Controller@accountUnfollowById')->middleware('auth:api'); // Route::get('accounts/{id}', 'PublicApiController@account'); Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware('auth:api'); From 4c7fbe9a08fea65240c6bd25afd5d7628fcc3c05 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 22:59:37 -0600 Subject: [PATCH 17/93] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd04895f3..451bcefae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Added ```/api/v1/accounts/{id}/following``` endpoint [607eb51b](https://github.com/pixelfed/pixelfed/commit/607eb51b) - Added ```/api/v1/accounts/{id}/statuses``` endpoint [8ce6c1f2](https://github.com/pixelfed/pixelfed/commit/8ce6c1f2) - Added ```/api/v1/accounts/{id}/follow``` endpoint [f3839026](https://github.com/pixelfed/pixelfed/commit/f3839026) +- Added ```/api/v1/accounts/{id}/unfollow``` endpoint [fadc96b2](https://github.com/pixelfed/pixelfed/commit/fadc96b2) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) From 4b9f7d6b14acbb6a0b3853b9592449c7ae6dce8c Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 24 Sep 2019 23:26:26 -0600 Subject: [PATCH 18/93] Add /api/v1/accounts/relationships endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 26 ++++++++++++++++++++ routes/web.php | 4 +-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 916474f0e..9d5799510 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -442,6 +442,32 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/accounts/relationships + * + * @param array|integer $id + * + * @return \App\Transformer\Api\RelationshipTransformer + */ + public function accountRelationshipsById(Request $request) + { + abort_if(!$request->user(), 403); + + $this->validate($request, [ + 'id' => 'required|array|min:1|max:20', + 'id.*' => 'required|integer|min:1|max:' . PHP_INT_MAX + ]); + $pid = $request->user()->profile_id ?? $request->user()->profile->id; + $ids = collect($request->input('id')); + $filtered = $ids->filter(function($v) use($pid) { + return $v != $pid; + }); + $relations = Profile::whereNull('status')->findOrFail($filtered->values()); + $fractal = new Fractal\Resource\Collection($relations, new RelationshipTransformer()); + $res = $this->fractal->createData($fractal)->toArray(); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index c225f170d..c56f29d9c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -79,7 +79,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::group(['prefix' => 'v1'], function () { Route::get('accounts/verify_credentials', 'ApiController@verifyCredentials')->middleware('auth:api'); Route::patch('accounts/update_credentials', 'Api\ApiV1Controller@accountUpdateCredentials')->middleware('auth:api'); - Route::get('accounts/relationships', 'PublicApiController@relationships')->middleware('auth:api'); + Route::get('accounts/relationships', 'Api\ApiV1Controller@accountRelationshipsById')->middleware('auth:api'); Route::get('accounts/{id}/statuses', 'Api\ApiV1Controller@accountStatusesById')->middleware('auth:api'); Route::get('accounts/{id}/following', 'Api\ApiV1Controller@accountFollowingById')->middleware('auth:api'); Route::get('accounts/{id}/followers', 'Api\ApiV1Controller@accountFollowersById')->middleware('auth:api'); @@ -115,7 +115,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::group(['prefix' => 'pixelfed'], function() { Route::group(['prefix' => 'v1'], function() { Route::get('accounts/verify_credentials', 'ApiController@verifyCredentials'); - Route::get('accounts/relationships', 'PublicApiController@relationships'); + Route::get('accounts/relationships', 'Api\ApiV1Controller@accountRelationshipsById'); Route::get('accounts/{id}/statuses', 'PublicApiController@accountStatuses'); Route::get('accounts/{id}/following', 'PublicApiController@accountFollowing'); Route::get('accounts/{id}/followers', 'PublicApiController@accountFollowers'); From b1fccf6d821a65cd754f39ee87d100296e7cdd2e Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 00:07:05 -0600 Subject: [PATCH 19/93] Add /api/v1/accounts/search endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 35 ++++++++++++++++++++ routes/web.php | 2 ++ 2 files changed, 37 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 9d5799510..545b5d0b1 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Illuminate\Support\Str; +use App\Util\ActivityPub\Helpers; use App\Jobs\StatusPipeline\StatusDelete; use App\Jobs\FollowPipeline\FollowPipeline; use Laravel\Passport\Passport; @@ -468,6 +469,40 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/accounts/search + * + * + * + * @return \App\Transformer\Api\AccountTransformer + */ + public function accountSearch(Request $request) + { + abort_if(!$request->user(), 403); + + $this->validate($request, [ + 'q' => 'required|string|min:1|max:255', + 'limit' => 'nullable|integer|min:1|max:40', + 'resolve' => 'nullable' + ]); + + $user = $request->user(); + $query = $request->input('q'); + $limit = $request->input('limit') ?? 20; + $resolve = (bool) $request->input('resolve', false); + $q = '%' . $query . '%'; + + $profiles = Profile::whereNull('status') + ->where('username', 'like', $q) + ->orWhere('name', 'like', $q) + ->limit($limit) + ->get(); + + $resource = new Fractal\Resource\Collection($profiles, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res, 200, [], JSON_PRETTY_PRINT); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index c56f29d9c..c162c5ffe 100644 --- a/routes/web.php +++ b/routes/web.php @@ -80,6 +80,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('accounts/verify_credentials', 'ApiController@verifyCredentials')->middleware('auth:api'); Route::patch('accounts/update_credentials', 'Api\ApiV1Controller@accountUpdateCredentials')->middleware('auth:api'); Route::get('accounts/relationships', 'Api\ApiV1Controller@accountRelationshipsById')->middleware('auth:api'); + Route::get('accounts/search', 'Api\ApiV1Controller@accountSearch')->middleware('auth:api'); Route::get('accounts/{id}/statuses', 'Api\ApiV1Controller@accountStatusesById')->middleware('auth:api'); Route::get('accounts/{id}/following', 'Api\ApiV1Controller@accountFollowingById')->middleware('auth:api'); Route::get('accounts/{id}/followers', 'Api\ApiV1Controller@accountFollowersById')->middleware('auth:api'); @@ -116,6 +117,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::group(['prefix' => 'v1'], function() { Route::get('accounts/verify_credentials', 'ApiController@verifyCredentials'); Route::get('accounts/relationships', 'Api\ApiV1Controller@accountRelationshipsById'); + Route::get('accounts/search', 'Api\ApiV1Controller@accountSearch'); Route::get('accounts/{id}/statuses', 'PublicApiController@accountStatuses'); Route::get('accounts/{id}/following', 'PublicApiController@accountFollowing'); Route::get('accounts/{id}/followers', 'PublicApiController@accountFollowers'); From 7f6b4817343f87810d304dc2fc5f9fa3424df57a Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 00:08:01 -0600 Subject: [PATCH 20/93] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 451bcefae..9e9021407 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ - Added ```/api/v1/accounts/{id}/statuses``` endpoint [8ce6c1f2](https://github.com/pixelfed/pixelfed/commit/8ce6c1f2) - Added ```/api/v1/accounts/{id}/follow``` endpoint [f3839026](https://github.com/pixelfed/pixelfed/commit/f3839026) - Added ```/api/v1/accounts/{id}/unfollow``` endpoint [fadc96b2](https://github.com/pixelfed/pixelfed/commit/fadc96b2) +- Added ```/api/v1/accounts/relationships``` endpoint [4b9f7d6b](https://github.com/pixelfed/pixelfed/commit/4b9f7d6b) +- Added ```/api/v1/accounts/search``` endpoint [b1fccf6d](https://github.com/pixelfed/pixelfed/commit/b1fccf6d) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) From 5a0c295ed1e0ee4c4808974bea24710f27fad60e Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 00:24:13 -0600 Subject: [PATCH 21/93] Update User model, fix filter relationship --- app/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/User.php b/app/User.php index 896ad12d6..72963400f 100644 --- a/app/User.php +++ b/app/User.php @@ -65,7 +65,7 @@ class User extends Authenticatable public function filters() { - return $this->hasMany(UserFilter::class); + return $this->hasMany(UserFilter::class, 'user_id', 'profile_id'); } public function receivesBroadcastNotificationsOn() From ac9f1bc04e942fbeaffdc52bfe981d675af54cb6 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 00:46:06 -0600 Subject: [PATCH 22/93] Add /api/v1/blocks endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 34 +++++++++++++++++++- routes/web.php | 2 ++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 545b5d0b1..1debc4ecd 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -500,7 +500,39 @@ class ApiV1Controller extends Controller $resource = new Fractal\Resource\Collection($profiles, new AccountTransformer()); $res = $this->fractal->createData($resource)->toArray(); - return response()->json($res, 200, [], JSON_PRETTY_PRINT); + return response()->json($res); + } + + /** + * GET /api/v1/blocks + * + * + * + * @return \App\Transformer\Api\AccountTransformer + */ + public function accountBlocks(Request $request) + { + abort_if(!$request->user(), 403); + + $this->validate($request, [ + 'limit' => 'nullable|integer|min:1|max:40', + 'page' => 'nullable|integer|min:1|max:10' + ]); + + $user = $request->user(); + $limit = $request->input('limit') ?? 40; + + $blocked = UserFilter::select('filterable_id','filterable_type','filter_type','user_id') + ->whereUserId($user->profile_id) + ->whereFilterableType('App\Profile') + ->whereFilterType('block') + ->simplePaginate($limit) + ->pluck('filterable_id'); + + $profiles = Profile::findOrFail($blocked); + $resource = new Fractal\Resource\Collection($profiles, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); } public function statusById(Request $request, $id) diff --git a/routes/web.php b/routes/web.php index c162c5ffe..ad649abed 100644 --- a/routes/web.php +++ b/routes/web.php @@ -86,6 +86,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('accounts/{id}/followers', 'Api\ApiV1Controller@accountFollowersById')->middleware('auth:api'); Route::post('accounts/{id}/follow', 'Api\ApiV1Controller@accountFollowById')->middleware('auth:api'); Route::post('accounts/{id}/unfollow', 'Api\ApiV1Controller@accountUnfollowById')->middleware('auth:api'); + Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware('auth:api'); // Route::get('accounts/{id}', 'PublicApiController@account'); Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware('auth:api'); @@ -123,6 +124,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('accounts/{id}/followers', 'PublicApiController@accountFollowers'); Route::get('accounts/{id}', 'PublicApiController@account'); Route::post('avatar/update', 'ApiController@avatarUpdate'); + Route::get('blocks', 'Api\ApiV1Controller@accountBlocks'); Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia'); Route::delete('media', 'ApiController@deleteMedia'); From c6b1ed97f99bff53a3616b91e3796e3aac02d9fe Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 01:02:28 -0600 Subject: [PATCH 23/93] Add /api/v1/accounts/{id}/block endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 40 ++++++++++++++++++++ routes/web.php | 1 + 2 files changed, 41 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 1debc4ecd..446993324 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -535,6 +535,46 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * POST /api/v1/accounts/{id}/block + * + * @param integer $id + * + * @return \App\Transformer\Api\RelationshipTransformer + */ + public function accountBlockById(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $user = $request->user(); + $pid = $user->profile_id ?? $user->profile->id; + + if($id == $pid) { + abort(400, 'You cannot block yourself'); + } + + $profile = Profile::findOrFail($id); + + Follower::whereProfileId($profile->id)->whereFollowingId($pid)->delete(); + Follower::whereProfileId($pid)->whereFollowingId($profile->id)->delete(); + Notification::whereProfileId($pid)->whereActorId($profile->id)->delete(); + + $filter = UserFilter::firstOrCreate([ + 'user_id' => $pid, + 'filterable_id' => $profile->id, + 'filterable_type' => 'App\Profile', + 'filter_type' => 'block', + ]); + + Cache::forget("user:filter:list:$pid"); + Cache::forget("api:local:exp:rec:$pid"); + + $resource = new Fractal\Resource\Item($profile, new RelationshipTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index ad649abed..62b160c3f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -87,6 +87,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('accounts/{id}/follow', 'Api\ApiV1Controller@accountFollowById')->middleware('auth:api'); Route::post('accounts/{id}/unfollow', 'Api\ApiV1Controller@accountUnfollowById')->middleware('auth:api'); Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware('auth:api'); + Route::post('accounts/{id}/block', 'Api\ApiV1Controller@accountBlockById')->middleware('auth:api'); // Route::get('accounts/{id}', 'PublicApiController@account'); Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware('auth:api'); From f4952e2ef794d02ff2ee76d38fc5030b265f3b38 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 01:04:13 -0600 Subject: [PATCH 24/93] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e9021407..a6f7aa13c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,11 @@ - Added ```/api/v1/accounts/{id}/unfollow``` endpoint [fadc96b2](https://github.com/pixelfed/pixelfed/commit/fadc96b2) - Added ```/api/v1/accounts/relationships``` endpoint [4b9f7d6b](https://github.com/pixelfed/pixelfed/commit/4b9f7d6b) - Added ```/api/v1/accounts/search``` endpoint [b1fccf6d](https://github.com/pixelfed/pixelfed/commit/b1fccf6d) +- Added ```/api/v1/blocks``` endpoint [ac9f1bc0](https://github.com/pixelfed/pixelfed/commit/ac9f1bc0) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) +- Update User model, fix filter relationship [5a0c295e](https://github.com/pixelfed/pixelfed/commit/5a0c295e) ### Changed - Updated Inbox Accept.Follow to use id of remote object [#1715](https://github.com/pixelfed/pixelfed/pull/1715) From 35226c99e293036d930f9ab8e7cc0b9bd3275705 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 01:10:01 -0600 Subject: [PATCH 25/93] Add /api/v1/accounts/{id}/unblock endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 36 ++++++++++++++++++++ routes/web.php | 1 + 2 files changed, 37 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 446993324..e6577d388 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -15,6 +15,7 @@ use App\{ FollowRequest, Like, Media, + Notification, Profile, Status, UserFilter, @@ -575,6 +576,41 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * POST /api/v1/accounts/{id}/unblock + * + * @param integer $id + * + * @return \App\Transformer\Api\RelationshipTransformer + */ + public function accountUnblockById(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $user = $request->user(); + $pid = $user->profile_id ?? $user->profile->id; + + if($id == $pid) { + abort(400, 'You cannot unblock yourself'); + } + + $profile = Profile::findOrFail($id); + + UserFilter::whereUserId($pid) + ->whereFilterableId($profile->id) + ->whereFilterableType('App\Profile') + ->whereFilterType('block') + ->delete(); + + Cache::forget("user:filter:list:$pid"); + Cache::forget("api:local:exp:rec:$pid"); + + $resource = new Fractal\Resource\Item($profile, new RelationshipTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 62b160c3f..368d43ab7 100644 --- a/routes/web.php +++ b/routes/web.php @@ -88,6 +88,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('accounts/{id}/unfollow', 'Api\ApiV1Controller@accountUnfollowById')->middleware('auth:api'); Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware('auth:api'); Route::post('accounts/{id}/block', 'Api\ApiV1Controller@accountBlockById')->middleware('auth:api'); + Route::post('accounts/{id}/unblock', 'Api\ApiV1Controller@accountUnblockById')->middleware('auth:api'); // Route::get('accounts/{id}', 'PublicApiController@account'); Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware('auth:api'); From 831b90d097a8ffacad9b18012c074ce15181b6ef Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 01:10:42 -0600 Subject: [PATCH 26/93] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6f7aa13c..4cd1075ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ - Added ```/api/v1/accounts/relationships``` endpoint [4b9f7d6b](https://github.com/pixelfed/pixelfed/commit/4b9f7d6b) - Added ```/api/v1/accounts/search``` endpoint [b1fccf6d](https://github.com/pixelfed/pixelfed/commit/b1fccf6d) - Added ```/api/v1/blocks``` endpoint [ac9f1bc0](https://github.com/pixelfed/pixelfed/commit/ac9f1bc0) +- Added ```/api/v1/accounts/{id}/block``` endpoint [c6b1ed97](https://github.com/pixelfed/pixelfed/commit/c6b1ed97) +- Added ```/api/v1/accounts/{id}/unblock``` endpoint [35226c99](https://github.com/pixelfed/pixelfed/commit/35226c99) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) From 6e43431a67cedd27ecd64d452cc7f2455b33c39f Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 01:17:25 -0600 Subject: [PATCH 27/93] Add /api/v1/custom_emojis endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 12 ++++++++++++ routes/web.php | 7 +++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index e6577d388..232f06e8d 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -611,6 +611,18 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/custom_emojis + * + * Return empty array, we don't support custom emoji + * + * @return array + */ + public function customEmojis() + { + return response()->json([]); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 368d43ab7..4a5c73d4d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -86,12 +86,13 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('accounts/{id}/followers', 'Api\ApiV1Controller@accountFollowersById')->middleware('auth:api'); Route::post('accounts/{id}/follow', 'Api\ApiV1Controller@accountFollowById')->middleware('auth:api'); Route::post('accounts/{id}/unfollow', 'Api\ApiV1Controller@accountUnfollowById')->middleware('auth:api'); - Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware('auth:api'); Route::post('accounts/{id}/block', 'Api\ApiV1Controller@accountBlockById')->middleware('auth:api'); Route::post('accounts/{id}/unblock', 'Api\ApiV1Controller@accountUnblockById')->middleware('auth:api'); // Route::get('accounts/{id}', 'PublicApiController@account'); Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware('auth:api'); + Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware('auth:api'); + Route::get('custom_emojis', 'Api\ApiV1Controller@customEmojis'); Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); Route::delete('media', 'ApiController@deleteMedia')->middleware('auth:api'); @@ -124,9 +125,11 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('accounts/{id}/statuses', 'PublicApiController@accountStatuses'); Route::get('accounts/{id}/following', 'PublicApiController@accountFollowing'); Route::get('accounts/{id}/followers', 'PublicApiController@accountFollowers'); + Route::post('accounts/{id}/block', 'Api\ApiV1Controller@accountBlockById'); + Route::post('accounts/{id}/unblock', 'Api\ApiV1Controller@accountUnblockById'); Route::get('accounts/{id}', 'PublicApiController@account'); Route::post('avatar/update', 'ApiController@avatarUpdate'); - Route::get('blocks', 'Api\ApiV1Controller@accountBlocks'); + Route::get('custom_emojis', 'Api\ApiV1Controller@customEmojis'); Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia'); Route::delete('media', 'ApiController@deleteMedia'); From bf14743ebd33808b42b7d5304353c11e58376668 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 01:18:37 -0600 Subject: [PATCH 28/93] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cd1075ff..32870be94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Added ```/api/v1/blocks``` endpoint [ac9f1bc0](https://github.com/pixelfed/pixelfed/commit/ac9f1bc0) - Added ```/api/v1/accounts/{id}/block``` endpoint [c6b1ed97](https://github.com/pixelfed/pixelfed/commit/c6b1ed97) - Added ```/api/v1/accounts/{id}/unblock``` endpoint [35226c99](https://github.com/pixelfed/pixelfed/commit/35226c99) +- Added ```/api/v1/custom_emojis``` endpoint [6e43431a](https://github.com/pixelfed/pixelfed/commit/6e43431a) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) From 83a6313f090e089f70ba63c357df83af1c3a8776 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 02:21:36 -0600 Subject: [PATCH 29/93] Add /api/v1/domain_blocks endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 14 ++++++++++++++ routes/web.php | 3 +++ 2 files changed, 17 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 232f06e8d..88853a4e3 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -623,6 +623,20 @@ class ApiV1Controller extends Controller return response()->json([]); } + + /** + * GET /api/v1/domain_blocks + * + * Return empty array + * + * @return array + */ + public function accountDomainBlocks(Request $request) + { + abort_if(!$request->user(), 403); + return response()->json([]); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 4a5c73d4d..d3e5fdbcc 100644 --- a/routes/web.php +++ b/routes/web.php @@ -91,6 +91,9 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact // Route::get('accounts/{id}', 'PublicApiController@account'); Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware('auth:api'); + Route::get('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware('auth:api'); + Route::post('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware('auth:api'); + Route::delete('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware('auth:api'); Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware('auth:api'); Route::get('custom_emojis', 'Api\ApiV1Controller@customEmojis'); Route::get('likes', 'ApiController@hydrateLikes'); From 9f8661e33ec3414f784fc7758b8169c216946149 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 02:23:05 -0600 Subject: [PATCH 30/93] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32870be94..ad7e5fd1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Added ```/api/v1/accounts/{id}/block``` endpoint [c6b1ed97](https://github.com/pixelfed/pixelfed/commit/c6b1ed97) - Added ```/api/v1/accounts/{id}/unblock``` endpoint [35226c99](https://github.com/pixelfed/pixelfed/commit/35226c99) - Added ```/api/v1/custom_emojis``` endpoint [6e43431a](https://github.com/pixelfed/pixelfed/commit/6e43431a) +- Added ```/api/v1/domain_blocks``` endpoint [83a6313f](https://github.com/pixelfed/pixelfed/commit/83a6313f) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) From 1f16221eb26828dd011187f31171653a75be543b Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 02:29:52 -0600 Subject: [PATCH 31/93] Add /api/v1/endorsements endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 14 +++++++++++++- routes/web.php | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 88853a4e3..7254df1ed 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -623,7 +623,6 @@ class ApiV1Controller extends Controller return response()->json([]); } - /** * GET /api/v1/domain_blocks * @@ -637,6 +636,19 @@ class ApiV1Controller extends Controller return response()->json([]); } + /** + * GET /api/v1/endorsements + * + * Return empty array + * + * @return array + */ + public function accountEndorsements(Request $request) + { + abort_if(!$request->user(), 403); + return response()->json([]); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index d3e5fdbcc..0e4706b3a 100644 --- a/routes/web.php +++ b/routes/web.php @@ -88,12 +88,15 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('accounts/{id}/unfollow', 'Api\ApiV1Controller@accountUnfollowById')->middleware('auth:api'); Route::post('accounts/{id}/block', 'Api\ApiV1Controller@accountBlockById')->middleware('auth:api'); Route::post('accounts/{id}/unblock', 'Api\ApiV1Controller@accountUnblockById')->middleware('auth:api'); + Route::post('accounts/{id}/pin', 'Api\ApiV1Controller@accountEndorsements')->middleware('auth:api'); + Route::post('accounts/{id}/unpin', 'Api\ApiV1Controller@accountEndorsements')->middleware('auth:api'); // Route::get('accounts/{id}', 'PublicApiController@account'); Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware('auth:api'); Route::get('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware('auth:api'); Route::post('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware('auth:api'); Route::delete('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware('auth:api'); + Route::get('endorsements', 'Api\ApiV1Controller@accountEndorsements')->middleware('auth:api'); Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware('auth:api'); Route::get('custom_emojis', 'Api\ApiV1Controller@customEmojis'); Route::get('likes', 'ApiController@hydrateLikes'); From fa4e291ad955f7b57ae013599409e914e84847ce Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 02:31:35 -0600 Subject: [PATCH 32/93] Update changelong --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad7e5fd1e..63fe49d1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Added ```/api/v1/accounts/{id}/unblock``` endpoint [35226c99](https://github.com/pixelfed/pixelfed/commit/35226c99) - Added ```/api/v1/custom_emojis``` endpoint [6e43431a](https://github.com/pixelfed/pixelfed/commit/6e43431a) - Added ```/api/v1/domain_blocks``` endpoint [83a6313f](https://github.com/pixelfed/pixelfed/commit/83a6313f) +- Added ```/api/v1/endorsements``` endpoint [1f16221e](https://github.com/pixelfed/pixelfed/commit/1f16221e) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) From b9cc06daa5a9910c1dc42de4bb48265d0ab26572 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 13:46:47 -0600 Subject: [PATCH 33/93] Add /api/v1/favourites endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 25 ++++++++++++++++++++ routes/web.php | 1 + 2 files changed, 26 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 7254df1ed..3f9f66bd7 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -649,6 +649,31 @@ class ApiV1Controller extends Controller return response()->json([]); } + /** + * GET /api/v1/favourites + * + * Return empty array + * + * @return array + */ + public function accountFavourites(Request $request) + { + abort_if(!$request->user(), 403); + + $user = $request->user(); + + $limit = $request->input('limit') ?? 20; + $favourites = Like::whereProfileId($user->profile_id) + ->latest() + ->simplePaginate($limit) + ->pluck('status_id'); + + $statuses = Status::findOrFail($favourites); + $resource = new Fractal\Resource\Collection($statuses, new StatusTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 0e4706b3a..fb0866c42 100644 --- a/routes/web.php +++ b/routes/web.php @@ -99,6 +99,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('endorsements', 'Api\ApiV1Controller@accountEndorsements')->middleware('auth:api'); Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware('auth:api'); Route::get('custom_emojis', 'Api\ApiV1Controller@customEmojis'); + Route::get('favourites', 'Api\ApiV1Controller@accountFavourites')->middleware('auth:api'); Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); Route::delete('media', 'ApiController@deleteMedia')->middleware('auth:api'); From 969e2f02965cc115f29f922c8de9c2504c5b4f3d Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 13:47:29 -0600 Subject: [PATCH 34/93] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63fe49d1d..bd9d820d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - Added ```/api/v1/custom_emojis``` endpoint [6e43431a](https://github.com/pixelfed/pixelfed/commit/6e43431a) - Added ```/api/v1/domain_blocks``` endpoint [83a6313f](https://github.com/pixelfed/pixelfed/commit/83a6313f) - Added ```/api/v1/endorsements``` endpoint [1f16221e](https://github.com/pixelfed/pixelfed/commit/1f16221e) +- Added ```/api/v1/favourites``` endpoint [b9cc06da](https://github.com/pixelfed/pixelfed/commit/b9cc06da) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) From 4edeba17baf6090cb41eca881a6fe872071a0fb0 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 21:06:43 -0600 Subject: [PATCH 35/93] Add /api/v1/statuses/{id}/favourite endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 34 ++++++++++++++++++-- routes/web.php | 2 ++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 3f9f66bd7..615493be0 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -6,6 +6,7 @@ use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Illuminate\Support\Str; use App\Util\ActivityPub\Helpers; +use App\Jobs\LikePipeline\LikePipeline; use App\Jobs\StatusPipeline\StatusDelete; use App\Jobs\FollowPipeline\FollowPipeline; use Laravel\Passport\Passport; @@ -652,9 +653,9 @@ class ApiV1Controller extends Controller /** * GET /api/v1/favourites * - * Return empty array + * Returns collection of liked statuses * - * @return array + * @return \App\Transformer\Api\StatusTransformer */ public function accountFavourites(Request $request) { @@ -674,6 +675,35 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * POST /api/v1/statuses/{id}/favourite + * + * @param integer $id + * + * @return \App\Transformer\Api\StatusTransformer + */ + public function statusFavouriteById(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $user = $request->user(); + + $status = Status::findOrFail($id); + + $like = Like::firstOrCreate([ + 'profile_id' => $user->profile_id, + 'status_id' => $status->id + ]); + + if($like->wasRecentlyCreated == true) { + LikePipeline::dispatch($like); + } + + $resource = new Fractal\Resource\Item($status, new StatusTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index fb0866c42..cfd4bb28f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -100,6 +100,8 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware('auth:api'); Route::get('custom_emojis', 'Api\ApiV1Controller@customEmojis'); Route::get('favourites', 'Api\ApiV1Controller@accountFavourites')->middleware('auth:api'); + Route::post('statuses/{id}/favourite', 'Api\ApiV1Controller@statusFavouriteById')->middleware('auth:api'); + Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); Route::delete('media', 'ApiController@deleteMedia')->middleware('auth:api'); From 437e18e3add79fff177c08cb9e317fc1cb135bd0 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 21:10:17 -0600 Subject: [PATCH 36/93] Add /api/v1/statuses/{id}/unfavourite endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 28 ++++++++++++++++++++ routes/web.php | 1 + 2 files changed, 29 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 615493be0..6eec4973b 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -704,6 +704,34 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * POST /api/v1/statuses/{id}/unfavourite + * + * @param integer $id + * + * @return \App\Transformer\Api\StatusTransformer + */ + public function statusUnfavouriteById(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $user = $request->user(); + + $status = Status::findOrFail($id); + + $like = Like::whereProfileId($user->profile_id) + ->whereStatusId($status->id) + ->first(); + + if($like) { + $like->delete(); + } + + $resource = new Fractal\Resource\Item($status, new StatusTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index cfd4bb28f..00e702611 100644 --- a/routes/web.php +++ b/routes/web.php @@ -101,6 +101,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('custom_emojis', 'Api\ApiV1Controller@customEmojis'); Route::get('favourites', 'Api\ApiV1Controller@accountFavourites')->middleware('auth:api'); Route::post('statuses/{id}/favourite', 'Api\ApiV1Controller@statusFavouriteById')->middleware('auth:api'); + Route::post('statuses/{id}/unfavourite', 'Api\ApiV1Controller@statusUnfavouriteById')->middleware('auth:api'); Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From d7170ca4b20bae7ad1966e2a21cf19e1dc06266e Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 21:10:43 -0600 Subject: [PATCH 37/93] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd9d820d3..db8b303ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ - Added ```/api/v1/domain_blocks``` endpoint [83a6313f](https://github.com/pixelfed/pixelfed/commit/83a6313f) - Added ```/api/v1/endorsements``` endpoint [1f16221e](https://github.com/pixelfed/pixelfed/commit/1f16221e) - Added ```/api/v1/favourites``` endpoint [b9cc06da](https://github.com/pixelfed/pixelfed/commit/b9cc06da) +- Added ```/api/v1/statuses/{id}/favourite``` endpoint [4edeba17](https://github.com/pixelfed/pixelfed/commit/4edeba17) +- Added ```/api/v1/statuses/{id}/unfavourite``` endpoint [437e18e3](https://github.com/pixelfed/pixelfed/commit/437e18e3) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) From b3d82edd0f99e29bd056c7c577de2b8a6122433b Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 21:28:30 -0600 Subject: [PATCH 38/93] Add /api/v1/filters endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 20 ++++++++++++++------ routes/api.php | 1 - routes/web.php | 1 + 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 6eec4973b..b0b6fb3d9 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -732,6 +732,20 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/filters + * + * Return empty response since we filter server side + * + * @return array + */ + public function accountFilters(Request $request) + { + abort_if(!$request->user(), 403); + + return response()->json([]); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); @@ -763,12 +777,6 @@ class ApiV1Controller extends Controller return response()->json($res, 200, [], JSON_PRETTY_PRINT); } - public function filters(Request $request) - { - // Pixelfed does not yet support keyword filters - return response()->json([]); - } - public function context(Request $request) { // todo diff --git a/routes/api.php b/routes/api.php index 65380a01a..da92e3bbe 100644 --- a/routes/api.php +++ b/routes/api.php @@ -9,7 +9,6 @@ Route::group(['prefix' => 'api'], function() { Route::group(['prefix' => 'v1'], function() { Route::post('apps', 'Api\ApiV1Controller@apps'); Route::get('instance', 'Api\ApiV1Controller@instance'); - Route::get('filters', 'Api\ApiV1Controller@filters'); Route::get('statuses/{id}', 'Api\ApiV1Controller@statusById'); Route::get('statuses/{id}/context', 'Api\ApiV1Controller@context'); }); diff --git a/routes/web.php b/routes/web.php index 00e702611..bc1bfdaa8 100644 --- a/routes/web.php +++ b/routes/web.php @@ -102,6 +102,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('favourites', 'Api\ApiV1Controller@accountFavourites')->middleware('auth:api'); Route::post('statuses/{id}/favourite', 'Api\ApiV1Controller@statusFavouriteById')->middleware('auth:api'); Route::post('statuses/{id}/unfavourite', 'Api\ApiV1Controller@statusUnfavouriteById')->middleware('auth:api'); + Route::get('filters', 'Api\ApiV1Controller@accountFilters')->middleware('auth:api'); Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From 9726913622598ce43299c7fc51e7ef5ba02fd0fb Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 21:51:51 -0600 Subject: [PATCH 39/93] Add /api/v1/follow_requests endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 22 ++++++++++++++++++++ routes/web.php | 1 + 2 files changed, 23 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index b0b6fb3d9..62f6793a3 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -746,6 +746,28 @@ class ApiV1Controller extends Controller return response()->json([]); } + /** + * GET /api/v1/follow_requests + * + * Return array of Accounts that have sent follow requests + * + * @return \App\Transformer\Api\AccountTransformer + */ + public function accountFollowRequests(Request $request) + { + abort_if(!$request->user(), 403); + + $user = $request->user(); + + $followRequests = FollowRequest::whereFollowingId($user->profile->id)->pluck('follower_id'); + + $profiles = Profile::find($followRequests); + + $resource = new Fractal\Resource\Collection($profiles, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index bc1bfdaa8..0b020f6ee 100644 --- a/routes/web.php +++ b/routes/web.php @@ -103,6 +103,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('statuses/{id}/favourite', 'Api\ApiV1Controller@statusFavouriteById')->middleware('auth:api'); Route::post('statuses/{id}/unfavourite', 'Api\ApiV1Controller@statusUnfavouriteById')->middleware('auth:api'); Route::get('filters', 'Api\ApiV1Controller@accountFilters')->middleware('auth:api'); + Route::get('follow_requests', 'Api\ApiV1Controller@accountFollowRequests')->middleware('auth:api'); Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From 7bdd9b2a14ebda0a754ade6cecc94956778015f7 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 21:56:56 -0600 Subject: [PATCH 40/93] Add /api/v1/follow_requests/{id}/authorize endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 16 ++++++++++++++++ routes/web.php | 1 + 2 files changed, 17 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 62f6793a3..966c5fcac 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -768,6 +768,22 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * POST /api/v1/follow_requests/{id}/authorize + * + * @param integer $id + * + * @return null + */ + public function accountFollowRequestAccept(Request $request, $id) + { + abort_if(!$request->user(), 403); + + // todo + + return response()->json([]); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 0b020f6ee..08dc9c6c5 100644 --- a/routes/web.php +++ b/routes/web.php @@ -104,6 +104,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('statuses/{id}/unfavourite', 'Api\ApiV1Controller@statusUnfavouriteById')->middleware('auth:api'); Route::get('filters', 'Api\ApiV1Controller@accountFilters')->middleware('auth:api'); Route::get('follow_requests', 'Api\ApiV1Controller@accountFollowRequests')->middleware('auth:api'); + Route::post('follow_requests/{id}/authorize', 'Api\ApiV1Controller@accountFollowRequestAccept')->middleware('auth:api'); Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From 62aa922aeda1fe9ca6a039fcb20e8d03e7ee1817 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 21:59:17 -0600 Subject: [PATCH 41/93] Add /api/v1/follow_requests/{id}/reject endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 16 ++++++++++++++++ routes/web.php | 1 + 2 files changed, 17 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 966c5fcac..33ada2d93 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -784,6 +784,22 @@ class ApiV1Controller extends Controller return response()->json([]); } + /** + * POST /api/v1/follow_requests/{id}/reject + * + * @param integer $id + * + * @return null + */ + public function accountFollowRequestReject(Request $request, $id) + { + abort_if(!$request->user(), 403); + + // todo + + return response()->json([]); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 08dc9c6c5..3623c031a 100644 --- a/routes/web.php +++ b/routes/web.php @@ -105,6 +105,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('filters', 'Api\ApiV1Controller@accountFilters')->middleware('auth:api'); Route::get('follow_requests', 'Api\ApiV1Controller@accountFollowRequests')->middleware('auth:api'); Route::post('follow_requests/{id}/authorize', 'Api\ApiV1Controller@accountFollowRequestAccept')->middleware('auth:api'); + Route::post('follow_requests/{id}/reject', 'Api\ApiV1Controller@accountFollowRequestReject')->middleware('auth:api'); Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From e52aeeedad161022e0d2e5ccb2c89d30968f1e49 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 22:04:02 -0600 Subject: [PATCH 42/93] Add /api/v1/suggestions endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 16 ++++++++++++++++ routes/web.php | 1 + 2 files changed, 17 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 33ada2d93..35cd204c2 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -800,6 +800,22 @@ class ApiV1Controller extends Controller return response()->json([]); } + /** + * GET /api/v1/suggestions + * + * Return empty array as we don't support suggestions + * + * @return null + */ + public function accountSuggestions(Request $request) + { + abort_if(!$request->user(), 403); + + // todo + + return response()->json([]); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 3623c031a..654d7280d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -106,6 +106,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('follow_requests', 'Api\ApiV1Controller@accountFollowRequests')->middleware('auth:api'); Route::post('follow_requests/{id}/authorize', 'Api\ApiV1Controller@accountFollowRequestAccept')->middleware('auth:api'); Route::post('follow_requests/{id}/reject', 'Api\ApiV1Controller@accountFollowRequestReject')->middleware('auth:api'); + Route::get('suggestions', 'Api\ApiV1Controller@accountSuggestions')->middleware('auth:api'); Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From 2a106c4e12a732afe2c3d9eca30dc5de1a2c8bf0 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 22:08:22 -0600 Subject: [PATCH 43/93] Add /api/v1/lists endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 39 +++++++++++++++----- routes/web.php | 1 + 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 35cd204c2..3914024e8 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -816,15 +816,13 @@ class ApiV1Controller extends Controller return response()->json([]); } - public function statusById(Request $request, $id) - { - $status = Status::whereVisibility('public')->findOrFail($id); - $resource = new Fractal\Resource\Item($status, new StatusTransformer()); - $res = $this->fractal->createData($resource)->toArray(); - - return response()->json($res); - } - + /** + * GET /api/v1/instance + * + * Information about the server. + * + * @return Instance + */ public function instance(Request $request) { $res = [ @@ -847,6 +845,29 @@ class ApiV1Controller extends Controller return response()->json($res, 200, [], JSON_PRETTY_PRINT); } + /** + * GET /api/v1/lists + * + * Return empty array as we don't support lists + * + * @return null + */ + public function accountLists(Request $request) + { + abort_if(!$request->user(), 403); + + return response()->json([]); + } + + public function statusById(Request $request, $id) + { + $status = Status::whereVisibility('public')->findOrFail($id); + $resource = new Fractal\Resource\Item($status, new StatusTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + + return response()->json($res); + } + public function context(Request $request) { // todo diff --git a/routes/web.php b/routes/web.php index 654d7280d..9eb5c7ba2 100644 --- a/routes/web.php +++ b/routes/web.php @@ -107,6 +107,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('follow_requests/{id}/authorize', 'Api\ApiV1Controller@accountFollowRequestAccept')->middleware('auth:api'); Route::post('follow_requests/{id}/reject', 'Api\ApiV1Controller@accountFollowRequestReject')->middleware('auth:api'); Route::get('suggestions', 'Api\ApiV1Controller@accountSuggestions')->middleware('auth:api'); + Route::get('lists', 'Api\ApiV1Controller@accountLists')->middleware('auth:api'); Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From dba172dfe747a4b4d3400b7c8a4d36178516a583 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 22:12:39 -0600 Subject: [PATCH 44/93] Add /api/v1/accounts/{id}/lists endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 14 ++++++++++++++ routes/web.php | 2 ++ 2 files changed, 16 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 3914024e8..d36052be8 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -859,6 +859,20 @@ class ApiV1Controller extends Controller return response()->json([]); } + /** + * GET /api/v1/accounts/{id}/lists + * + * @param integer $id + * + * @return null + */ + public function accountListsById(Request $request, $id) + { + abort_if(!$request->user(), 403); + + return response()->json([]); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 9eb5c7ba2..6de22b8ea 100644 --- a/routes/web.php +++ b/routes/web.php @@ -108,6 +108,8 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('follow_requests/{id}/reject', 'Api\ApiV1Controller@accountFollowRequestReject')->middleware('auth:api'); Route::get('suggestions', 'Api\ApiV1Controller@accountSuggestions')->middleware('auth:api'); Route::get('lists', 'Api\ApiV1Controller@accountLists')->middleware('auth:api'); + Route::get('accounts/{id}/lists', 'Api\ApiV1Controller@accountListsById')->middleware('auth:api'); + Route::get('lists/{id}/accounts', 'Api\ApiV1Controller@accountListsById')->middleware('auth:api'); Route::get('likes', 'ApiController@hydrateLikes'); Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From 9b5aac4f50528282855f5074f757c44ee8b4959c Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 22:38:44 -0600 Subject: [PATCH 45/93] Remove deprecated AttachmentTransformer --- app/Transformer/Api/AttachmentTransformer.php | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 app/Transformer/Api/AttachmentTransformer.php diff --git a/app/Transformer/Api/AttachmentTransformer.php b/app/Transformer/Api/AttachmentTransformer.php deleted file mode 100644 index 76c5b6ae3..000000000 --- a/app/Transformer/Api/AttachmentTransformer.php +++ /dev/null @@ -1,28 +0,0 @@ - (string) $media->id, - 'type' => $media->activityVerb(), - 'url' => $media->url(), - 'remote_url' => null, - 'preview_url' => $media->thumbnailUrl(), - 'text_url' => null, - 'meta' => null, - 'description' => $media->caption, - 'license' => $media->license, - 'is_nsfw' => $media->is_nsfw, - 'orientation' => $media->orientation, - 'filter_name' => $media->filter_name, - 'filter_class' => $media->filter_class, - 'mime' => $media->mime, - ]; - } -} From 39f3e3138d693905d8aa88d221ee6ed9c1f90985 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 22:54:05 -0600 Subject: [PATCH 46/93] Add /api/v1/media endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 97 +++++++++++++++++++- routes/web.php | 15 +-- 2 files changed, 101 insertions(+), 11 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index d36052be8..40cc17298 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -6,11 +6,8 @@ use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Illuminate\Support\Str; use App\Util\ActivityPub\Helpers; -use App\Jobs\LikePipeline\LikePipeline; -use App\Jobs\StatusPipeline\StatusDelete; -use App\Jobs\FollowPipeline\FollowPipeline; use Laravel\Passport\Passport; -use Auth, Cache, DB; +use Auth, Cache, DB, URL; use App\{ Follower, FollowRequest, @@ -24,6 +21,7 @@ use App\{ use League\Fractal; use App\Transformer\Api\{ AccountTransformer, + MediaTransformer, RelationshipTransformer, StatusTransformer, }; @@ -31,6 +29,16 @@ use App\Http\Controllers\FollowerController; use League\Fractal\Serializer\ArraySerializer; use League\Fractal\Pagination\IlluminatePaginatorAdapter; +use App\Jobs\LikePipeline\LikePipeline; +use App\Jobs\StatusPipeline\StatusDelete; +use App\Jobs\FollowPipeline\FollowPipeline; +use App\Jobs\ImageOptimizePipeline\ImageOptimize; +use App\Jobs\VideoPipeline\{ + VideoOptimize, + VideoPostProcess, + VideoThumbnail +}; + use App\Services\NotificationService; class ApiV1Controller extends Controller @@ -873,6 +881,87 @@ class ApiV1Controller extends Controller return response()->json([]); } + /** + * POST /api/v1/media + * + * + * @return App\Transformer\Api\MediaTransformer + */ + public function mediaUpload(Request $request) + { + abort_if(!$request->user(), 403); + + $this->validate($request, [ + 'file.*' => function() { + return [ + 'required', + 'mimes:' . config('pixelfed.media_types'), + 'max:' . config('pixelfed.max_photo_size'), + ]; + }, + 'filter_name' => 'nullable|string|max:24', + 'filter_class' => 'nullable|alpha_dash|max:24' + ]); + + $user = $request->user(); + $profile = $user->profile; + + if(config('pixelfed.enforce_account_limit') == true) { + $size = Cache::remember($user->storageUsedKey(), now()->addDays(3), function() use($user) { + return Media::whereUserId($user->id)->sum('size') / 1000; + }); + $limit = (int) config('pixelfed.max_account_size'); + if ($size >= $limit) { + abort(403, 'Account size limit reached.'); + } + } + + $monthHash = hash('sha1', date('Y').date('m')); + $userHash = hash('sha1', $user->id . (string) $user->created_at); + + $photo = $request->file('file'); + + $mimes = explode(',', config('pixelfed.media_types')); + if(in_array($photo->getMimeType(), $mimes) == false) { + abort(403, 'Invalid or unsupported mime type.'); + } + + $storagePath = "public/m/{$monthHash}/{$userHash}"; + $path = $photo->store($storagePath); + $hash = \hash_file('sha256', $photo); + + $media = new Media(); + $media->status_id = null; + $media->profile_id = $profile->id; + $media->user_id = $user->id; + $media->media_path = $path; + $media->original_sha256 = $hash; + $media->size = $photo->getSize(); + $media->mime = $photo->getMimeType(); + $media->filter_class = $request->input('filter_class'); + $media->filter_name = $request->input('filter_name'); + $media->save(); + + switch ($media->mime) { + case 'image/jpeg': + case 'image/png': + ImageOptimize::dispatch($media); + break; + + case 'video/mp4': + VideoThumbnail::dispatch($media); + $preview_url = '/storage/no-preview.png'; + $url = '/storage/no-preview.png'; + break; + } + + $resource = new Fractal\Resource\Item($media, new MediaTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + $res['preview_url'] = url('/storage/no-preview.png'); + $res['url'] = url('/storage/no-preview.png'); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 6de22b8ea..2c8480771 100644 --- a/routes/web.php +++ b/routes/web.php @@ -110,14 +110,15 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('lists', 'Api\ApiV1Controller@accountLists')->middleware('auth:api'); Route::get('accounts/{id}/lists', 'Api\ApiV1Controller@accountListsById')->middleware('auth:api'); Route::get('lists/{id}/accounts', 'Api\ApiV1Controller@accountListsById')->middleware('auth:api'); + Route::post('media', 'Api\ApiV1Controller@mediaUpload')->middleware('auth:api'); - Route::get('likes', 'ApiController@hydrateLikes'); - Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); - Route::delete('media', 'ApiController@deleteMedia')->middleware('auth:api'); - Route::get('notifications', 'ApiController@notifications')->middleware('auth:api'); - Route::get('timelines/public', 'PublicApiController@publicTimelineApi'); - Route::get('timelines/home', 'PublicApiController@homeTimelineApi')->middleware('auth:api'); - Route::post('status', 'Api\ApiV1Controller@createStatus')->middleware('auth:api'); + // Route::get('likes', 'ApiController@hydrateLikes'); + // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); + // Route::delete('media', 'ApiController@deleteMedia')->middleware('auth:api'); + // Route::get('notifications', 'ApiController@notifications')->middleware('auth:api'); + // Route::get('timelines/public', 'PublicApiController@publicTimelineApi'); + // Route::get('timelines/home', 'PublicApiController@homeTimelineApi')->middleware('auth:api'); + // Route::post('status', 'Api\ApiV1Controller@createStatus')->middleware('auth:api'); }); Route::group(['prefix' => 'v2'], function() { Route::get('config', 'ApiController@siteConfiguration'); From fcf231f4308eedf27acc709d14245c94e9a827db Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 23:01:37 -0600 Subject: [PATCH 47/93] Add /api/v1/media/{id} endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 35 +++++++++++++++++++- routes/web.php | 1 + 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 40cc17298..aa742c596 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -900,7 +900,8 @@ class ApiV1Controller extends Controller ]; }, 'filter_name' => 'nullable|string|max:24', - 'filter_class' => 'nullable|alpha_dash|max:24' + 'filter_class' => 'nullable|alpha_dash|max:24', + 'description' => 'nullable|string|max:420' ]); $user = $request->user(); @@ -938,6 +939,7 @@ class ApiV1Controller extends Controller $media->original_sha256 = $hash; $media->size = $photo->getSize(); $media->mime = $photo->getMimeType(); + $media->caption = $request->input('description'); $media->filter_class = $request->input('filter_class'); $media->filter_name = $request->input('filter_name'); $media->save(); @@ -962,6 +964,37 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * PUT /api/v1/media/{id} + * + * @param integer $id + * + * @return App\Transformer\Api\MediaTransformer + */ + public function mediaUpdate(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $this->validate($request, [ + 'description' => 'nullable|string|max:420' + ]); + + $user = $request->user(); + + $media = Media::whereUserId($user->id) + ->whereNull('status_id') + ->findOrFail($id); + + $media->caption = $request->input('description'); + $media->save(); + + $resource = new Fractal\Resource\Item($media, new MediaTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + $res['preview_url'] = url('/storage/no-preview.png'); + $res['url'] = url('/storage/no-preview.png'); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 2c8480771..3ad9f6c81 100644 --- a/routes/web.php +++ b/routes/web.php @@ -111,6 +111,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('accounts/{id}/lists', 'Api\ApiV1Controller@accountListsById')->middleware('auth:api'); Route::get('lists/{id}/accounts', 'Api\ApiV1Controller@accountListsById')->middleware('auth:api'); Route::post('media', 'Api\ApiV1Controller@mediaUpload')->middleware('auth:api'); + Route::put('media/{id}', 'Api\ApiV1Controller@mediaUpdate')->middleware('auth:api'); // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From b280d183ade512b403f895c5c3b74235f0b6b478 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 23:09:50 -0600 Subject: [PATCH 48/93] Add /api/v1/mutes endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 30 ++++++++++++++++++++ routes/web.php | 3 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index aa742c596..bbb58ac2e 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -995,6 +995,36 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/mutes + * + * + * @return App\Transformer\Api\AccountTransformer + */ + public function accountMutes(Request $request) + { + abort_if(!$request->user(), 403); + + $this->validate($request, [ + 'limit' => 'nullable|integer|min:1|max:40' + ]); + + $user = $request->user(); + $limit = $request->input('limit') ?? 40; + + $mutes = UserFilter::whereUserId($user->profile_id) + ->whereFilterableType('App\Profile') + ->whereFilterType('mute') + ->simplePaginate($limit) + ->pluck('filterable_id'); + + $accounts = Profile::find($mutes); + + $resource = new Fractal\Resource\Collection($accounts, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 3ad9f6c81..58592fc34 100644 --- a/routes/web.php +++ b/routes/web.php @@ -112,7 +112,8 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('lists/{id}/accounts', 'Api\ApiV1Controller@accountListsById')->middleware('auth:api'); Route::post('media', 'Api\ApiV1Controller@mediaUpload')->middleware('auth:api'); Route::put('media/{id}', 'Api\ApiV1Controller@mediaUpdate')->middleware('auth:api'); - + Route::get('mutes', 'Api\ApiV1Controller@accountMutes')->middleware('auth:api'); + // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); // Route::delete('media', 'ApiController@deleteMedia')->middleware('auth:api'); From 3e98dce4de06fe24645b9bc9ef103874557f4266 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 23:31:19 -0600 Subject: [PATCH 49/93] Add /api/v1/accounts/{id}/mute endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 32 ++++++++++++++++++++ routes/web.php | 3 +- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index bbb58ac2e..415cebed7 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1025,6 +1025,38 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * POST /api/v1/accounts/{id}/mute + * + * @param integer $id + * + * @return App\Transformer\Api\AccountTransformer + */ + public function accountMuteById(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $user = $request->user(); + + $account = Profile::findOrFail($id); + + $filter = UserFilter::firstOrCreate([ + 'user_id' => $user->profile_id, + 'filterable_id' => $account->id, + 'filterable_type' => 'App\Profile', + 'filter_type' => 'mute', + ]); + + $pid = $user->profile_id; + Cache::forget("user:filter:list:$pid"); + Cache::forget("feature:discover:posts:$pid"); + Cache::forget("api:local:exp:rec:$pid"); + + $resource = new Fractal\Resource\Item($account, new RelationshipTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 58592fc34..127cf9a34 100644 --- a/routes/web.php +++ b/routes/web.php @@ -113,7 +113,8 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('media', 'Api\ApiV1Controller@mediaUpload')->middleware('auth:api'); Route::put('media/{id}', 'Api\ApiV1Controller@mediaUpdate')->middleware('auth:api'); Route::get('mutes', 'Api\ApiV1Controller@accountMutes')->middleware('auth:api'); - + Route::post('accounts/{id}/mute', 'Api\ApiV1Controller@accountMuteById')->middleware('auth:api'); + // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); // Route::delete('media', 'ApiController@deleteMedia')->middleware('auth:api'); From 41c96ddd6ada638e79a1e82bc40342f0e27e2d9f Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 23:36:13 -0600 Subject: [PATCH 50/93] Add /api/v1/accounts/{id}/unmute endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 40 ++++++++++++++++++-- routes/web.php | 3 +- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 415cebed7..4d501595a 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1030,24 +1030,24 @@ class ApiV1Controller extends Controller * * @param integer $id * - * @return App\Transformer\Api\AccountTransformer + * @return App\Transformer\Api\RelationshipTransformer */ public function accountMuteById(Request $request, $id) { abort_if(!$request->user(), 403); $user = $request->user(); + $pid = $user->profile_id; $account = Profile::findOrFail($id); $filter = UserFilter::firstOrCreate([ - 'user_id' => $user->profile_id, + 'user_id' => $pid, 'filterable_id' => $account->id, 'filterable_type' => 'App\Profile', 'filter_type' => 'mute', ]); - $pid = $user->profile_id; Cache::forget("user:filter:list:$pid"); Cache::forget("feature:discover:posts:$pid"); Cache::forget("api:local:exp:rec:$pid"); @@ -1057,6 +1057,40 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * POST /api/v1/accounts/{id}/unmute + * + * @param integer $id + * + * @return App\Transformer\Api\RelationshipTransformer + */ + public function accountUnmuteById(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $user = $request->user(); + $pid = $user->profile_id; + + $account = Profile::findOrFail($id); + + $filter = UserFilter::whereUserId($pid) + ->whereFilterableId($account->id) + ->whereFilterableType('App\Profile') + ->whereFilterType('mute') + ->first(); + + if($filter) { + $filter->delete(); + Cache::forget("user:filter:list:$pid"); + Cache::forget("feature:discover:posts:$pid"); + Cache::forget("api:local:exp:rec:$pid"); + } + + $resource = new Fractal\Resource\Item($account, new RelationshipTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index 127cf9a34..d295d3608 100644 --- a/routes/web.php +++ b/routes/web.php @@ -91,7 +91,6 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('accounts/{id}/pin', 'Api\ApiV1Controller@accountEndorsements')->middleware('auth:api'); Route::post('accounts/{id}/unpin', 'Api\ApiV1Controller@accountEndorsements')->middleware('auth:api'); // Route::get('accounts/{id}', 'PublicApiController@account'); - Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware('auth:api'); Route::get('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware('auth:api'); Route::post('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware('auth:api'); @@ -114,6 +113,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::put('media/{id}', 'Api\ApiV1Controller@mediaUpdate')->middleware('auth:api'); Route::get('mutes', 'Api\ApiV1Controller@accountMutes')->middleware('auth:api'); Route::post('accounts/{id}/mute', 'Api\ApiV1Controller@accountMuteById')->middleware('auth:api'); + Route::post('accounts/{id}/unmute', 'Api\ApiV1Controller@accountUnmuteById')->middleware('auth:api'); // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); @@ -122,6 +122,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact // Route::get('timelines/public', 'PublicApiController@publicTimelineApi'); // Route::get('timelines/home', 'PublicApiController@homeTimelineApi')->middleware('auth:api'); // Route::post('status', 'Api\ApiV1Controller@createStatus')->middleware('auth:api'); + Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); }); Route::group(['prefix' => 'v2'], function() { Route::get('config', 'ApiController@siteConfiguration'); From 8e27eb4b4da3e916a43661a3872d7b73e10844f8 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 25 Sep 2019 23:48:22 -0600 Subject: [PATCH 51/93] Update changelog --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index db8b303ee..c9569a0aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,19 @@ - Added ```/api/v1/favourites``` endpoint [b9cc06da](https://github.com/pixelfed/pixelfed/commit/b9cc06da) - Added ```/api/v1/statuses/{id}/favourite``` endpoint [4edeba17](https://github.com/pixelfed/pixelfed/commit/4edeba17) - Added ```/api/v1/statuses/{id}/unfavourite``` endpoint [437e18e3](https://github.com/pixelfed/pixelfed/commit/437e18e3) +- Added ```/api/v1/filters``` endpoint [b3d82edd](https://github.com/pixelfed/pixelfed/commit/b3d82edd) +- Added ```/api/v1/follow_requests``` endpoint [97269136](https://github.com/pixelfed/pixelfed/commit/97269136) +- Added ```/api/v1/follow_requests/{id}/authorize``` endpoint [7bdd9b2a](https://github.com/pixelfed/pixelfed/commit/7bdd9b2a) +- Added ```/api/v1/follow_requests/{id}/reject``` endpoint [62aa922a](https://github.com/pixelfed/pixelfed/commit/62aa922a) +- Added ```/api/v1/suggestions``` endpoint [e52aeeed](https://github.com/pixelfed/pixelfed/commit/e52aeeed) +- Added ```/api/v1/lists``` endpoint [2a106c4e](https://github.com/pixelfed/pixelfed/commit/2a106c4e) +- Added ```/api/v1/accounts/{id}/lists``` endpoint [dba172df](https://github.com/pixelfed/pixelfed/commit/dba172df) +- Added ```/api/v1/lists/{id}/accounts``` endpoint [dba172df](https://github.com/pixelfed/pixelfed/commit/dba172df) +- Added ```/api/v1/media``` endpoint [39f3e313](https://github.com/pixelfed/pixelfed/commit/39f3e313) +- Added ```/api/v1/media/{id}``` endpoint [fcf231f4](https://github.com/pixelfed/pixelfed/commit/fcf231f4) +- Added ```/api/v1/mutes``` endpoint [b280d183](https://github.com/pixelfed/pixelfed/commit/b280d183) +- Added ```/api/v1/accounts/{id}/mute``` endpoint [3e98dce4](https://github.com/pixelfed/pixelfed/commit/3e98dce4) +- Added ```/api/v1/accounts/{id}/unmute``` endpoint [41c96ddd](https://github.com/pixelfed/pixelfed/commit/41c96ddd) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) @@ -29,6 +42,9 @@ - Updated Inbox Accept.Follow to use id of remote object [#1715](https://github.com/pixelfed/pixelfed/pull/1715) - Update StatusTransformer, make spoiler_text non-nullable [b66cf9cd](https://github.com/pixelfed/pixelfed/commit/b66cf9cd) - Update FollowerController, make follow and unfollow methods public [6237897d](https://github.com/pixelfed/pixelfed/commit/6237897d) + +## Deprecated +- Removed deprecated AttachmentTransformer, superceeded by MediaTransformer [9b5aac4f](https://github.com/pixelfed/pixelfed/commit/9b5aac4f) ## [v0.10.5 (2019-09-24)](https://github.com/pixelfed/pixelfed/compare/v0.10.4...v0.10.5) From 9b130cfe9bc74a2a9fc0a7be0d467aa0b6ebd968 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 01:30:15 -0600 Subject: [PATCH 52/93] Add new api transformers --- .../Api/Mastodon/v1/AccountTransformer.php | 42 ++++++++++ .../Api/Mastodon/v1/HashtagTransformer.php | 17 ++++ .../Api/Mastodon/v1/MediaTransformer.php | 23 ++++++ .../Api/Mastodon/v1/MentionTransformer.php | 19 +++++ .../Mastodon/v1/NotificationTransformer.php | 59 ++++++++++++++ .../Api/Mastodon/v1/StatusTransformer.php | 81 +++++++++++++++++++ 6 files changed, 241 insertions(+) create mode 100644 app/Transformer/Api/Mastodon/v1/AccountTransformer.php create mode 100644 app/Transformer/Api/Mastodon/v1/HashtagTransformer.php create mode 100644 app/Transformer/Api/Mastodon/v1/MediaTransformer.php create mode 100644 app/Transformer/Api/Mastodon/v1/MentionTransformer.php create mode 100644 app/Transformer/Api/Mastodon/v1/NotificationTransformer.php create mode 100644 app/Transformer/Api/Mastodon/v1/StatusTransformer.php diff --git a/app/Transformer/Api/Mastodon/v1/AccountTransformer.php b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php new file mode 100644 index 000000000..b06d8ea56 --- /dev/null +++ b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php @@ -0,0 +1,42 @@ +domain == null; + $is_admin = !$local ? false : $profile->user->is_admin; + $acct = $local ? $profile->username : substr($profile->username, 1); + $username = $local ? $profile->username : explode('@', $acct)[0]; + return [ + 'id' => (string) $profile->id, + 'username' => $username, + 'acct' => $acct, + 'display_name' => $profile->name, + 'locked' => (bool) $profile->is_private, + 'created_at' => $profile->created_at->format('c'), + 'followers_count' => $profile->followerCount(), + 'following_count' => $profile->followingCount(), + 'statuses_count' => (int) $profile->statusCount(), + 'note' => $profile->bio ?? '', + 'url' => $profile->url(), + 'avatar' => $profile->avatarUrl(), + 'avatar_static' => $profile->avatarUrl(), + 'header' => '', + 'header_static' => '', + 'header_bg' => $profile->header_bg, + 'emojis' => [], + 'moved' => null, + 'fields' => [], + 'bot' => false, + 'website' => $profile->website, + 'software' => 'pixelfed', + 'is_admin' => (bool) $is_admin, + ]; + } +} diff --git a/app/Transformer/Api/Mastodon/v1/HashtagTransformer.php b/app/Transformer/Api/Mastodon/v1/HashtagTransformer.php new file mode 100644 index 000000000..7956a8adc --- /dev/null +++ b/app/Transformer/Api/Mastodon/v1/HashtagTransformer.php @@ -0,0 +1,17 @@ + $hashtag->name, + 'url' => $hashtag->url(), + ]; + } +} diff --git a/app/Transformer/Api/Mastodon/v1/MediaTransformer.php b/app/Transformer/Api/Mastodon/v1/MediaTransformer.php new file mode 100644 index 000000000..ceb96abec --- /dev/null +++ b/app/Transformer/Api/Mastodon/v1/MediaTransformer.php @@ -0,0 +1,23 @@ + (string) $media->id, + 'type' => lcfirst($media->activityVerb()), + 'url' => $media->url(), + 'remote_url' => null, + 'preview_url' => $media->thumbnailUrl(), + 'text_url' => null, + 'meta' => null, + 'description' => $media->caption + ]; + } +} \ No newline at end of file diff --git a/app/Transformer/Api/Mastodon/v1/MentionTransformer.php b/app/Transformer/Api/Mastodon/v1/MentionTransformer.php new file mode 100644 index 000000000..774f4122e --- /dev/null +++ b/app/Transformer/Api/Mastodon/v1/MentionTransformer.php @@ -0,0 +1,19 @@ + (string) $profile->id, + 'url' => $profile->url(), + 'username' => $profile->username, + 'acct' => $profile->username, + ]; + } +} diff --git a/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php b/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php new file mode 100644 index 000000000..0f16da9be --- /dev/null +++ b/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php @@ -0,0 +1,59 @@ + (string) $notification->id, + 'type' => $this->replaceTypeVerb($notification->action), + 'created_at' => (string) $notification->created_at->format('c'), + ]; + } + + public function includeAccount(Notification $notification) + { + return $this->item($notification->actor, new AccountTransformer()); + } + + public function includeStatus(Notification $notification) + { + $item = $notification; + if($item->item_id && $item->item_type == 'App\Status') { + $status = Status::with('media')->find($item->item_id); + if($status) { + return $this->item($status, new StatusTransformer()); + } else { + return null; + } + } else { + return null; + } + } + + public function replaceTypeVerb($verb) + { + $verbs = [ + 'follow' => 'follow', + 'mention' => 'mention', + 'reblog' => 'share', + 'share' => 'share', + 'like' => 'favourite', + 'comment' => 'comment', + ]; + return $verbs[$verb]; + } +} diff --git a/app/Transformer/Api/Mastodon/v1/StatusTransformer.php b/app/Transformer/Api/Mastodon/v1/StatusTransformer.php new file mode 100644 index 000000000..6ddaf468b --- /dev/null +++ b/app/Transformer/Api/Mastodon/v1/StatusTransformer.php @@ -0,0 +1,81 @@ + (string) $status->id, + 'uri' => $status->url(), + 'url' => $status->url(), + 'in_reply_to_id' => $status->in_reply_to_id, + 'in_reply_to_account_id' => $status->in_reply_to_profile_id, + 'reblog' => null, + 'content' => $status->rendered ?? $status->caption, + 'created_at' => $status->created_at->format('c'), + 'emojis' => [], + 'reblogs_count' => $status->reblogs_count != 0 ? $status->reblogs_count: $status->shares()->count(), + 'favourites_count' => $status->likes_count != 0 ? $status->likes_count: $status->likes()->count(), + 'reblogged' => null, + 'favourited' => null, + 'muted' => null, + 'sensitive' => (bool) $status->is_nsfw, + 'spoiler_text' => $status->cw_summary ?? '', + 'visibility' => $status->visibility ?? $status->scope, + 'application' => [ + 'name' => 'web', + 'website' => null + ], + 'language' => null, + 'pinned' => null, + 'mentions' => [], + + 'parent' => [], + 'place' => $status->place + ]; + } + + public function includeAccount(Status $status) + { + $account = $status->profile; + + return $this->item($account, new AccountTransformer()); + } + + public function includeMediaAttachments(Status $status) + { + return Cache::remember('status:transformer:media:attachments:'.$status->id, now()->addDays(14), function() use($status) { + if(in_array($status->type, ['photo', 'video', 'photo:album', 'loop', 'photo:video:album'])) { + $media = $status->media()->orderBy('order')->get(); + return $this->collection($media, new MediaTransformer()); + } + }); + } + + public function includeMentions(Status $status) + { + $mentions = $status->mentions; + + return $this->collection($mentions, new MentionTransformer()); + } + + public function includeTags(Status $status) + { + $hashtags = $status->hashtags; + + return $this->collection($hashtags, new HashtagTransformer()); + } +} \ No newline at end of file From 39449f363840a2c064a0435dbac07cabb29260bd Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 01:37:22 -0600 Subject: [PATCH 53/93] Add /api/v1/notifications endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 47 +++++++++++++++++++- routes/web.php | 1 + 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 4d501595a..0693827cf 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -19,12 +19,15 @@ use App\{ UserFilter, }; use League\Fractal; -use App\Transformer\Api\{ +use App\Transformer\Api\Mastodon\v1\{ AccountTransformer, MediaTransformer, - RelationshipTransformer, + NotificationTransformer, StatusTransformer, }; +use App\Transformer\Api\{ + RelationshipTransformer, +}; use App\Http\Controllers\FollowerController; use League\Fractal\Serializer\ArraySerializer; use League\Fractal\Pagination\IlluminatePaginatorAdapter; @@ -1091,6 +1094,46 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/notifications + * + * + * @return App\Transformer\Api\NotificationTransformer + */ + public function accountNotifications(Request $request) + { + abort_if(!$request->user(), 403); + $this->validate($request, [ + 'page' => 'nullable|integer|min:1|max:10', + 'limit' => 'nullable|integer|min:1|max:40', + 'max_id' => 'nullable|integer|min:1', + 'min_id' => 'nullable|integer|min:0', + ]); + $pid = $request->user()->profile_id; + $limit = $request->input('limit') ?? 20; + $timeago = now()->subMonths(6); + $min = $request->input('min_id'); + $max = $request->input('max_id'); + if($min || $max) { + $dir = $min ? '>' : '<'; + $id = $min ?? $max; + $notifications = Notification::whereProfileId($pid) + ->whereDate('created_at', '>', $timeago) + ->latest() + ->where('id', $dir, $id) + ->limit($limit) + ->get(); + } else { + $notifications = Notification::whereProfileId($pid) + ->whereDate('created_at', '>', $timeago) + ->latest() + ->simplePaginate($limit); + } + $resource = new Fractal\Resource\Collection($notifications, new NotificationTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index d295d3608..bcfcefd97 100644 --- a/routes/web.php +++ b/routes/web.php @@ -114,6 +114,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('mutes', 'Api\ApiV1Controller@accountMutes')->middleware('auth:api'); Route::post('accounts/{id}/mute', 'Api\ApiV1Controller@accountMuteById')->middleware('auth:api'); Route::post('accounts/{id}/unmute', 'Api\ApiV1Controller@accountUnmuteById')->middleware('auth:api'); + Route::get('notifications', 'Api\ApiV1Controller@accountNotifications')->middleware('auth:api'); // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From ed651361099c1ac4edb1f5881fa1137021264d3a Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 01:38:39 -0600 Subject: [PATCH 54/93] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9569a0aa..1633bca02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ - Added ```/api/v1/mutes``` endpoint [b280d183](https://github.com/pixelfed/pixelfed/commit/b280d183) - Added ```/api/v1/accounts/{id}/mute``` endpoint [3e98dce4](https://github.com/pixelfed/pixelfed/commit/3e98dce4) - Added ```/api/v1/accounts/{id}/unmute``` endpoint [41c96ddd](https://github.com/pixelfed/pixelfed/commit/41c96ddd) +- Added ```/api/v1/notifications``` endpoint [39449f36](https://github.com/pixelfed/pixelfed/commit/39449f36) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) From cf3405d852c1b51ce05ee1423df66a89c7f1ea7f Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 18:30:56 -0600 Subject: [PATCH 55/93] Add /api/v1/timelines/home endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 88 ++++++++++++++++++++ routes/web.php | 3 +- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 0693827cf..b1c8f15dd 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1134,6 +1134,94 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/timelines/home + * + * + * @return App\Transformer\Api\StatusTransformer + */ + public function timelineHome(Request $request) + { + abort_if(!$request->user(), 403); + + $this->validate($request,[ + 'page' => 'nullable|integer|max:40', + 'min_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, + 'max_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, + 'limit' => 'nullable|integer|max:40' + ]); + + $page = $request->input('page'); + $min = $request->input('min_id'); + $max = $request->input('max_id'); + $limit = $request->input('limit') ?? 3; + + $pid = $request->user()->profile_id; + + $following = Cache::remember('profile:following:'.$pid, now()->addMinutes(1440), function() use($pid) { + $following = Follower::whereProfileId($pid)->pluck('following_id'); + return $following->push($pid)->toArray(); + }); + + if($min || $max) { + $dir = $min ? '>' : '<'; + $id = $min ?? $max; + $timeline = Status::select( + 'id', + 'uri', + 'caption', + 'rendered', + 'profile_id', + 'type', + 'in_reply_to_id', + 'reblog_of_id', + 'is_nsfw', + 'scope', + 'local', + 'reply_count', + 'comments_disabled', + 'place_id', + 'created_at', + 'updated_at' + )->whereIn('type', ['photo', 'photo:album', 'video', 'video:album']) + ->with('profile', 'hashtags', 'mentions') + ->where('id', $dir, $id) + ->whereIn('profile_id', $following) + ->whereIn('visibility',['public', 'unlisted', 'private']) + ->latest() + ->limit($limit) + ->get(); + } else { + $timeline = Status::select( + 'id', + 'uri', + 'caption', + 'rendered', + 'profile_id', + 'type', + 'in_reply_to_id', + 'reblog_of_id', + 'is_nsfw', + 'scope', + 'local', + 'reply_count', + 'comments_disabled', + 'place_id', + 'created_at', + 'updated_at' + )->whereIn('type', ['photo', 'photo:album', 'video', 'video:album']) + ->with('profile', 'hashtags', 'mentions') + ->whereIn('profile_id', $following) + ->whereIn('visibility',['public', 'unlisted', 'private']) + ->latest() + ->simplePaginate($limit); + } + + $fractal = new Fractal\Resource\Collection($timeline, new StatusTransformer()); + $res = $this->fractal->createData($fractal)->toArray(); + return response()->json($res, 200, [], JSON_PRETTY_PRINT); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index bcfcefd97..6537a6423 100644 --- a/routes/web.php +++ b/routes/web.php @@ -115,13 +115,14 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('accounts/{id}/mute', 'Api\ApiV1Controller@accountMuteById')->middleware('auth:api'); Route::post('accounts/{id}/unmute', 'Api\ApiV1Controller@accountUnmuteById')->middleware('auth:api'); Route::get('notifications', 'Api\ApiV1Controller@accountNotifications')->middleware('auth:api'); + + Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome'); // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); // Route::delete('media', 'ApiController@deleteMedia')->middleware('auth:api'); // Route::get('notifications', 'ApiController@notifications')->middleware('auth:api'); // Route::get('timelines/public', 'PublicApiController@publicTimelineApi'); - // Route::get('timelines/home', 'PublicApiController@homeTimelineApi')->middleware('auth:api'); // Route::post('status', 'Api\ApiV1Controller@createStatus')->middleware('auth:api'); Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); }); From ae8f688770be72d39623105bd417637d41563a7b Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 18:34:29 -0600 Subject: [PATCH 56/93] Update web routes --- routes/web.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/web.php b/routes/web.php index 6537a6423..f3f31a9f2 100644 --- a/routes/web.php +++ b/routes/web.php @@ -116,7 +116,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('accounts/{id}/unmute', 'Api\ApiV1Controller@accountUnmuteById')->middleware('auth:api'); Route::get('notifications', 'Api\ApiV1Controller@accountNotifications')->middleware('auth:api'); - Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome'); + Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware('auth:api'); // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); @@ -124,7 +124,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact // Route::get('notifications', 'ApiController@notifications')->middleware('auth:api'); // Route::get('timelines/public', 'PublicApiController@publicTimelineApi'); // Route::post('status', 'Api\ApiV1Controller@createStatus')->middleware('auth:api'); - Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); + Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById')->middleware('auth:api'); }); Route::group(['prefix' => 'v2'], function() { Route::get('config', 'ApiController@siteConfiguration'); From 336f90696803cd21017ee6be9de4475f10b98800 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 18:41:27 -0600 Subject: [PATCH 57/93] Add /api/v1/conversations endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 16 +++++++++++++++- routes/web.php | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index b1c8f15dd..920736d47 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1219,7 +1219,21 @@ class ApiV1Controller extends Controller $fractal = new Fractal\Resource\Collection($timeline, new StatusTransformer()); $res = $this->fractal->createData($fractal)->toArray(); - return response()->json($res, 200, [], JSON_PRETTY_PRINT); + return response()->json($res); + } + + /** + * GET /api/v1/conversations + * + * Not implemented + * + * @return array + */ + public function conversations(Request $request) + { + abort_if(!$request->user(), 403); + + return response()->json([]); } public function statusById(Request $request, $id) diff --git a/routes/web.php b/routes/web.php index f3f31a9f2..ac469c1fc 100644 --- a/routes/web.php +++ b/routes/web.php @@ -117,6 +117,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('notifications', 'Api\ApiV1Controller@accountNotifications')->middleware('auth:api'); Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware('auth:api'); + Route::get('conversations', 'Api\ApiV1Controller@conversations')->middleware('auth:api'); // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From f3eeb9c978988a35bf621738c9c56a17b0cc0a57 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 19:35:15 -0600 Subject: [PATCH 58/93] Add /api/v1/timelines/public endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 77 ++++++++++++++++++++ routes/web.php | 1 + 2 files changed, 78 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 920736d47..d758a9598 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1236,6 +1236,83 @@ class ApiV1Controller extends Controller return response()->json([]); } + /** + * GET /api/v1/timelines/public + * + * + * @return App\Transformer\Api\StatusTransformer + */ + public function timelinePublic(Request $request) + { + $this->validate($request,[ + 'page' => 'nullable|integer|max:40', + 'min_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, + 'max_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, + 'limit' => 'nullable|integer|max:40' + ]); + + $page = $request->input('page'); + $min = $request->input('min_id'); + $max = $request->input('max_id'); + $limit = $request->input('limit') ?? 3; + + if($min || $max) { + $dir = $min ? '>' : '<'; + $id = $min ?? $max; + $timeline = Status::select( + 'id', + 'uri', + 'caption', + 'rendered', + 'profile_id', + 'type', + 'in_reply_to_id', + 'reblog_of_id', + 'is_nsfw', + 'scope', + 'local', + 'reply_count', + 'comments_disabled', + 'place_id', + 'created_at', + 'updated_at' + )->whereIn('type', ['photo', 'photo:album', 'video', 'video:album']) + ->with('profile', 'hashtags', 'mentions') + ->where('id', $dir, $id) + ->whereVisibility('public') + ->latest() + ->limit($limit) + ->get(); + } else { + $timeline = Status::select( + 'id', + 'uri', + 'caption', + 'rendered', + 'profile_id', + 'type', + 'in_reply_to_id', + 'reblog_of_id', + 'is_nsfw', + 'scope', + 'local', + 'reply_count', + 'comments_disabled', + 'place_id', + 'created_at', + 'updated_at' + )->whereIn('type', ['photo', 'photo:album', 'video', 'video:album']) + ->with('profile', 'hashtags', 'mentions') + ->whereVisibility('public') + ->latest() + ->simplePaginate($limit); + } + + $fractal = new Fractal\Resource\Collection($timeline, new StatusTransformer()); + $res = $this->fractal->createData($fractal)->toArray(); + return response()->json($res); + } + public function statusById(Request $request, $id) { $status = Status::whereVisibility('public')->findOrFail($id); diff --git a/routes/web.php b/routes/web.php index ac469c1fc..16e9eca13 100644 --- a/routes/web.php +++ b/routes/web.php @@ -118,6 +118,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware('auth:api'); Route::get('conversations', 'Api\ApiV1Controller@conversations')->middleware('auth:api'); + Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic'); // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From 35275572b1793dccbbf5deefaa42b7fcca4df697 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 19:45:06 -0600 Subject: [PATCH 59/93] Update DiscoverComponent, change api namespace --- resources/assets/js/components/DiscoverComponent.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/assets/js/components/DiscoverComponent.vue b/resources/assets/js/components/DiscoverComponent.vue index 7b5df69c5..a22c3b0d3 100644 --- a/resources/assets/js/components/DiscoverComponent.vue +++ b/resources/assets/js/components/DiscoverComponent.vue @@ -80,7 +80,7 @@ methods: { fetchData() { - axios.get('/api/v2/discover/posts') + axios.get('/api/pixelfed/v2/discover/posts') .then((res) => { this.posts = res.data.posts; this.loaded = true; From 7650a17bf1bacfc384d62b950fe6303f924a75e7 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 19:45:28 -0600 Subject: [PATCH 60/93] Update compiled assets --- public/js/discover.js | Bin 10930 -> 10943 bytes public/mix-manifest.json | Bin 1655 -> 1655 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/public/js/discover.js b/public/js/discover.js index b62111b0f5273a96c76cbd2a3498b59ede8342a8..a483b799748c91c20169706869309d429e3c12e6 100644 GIT binary patch delta 946 zcmZ8g%}*0S6wj8HPw{{UQfUbtu*|Z{0tExKP8vW|LhvJzgIzaf=uTmh?QY%KRA=s-?{sI#d6R##-JbB>c(YJ*V!yexL=Dm6E&3o_nKCXXRe|r=y*<~d6 zy4E^or;FF8X-59;S~$m(-L-T4p?mk}u%IYhc1QN-xS9{L*dvpK5N>eSX505l7)?wd zHP5pbwV-r0p7k{@e?{inX4a2nn87m{%GS=A@NQ`)2sJc6P9v zPN#&KvGSoHZWhkC1rbJ?kcIXHq+cNG z-KyiLIcC_bM5|6fxa^Co?VQvb5PcyYk3g;Fz~F5`CUfG3XH=*k2*Y9SX0VkLnx>wq zOkrXF)Cy3|l{_DV!^2q zk%K8&c@XkjBHk%1Qs;J7G*1$nQD{OTm5gvADY_zGr`G#0chBTL2xkP(M1)?H|42Gv8#9t`I}{uzD+lYTL>4C6Z<`5A%3{^+}2LEMl> zm=X>TxryJv)$jP=B`3C5td^M@7)77afIVc}!ClX0*aIFA&~9_ I930#G2ca1>UjP6A delta 953 zcmZ8g%}*0S6wlJqmM=*(kpRV%EtVN}Sqi8?>(~HMG>FInVq7<7+ntt)+udeo+dxX= z$&-m+L-cIC8Vxocj0ca#n8?wKi5HLl1Dcrlwh&_6!`t7yH}Cs5AJ*TjKiX^N+ipk_ z7w<#QXF1OK8RU{QA%ttpvFO%n5y=x1GS2bL|5{Kw3eR{77rWuvkh|fD{qSh`PHl5Z z{0@I@XT(!w(L16DDYA5oVfYj|F$Td@E;b@JA?aRZNMd3?@*42n=uniWQpnS}coCH^ zG2-j4k(HflIZr*A5P!Qu-C~02X(N^L^x$vo>>wwV8fN;GkqZQIGH^yMC?i>6qAM1M z6ezY3;wls6*w#>x#MW-}f?J_iEFxQ`Z;sc-WrbsvHQPF(lEj*woikE+ZD!7T{B|Xp zo;g>TnLaBzr1>MfCe@Dc7wJiJzAGt-pWWTf?d}WGaTo@)=^%OevZcrvI&OaInd=%n zjC4j;ovLl)EY&PpG^@5xxESik5l-q2DB@~=e;bUXICyG_k#v@wceRS?`CPN9Q}Q>n zOi}QmN@oW04y*uiw&;2Y91c}S4&w9Rz%nybigAP5oYrfmmoSNLv>XnS{O3Q$$_Ul+CZ{IKdLPa0~OTFeAEWvJY(dIh>- zR^T{oG_tTvBL_l!i}%NvLF&xPu;!n5DV*S0Rzy_uJ=5XPS~->SH3*68pdLn?h`sg` z;@R+eA8)iSa^{q5>bnkZb;v|WPWCZ%coM5FS=91CY7~rKbzsayt_ReAm&}3umAnr` zxi@k#%&=;T-qRzZp( zC|RdKQD5_D*{#vVzyOq_2Jq`}AvqtO7pI=TK%py&fSZ9m<7;N6LLKYChvP=0p|&1W N&)7hVjzSsR{R`W7G<*O6 diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 344c2149b64a53152a0a116afee84781de5ecf91..abdb49fdb7926d2da94a4fd1e2fb18e7eb7dad08 100644 GIT binary patch delta 33 ocmey)^POjdG>b@DQnHDqp^eEqTC$0$aiY1Iu|bldiAh>=nn~(reHITU0J4b*qW}N^ From 0b0bf59dd9ea39c41148fb1c5d390ce23d593e38 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 19:46:45 -0600 Subject: [PATCH 61/93] Update web routes --- routes/web.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/routes/web.php b/routes/web.php index 16e9eca13..3803c9309 100644 --- a/routes/web.php +++ b/routes/web.php @@ -131,7 +131,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::group(['prefix' => 'v2'], function() { Route::get('config', 'ApiController@siteConfiguration'); Route::get('discover', 'InternalApiController@discover'); - Route::get('discover/posts', 'InternalApiController@discoverPosts'); + Route::get('discover/posts', 'InternalApiController@discoverPosts')->middleware('auth:api'); Route::get('profile/{username}/status/{postid}', 'PublicApiController@status'); Route::get('comments/{username}/status/{postId}', 'PublicApiController@statusComments'); Route::get('likes/profile/{username}/status/{id}', 'PublicApiController@statusLikes'); @@ -164,6 +164,23 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('timelines/public', 'PublicApiController@publicTimelineApi'); Route::get('timelines/home', 'PublicApiController@homeTimelineApi'); }); + + Route::group(['prefix' => 'v2'], function() { + Route::get('config', 'ApiController@siteConfiguration'); + Route::get('discover', 'InternalApiController@discover'); + Route::get('discover/posts', 'InternalApiController@discoverPosts'); + Route::get('profile/{username}/status/{postid}', 'PublicApiController@status'); + Route::get('comments/{username}/status/{postId}', 'PublicApiController@statusComments'); + Route::get('likes/profile/{username}/status/{id}', 'PublicApiController@statusLikes'); + Route::get('shares/profile/{username}/status/{id}', 'PublicApiController@statusShares'); + Route::get('status/{id}/replies', 'InternalApiController@statusReplies'); + Route::post('moderator/action', 'InternalApiController@modAction'); + Route::get('discover/categories', 'InternalApiController@discoverCategories'); + Route::get('loops', 'DiscoverController@loopsApi'); + Route::post('loops/watch', 'DiscoverController@loopWatch'); + Route::get('discover/tag', 'DiscoverController@getHashtags'); + Route::post('status/compose', 'InternalApiController@composePost')->middleware('throttle:maxPostsPerHour,60')->middleware('throttle:maxPostsPerDay,1440'); + }); }); Route::group(['prefix' => 'local'], function () { // Route::get('accounts/verify_credentials', 'ApiController@verifyCredentials'); From be7eae8494128ca8f4465a02c4333e7b4bd290dc Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 19:52:56 -0600 Subject: [PATCH 62/93] Update verify_credentials endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 28 ++++++++++++++++++++ routes/web.php | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index d758a9598..ac6090e5f 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -89,6 +89,34 @@ class ApiV1Controller extends Controller return $res; } + /** + * GET /api/v1/accounts/verify_credentials + * + * + * @return \App\Transformer\Api\AccountTransformer + */ + public function verifyCredentials(Request $request) + { + abort_if(!$request->user(), 403); + $id = $request->user()->id; + + $res = Cache::remember('mastoapi:user:account:id:'.$id, now()->addHours(6), function() use($id) { + $profile = Profile::whereNull('status')->whereUserId($id)->firstOrFail(); + $resource = new Fractal\Resource\Item($profile, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + $res['source'] = [ + 'privacy' => $profile->is_private ? 'private' : 'public', + 'sensitive' => $profile->cw ? true : false, + 'language' => 'en', + 'note' => '', + 'fields' => [] + ]; + return $res; + }); + + return response()->json($res); + } + /** * GET /api/v1/accounts/{id} * diff --git a/routes/web.php b/routes/web.php index 3803c9309..2dd34256b 100644 --- a/routes/web.php +++ b/routes/web.php @@ -77,7 +77,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('nodeinfo/2.0.json', 'FederationController@nodeinfo'); Route::group(['prefix' => 'v1'], function () { - Route::get('accounts/verify_credentials', 'ApiController@verifyCredentials')->middleware('auth:api'); + Route::get('accounts/verify_credentials', 'Api\ApiV1Controller@verifyCredentials')->middleware('auth:api'); Route::patch('accounts/update_credentials', 'Api\ApiV1Controller@accountUpdateCredentials')->middleware('auth:api'); Route::get('accounts/relationships', 'Api\ApiV1Controller@accountRelationshipsById')->middleware('auth:api'); Route::get('accounts/search', 'Api\ApiV1Controller@accountSearch')->middleware('auth:api'); From 5ff4ba080756d24bdaf0c7b05e98de8d2ff2a8df Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 20:15:49 -0600 Subject: [PATCH 63/93] Update mastodon api transformers, fix timestamps --- app/Transformer/Api/Mastodon/v1/AccountTransformer.php | 2 +- app/Transformer/Api/Mastodon/v1/StatusTransformer.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Transformer/Api/Mastodon/v1/AccountTransformer.php b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php index b06d8ea56..12e003583 100644 --- a/app/Transformer/Api/Mastodon/v1/AccountTransformer.php +++ b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php @@ -19,7 +19,7 @@ class AccountTransformer extends Fractal\TransformerAbstract 'acct' => $acct, 'display_name' => $profile->name, 'locked' => (bool) $profile->is_private, - 'created_at' => $profile->created_at->format('c'), + 'created_at' => $profile->created_at->toIso8601ZuluString(), 'followers_count' => $profile->followerCount(), 'following_count' => $profile->followingCount(), 'statuses_count' => (int) $profile->statusCount(), diff --git a/app/Transformer/Api/Mastodon/v1/StatusTransformer.php b/app/Transformer/Api/Mastodon/v1/StatusTransformer.php index 6ddaf468b..40b3f7ba8 100644 --- a/app/Transformer/Api/Mastodon/v1/StatusTransformer.php +++ b/app/Transformer/Api/Mastodon/v1/StatusTransformer.php @@ -25,7 +25,7 @@ class StatusTransformer extends Fractal\TransformerAbstract 'in_reply_to_account_id' => $status->in_reply_to_profile_id, 'reblog' => null, 'content' => $status->rendered ?? $status->caption, - 'created_at' => $status->created_at->format('c'), + 'created_at' => $status->created_at->toIso8601ZuluString(), 'emojis' => [], 'reblogs_count' => $status->reblogs_count != 0 ? $status->reblogs_count: $status->shares()->count(), 'favourites_count' => $status->likes_count != 0 ? $status->likes_count: $status->likes()->count(), From 68e09477d05bb81a3d1230d97f72c9be3147c7e4 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 20:16:56 -0600 Subject: [PATCH 64/93] Update NotificationTransformer --- app/Transformer/Api/Mastodon/v1/NotificationTransformer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php b/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php index 0f16da9be..79717728c 100644 --- a/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php +++ b/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php @@ -20,7 +20,7 @@ class NotificationTransformer extends Fractal\TransformerAbstract return [ 'id' => (string) $notification->id, 'type' => $this->replaceTypeVerb($notification->action), - 'created_at' => (string) $notification->created_at->format('c'), + 'created_at' => (string) $notification->created_at->toIso8601ZuluString(), ]; } From 43c18e866c13ad610d34f4dd32ae1893800028ba Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 20:39:52 -0600 Subject: [PATCH 65/93] Update api controller --- app/Http/Controllers/Api/ApiV1Controller.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index ac6090e5f..88becd0f4 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1133,7 +1133,7 @@ class ApiV1Controller extends Controller abort_if(!$request->user(), 403); $this->validate($request, [ 'page' => 'nullable|integer|min:1|max:10', - 'limit' => 'nullable|integer|min:1|max:40', + 'limit' => 'nullable|integer|min:1|max:80', 'max_id' => 'nullable|integer|min:1', 'min_id' => 'nullable|integer|min:0', ]); @@ -1176,7 +1176,7 @@ class ApiV1Controller extends Controller 'page' => 'nullable|integer|max:40', 'min_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, 'max_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, - 'limit' => 'nullable|integer|max:40' + 'limit' => 'nullable|integer|max:80' ]); $page = $request->input('page'); @@ -1276,7 +1276,7 @@ class ApiV1Controller extends Controller 'page' => 'nullable|integer|max:40', 'min_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, 'max_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, - 'limit' => 'nullable|integer|max:40' + 'limit' => 'nullable|integer|max:80' ]); $page = $request->input('page'); From 11cd75e8e84a2a021d0a5d473d88aaecb454c8c5 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 20:49:44 -0600 Subject: [PATCH 66/93] Update ApiController --- app/Http/Controllers/Api/ApiV1Controller.php | 37 ++++++++++++-------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 88becd0f4..e4020228c 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -200,14 +200,18 @@ class ApiV1Controller extends Controller abort_if(!$request->user(), 403); $profile = Profile::whereNull('status')->findOrFail($id); - $settings = $profile->user->settings; - if($settings->show_profile_followers == true) { - $limit = $request->input('limit') ?? 40; - $followers = $profile->followers()->paginate($limit); - $resource = new Fractal\Resource\Collection($followers, new AccountTransformer()); - $res = $this->fractal->createData($resource)->toArray(); - } else { + if($profile->domain) { $res = []; + } else { + $settings = $profile->user->settings; + if($settings->show_profile_followers == true) { + $limit = $request->input('limit') ?? 40; + $followers = $profile->followers()->paginate($limit); + $resource = new Fractal\Resource\Collection($followers, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + } else { + $res = []; + } } return response()->json($res); } @@ -224,15 +228,20 @@ class ApiV1Controller extends Controller abort_if(!$request->user(), 403); $profile = Profile::whereNull('status')->findOrFail($id); - $settings = $profile->user->settings; - if($settings->show_profile_following == true) { - $limit = $request->input('limit') ?? 40; - $following = $profile->following()->paginate($limit); - $resource = new Fractal\Resource\Collection($following, new AccountTransformer()); - $res = $this->fractal->createData($resource)->toArray(); - } else { + if($profile->domain) { $res = []; + } else { + $settings = $profile->user->settings; + if($settings->show_profile_following == true) { + $limit = $request->input('limit') ?? 40; + $following = $profile->following()->paginate($limit); + $resource = new Fractal\Resource\Collection($following, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + } else { + $res = []; + } } + return response()->json($res); } From 55ee29f30163fda642ee7b70a1ba22963ba6b613 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 21:03:08 -0600 Subject: [PATCH 67/93] Update APIV1Controller, fix cors bug --- app/Http/Controllers/Api/ApiV1Controller.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index e4020228c..f41fc2c19 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -86,7 +86,9 @@ class ApiV1Controller extends Controller 'client_secret' => $client->secret, 'vapid_key' => null ]; - return $res; + return response()->json($res, 200, [ + 'Access-Control-Allow-Origin' => '*' + ]); } /** @@ -241,7 +243,7 @@ class ApiV1Controller extends Controller $res = []; } } - + return response()->json($res); } From 70f4b8607ac66cbf9f690ae5dccf92ba774368b1 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 21:35:25 -0600 Subject: [PATCH 68/93] Update AccountTransformer --- app/Transformer/Api/Mastodon/v1/AccountTransformer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Transformer/Api/Mastodon/v1/AccountTransformer.php b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php index 12e003583..e2e1b4a29 100644 --- a/app/Transformer/Api/Mastodon/v1/AccountTransformer.php +++ b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php @@ -11,7 +11,7 @@ class AccountTransformer extends Fractal\TransformerAbstract { $local = $profile->domain == null; $is_admin = !$local ? false : $profile->user->is_admin; - $acct = $local ? $profile->username : substr($profile->username, 1); + $acct = $local ? $profile->username + '@' + config('pixelfed.domain.app') : substr($profile->username, 1); $username = $local ? $profile->username : explode('@', $acct)[0]; return [ 'id' => (string) $profile->id, From e4669a8aab01eabb433bf5ad4dc45092172a1a47 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 21:36:49 -0600 Subject: [PATCH 69/93] Update AccountTransformer, tfw you confuse javascript and php operators --- app/Transformer/Api/Mastodon/v1/AccountTransformer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Transformer/Api/Mastodon/v1/AccountTransformer.php b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php index e2e1b4a29..3c621c357 100644 --- a/app/Transformer/Api/Mastodon/v1/AccountTransformer.php +++ b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php @@ -11,7 +11,7 @@ class AccountTransformer extends Fractal\TransformerAbstract { $local = $profile->domain == null; $is_admin = !$local ? false : $profile->user->is_admin; - $acct = $local ? $profile->username + '@' + config('pixelfed.domain.app') : substr($profile->username, 1); + $acct = $local ? $profile->username . '@' . config('pixelfed.domain.app') : substr($profile->username, 1); $username = $local ? $profile->username : explode('@', $acct)[0]; return [ 'id' => (string) $profile->id, From 530149f0f4892fd0f57f09529058b300f95bbf51 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 21:53:55 -0600 Subject: [PATCH 70/93] Update AccountTransformer --- app/Http/Controllers/Api/ApiV1Controller.php | 8 ++++---- app/Transformer/Api/Mastodon/v1/AccountTransformer.php | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index f41fc2c19..0c945ee17 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -102,19 +102,19 @@ class ApiV1Controller extends Controller abort_if(!$request->user(), 403); $id = $request->user()->id; - $res = Cache::remember('mastoapi:user:account:id:'.$id, now()->addHours(6), function() use($id) { + //$res = Cache::remember('mastoapi:user:account:id:'.$id, now()->addHours(6), function() use($id) { $profile = Profile::whereNull('status')->whereUserId($id)->firstOrFail(); $resource = new Fractal\Resource\Item($profile, new AccountTransformer()); $res = $this->fractal->createData($resource)->toArray(); $res['source'] = [ 'privacy' => $profile->is_private ? 'private' : 'public', 'sensitive' => $profile->cw ? true : false, - 'language' => 'en', + 'language' => null, 'note' => '', 'fields' => [] ]; - return $res; - }); + // return $res; + // }); return response()->json($res); } diff --git a/app/Transformer/Api/Mastodon/v1/AccountTransformer.php b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php index 3c621c357..abcbf3bf8 100644 --- a/app/Transformer/Api/Mastodon/v1/AccountTransformer.php +++ b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php @@ -29,12 +29,10 @@ class AccountTransformer extends Fractal\TransformerAbstract 'avatar_static' => $profile->avatarUrl(), 'header' => '', 'header_static' => '', - 'header_bg' => $profile->header_bg, 'emojis' => [], 'moved' => null, - 'fields' => [], - 'bot' => false, - 'website' => $profile->website, + 'fields' => null, + 'bot' => null, 'software' => 'pixelfed', 'is_admin' => (bool) $is_admin, ]; From abcc62a3fc0961c9a22953e922b09f96d0f13a83 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 21:58:40 -0600 Subject: [PATCH 71/93] Update NotificationTransformer --- app/Transformer/Api/Mastodon/v1/NotificationTransformer.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php b/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php index 79717728c..877f66286 100644 --- a/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php +++ b/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php @@ -49,10 +49,9 @@ class NotificationTransformer extends Fractal\TransformerAbstract $verbs = [ 'follow' => 'follow', 'mention' => 'mention', - 'reblog' => 'share', - 'share' => 'share', + 'share' => 'reblog', 'like' => 'favourite', - 'comment' => 'comment', + 'comment' => 'mention', ]; return $verbs[$verb]; } From 253266329562e3b0805129e34a6bd06e513dc583 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 22:18:52 -0600 Subject: [PATCH 72/93] Update StatusTransformer --- app/Transformer/Api/Mastodon/v1/StatusTransformer.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/Transformer/Api/Mastodon/v1/StatusTransformer.php b/app/Transformer/Api/Mastodon/v1/StatusTransformer.php index 40b3f7ba8..ad85a8558 100644 --- a/app/Transformer/Api/Mastodon/v1/StatusTransformer.php +++ b/app/Transformer/Api/Mastodon/v1/StatusTransformer.php @@ -27,6 +27,7 @@ class StatusTransformer extends Fractal\TransformerAbstract 'content' => $status->rendered ?? $status->caption, 'created_at' => $status->created_at->toIso8601ZuluString(), 'emojis' => [], + 'replies_count' => 0, 'reblogs_count' => $status->reblogs_count != 0 ? $status->reblogs_count: $status->shares()->count(), 'favourites_count' => $status->likes_count != 0 ? $status->likes_count: $status->likes()->count(), 'reblogged' => null, @@ -35,16 +36,16 @@ class StatusTransformer extends Fractal\TransformerAbstract 'sensitive' => (bool) $status->is_nsfw, 'spoiler_text' => $status->cw_summary ?? '', 'visibility' => $status->visibility ?? $status->scope, + 'mentions' => [], + 'tags' => [], + 'card' => null, + 'poll' => null, 'application' => [ 'name' => 'web', 'website' => null ], 'language' => null, 'pinned' => null, - 'mentions' => [], - - 'parent' => [], - 'place' => $status->place ]; } From 5d97fc87767281ac4b338a41b7cbb18ec4e2d09a Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 22:19:41 -0600 Subject: [PATCH 73/93] Update StatusTransformer --- app/Transformer/Api/Mastodon/v1/StatusTransformer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Transformer/Api/Mastodon/v1/StatusTransformer.php b/app/Transformer/Api/Mastodon/v1/StatusTransformer.php index ad85a8558..87847e865 100644 --- a/app/Transformer/Api/Mastodon/v1/StatusTransformer.php +++ b/app/Transformer/Api/Mastodon/v1/StatusTransformer.php @@ -58,7 +58,7 @@ class StatusTransformer extends Fractal\TransformerAbstract public function includeMediaAttachments(Status $status) { - return Cache::remember('status:transformer:media:attachments:'.$status->id, now()->addDays(14), function() use($status) { + return Cache::remember('mastoapi:status:transformer:media:attachments:'.$status->id, now()->addDays(14), function() use($status) { if(in_array($status->type, ['photo', 'video', 'photo:album', 'loop', 'photo:video:album'])) { $media = $status->media()->orderBy('order')->get(); return $this->collection($media, new MediaTransformer()); From 7243489088758a141c6f686b6850a663a8114efb Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 22:24:03 -0600 Subject: [PATCH 74/93] Update mastodon api transformers --- app/Transformer/Api/Mastodon/v1/AccountTransformer.php | 2 +- app/Transformer/Api/Mastodon/v1/NotificationTransformer.php | 2 +- app/Transformer/Api/Mastodon/v1/StatusTransformer.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Transformer/Api/Mastodon/v1/AccountTransformer.php b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php index abcbf3bf8..0d062851e 100644 --- a/app/Transformer/Api/Mastodon/v1/AccountTransformer.php +++ b/app/Transformer/Api/Mastodon/v1/AccountTransformer.php @@ -19,7 +19,7 @@ class AccountTransformer extends Fractal\TransformerAbstract 'acct' => $acct, 'display_name' => $profile->name, 'locked' => (bool) $profile->is_private, - 'created_at' => $profile->created_at->toIso8601ZuluString(), + 'created_at' => $profile->created_at->toJSON(), 'followers_count' => $profile->followerCount(), 'following_count' => $profile->followingCount(), 'statuses_count' => (int) $profile->statusCount(), diff --git a/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php b/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php index 877f66286..595ac17df 100644 --- a/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php +++ b/app/Transformer/Api/Mastodon/v1/NotificationTransformer.php @@ -20,7 +20,7 @@ class NotificationTransformer extends Fractal\TransformerAbstract return [ 'id' => (string) $notification->id, 'type' => $this->replaceTypeVerb($notification->action), - 'created_at' => (string) $notification->created_at->toIso8601ZuluString(), + 'created_at' => (string) $notification->created_at->toJSON(), ]; } diff --git a/app/Transformer/Api/Mastodon/v1/StatusTransformer.php b/app/Transformer/Api/Mastodon/v1/StatusTransformer.php index 87847e865..2cd6f123f 100644 --- a/app/Transformer/Api/Mastodon/v1/StatusTransformer.php +++ b/app/Transformer/Api/Mastodon/v1/StatusTransformer.php @@ -25,7 +25,7 @@ class StatusTransformer extends Fractal\TransformerAbstract 'in_reply_to_account_id' => $status->in_reply_to_profile_id, 'reblog' => null, 'content' => $status->rendered ?? $status->caption, - 'created_at' => $status->created_at->toIso8601ZuluString(), + 'created_at' => $status->created_at->toJSON(), 'emojis' => [], 'replies_count' => 0, 'reblogs_count' => $status->reblogs_count != 0 ? $status->reblogs_count: $status->shares()->count(), From 3570e7acbb790f6bb7e8e431800e2f130c0165fc Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 22:42:33 -0600 Subject: [PATCH 75/93] Update api controller --- app/Http/Controllers/Api/ApiV1Controller.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 0c945ee17..535c0cb87 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1315,7 +1315,8 @@ class ApiV1Controller extends Controller 'place_id', 'created_at', 'updated_at' - )->whereIn('type', ['photo', 'photo:album', 'video', 'video:album']) + )->whereNull('uri') + ->whereIn('type', ['photo', 'photo:album', 'video', 'video:album']) ->with('profile', 'hashtags', 'mentions') ->where('id', $dir, $id) ->whereVisibility('public') @@ -1340,7 +1341,8 @@ class ApiV1Controller extends Controller 'place_id', 'created_at', 'updated_at' - )->whereIn('type', ['photo', 'photo:album', 'video', 'video:album']) + )->whereNull('uri') + ->whereIn('type', ['photo', 'photo:album', 'video', 'video:album']) ->with('profile', 'hashtags', 'mentions') ->whereVisibility('public') ->latest() From db3b873a504133cdc566f81c126fb8df31baf1bd Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 22:43:16 -0600 Subject: [PATCH 76/93] Update csrf middleware --- app/Http/Middleware/VerifyCsrfToken.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 0c13b8548..f44fd7ac4 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -12,6 +12,6 @@ class VerifyCsrfToken extends Middleware * @var array */ protected $except = [ - // + '/api/v1/*' ]; } From 9225120835ba814c1607a1094926c0f9bc967bda Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 26 Sep 2019 23:19:57 -0600 Subject: [PATCH 77/93] Add /api/v1/statuses/{id}/card endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 62 ++++++++++++++++---- routes/api.php | 2 - routes/web.php | 4 ++ 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 535c0cb87..3b017ad9d 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -927,7 +927,7 @@ class ApiV1Controller extends Controller * POST /api/v1/media * * - * @return App\Transformer\Api\MediaTransformer + * @return MediaTransformer */ public function mediaUpload(Request $request) { @@ -1011,7 +1011,7 @@ class ApiV1Controller extends Controller * * @param integer $id * - * @return App\Transformer\Api\MediaTransformer + * @return MediaTransformer */ public function mediaUpdate(Request $request, $id) { @@ -1041,7 +1041,7 @@ class ApiV1Controller extends Controller * GET /api/v1/mutes * * - * @return App\Transformer\Api\AccountTransformer + * @return AccountTransformer */ public function accountMutes(Request $request) { @@ -1072,7 +1072,7 @@ class ApiV1Controller extends Controller * * @param integer $id * - * @return App\Transformer\Api\RelationshipTransformer + * @return RelationshipTransformer */ public function accountMuteById(Request $request, $id) { @@ -1104,7 +1104,7 @@ class ApiV1Controller extends Controller * * @param integer $id * - * @return App\Transformer\Api\RelationshipTransformer + * @return RelationshipTransformer */ public function accountUnmuteById(Request $request, $id) { @@ -1137,7 +1137,7 @@ class ApiV1Controller extends Controller * GET /api/v1/notifications * * - * @return App\Transformer\Api\NotificationTransformer + * @return NotificationTransformer */ public function accountNotifications(Request $request) { @@ -1177,7 +1177,7 @@ class ApiV1Controller extends Controller * GET /api/v1/timelines/home * * - * @return App\Transformer\Api\StatusTransformer + * @return StatusTransformer */ public function timelineHome(Request $request) { @@ -1279,7 +1279,7 @@ class ApiV1Controller extends Controller * GET /api/v1/timelines/public * * - * @return App\Transformer\Api\StatusTransformer + * @return StatusTransformer */ public function timelinePublic(Request $request) { @@ -1354,8 +1354,17 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/statuses/{id} + * + * @param integer $id + * + * @return StatusTransformer + */ public function statusById(Request $request, $id) { + abort_if(!$request->user(), 403); + $status = Status::whereVisibility('public')->findOrFail($id); $resource = new Fractal\Resource\Item($status, new StatusTransformer()); $res = $this->fractal->createData($resource)->toArray(); @@ -1363,9 +1372,42 @@ class ApiV1Controller extends Controller return response()->json($res); } - public function context(Request $request) + /** + * GET /api/v1/statuses/{id}/context + * + * @param integer $id + * + * @return StatusTransformer + */ + public function statusContext(Request $request, $id) { - // todo + abort_if(!$request->user(), 403); + + $status = Status::whereVisibility('public')->findOrFail($id); + + // Return empty response since we don't handle threading like this + $res = [ + 'ancestors' => [], + 'descendants' => [] + ]; + + return response()->json($res); + } + + /** + * GET /api/v1/statuses/{id}/card + * + * @param integer $id + * + * @return StatusTransformer + */ + public function statusCard(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $status = Status::whereVisibility('public')->findOrFail($id); + + // Return empty response since we don't handle threading like this $res = [ 'ancestors' => [], 'descendants' => [] diff --git a/routes/api.php b/routes/api.php index da92e3bbe..78c263701 100644 --- a/routes/api.php +++ b/routes/api.php @@ -9,7 +9,5 @@ Route::group(['prefix' => 'api'], function() { Route::group(['prefix' => 'v1'], function() { Route::post('apps', 'Api\ApiV1Controller@apps'); Route::get('instance', 'Api\ApiV1Controller@instance'); - Route::get('statuses/{id}', 'Api\ApiV1Controller@statusById'); - Route::get('statuses/{id}/context', 'Api\ApiV1Controller@context'); }); }); diff --git a/routes/web.php b/routes/web.php index 2dd34256b..19ac6c7bc 100644 --- a/routes/web.php +++ b/routes/web.php @@ -116,6 +116,10 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('accounts/{id}/unmute', 'Api\ApiV1Controller@accountUnmuteById')->middleware('auth:api'); Route::get('notifications', 'Api\ApiV1Controller@accountNotifications')->middleware('auth:api'); + Route::get('statuses/{id}', 'Api\ApiV1Controller@statusById')->middleware('auth:api'); + Route::get('statuses/{id}/context', 'Api\ApiV1Controller@statusContext')->middleware('auth:api'); + Route::get('statuses/{id}/card', 'Api\ApiV1Controller@statusCard')->middleware('auth:api'); + Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware('auth:api'); Route::get('conversations', 'Api\ApiV1Controller@conversations')->middleware('auth:api'); Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic'); From 118006ed2d2155ba61d51aa5d00162518faa386c Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Fri, 27 Sep 2019 00:57:58 -0600 Subject: [PATCH 78/93] Add /api/v1/statuses/{id}/reblogged_by endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 31 ++++++++++++++++---- routes/web.php | 1 + 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 3b017ad9d..a38018c55 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1407,11 +1407,32 @@ class ApiV1Controller extends Controller $status = Status::whereVisibility('public')->findOrFail($id); - // Return empty response since we don't handle threading like this - $res = [ - 'ancestors' => [], - 'descendants' => [] - ]; + // Return empty response since we don't handle support cards + $res = []; + + return response()->json($res); + } + + /** + * GET /api/v1/statuses/{id}/reblogged_by + * + * @param integer $id + * + * @return AccountTransformer + */ + public function statusRebloggedBy(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $this->validate($request, [ + 'limit' => 'nullable|integer|min:1|max:80' + ]); + + $limit = $request->input('limit') ?? 40; + $status = Status::whereVisibility('public')->findOrFail($id); + $shared = $status->sharedBy()->latest()->simplePaginate($limit); + $resource = new Fractal\Resource\Collection($shared, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); return response()->json($res); } diff --git a/routes/web.php b/routes/web.php index 19ac6c7bc..98ebf64c1 100644 --- a/routes/web.php +++ b/routes/web.php @@ -119,6 +119,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('statuses/{id}', 'Api\ApiV1Controller@statusById')->middleware('auth:api'); Route::get('statuses/{id}/context', 'Api\ApiV1Controller@statusContext')->middleware('auth:api'); Route::get('statuses/{id}/card', 'Api\ApiV1Controller@statusCard')->middleware('auth:api'); + Route::get('statuses/{id}/reblogged_by', 'Api\ApiV1Controller@statusRebloggedBy')->middleware('auth:api'); Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware('auth:api'); Route::get('conversations', 'Api\ApiV1Controller@conversations')->middleware('auth:api'); From 5cdff57d5951b2443d49e7c3e0e51c3816d5b823 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Fri, 27 Sep 2019 01:01:48 -0600 Subject: [PATCH 79/93] Add /api/v1/statuses/{id}/favourited_by endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 24 ++++++++++++++++++++ routes/web.php | 1 + 2 files changed, 25 insertions(+) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index a38018c55..1ab77f920 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1437,6 +1437,30 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * GET /api/v1/statuses/{id}/favourited_by + * + * @param integer $id + * + * @return AccountTransformer + */ + public function statusFavouritedBy(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $this->validate($request, [ + 'limit' => 'nullable|integer|min:1|max:80' + ]); + + $limit = $request->input('limit') ?? 40; + $status = Status::whereVisibility('public')->findOrFail($id); + $liked = $status->likedBy()->latest()->simplePaginate($limit); + $resource = new Fractal\Resource\Collection($liked, new AccountTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + + return response()->json($res); + } + public function createStatus(Request $request) { abort_if(!$request->user(), 403); diff --git a/routes/web.php b/routes/web.php index 98ebf64c1..5bb292f5c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -120,6 +120,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('statuses/{id}/context', 'Api\ApiV1Controller@statusContext')->middleware('auth:api'); Route::get('statuses/{id}/card', 'Api\ApiV1Controller@statusCard')->middleware('auth:api'); Route::get('statuses/{id}/reblogged_by', 'Api\ApiV1Controller@statusRebloggedBy')->middleware('auth:api'); + Route::get('statuses/{id}/favourited_by', 'Api\ApiV1Controller@statusFavouritedBy')->middleware('auth:api'); Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware('auth:api'); Route::get('conversations', 'Api\ApiV1Controller@conversations')->middleware('auth:api'); From f85a780907c166c719d08ca0cbf0cc3d3d67c653 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Fri, 27 Sep 2019 01:10:27 -0600 Subject: [PATCH 80/93] Update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1633bca02..350b16bfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,13 @@ - Added ```/api/v1/accounts/{id}/mute``` endpoint [3e98dce4](https://github.com/pixelfed/pixelfed/commit/3e98dce4) - Added ```/api/v1/accounts/{id}/unmute``` endpoint [41c96ddd](https://github.com/pixelfed/pixelfed/commit/41c96ddd) - Added ```/api/v1/notifications``` endpoint [39449f36](https://github.com/pixelfed/pixelfed/commit/39449f36) +- Added ```/api/v1/timelines/home``` endpoint [cf3405d8](https://github.com/pixelfed/pixelfed/commit/cf3405d8) +- Added ```/api/v1/conversations``` endpoint [336f9069](https://github.com/pixelfed/pixelfed/commit/336f9069) +- Added ```/api/v1/timelines/public``` endpoint [f3eeb9c9](https://github.com/pixelfed/pixelfed/commit/f3eeb9c9) +- Added ```/api/v1/statuses/{id}/card``` endpoint [92251208](https://github.com/pixelfed/pixelfed/commit/92251208) +- Added ```/api/v1/statuses/{id}/reblogged_by``` endpoint [118006ed](https://github.com/pixelfed/pixelfed/commit/118006ed) +- Added ```/api/v1/statuses/{id}/favourited_by``` endpoint [5cdff57d](https://github.com/pixelfed/pixelfed/commit/5cdff57d) +- Added ```/api/``` endpoint [](https://github.com/pixelfed/pixelfed/commit/) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) @@ -43,6 +50,7 @@ - Updated Inbox Accept.Follow to use id of remote object [#1715](https://github.com/pixelfed/pixelfed/pull/1715) - Update StatusTransformer, make spoiler_text non-nullable [b66cf9cd](https://github.com/pixelfed/pixelfed/commit/b66cf9cd) - Update FollowerController, make follow and unfollow methods public [6237897d](https://github.com/pixelfed/pixelfed/commit/6237897d) +- Update DiscoverComponent, change api namespace [35275572](https://github.com/pixelfed/pixelfed/commit/35275572) ## Deprecated - Removed deprecated AttachmentTransformer, superceeded by MediaTransformer [9b5aac4f](https://github.com/pixelfed/pixelfed/commit/9b5aac4f) From 3aa729a362e7010800b0a32dfdb9ecdbeff90233 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 28 Sep 2019 22:50:56 -0600 Subject: [PATCH 81/93] Add /api/v1/statuses endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 92 +++++++++++++++++++- routes/web.php | 2 +- 2 files changed, 89 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 1ab77f920..b8fee3d78 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -31,8 +31,10 @@ use App\Transformer\Api\{ use App\Http\Controllers\FollowerController; use League\Fractal\Serializer\ArraySerializer; use League\Fractal\Pagination\IlluminatePaginatorAdapter; - +use App\Http\Controllers\StatusController; use App\Jobs\LikePipeline\LikePipeline; +use App\Util\Media\Filter; +use App\Jobs\StatusPipeline\NewStatusPipeline; use App\Jobs\StatusPipeline\StatusDelete; use App\Jobs\FollowPipeline\FollowPipeline; use App\Jobs\ImageOptimizePipeline\ImageOptimize; @@ -1461,21 +1463,103 @@ class ApiV1Controller extends Controller return response()->json($res); } + /** + * POST /api/v1/statuses + * + * + * @return StatusTransformer + */ public function createStatus(Request $request) { abort_if(!$request->user(), 403); $this->validate($request, [ - 'status' => 'string', - 'media_ids' => 'array', + 'status' => 'nullable|string', + 'in_reply_to_id' => 'nullable|integer', + 'media_ids' => 'array|max:' . config('pixelfed.max_album_length'), 'media_ids.*' => 'integer|min:1', 'sensitive' => 'nullable|boolean', 'visibility' => 'string|in:private,unlisted,public', - 'in_reply_to_id' => 'integer' ]); + if(config('costar.enabled') == true) { + $blockedKeywords = config('costar.keyword.block'); + if($blockedKeywords !== null && $request->status) { + $keywords = config('costar.keyword.block'); + foreach($keywords as $kw) { + if(Str::contains($request->status, $kw) == true) { + abort(400, 'Invalid object. Contains banned keyword.'); + } + } + } + } + if(!$request->filled('media_ids') && !$request->filled('in_reply_to_id')) { abort(403, 'Empty statuses are not allowed'); } + + $ids = $request->input('media_ids'); + $in_reply_to_id = $request->input('in_reply_to_id'); + $user = $request->user(); + + if($in_reply_to_id) { + $parent = Status::findOrFail($in_reply_to_id); + + $status = new Status; + $status->caption = strip_tags($request->input('status')); + $status->scope = $request->input('visibility'); + $status->visibility = $request->input('visibility'); + $status->profile_id = $user->profile_id; + $status->is_nsfw = $user->profile->cw == true ? true : $request->input('sensitive'); + $status->in_reply_to_id = $parent->id; + $status->in_reply_to_profile_id = $parent->profile_id; + $status->save(); + } else if($ids) { + $status = new Status; + $status->caption = strip_tags($request->input('status')); + $status->profile_id = $user->profile_id; + $status->scope = 'draft'; + $status->is_nsfw = $user->profile->cw == true ? true : $request->input('sensitive'); + $status->save(); + + $mimes = []; + + foreach($ids as $k => $v) { + if($k + 1 > config('pixelfed.max_album_length')) { + continue; + } + $m = Media::findOrFail($v); + if($m->profile_id !== $user->profile_id || $m->status_id) { + abort(403, 'Invalid media id'); + } + $m->status_id = $status->id; + $m->save(); + array_push($mimes, $m->mime); + } + + if(empty($mimes)) { + $status->delete(); + abort(500, 'Invalid media ids'); + } + + $status->scope = $request->input('visibility'); + $status->visibility = $request->input('visibility'); + $status->type = StatusController::mimeTypeCheck($mimes); + $status->save(); + } + + if(!$status) { + $oops = 'An error occured. RefId: '.time().'-'.$user->profile_id.':'.Str::random(5).':'.Str::random(10); + abort(500, $oops); + } + + NewStatusPipeline::dispatch($status); + Cache::forget('user:account:id:'.$user->id); + Cache::forget('profile:status_count:'.$user->profile_id); + Cache::forget($user->storageUsedKey()); + + $resource = new Fractal\Resource\Item($status, new StatusTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); } } \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 5bb292f5c..9344c9dee 100644 --- a/routes/web.php +++ b/routes/web.php @@ -125,13 +125,13 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware('auth:api'); Route::get('conversations', 'Api\ApiV1Controller@conversations')->middleware('auth:api'); Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic'); + Route::post('status', 'Api\ApiV1Controller@createStatus')->middleware('auth:api'); // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); // Route::delete('media', 'ApiController@deleteMedia')->middleware('auth:api'); // Route::get('notifications', 'ApiController@notifications')->middleware('auth:api'); // Route::get('timelines/public', 'PublicApiController@publicTimelineApi'); - // Route::post('status', 'Api\ApiV1Controller@createStatus')->middleware('auth:api'); Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById')->middleware('auth:api'); }); Route::group(['prefix' => 'v2'], function() { From 7e0f9ac3d4f3913d61f46438982ff7034df7403f Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 28 Sep 2019 22:57:08 -0600 Subject: [PATCH 82/93] Fix route typo --- routes/web.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/web.php b/routes/web.php index 9344c9dee..b9063cc02 100644 --- a/routes/web.php +++ b/routes/web.php @@ -125,7 +125,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware('auth:api'); Route::get('conversations', 'Api\ApiV1Controller@conversations')->middleware('auth:api'); Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic'); - Route::post('status', 'Api\ApiV1Controller@createStatus')->middleware('auth:api'); + Route::post('statuses', 'Api\ApiV1Controller@createStatus')->middleware('auth:api'); // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From 10cb2d40048a2063fc8d70bf66b81ab2c1807cce Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 28 Sep 2019 23:00:31 -0600 Subject: [PATCH 83/93] Update ApiController --- app/Http/Controllers/Api/ApiV1Controller.php | 18 +++++++++++++++--- routes/web.php | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index b8fee3d78..edc8e5fab 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1469,7 +1469,7 @@ class ApiV1Controller extends Controller * * @return StatusTransformer */ - public function createStatus(Request $request) + public function statusCreate(Request $request) { abort_if(!$request->user(), 403); @@ -1510,7 +1510,7 @@ class ApiV1Controller extends Controller $status->scope = $request->input('visibility'); $status->visibility = $request->input('visibility'); $status->profile_id = $user->profile_id; - $status->is_nsfw = $user->profile->cw == true ? true : $request->input('sensitive'); + $status->is_nsfw = $user->profile->cw == true ? true : $request->input('sensitive', false); $status->in_reply_to_id = $parent->id; $status->in_reply_to_profile_id = $parent->profile_id; $status->save(); @@ -1519,7 +1519,7 @@ class ApiV1Controller extends Controller $status->caption = strip_tags($request->input('status')); $status->profile_id = $user->profile_id; $status->scope = 'draft'; - $status->is_nsfw = $user->profile->cw == true ? true : $request->input('sensitive'); + $status->is_nsfw = $user->profile->cw == true ? true : $request->input('sensitive', false); $status->save(); $mimes = []; @@ -1562,4 +1562,16 @@ class ApiV1Controller extends Controller $res = $this->fractal->createData($resource)->toArray(); return response()->json($res); } + + /** + * DELETE /api/v1/statuses + * + * @param integer $id + * + * @return null + */ + public function statusDelete(Request $request) + { + abort_if(!$request->user(), 403); + } } \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index b9063cc02..c534bcde8 100644 --- a/routes/web.php +++ b/routes/web.php @@ -125,7 +125,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware('auth:api'); Route::get('conversations', 'Api\ApiV1Controller@conversations')->middleware('auth:api'); Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic'); - Route::post('statuses', 'Api\ApiV1Controller@createStatus')->middleware('auth:api'); + Route::post('statuses', 'Api\ApiV1Controller@statusCreate')->middleware('auth:api'); // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From 0a20b8321bbf1ebbcdc1390800b13310dc00b29e Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 29 Sep 2019 00:09:01 -0600 Subject: [PATCH 84/93] Add /api/v1/statuses endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index edc8e5fab..6314cd0de 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1570,8 +1570,16 @@ class ApiV1Controller extends Controller * * @return null */ - public function statusDelete(Request $request) + public function statusDelete(Request $request, $id) { abort_if(!$request->user(), 403); + + $status = Status::whereProfileId($request->user()->profile->id) + ->findOrFail($id); + + Cache::forget('profile:status_count:'.$status->profile_id); + StatusDelete::dispatch($status); + + return response()->json(['Status successfully deleted.']); } } \ No newline at end of file From 43cef2829638d94a84330decc15c60f93bbc7275 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 29 Sep 2019 00:36:02 -0600 Subject: [PATCH 85/93] Add /api/v1/statuses/{id}/reblog endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 33 ++++++++++++++++++-- routes/web.php | 2 ++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 6314cd0de..bd94df4ab 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -6,6 +6,7 @@ use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Illuminate\Support\Str; use App\Util\ActivityPub\Helpers; +use App\Util\Media\Filter; use Laravel\Passport\Passport; use Auth, Cache, DB, URL; use App\{ @@ -33,7 +34,7 @@ use League\Fractal\Serializer\ArraySerializer; use League\Fractal\Pagination\IlluminatePaginatorAdapter; use App\Http\Controllers\StatusController; use App\Jobs\LikePipeline\LikePipeline; -use App\Util\Media\Filter; +use App\Jobs\SharePipeline\SharePipeline; use App\Jobs\StatusPipeline\NewStatusPipeline; use App\Jobs\StatusPipeline\StatusDelete; use App\Jobs\FollowPipeline\FollowPipeline; @@ -43,7 +44,6 @@ use App\Jobs\VideoPipeline\{ VideoPostProcess, VideoThumbnail }; - use App\Services\NotificationService; class ApiV1Controller extends Controller @@ -1582,4 +1582,33 @@ class ApiV1Controller extends Controller return response()->json(['Status successfully deleted.']); } + + /** + * POST /api/v1/statuses/{id}/reblog + * + * @param integer $id + * + * @return StatusTransformer + */ + public function statusShare(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $user = $request->user(); + $status = Status::findOrFail($id); + + $share = Status::firstOrCreate([ + 'profile_id' = $user->profile_id, + 'reblog_of_id' = $status->id, + 'in_reply_to_profile_id' = $status->profile_id + ]); + + if($share->wasRecentlyCreated == true) { + SharePipeline::dispatch($share); + } + + $resource = new Fractal\Resource\Item($share, new StatusTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); + } } \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index c534bcde8..81ee42325 100644 --- a/routes/web.php +++ b/routes/web.php @@ -126,6 +126,8 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('conversations', 'Api\ApiV1Controller@conversations')->middleware('auth:api'); Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic'); Route::post('statuses', 'Api\ApiV1Controller@statusCreate')->middleware('auth:api'); + Route::delete('statuses/{id}', 'Api\ApiV1Controller@statusDelete')->middleware('auth:api'); + Route::post('statuses/{id}/reblog', 'Api\ApiV1Controller@statusShare')->middleware('auth:api'); // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From 3147fe5ca360baf7856b93e670fe14f50d8f806c Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 29 Sep 2019 01:11:31 -0600 Subject: [PATCH 86/93] Add /api/v1/statuses/{id}/unreblog endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 28 +++++++++++++++++++- routes/web.php | 1 + 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index bd94df4ab..ac99db92b 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1607,7 +1607,33 @@ class ApiV1Controller extends Controller SharePipeline::dispatch($share); } - $resource = new Fractal\Resource\Item($share, new StatusTransformer()); + $resource = new Fractal\Resource\Item($status, new StatusTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + return response()->json($res); + } + + /** + * POST /api/v1/statuses/{id}/unreblog + * + * @param integer $id + * + * @return StatusTransformer + */ + public function statusUnshare(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $user = $request->user(); + $status = Status::findOrFail($id); + + Status::whereProfileId($user->profile_id) + ->whereReblogOfId($status->id) + ->delete(); + $count = $status->reblogs_count; + $status->reblogs_count = $count > 0 ? $count - 1 : 0; + $status->save(); + + $resource = new Fractal\Resource\Item($status, new StatusTransformer()); $res = $this->fractal->createData($resource)->toArray(); return response()->json($res); } diff --git a/routes/web.php b/routes/web.php index 81ee42325..f1c1db510 100644 --- a/routes/web.php +++ b/routes/web.php @@ -128,6 +128,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('statuses', 'Api\ApiV1Controller@statusCreate')->middleware('auth:api'); Route::delete('statuses/{id}', 'Api\ApiV1Controller@statusDelete')->middleware('auth:api'); Route::post('statuses/{id}/reblog', 'Api\ApiV1Controller@statusShare')->middleware('auth:api'); + Route::post('statuses/{id}/unreblog', 'Api\ApiV1Controller@statusUnshare')->middleware('auth:api'); // Route::get('likes', 'ApiController@hydrateLikes'); // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); From 1f9da762a8213f34d59b066dd9ced75d264be39e Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 29 Sep 2019 01:28:54 -0600 Subject: [PATCH 87/93] Update changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 350b16bfb..4383744c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,10 @@ - Added ```/api/v1/statuses/{id}/card``` endpoint [92251208](https://github.com/pixelfed/pixelfed/commit/92251208) - Added ```/api/v1/statuses/{id}/reblogged_by``` endpoint [118006ed](https://github.com/pixelfed/pixelfed/commit/118006ed) - Added ```/api/v1/statuses/{id}/favourited_by``` endpoint [5cdff57d](https://github.com/pixelfed/pixelfed/commit/5cdff57d) -- Added ```/api/``` endpoint [](https://github.com/pixelfed/pixelfed/commit/) +- Added POST ```/api/v1/statuses``` endpoint [3aa729a3](https://github.com/pixelfed/pixelfed/commit/3aa729a3) +- Added DELETE ```/api/v1/statuses``` endpoint [0a20b832](https://github.com/pixelfed/pixelfed/commit/0a20b832) +- Added POST ```/api/v1/statuses/{id}/reblog``` endpoint [43cef282](https://github.com/pixelfed/pixelfed/commit/43cef282) +- Added POST ```/api/v1/statuses/{id}/unreblog``` endpoint [3147fe5c](https://github.com/pixelfed/pixelfed/commit/3147fe5c) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) From 01a3841bc70f9bc2925a6469d9525582d87273f5 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 29 Sep 2019 02:55:26 -0600 Subject: [PATCH 88/93] Update ApiController --- app/Http/Controllers/Api/ApiV1Controller.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index ac99db92b..85a889da0 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1598,9 +1598,9 @@ class ApiV1Controller extends Controller $status = Status::findOrFail($id); $share = Status::firstOrCreate([ - 'profile_id' = $user->profile_id, - 'reblog_of_id' = $status->id, - 'in_reply_to_profile_id' = $status->profile_id + 'profile_id' => $user->profile_id, + 'reblog_of_id' => $status->id, + 'in_reply_to_profile_id' => $status->profile_id ]); if($share->wasRecentlyCreated == true) { From 2ff53be458295d2ecc479147f51d52460cb18b62 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 29 Sep 2019 22:05:12 -0600 Subject: [PATCH 89/93] Add /api/v1/timelines/tag/{hashtag} endpoint --- app/Http/Controllers/Api/ApiV1Controller.php | 16 ++++++++ routes/web.php | 43 +++++++++----------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 85a889da0..a90327f4d 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1637,4 +1637,20 @@ class ApiV1Controller extends Controller $res = $this->fractal->createData($resource)->toArray(); return response()->json($res); } + + /** + * GET /api/v1/timelines/tag/{hashtag} + * + * @param string $hashtag + * + * @return StatusTransformer + */ + public function timelineHashtag(Request $request, $hashtag) + { + abort_if(!$request->user(), 403); + + // todo + $res = []; + return response()->json($res); + } } \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index f1c1db510..fc9c685d5 100644 --- a/routes/web.php +++ b/routes/web.php @@ -90,52 +90,49 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::post('accounts/{id}/unblock', 'Api\ApiV1Controller@accountUnblockById')->middleware('auth:api'); Route::post('accounts/{id}/pin', 'Api\ApiV1Controller@accountEndorsements')->middleware('auth:api'); Route::post('accounts/{id}/unpin', 'Api\ApiV1Controller@accountEndorsements')->middleware('auth:api'); - // Route::get('accounts/{id}', 'PublicApiController@account'); + Route::post('accounts/{id}/mute', 'Api\ApiV1Controller@accountMuteById')->middleware('auth:api'); + Route::post('accounts/{id}/unmute', 'Api\ApiV1Controller@accountUnmuteById')->middleware('auth:api'); + Route::get('accounts/{id}/lists', 'Api\ApiV1Controller@accountListsById')->middleware('auth:api'); + Route::get('lists/{id}/accounts', 'Api\ApiV1Controller@accountListsById')->middleware('auth:api'); + Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById')->middleware('auth:api'); + Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware('auth:api'); + Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware('auth:api'); + Route::get('conversations', 'Api\ApiV1Controller@conversations')->middleware('auth:api'); + Route::get('custom_emojis', 'Api\ApiV1Controller@customEmojis'); Route::get('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware('auth:api'); Route::post('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware('auth:api'); Route::delete('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware('auth:api'); Route::get('endorsements', 'Api\ApiV1Controller@accountEndorsements')->middleware('auth:api'); - Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware('auth:api'); - Route::get('custom_emojis', 'Api\ApiV1Controller@customEmojis'); Route::get('favourites', 'Api\ApiV1Controller@accountFavourites')->middleware('auth:api'); - Route::post('statuses/{id}/favourite', 'Api\ApiV1Controller@statusFavouriteById')->middleware('auth:api'); - Route::post('statuses/{id}/unfavourite', 'Api\ApiV1Controller@statusUnfavouriteById')->middleware('auth:api'); Route::get('filters', 'Api\ApiV1Controller@accountFilters')->middleware('auth:api'); Route::get('follow_requests', 'Api\ApiV1Controller@accountFollowRequests')->middleware('auth:api'); Route::post('follow_requests/{id}/authorize', 'Api\ApiV1Controller@accountFollowRequestAccept')->middleware('auth:api'); Route::post('follow_requests/{id}/reject', 'Api\ApiV1Controller@accountFollowRequestReject')->middleware('auth:api'); - Route::get('suggestions', 'Api\ApiV1Controller@accountSuggestions')->middleware('auth:api'); Route::get('lists', 'Api\ApiV1Controller@accountLists')->middleware('auth:api'); - Route::get('accounts/{id}/lists', 'Api\ApiV1Controller@accountListsById')->middleware('auth:api'); - Route::get('lists/{id}/accounts', 'Api\ApiV1Controller@accountListsById')->middleware('auth:api'); Route::post('media', 'Api\ApiV1Controller@mediaUpload')->middleware('auth:api'); Route::put('media/{id}', 'Api\ApiV1Controller@mediaUpdate')->middleware('auth:api'); Route::get('mutes', 'Api\ApiV1Controller@accountMutes')->middleware('auth:api'); - Route::post('accounts/{id}/mute', 'Api\ApiV1Controller@accountMuteById')->middleware('auth:api'); - Route::post('accounts/{id}/unmute', 'Api\ApiV1Controller@accountUnmuteById')->middleware('auth:api'); Route::get('notifications', 'Api\ApiV1Controller@accountNotifications')->middleware('auth:api'); + Route::get('suggestions', 'Api\ApiV1Controller@accountSuggestions')->middleware('auth:api'); - Route::get('statuses/{id}', 'Api\ApiV1Controller@statusById')->middleware('auth:api'); + Route::post('statuses/{id}/favourite', 'Api\ApiV1Controller@statusFavouriteById')->middleware('auth:api'); + Route::post('statuses/{id}/unfavourite', 'Api\ApiV1Controller@statusUnfavouriteById')->middleware('auth:api'); Route::get('statuses/{id}/context', 'Api\ApiV1Controller@statusContext')->middleware('auth:api'); Route::get('statuses/{id}/card', 'Api\ApiV1Controller@statusCard')->middleware('auth:api'); Route::get('statuses/{id}/reblogged_by', 'Api\ApiV1Controller@statusRebloggedBy')->middleware('auth:api'); Route::get('statuses/{id}/favourited_by', 'Api\ApiV1Controller@statusFavouritedBy')->middleware('auth:api'); - - Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware('auth:api'); - Route::get('conversations', 'Api\ApiV1Controller@conversations')->middleware('auth:api'); - Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic'); - Route::post('statuses', 'Api\ApiV1Controller@statusCreate')->middleware('auth:api'); - Route::delete('statuses/{id}', 'Api\ApiV1Controller@statusDelete')->middleware('auth:api'); Route::post('statuses/{id}/reblog', 'Api\ApiV1Controller@statusShare')->middleware('auth:api'); Route::post('statuses/{id}/unreblog', 'Api\ApiV1Controller@statusUnshare')->middleware('auth:api'); + Route::delete('statuses/{id}', 'Api\ApiV1Controller@statusDelete')->middleware('auth:api'); + Route::get('statuses/{id}', 'Api\ApiV1Controller@statusById')->middleware('auth:api'); + Route::post('statuses', 'Api\ApiV1Controller@statusCreate')->middleware('auth:api'); + + + Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware('auth:api'); + Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic'); + Route::get('timelines/tag/{hashtag}', 'Api\ApiV1Controller@timelineHashtag')->middleware('auth:api'); - // Route::get('likes', 'ApiController@hydrateLikes'); - // Route::post('media', 'ApiController@uploadMedia')->middleware('auth:api'); - // Route::delete('media', 'ApiController@deleteMedia')->middleware('auth:api'); - // Route::get('notifications', 'ApiController@notifications')->middleware('auth:api'); - // Route::get('timelines/public', 'PublicApiController@publicTimelineApi'); - Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById')->middleware('auth:api'); }); Route::group(['prefix' => 'v2'], function() { Route::get('config', 'ApiController@siteConfiguration'); From df4fa7fbfe4bfb26c7d9444e224135034d08fead Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 29 Sep 2019 22:06:57 -0600 Subject: [PATCH 90/93] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4383744c9..87732232a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ - Added DELETE ```/api/v1/statuses``` endpoint [0a20b832](https://github.com/pixelfed/pixelfed/commit/0a20b832) - Added POST ```/api/v1/statuses/{id}/reblog``` endpoint [43cef282](https://github.com/pixelfed/pixelfed/commit/43cef282) - Added POST ```/api/v1/statuses/{id}/unreblog``` endpoint [3147fe5c](https://github.com/pixelfed/pixelfed/commit/3147fe5c) +- Added GET ```/api/v1/timelines/tag/{hashtag}``` endpoint [2ff53be4](https://github.com/pixelfed/pixelfed/commit/2ff53be4) ### Fixed - Update developer settings pages, fix vue bug [cd365ab3](https://github.com/pixelfed/pixelfed/commit/cd365ab3) From 7ffb1bd05d2c90d56eb607eeee7f3fb391b1ae48 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 29 Sep 2019 22:36:10 -0600 Subject: [PATCH 91/93] Update composer.json --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8aebac042..93aad5904 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ "ext-bcmath": "*", "ext-ctype": "*", "ext-curl": "*", + "ext-intl": "*", "ext-json": "*", "ext-mbstring": "*", "ext-openssl": "*", @@ -18,7 +19,7 @@ "intervention/image": "^2.4", "jenssegers/agent": "^2.6", "laravel/framework": "5.8.*", - "laravel/horizon": "^3.1", + "laravel/horizon": "^3.3", "laravel/passport": "^7.0", "laravel/tinker": "^1.0", "league/flysystem-aws-s3-v3": "~1.0", From 66a7cc519549482807b02ef658701028b36cdf54 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 29 Sep 2019 22:42:49 -0600 Subject: [PATCH 92/93] Update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87732232a..baf201a1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,11 @@ ## Deprecated - Removed deprecated AttachmentTransformer, superceeded by MediaTransformer [9b5aac4f](https://github.com/pixelfed/pixelfed/commit/9b5aac4f) + +### To enable mobile app support +- Run ```php artisan passport:keys``` +- Add ```OAUTH_ENABLED=true``` to .env +- Run ```php artisan config:cache``` ## [v0.10.5 (2019-09-24)](https://github.com/pixelfed/pixelfed/compare/v0.10.4...v0.10.5) From f590f616b38ff800988c5053bfce414ba3d9e44a Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 29 Sep 2019 22:43:18 -0600 Subject: [PATCH 93/93] Bump version to v0.10.6 --- config/pixelfed.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/pixelfed.php b/config/pixelfed.php index ed10f11fc..a9710a2aa 100644 --- a/config/pixelfed.php +++ b/config/pixelfed.php @@ -23,7 +23,7 @@ return [ | This value is the version of your Pixelfed instance. | */ - 'version' => '0.10.5', + 'version' => '0.10.6', /* |--------------------------------------------------------------------------