diff --git a/app/Status.php b/app/Status.php index a76d6dad7..9cc6cc757 100644 --- a/app/Status.php +++ b/app/Status.php @@ -370,6 +370,13 @@ class Status extends Model return $mention->permalink(); })->toArray(); + if($this->in_reply_to_id != null) { + $parent = $this->parent(); + if($parent) { + $mentions = array_merge([$parent->profile->permalink()], $mentions); + } + } + switch ($scope) { case 'public': $res['to'] = [ @@ -379,18 +386,14 @@ class Status extends Model break; case 'unlisted': - $res['to'] = [ - $this->profile->permalink('/followers') - ]; + $res['to'] = array_merge([$this->profile->permalink('/followers')], $mentions); $res['cc'] = [ "https://www.w3.org/ns/activitystreams#Public" ]; break; case 'private': - $res['to'] = [ - $this->profile->permalink('/followers') - ]; + $res['to'] = array_merge([$this->profile->permalink('/followers')], $mentions); $res['cc'] = []; break; diff --git a/app/Transformer/ActivityPub/Verb/CreateNote.php b/app/Transformer/ActivityPub/Verb/CreateNote.php index 83f7e6020..5bd712849 100644 --- a/app/Transformer/ActivityPub/Verb/CreateNote.php +++ b/app/Transformer/ActivityPub/Verb/CreateNote.php @@ -4,6 +4,7 @@ namespace App\Transformer\ActivityPub\Verb; use App\Status; use League\Fractal; +use Illuminate\Support\Str; class CreateNote extends Fractal\TransformerAbstract { @@ -11,12 +12,33 @@ class CreateNote extends Fractal\TransformerAbstract { $mentions = $status->mentions->map(function ($mention) { + $webfinger = $mention->emailUrl(); + $name = Str::startsWith($webfinger, '@') ? + $webfinger : + '@' . $webfinger; return [ 'type' => 'Mention', 'href' => $mention->permalink(), - 'name' => $mention->emailUrl() + 'name' => $name ]; })->toArray(); + + if($status->in_reply_to_id != null) { + $parent = $status->parent()->profile; + if($parent) { + $webfinger = $parent->emailUrl(); + $name = Str::startsWith($webfinger, '@') ? + $webfinger : + '@' . $webfinger; + $reply = [ + 'type' => 'Mention', + 'href' => $parent->permalink(), + 'name' => $name + ]; + $mentions = array_merge($reply, $mentions); + } + } + $hashtags = $status->hashtags->map(function ($hashtag) { return [ 'type' => 'Hashtag', diff --git a/app/Transformer/ActivityPub/Verb/Note.php b/app/Transformer/ActivityPub/Verb/Note.php index d27875967..f58ca6f4b 100644 --- a/app/Transformer/ActivityPub/Verb/Note.php +++ b/app/Transformer/ActivityPub/Verb/Note.php @@ -4,6 +4,7 @@ namespace App\Transformer\ActivityPub\Verb; use App\Status; use League\Fractal; +use Illuminate\Support\Str; class Note extends Fractal\TransformerAbstract { @@ -11,12 +12,33 @@ class Note extends Fractal\TransformerAbstract { $mentions = $status->mentions->map(function ($mention) { + $webfinger = $mention->emailUrl(); + $name = Str::startsWith($webfinger, '@') ? + $webfinger : + '@' . $webfinger; return [ 'type' => 'Mention', 'href' => $mention->permalink(), - 'name' => $mention->emailUrl() + 'name' => $name ]; })->toArray(); + + if($status->in_reply_to_id != null) { + $parent = $status->parent()->profile; + if($parent) { + $webfinger = $parent->emailUrl(); + $name = Str::startsWith($webfinger, '@') ? + $webfinger : + '@' . $webfinger; + $reply = [ + 'type' => 'Mention', + 'href' => $parent->permalink(), + 'name' => $name + ]; + $mentions = array_merge($reply, $mentions); + } + } + $hashtags = $status->hashtags->map(function ($hashtag) { return [ 'type' => 'Hashtag', diff --git a/routes/api.php b/routes/api.php index 20e63413c..d3317352e 100644 --- a/routes/api.php +++ b/routes/api.php @@ -2,67 +2,69 @@ use Illuminate\Http\Request; +$middleware = ['auth:api','twofactor','validemail','localization']; + Route::post('/users/{username}/inbox', 'FederationController@userInbox'); -Route::group(['prefix' => 'api'], function() { - Route::group(['prefix' => 'v1'], function() { +Route::group(['prefix' => 'api'], function() use($middleware) { + Route::group(['prefix' => 'v1'], function() use($middleware) { Route::post('apps', 'Api\ApiV1Controller@apps'); Route::get('instance', 'Api\ApiV1Controller@instance'); - 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'); - 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::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::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::get('accounts/verify_credentials', 'Api\ApiV1Controller@verifyCredentials')->middleware($middleware); + Route::patch('accounts/update_credentials', 'Api\ApiV1Controller@accountUpdateCredentials')->middleware($middleware); + Route::get('accounts/relationships', 'Api\ApiV1Controller@accountRelationshipsById')->middleware($middleware); + Route::get('accounts/search', 'Api\ApiV1Controller@accountSearch')->middleware($middleware); + Route::get('accounts/{id}/statuses', 'Api\ApiV1Controller@accountStatusesById')->middleware($middleware); + Route::get('accounts/{id}/following', 'Api\ApiV1Controller@accountFollowingById')->middleware($middleware); + Route::get('accounts/{id}/followers', 'Api\ApiV1Controller@accountFollowersById')->middleware($middleware); + Route::post('accounts/{id}/follow', 'Api\ApiV1Controller@accountFollowById')->middleware($middleware); + Route::post('accounts/{id}/unfollow', 'Api\ApiV1Controller@accountUnfollowById')->middleware($middleware); + Route::post('accounts/{id}/block', 'Api\ApiV1Controller@accountBlockById')->middleware($middleware); + Route::post('accounts/{id}/unblock', 'Api\ApiV1Controller@accountUnblockById')->middleware($middleware); + Route::post('accounts/{id}/pin', 'Api\ApiV1Controller@accountEndorsements')->middleware($middleware); + Route::post('accounts/{id}/unpin', 'Api\ApiV1Controller@accountEndorsements')->middleware($middleware); + Route::post('accounts/{id}/mute', 'Api\ApiV1Controller@accountMuteById')->middleware($middleware); + Route::post('accounts/{id}/unmute', 'Api\ApiV1Controller@accountUnmuteById')->middleware($middleware); + Route::get('accounts/{id}/lists', 'Api\ApiV1Controller@accountListsById')->middleware($middleware); + Route::get('lists/{id}/accounts', 'Api\ApiV1Controller@accountListsById')->middleware($middleware); + Route::get('accounts/{id}', 'Api\ApiV1Controller@accountById')->middleware($middleware); - 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::post('avatar/update', 'ApiController@avatarUpdate')->middleware($middleware); + Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware($middleware); + Route::get('conversations', 'Api\ApiV1Controller@conversations')->middleware($middleware); 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('favourites', 'Api\ApiV1Controller@accountFavourites')->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('lists', 'Api\ApiV1Controller@accountLists')->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('notifications', 'Api\ApiV1Controller@accountNotifications')->middleware('auth:api'); - Route::get('suggestions', 'Api\ApiV1Controller@accountSuggestions')->middleware('auth:api'); + Route::get('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware($middleware); + Route::post('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware($middleware); + Route::delete('domain_blocks', 'Api\ApiV1Controller@accountDomainBlocks')->middleware($middleware); + Route::get('endorsements', 'Api\ApiV1Controller@accountEndorsements')->middleware($middleware); + Route::get('favourites', 'Api\ApiV1Controller@accountFavourites')->middleware($middleware); + Route::get('filters', 'Api\ApiV1Controller@accountFilters')->middleware($middleware); + Route::get('follow_requests', 'Api\ApiV1Controller@accountFollowRequests')->middleware($middleware); + Route::post('follow_requests/{id}/authorize', 'Api\ApiV1Controller@accountFollowRequestAccept')->middleware($middleware); + Route::post('follow_requests/{id}/reject', 'Api\ApiV1Controller@accountFollowRequestReject')->middleware($middleware); + Route::get('lists', 'Api\ApiV1Controller@accountLists')->middleware($middleware); + Route::post('media', 'Api\ApiV1Controller@mediaUpload')->middleware($middleware); + Route::put('media/{id}', 'Api\ApiV1Controller@mediaUpdate')->middleware($middleware); + Route::get('mutes', 'Api\ApiV1Controller@accountMutes')->middleware($middleware); + Route::get('notifications', 'Api\ApiV1Controller@accountNotifications')->middleware($middleware); + Route::get('suggestions', 'Api\ApiV1Controller@accountSuggestions')->middleware($middleware); - 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::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::post('statuses/{id}/favourite', 'Api\ApiV1Controller@statusFavouriteById')->middleware($middleware); + Route::post('statuses/{id}/unfavourite', 'Api\ApiV1Controller@statusUnfavouriteById')->middleware($middleware); + Route::get('statuses/{id}/context', 'Api\ApiV1Controller@statusContext')->middleware($middleware); + Route::get('statuses/{id}/card', 'Api\ApiV1Controller@statusCard')->middleware($middleware); + Route::get('statuses/{id}/reblogged_by', 'Api\ApiV1Controller@statusRebloggedBy')->middleware($middleware); + Route::get('statuses/{id}/favourited_by', 'Api\ApiV1Controller@statusFavouritedBy')->middleware($middleware); + Route::post('statuses/{id}/reblog', 'Api\ApiV1Controller@statusShare')->middleware($middleware); + Route::post('statuses/{id}/unreblog', 'Api\ApiV1Controller@statusUnshare')->middleware($middleware); + Route::delete('statuses/{id}', 'Api\ApiV1Controller@statusDelete')->middleware($middleware); + Route::get('statuses/{id}', 'Api\ApiV1Controller@statusById')->middleware($middleware); + Route::post('statuses', 'Api\ApiV1Controller@statusCreate')->middleware($middleware); - Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware('auth:api'); + Route::get('timelines/home', 'Api\ApiV1Controller@timelineHome')->middleware($middleware); Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic'); - Route::get('timelines/tag/{hashtag}', 'Api\ApiV1Controller@timelineHashtag')->middleware('auth:api'); + Route::get('timelines/tag/{hashtag}', 'Api\ApiV1Controller@timelineHashtag')->middleware($middleware); }); });