target = $target; $this->activity = $activity; } /** * Get the middleware the job should pass through. * * @return array */ public function middleware(): array { return [ new WithoutOverlapping('process-move:'.$this->target), (new ThrottlesExceptions(2, 5 * 60))->backoff(5), ]; } /** * Determine the time at which the job should timeout. */ public function retryUntil(): DateTime { return now()->addMinutes(5); } /** * Execute the job. */ public function handle(): void { if (config('app.env') !== 'production' || (bool) config_cache('federation.activitypub.enabled') == false) { throw new Exception('Activitypub not enabled'); } if (! self::checkTarget()) { throw new Exception('Invalid target'); } if (! self::checkActor()) { throw new Exception('Invalid actor'); } return; } protected function checkTarget() { $res = ActivityPubFetchService::fetchRequest($this->target, true); if (! $res || ! isset($res['alsoKnownAs'])) { Log::info('[AP][INBOX][MOVE] target_aka failure'); return false; } $res = Helpers::profileFetch($this->target); if (! $res) { Log::info('[AP][INBOX][MOVE] target fetch failure'); return false; } if (is_string($res['alsoKnownAs'])) { return self::lowerTrim($res['alsoKnownAs']) === self::lowerTrim($this->activity); } if (is_array($res['alsoKnownAs'])) { $map = Arr::map($res['alsoKnownAs'], function ($value, $key) { return trim(strtolower($value)); }); $res = in_array($this->activity, $map); $debugMessage = $res ? '[AP][INBOX][MOVE] aka target is valid' : '[AP][INBOX][MOVE] aka target is invalid'; Log::info($debugMessage); return $res; } return false; } protected function checkActor() { $res = ActivityPubFetchService::fetchRequest($this->activity, true); if (! $res || ! isset($res['movedTo'])) { Log::info('[AP][INBOX][MOVE] actor_movedTo failure'); return false; } $res = Helpers::profileFetch($this->activity); if (! $res) { Log::info('[AP][INBOX][MOVE] actor fetch failure'); return false; } if (is_string($res['movedTo'])) { return self::lowerTrim($res['movedTo']) === self::lowerTrim($this->target); } return false; } protected function lowerTrim($str) { return trim(strtolower($str)); } }