diff --git a/CHANGELOG.md b/CHANGELOG.md index 75c857a4..99bbcb86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,11 @@ - Updated NotificationCard.vue component, add follow requests at top of card, remove card-header ([5e48ffca](https://github.com/pixelfed/pixelfed/commit/5e48ffca)) - Updated RemoteProfile.vue component, add warning for empty profiles and last_fetched_at ([66f44a9d](https://github.com/pixelfed/pixelfed/commit/66f44a9d)) - Updated ApiV1Controller, enforce public timeline setting ([285bd485](https://github.com/pixelfed/pixelfed/commit/285bd485)) -- Update SearchController, fix self search bug and rank local matches higher ([f67fada2](https://github.com/pixelfed/pixelfed/commit/f67fada2)) +- Updated SearchController, fix self search bug and rank local matches higher ([f67fada2](https://github.com/pixelfed/pixelfed/commit/f67fada2)) +- Updated FederationController, improve webfinger logic, fixes ([#2180](https://github.com/pixelfed/pixelfed/issues/2180)) ([302ff874](https://github.com/pixelfed/pixelfed/commit/302ff874)) +- Updated ApiV1Controller, fix broken auth check on public timelines. Fixes ([#2168](https://github.com/pixelfed/pixelfed/issues/2168)) ([aa49afc7](https://github.com/pixelfed/pixelfed/commit/aa49afc7)) +- Updated SearchApiV2Service, fix offset bug ([#2116](https://github.com/pixelfed/pixelfed/issues/2116)) ([a0c0c84d](https://github.com/pixelfed/pixelfed/commit/a0c0c84d)) +- Updated api routes, fixes ([#2114](https://github.com/pixelfed/pixelfed/issues/2114)) ([50bbeddd](https://github.com/pixelfed/pixelfed/commit/50bbeddd)) ## [v0.10.9 (2020-04-17)](https://github.com/pixelfed/pixelfed/compare/v0.10.8...v0.10.9) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 83cc2af0..1a9e4220 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1397,8 +1397,6 @@ class ApiV1Controller extends Controller */ public function timelinePublic(Request $request) { - abort_if(!config('instance.timeline.local.is_public') && !$request->user(), 403); - $this->validate($request,[ 'page' => 'nullable|integer|max:40', 'min_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, diff --git a/app/Http/Controllers/DiscoverController.php b/app/Http/Controllers/DiscoverController.php index fd90d228..4f443ed2 100644 --- a/app/Http/Controllers/DiscoverController.php +++ b/app/Http/Controllers/DiscoverController.php @@ -135,6 +135,7 @@ class DiscoverController extends Controller public function profilesDirectory(Request $request) { + return redirect('/')->with('statusRedirect', 'The Profile Directory is unavailable at this time.'); return view('discover.profiles.home'); } @@ -144,6 +145,8 @@ class DiscoverController extends Controller 'page' => 'integer|max:10' ]); + return ['error' => 'Temporarily unavailable.']; + $page = $request->input('page') ?? 1; $key = 'discover:profiles:page:' . $page; $ttl = now()->addHours(12); diff --git a/app/Http/Controllers/FederationController.php b/app/Http/Controllers/FederationController.php index 8b7292c0..182725ad 100644 --- a/app/Http/Controllers/FederationController.php +++ b/app/Http/Controllers/FederationController.php @@ -46,14 +46,14 @@ class FederationController extends Controller public function webfinger(Request $request) { - abort_if(!config('federation.webfinger.enabled'), 404); + abort_if(!config('federation.webfinger.enabled'), 400); - $this->validate($request, ['resource'=>'required|string|min:3|max:255']); + abort_if(!$request->filled('resource'), 400); $resource = $request->input('resource'); $parsed = Nickname::normalizeProfileUrl($resource); if($parsed['domain'] !== config('pixelfed.domain.app')) { - abort(404); + abort(400); } $username = $parsed['username']; $profile = Profile::whereNull('domain')->whereUsername($username)->firstOrFail(); @@ -108,7 +108,7 @@ class FederationController extends Controller return ProfileController::accountCheck($profile); } $body = $request->getContent(); - $bodyDecoded = json_decode($body, true, 8); + $bodyDecoded = json_decode($body, true, 12); if($this->verifySignature($request, $profile) == true) { InboxWorker::dispatch($request->headers->all(), $profile, $bodyDecoded); } else if($this->blindKeyRotation($request, $profile) == true) { diff --git a/app/Services/SearchApiV2Service.php b/app/Services/SearchApiV2Service.php index 940812d7..7fc7c626 100644 --- a/app/Services/SearchApiV2Service.php +++ b/app/Services/SearchApiV2Service.php @@ -86,13 +86,12 @@ class SearchApiV2Service protected function accounts() { - $limit = $this->query->input('limit', 20); + $limit = $this->query->input('limit') ?? 20; + $offset = $this->query->input('offset') ?? 0; $query = '%' . $this->query->input('q') . '%'; $results = Profile::whereNull('status') ->where('username', 'like', $query) - ->when($this->query->input('offset') != null, function($q, $offset) { - return $q->offset($offset); - }) + ->offset($offset) ->limit($limit) ->get(); @@ -104,13 +103,12 @@ class SearchApiV2Service protected function hashtags() { - $limit = $this->query->input('limit', 20); + $limit = $this->query->input('limit') ?? 20; + $offset = $this->query->input('offset') ?? 0; $query = '%' . $this->query->input('q') . '%'; return Hashtag::whereIsBanned(false) ->where('name', 'like', $query) - ->when($this->query->input('offset') != null, function($q, $offset) { - return $q->offset($offset); - }) + ->offset($offset) ->limit($limit) ->get() ->map(function($tag) { @@ -124,21 +122,8 @@ class SearchApiV2Service protected function statuses() { - $limit = $this->query->input('limit', 20); - $query = '%' . $this->query->input('q') . '%'; - $results = Status::where('caption', 'like', $query) - ->whereScope('public') - ->when($this->query->input('offset') != null, function($q, $offset) { - return $q->offset($offset); - }) - ->limit($limit) - ->orderByDesc('created_at') - ->get(); - - $fractal = new Fractal\Manager(); - $fractal->setSerializer(new ArraySerializer()); - $resource = new Fractal\Resource\Collection($results, new StatusTransformer()); - return $fractal->createData($resource)->toArray(); + // Removed until we provide more relevent sorting/results + return []; } protected function statusesById() @@ -148,9 +133,6 @@ class SearchApiV2Service $query = '%' . $this->query->input('q') . '%'; $results = Status::where('caption', 'like', $query) ->whereProfileId($accountId) - ->when($this->query->input('offset') != null, function($q, $offset) { - return $q->offset($offset); - }) ->limit($limit) ->get(); diff --git a/app/Util/ActivityPub/Inbox.php b/app/Util/ActivityPub/Inbox.php index 4b8f9392..10b54841 100644 --- a/app/Util/ActivityPub/Inbox.php +++ b/app/Util/ActivityPub/Inbox.php @@ -18,10 +18,11 @@ use App\Util\ActivityPub\Helpers; use App\Jobs\LikePipeline\LikePipeline; use App\Jobs\FollowPipeline\FollowPipeline; -use App\Util\ActivityPub\Validator\{ - Accept, - Follow -}; +use App\Util\ActivityPub\Validator\Accept as AcceptValidator; +use App\Util\ActivityPub\Validator\Announce as AnnounceValidator; +use App\Util\ActivityPub\Validator\Follow as FollowValidator; +use App\Util\ActivityPub\Validator\Like as LikeValidator; +use App\Util\ActivityPub\Validator\UndoFollow as UndoFollowValidator; class Inbox { @@ -41,9 +42,15 @@ class Inbox { $this->handleVerb(); - (new Activity())->create([ - 'data' => json_encode($this->payload) - ]); + if(!Activity::where('data->id', $this->payload['id'])->exists()){ + (new Activity())->create([ + 'to_id' => $this->profile->id, + 'data' => json_encode($this->payload) + ]); + } + + return; + } public function handleVerb() @@ -59,11 +66,12 @@ class Inbox break; case 'Announce': + if(AnnounceValidator::validate($this->payload) == false) { return; } $this->handleAnnounceActivity(); break; case 'Accept': - if(Accept::validate($this->payload) == false) { return; } + if(AcceptValidator::validate($this->payload) == false) { return; } $this->handleAcceptActivity(); break; diff --git a/app/Util/ActivityPub/Validator/Announce.php b/app/Util/ActivityPub/Validator/Announce.php index c66fedbb..b6f89eec 100644 --- a/app/Util/ActivityPub/Validator/Announce.php +++ b/app/Util/ActivityPub/Validator/Announce.php @@ -16,11 +16,11 @@ class Announce { 'required', Rule::in(['Announce']) ], - 'actor' => 'required|url|active_url', + 'actor' => 'required|url', 'published' => 'required|date', 'to' => 'required', 'cc' => 'required', - 'object' => 'required|url|active_url' + 'object' => 'required|url' ])->passes(); return $valid; diff --git a/app/Util/ActivityPub/Validator/Follow.php b/app/Util/ActivityPub/Validator/Follow.php index a9c6ca2e..b249f7a3 100644 --- a/app/Util/ActivityPub/Validator/Follow.php +++ b/app/Util/ActivityPub/Validator/Follow.php @@ -16,8 +16,8 @@ class Follow { 'required', Rule::in(['Follow']) ], - 'actor' => 'required|url|active_url', - 'object' => 'required|url|active_url' + 'actor' => 'required|url', + 'object' => 'required|url' ])->passes(); return $valid; diff --git a/app/Util/ActivityPub/Validator/Like.php b/app/Util/ActivityPub/Validator/Like.php index 2573c1af..6fbdc2b7 100644 --- a/app/Util/ActivityPub/Validator/Like.php +++ b/app/Util/ActivityPub/Validator/Like.php @@ -16,8 +16,8 @@ class Like { 'required', Rule::in(['Like']) ], - 'actor' => 'required|url|active_url', - 'object' => 'required|url|active_url' + 'actor' => 'required|url', + 'object' => 'required|url' ])->passes(); return $valid; diff --git a/package-lock.json b/package-lock.json index b4f69768..c844d510 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5088,9 +5088,9 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "jquery": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", - "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz", + "integrity": "sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ==" }, "js-base64": { "version": "2.5.2", diff --git a/package.json b/package.json index e9a07bfe..ca7cfa12 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "axios": "^0.18.1", "bootstrap": "^4.4.1", "cross-env": "^5.2.1", - "jquery": "^3.4.1", + "jquery": "^3.5.0", "lodash": ">=4.17.13", "popper.js": "^1.16.1", "resolve-url-loader": "^2.3.2", diff --git a/resources/lang/fr/exception.php b/resources/lang/fr/exception.php new file mode 100644 index 00000000..bd0fedb0 --- /dev/null +++ b/resources/lang/fr/exception.php @@ -0,0 +1,10 @@ + [ + 'invalid' => [ + 'album' => 'Doit contenir une seule photo ou vidéo ou plusieurs photos.', + ], + ], + +]; diff --git a/resources/lang/fr/navmenu.php b/resources/lang/fr/navmenu.php index cae51c6e..34547d54 100644 --- a/resources/lang/fr/navmenu.php +++ b/resources/lang/fr/navmenu.php @@ -14,4 +14,5 @@ return [ 'admin' => 'Admin', 'logout' => 'Se déconnecter', 'directMessages' => 'Messages Directs', + 'composePost' => 'Composer une publication', ]; diff --git a/resources/views/timeline/home.blade.php b/resources/views/timeline/home.blade.php index f16cab7a..c95e7f6c 100644 --- a/resources/views/timeline/home.blade.php +++ b/resources/views/timeline/home.blade.php @@ -1,15 +1,41 @@ @extends('layouts.app') +{{-- @extends('layouts.blank') --}} @section('content') - - - +@if(session('statusRedirect')) +
+
+
+

+
+
+

+ {{ session('statusRedirect') }} +

+
+
+

+ +

+
+
+
+@endif + + + @endsection @push('scripts') diff --git a/routes/api.php b/routes/api.php index f37a496f..d891eb2c 100644 --- a/routes/api.php +++ b/routes/api.php @@ -7,6 +7,7 @@ $middleware = ['auth:api','twofactor','validemail','localization']; Route::post('/users/{username}/inbox', 'FederationController@userInbox'); 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'); @@ -28,7 +29,7 @@ Route::group(['prefix' => 'api'], function() use($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::get('accounts/{id}', 'Api\ApiV1Controller@accountById'); Route::post('avatar/update', 'ApiController@avatarUpdate')->middleware($middleware); Route::get('blocks', 'Api\ApiV1Controller@accountBlocks')->middleware($middleware); @@ -67,18 +68,19 @@ Route::group(['prefix' => 'api'], function() use($middleware) { Route::get('timelines/public', 'Api\ApiV1Controller@timelinePublic'); Route::get('timelines/tag/{hashtag}', 'Api\ApiV1Controller@timelineHashtag')->middleware($middleware); }); - Route::group(['prefix' => 'stories'], function () use($middleware) { - Route::get('v1/me', 'StoryController@apiV1Me'); - Route::get('v1/recent', 'StoryController@apiV1Recent'); - Route::post('v1/add', 'StoryController@apiV1Add')->middleware(array_merge($middleware, ['throttle:maxStoriesPerDay,1440'])); - Route::get('v1/item/{id}', 'StoryController@apiV1Item'); - Route::get('v1/fetch/{id}', 'StoryController@apiV1Fetch'); - Route::get('v1/profile/{id}', 'StoryController@apiV1Profile'); - Route::get('v1/exists/{id}', 'StoryController@apiV1Exists'); - Route::delete('v1/delete/{id}', 'StoryController@apiV1Delete')->middleware(array_merge($middleware, ['throttle:maxStoryDeletePerDay,1440'])); - Route::post('v1/viewed', 'StoryController@apiV1Viewed'); - }); - Route::group(['prefix' => 'v2'], function() use($middleware) { - Route::get('search', 'Api\ApiV1Controller@searchV2')->middleware($middleware); - }); + Route::group(['prefix' => 'stories'], function () use($middleware) { + Route::get('v1/me', 'StoryController@apiV1Me'); + Route::get('v1/recent', 'StoryController@apiV1Recent'); + Route::post('v1/add', 'StoryController@apiV1Add')->middleware(array_merge($middleware, ['throttle:maxStoriesPerDay,1440'])); + Route::get('v1/item/{id}', 'StoryController@apiV1Item'); + Route::get('v1/fetch/{id}', 'StoryController@apiV1Fetch'); + Route::get('v1/profile/{id}', 'StoryController@apiV1Profile'); + Route::get('v1/exists/{id}', 'StoryController@apiV1Exists'); + Route::delete('v1/delete/{id}', 'StoryController@apiV1Delete')->middleware(array_merge($middleware, ['throttle:maxStoryDeletePerDay,1440'])); + Route::post('v1/viewed', 'StoryController@apiV1Viewed'); + }); + Route::group(['prefix' => 'v2'], function() use($middleware) { + Route::get('search', 'Api\ApiV1Controller@searchV2')->middleware($middleware); + }); + }); diff --git a/tests/Unit/ActivityPub/FollowTest.php b/tests/Unit/ActivityPub/FollowTest.php deleted file mode 100644 index 4edc33a5..00000000 --- a/tests/Unit/ActivityPub/FollowTest.php +++ /dev/null @@ -1,27 +0,0 @@ -mastodon = '{"type":"Follow","signature":{"type":"RsaSignature2017","signatureValue":"Kn1/UkAQGJVaXBfWLAHcnwHg8YMAUqlEaBuYLazAG+pz5hqivsyrBmPV186Xzr+B4ZLExA9+SnOoNx/GOz4hBm0kAmukNSILAsUd84tcJ2yT9zc1RKtembK4WiwOw7li0+maeDN0HaB6t+6eTqsCWmtiZpprhXD8V1GGT8yG7X24fQ9oFGn+ng7lasbcCC0988Y1eGqNe7KryxcPuQz57YkDapvtONzk8gyLTkZMV4De93MyRHq6GVjQVIgtiYabQAxrX6Q8C+4P/jQoqdWJHEe+MY5JKyNaT/hMPt2Md1ok9fZQBGHlErk22/zy8bSN19GdG09HmIysBUHRYpBLig==","creator":"http://mastodon.example.org/users/admin#main-key","created":"2018-02-17T13:29:31Z"},"object":"http://localtesting.pleroma.lol/users/lain","nickname":"lain","id":"http://mastodon.example.org/users/admin#follows/2","actor":"http://mastodon.example.org/users/admin","@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"toot":"http://joinmastodon.org/ns#","sensitive":"as:sensitive","ostatus":"http://ostatus.org#","movedTo":"as:movedTo","manuallyApprovesFollowers":"as:manuallyApprovesFollowers","inReplyToAtomUri":"ostatus:inReplyToAtomUri","conversation":"ostatus:conversation","atomUri":"ostatus:atomUri","Hashtag":"as:Hashtag","Emoji":"toot:Emoji"}]}'; - - } - - /** @test */ - public function validateMastodonFollowObject() - { - $mastodon = json_decode($this->mastodon, true); - $mastodon = Helpers::validateObject($mastodon); - $this->assertTrue($mastodon); - } -} \ No newline at end of file diff --git a/tests/Unit/ActivityPub/Verb/AcceptVerbTest.php b/tests/Unit/ActivityPub/Verb/AcceptVerbTest.php index 81f631df..cdf998af 100644 --- a/tests/Unit/ActivityPub/Verb/AcceptVerbTest.php +++ b/tests/Unit/ActivityPub/Verb/AcceptVerbTest.php @@ -39,6 +39,42 @@ class AcceptVerbTest extends TestCase 'object' => 'https://example.org/u/alice' ] ]; + $this->mastodonAccept = [ + "@context" => [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + [ + "toot" => "https://joinmastodon.org/ns#", + "sensitive" => "as:sensitive", + "ostatus" => "https://ostatus.org#", + "movedTo" => "as:movedTo", + "manuallyApprovesFollowers" => "as:manuallyApprovesFollowers", + "inReplyToAtomUri" => "ostatus:inReplyToAtomUri", + "conversation" => "ostatus:conversation", + "atomUri" => "ostatus:atomUri", + "Hashtag" => "as:Hashtag", + "Emoji" => "toot:Emoji", + ], + ], + + "type" => "Accept", + + "object" => [ + "type" => "Follow", + "object" => "https://mastodon.example.org/users/admin", + "id" => "https://pixelfed.dev/users/dsup#follows/4", + "actor" => "https://pixelfed.dev/users/dsup", + ], + "nickname" => "dsup", + "id" => "https://mastodon.example.org/users/admin#accepts/follows/4", + "actor" => "https://mastodon.example.org/users/admin", + "signature" => [ + "type" => "RsaSignature2017", + "signatureValue" => "rBzK4Kqhd4g7HDS8WE5oRbWQb2R+HF/6awbUuMWhgru/xCODT0SJWSri0qWqEO4fPcpoUyz2d25cw6o+iy9wiozQb3hQNnu69AR+H5Mytc06+g10KCHexbGhbAEAw/7IzmeXELHUbaqeduaDIbdt1zw4RkwLXdqgQcGXTJ6ND1wM3WMHXQCK1m0flasIXFoBxpliPAGiElV8s0+Ltuh562GvflG3kB3WO+j+NaR0ZfG5G9N88xMj9UQlCKit5gpAE5p6syUsCU2WGBHywTumv73i3OVTIFfq+P9AdMsRuzw1r7zoKEsthW4aOzLQDi01ZjvdBz8zH6JnjDU7SMN/Ig==", + "creator" => "https://mastodon.example.org/users/admin#main-key", + "created" => "2018-02-17T14:36:41Z", + ], + ]; } /** @test */ @@ -52,4 +88,10 @@ class AcceptVerbTest extends TestCase { $this->assertFalse(Accept::validate($this->invalidAccept)); } + + /** @test */ + public function mastodon_accept() + { + $this->assertTrue(Accept::validate($this->mastodonAccept)); + } } diff --git a/tests/Unit/ActivityPub/Verb/AnnounceTest.php b/tests/Unit/ActivityPub/Verb/AnnounceTest.php index 7b7eef14..520e9bd3 100644 --- a/tests/Unit/ActivityPub/Verb/AnnounceTest.php +++ b/tests/Unit/ActivityPub/Verb/AnnounceTest.php @@ -126,6 +126,44 @@ class AnnounceTest extends TestCase ], "object" => "https://example.org/p/bob/100000000000000", ]; + + $this->mastodonAnnounce = [ + "type" => "Announce", + "to" => [ + "https://www.w3.org/ns/activitystreams#Public", + ], + "signature" => [ + "type" => "RsaSignature2017", + "signatureValue" => "T95DRE0eAligvMuRMkQA01lsoz2PKi4XXF+cyZ0BqbrO12p751TEWTyyRn5a+HH0e4kc77EUhQVXwMq80WAYDzHKVUTf2XBJPBa68vl0j6RXw3+HK4ef5hR4KWFNBU34yePS7S1fEmc1mTG4Yx926wtmZwDpEMTp1CXOeVEjCYzmdyHpepPPH2ZZettiacmPRSqBLPGWZoot7kH/SioIdnrMGY0I7b+rqkIdnnEcdhu9N1BKPEO9Sr+KmxgAUiidmNZlbBXX6gCxp8BiIdH4ABsIcwoDcGNkM5EmWunGW31LVjsEQXhH5c1Wly0ugYYPCg/0eHLNBOhKkY/teSM8Lg==", + "creator" => "https://mastodon.example.org/users/admin#main-key", + "created" => "2018-02-17T19:39:15Z", + ], + "published" => "2018-02-17T19:39:15Z", + "object" => "https://mastodon.example.org/@admin/99541947525187367", + "id" => "https://mastodon.example.org/users/admin/statuses/99542391527669785/activity", + "cc" => [ + "https://mastodon.example.org/users/admin", + "https://mastodon.example.org/users/admin/followers", + ], + "atomUri" => "https://mastodon.example.org/users/admin/statuses/99542391527669785/activity", + "actor" => "https://mastodon.example.org/users/admin", + "@context" => [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + [ + "toot" => "https://joinmastodon.org/ns#", + "sensitive" => "as:sensitive", + "ostatus" => "https://ostatus.org#", + "movedTo" => "as:movedTo", + "manuallyApprovesFollowers" => "as:manuallyApprovesFollowers", + "inReplyToAtomUri" => "ostatus:inReplyToAtomUri", + "conversation" => "ostatus:conversation", + "atomUri" => "ostatus:atomUri", + "Hashtag" => "as:Hashtag", + "Emoji" => "toot:Emoji", + ], + ], + ]; } /** @test */ @@ -165,4 +203,10 @@ class AnnounceTest extends TestCase $this->assertFalse(Announce::validate($this->invalidActor)); $this->assertFalse(Announce::validate($this->invalidActor2)); } + + /** @test */ + public function mastodon_announce() + { + $this->assertTrue(Announce::validate($this->mastodonAnnounce)); + } } diff --git a/tests/Unit/ActivityPub/Verb/FollowTest.php b/tests/Unit/ActivityPub/Verb/FollowTest.php new file mode 100644 index 00000000..58f2b96d --- /dev/null +++ b/tests/Unit/ActivityPub/Verb/FollowTest.php @@ -0,0 +1,53 @@ +basicFollow = [ + "type" => "Follow", + "signature" => [ + "type" => "RsaSignature2017", + "signatureValue" => "Kn1/UkAQGJVaXBfWLAHcnwHg8YMAUqlEaBuYLazAG+pz5hqivsyrBmPV186Xzr+B4ZLExA9+SnOoNx/GOz4hBm0kAmukNSILAsUd84tcJ2yT9zc1RKtembK4WiwOw7li0+maeDN0HaB6t+6eTqsCWmtiZpprhXD8V1GGT8yG7X24fQ9oFGn+ng7lasbcCC0988Y1eGqNe7KryxcPuQz57YkDapvtONzk8gyLTkZMV4De93MyRHq6GVjQVIgtiYabQAxrX6Q8C+4P/jQoqdWJHEe+MY5JKyNaT/hMPt2Md1ok9fZQBGHlErk22/zy8bSN19GdG09HmIysBUHRYpBLig==", + "creator" => "http://mastodon.example.org/users/admin#main-key", + "created" => "2018-02-17T13:29:31Z", + ], + "object" => "http://pixelfed.dev/users/dsup", + "nickname" => "dsup", + "id" => "http://mastodon.example.org/users/admin#follows/2", + "actor" => "http://mastodon.example.org/users/admin", + "@context" => [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + [ + "toot" => "http://joinmastodon.org/ns#", + "sensitive" => "as:sensitive", + "ostatus" => "http://ostatus.org#", + "movedTo" => "as:movedTo", + "manuallyApprovesFollowers" => "as:manuallyApprovesFollowers", + "inReplyToAtomUri" => "ostatus:inReplyToAtomUri", + "conversation" => "ostatus:conversation", + "atomUri" => "ostatus:atomUri", + "Hashtag" => "as:Hashtag", + "Emoji" => "toot:Emoji", + ], + ], + ]; + } + + /** @test */ + public function basic_follow() + { + $this->assertTrue(Follow::validate($this->basicFollow)); + } +} \ No newline at end of file diff --git a/tests/Unit/ActivityPub/Verb/LikeTest.php b/tests/Unit/ActivityPub/Verb/LikeTest.php new file mode 100644 index 00000000..f23fa00a --- /dev/null +++ b/tests/Unit/ActivityPub/Verb/LikeTest.php @@ -0,0 +1,53 @@ +basicLike = [ + "type" => "Like", + "signature" => [ + "type" => "RsaSignature2017", + "signatureValue" => "fdxMfQSMwbC6wP6sh6neS/vM5879K67yQkHTbiT5Npr5wAac0y6+o3Ij+41tN3rL6wfuGTosSBTHOtta6R4GCOOhCaCSLMZKypnp1VltCzLDoyrZELnYQIC8gpUXVmIycZbREk22qWUe/w7DAFaKK4UscBlHDzeDVcA0K3Se5Sluqi9/Zh+ldAnEzj/rSEPDjrtvf5wGNf3fHxbKSRKFt90JvKK6hS+vxKUhlRFDf6/SMETw+EhwJSNW4d10yMUakqUWsFv4Acq5LW7l+HpYMvlYY1FZhNde1+uonnCyuQDyvzkff8zwtEJmAXC4RivO/VVLa17SmqheJZfI8oluVg==", + "creator" => "http://mastodon.example.org/users/admin#main-key", + "created" => "2018-02-17T18:57:49Z", + ], + "object" => "http://pixelfed.dev/p/1", + "nickname" => "dsup", + "id" => "http://mastodon.example.org/users/admin#likes/2", + "actor" => "http://mastodon.example.org/users/admin", + "@context" => [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + [ + "toot" => "http://joinmastodon.org/ns#", + "sensitive" => "as:sensitive", + "ostatus" => "http://ostatus.org#", + "movedTo" => "as:movedTo", + "manuallyApprovesFollowers" => "as:manuallyApprovesFollowers", + "inReplyToAtomUri" => "ostatus:inReplyToAtomUri", + "conversation" => "ostatus:conversation", + "atomUri" => "ostatus:atomUri", + "Hashtag" => "as:Hashtag", + "Emoji" => "toot:Emoji", + ], + ], + ]; + } + + /** @test */ + public function basic_like() + { + $this->assertTrue(Like::validate($this->basicLike)); + } +} \ No newline at end of file