diff --git a/TODO.md b/TODO.md index 0b4fa20..36b1cb1 100644 --- a/TODO.md +++ b/TODO.md @@ -54,3 +54,6 @@ - [x] Fix that weird json encoding in the object field of an activity - [ ] The profile attachments are not working, they are not being federalised somehow (the interests thingy) - [ ] Endpoints for getting notes (/ap/v1/note/{note}) + - [ ] Fix hashtags on post update + - [x] Use jobs when posting activities + - [ ] Sign the get activities for mastodon when secure mode is enable diff --git a/app/Http/Controllers/AP/APOutboxController.php b/app/Http/Controllers/AP/APOutboxController.php index eee7b75..86a8199 100644 --- a/app/Http/Controllers/AP/APOutboxController.php +++ b/app/Http/Controllers/AP/APOutboxController.php @@ -173,8 +173,9 @@ class APOutboxController extends Controller "object" => $object_actor->id, ]); - if (!$response || $response->getStatusCode () < 200 || $response->getStatusCode () >= 300) - return response ()->json ([ "error" => "failed to post activity" ], 500); + // TODO: Check if it was successfully sent + /* if (!$response || $response->getStatusCode () < 200 || $response->getStatusCode () >= 300) + return response ()->json ([ "error" => "failed to post activity" ], 500); */ return [ "success" => "followed" @@ -197,8 +198,9 @@ class APOutboxController extends Controller $unfollow_activity = TypeActivity::craft_undo ($follow_activity, $user->actor ()->first ()); $response = TypeActivity::post_activity ($unfollow_activity, $user->actor ()->first (), $object_actor); - if (!$response || $response->getStatusCode () < 200 || $response->getStatusCode () >= 300) - return response ()->json ([ "error" => "failed to post activity" ], 500); + // TODO: Check if it was successfully sent + /* if (!$response || $response->getStatusCode () < 200 || $response->getStatusCode () >= 300) + return response ()->json ([ "error" => "failed to post activity" ], 500); */ $follow_activity->delete (); return [ @@ -243,8 +245,9 @@ class APOutboxController extends Controller $response = TypeActivity::post_activity ($like_activity, $actor, $object->get_actor ()->first ()); - if (!$response || $response->getStatusCode () < 200 || $response->getStatusCode () >= 300) - return response ()->json ([ "error" => "failed to post activity" ], 500); + // TODO: Check if it was successfully sent + /* if (!$response || $response->getStatusCode () < 200 || $response->getStatusCode () >= 300) + return response ()->json ([ "error" => "failed to post activity" ], 500); */ return [ "success" => "liked" diff --git a/app/Jobs/PostActivityJob.php b/app/Jobs/PostActivityJob.php new file mode 100644 index 0000000..d4ce1bb --- /dev/null +++ b/app/Jobs/PostActivityJob.php @@ -0,0 +1,101 @@ +activity = $activity; + $this->actor = $actor; + $this->target = $target; + $this->should_sign = $should_sign; + } + + /** + * Execute the job. + */ + public function handle(): void + { + $crafted_activity = TypeActivity::craft_response($this->activity); + + if ($this->should_sign) + { + $crafted_activity ["to"] = [ + "https://www.w3.org/ns/activitystreams#Public", + ]; + + $crafted_activity ["cc"] = [ + $this->actor->following + ]; + + $key = TypeActivity::get_private_key($this->actor); + $activity_json = json_encode($crafted_activity, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + $signature = TypeActivity::sign($activity_json, $key); + + $crafted_activity ["signature"] = [ + "type" => "RsaSignature2017", + "creator" => $this->actor->actor_id . "#main-key", + "created" => gmdate("Y-m-d\TH:i:s\Z"), + "signatureValue" => base64_encode($signature) + ]; + + $activity_json = json_encode($crafted_activity, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + } + + $activity_json = json_encode($crafted_activity, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + $activity_json = mb_convert_encoding($activity_json, "UTF-8"); + + $headers = TypeActivity::craft_signed_headers($activity_json, $this->actor, $this->target); + if (!$headers) + { + throw new \Exception("Failed to craft headers"); + } + + $target_inbox = null; + + if ($this->target instanceof Actor) + { + $target_inbox = $this->target->inbox; + } + else + { + $target_inbox = $this->target; + } + + $client = new Client (); + $response = $client->post($target_inbox, [ + "headers" => $headers, + "body" => $activity_json, + "debug" => true + ]); + } + + public function failed (\Exception $exception) + { + Log::error("Failed to post activity: " . $exception->getMessage()); + } +} diff --git a/app/Types/TypeActivity.php b/app/Types/TypeActivity.php index 175d509..fc9c8bc 100644 --- a/app/Types/TypeActivity.php +++ b/app/Types/TypeActivity.php @@ -6,6 +6,8 @@ use App\Models\Actor; use App\Models\Activity; use App\Models\Instance; +use App\Jobs\PostActivityJob; + use GuzzleHttp\Client; use Illuminate\Support\Facades\Log; @@ -194,74 +196,11 @@ class TypeActivity { public static function post_activity (Activity $activity, Actor $source, $target, $should_sign = false) { - $crafted_activity = TypeActivity::craft_response ($activity); + PostActivityJob::dispatch ($activity, $source, $target, $should_sign); - if ($should_sign) - { - $crafted_activity["to"] = [ - "https://www.w3.org/ns/activitystreams#Public" - ]; - - $crafted_activity["cc"] = [ - $source->following - ]; - - $key = TypeActivity::get_private_key ($source); - $activity_json = json_encode ($crafted_activity, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION); - $signature = TypeActivity::sign ($activity_json, $key); - - $crafted_activity ["signature"] = [ - "type" => "RsaSignature2017", - "creator" => $source->actor_id . "#main-key", - "created" => gmdate ("Y-m-d\TH:i:s\Z"), - "signatureValue" => base64_encode ($signature) - ]; - - $activity_json = json_encode ($crafted_activity, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION); - } - - $activity_json = json_encode ($crafted_activity, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION); - $activity_json = mb_convert_encoding ($activity_json, "UTF-8"); - - $headers = TypeActivity::craft_signed_headers ($activity_json, $source, $target); - if (!$headers) - { - Log::error ("Failed to craft headers"); - return null; - } - - try { - $target_inbox = null; - - if ($target instanceof Actor) - { - $target_inbox = $target->inbox; - } - else - { - $target_inbox = $target; - } - - $client = new Client (); - $response = $client->post ($target_inbox, [ - "headers" => $headers, - "body" => $activity_json, - "debug" => true - ]); - } - catch (RequestException $e) - { - $response = $e->getResponse (); - if ($response) - { - Log::error ("Failed to post activity: " . $response->getBody ()); - } - - Log::error ("Failed to post activity: " . $e->getMessage ()); - return null; - } - - return $response; + return [ + "success" => "activity posted" + ]; } public static function post_to_instances (Activity $activity, Actor $source) @@ -272,11 +211,12 @@ class TypeActivity { if (!$instance->inbox) continue; - $response = TypeActivity::post_activity ($activity, $source, $instance->inbox, true); - if (!$response || $response->getStatusCode () < 200 || $response->getStatusCode () >= 300) + TypeActivity::post_activity ($activity, $source, $instance->inbox, true); + // TODO: Check if it was successfully posted + /* if (!$response || $response->getStatusCode () < 200 || $response->getStatusCode () >= 300) { Log::info ("failed to post activity to " . $instance->inbox); - } + } */ } } diff --git a/resources/views/users/profile.blade.php b/resources/views/users/profile.blade.php index 1227148..5d747d0 100644 --- a/resources/views/users/profile.blade.php +++ b/resources/views/users/profile.blade.php @@ -59,29 +59,37 @@ @if (!auth ()->user ()->is ($user))
@else