diff --git a/app/Util/ActivityPub/Concern/HTTPSignature.php b/app/Util/ActivityPub/Concern/HTTPSignature.php new file mode 100644 index 00000000..e612243d --- /dev/null +++ b/app/Util/ActivityPub/Concern/HTTPSignature.php @@ -0,0 +1,94 @@ +is_url === false) { + return true; + } + + $url = $this->profile; + try { + $url = filter_var($url, FILTER_VALIDATE_URL); + $parsed = parse_url($url, PHP_URL_HOST); + if(!$parsed || in_array($parsed, $this->localhosts)) { + return false; + } + } catch (Exception $e) { + return false; + } + return true; + } + + public function fetchPublicKey($profile, bool $is_url = true) + { + $this->profile = $profile; + $this->is_url = $is_url; + $valid = $this->validateUrl(); + if(!$valid) { + throw new \Exception('Invalid URL provided'); + } + if($is_url && isset($profile->public_key) && $profile->public_key) { + return $profile->public_key; + } + + try { + $url = $this->profile; + $res = Zttp::timeout(60)->withoutVerifying()->withHeaders([ + 'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', + 'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org' + ])->get($url); + $actor = json_decode($res->getBody(), true); + } catch (Exception $e) { + throw new Exception('Unable to fetch public key'); + } + + return $actor['publicKey']['publicKeyPem']; + } + + public function sendSignedObject($senderProfile, $url, $body) + { + $profile = $senderProfile; + $context = new Context([ + 'keys' => [$profile->keyId() => $profile->private_key], + 'algorithm' => 'rsa-sha256', + 'headers' => ['(request-target)', 'Date'], + ]); + + $handlerStack = GuzzleHttpSignatures::defaultHandlerFromContext($context); + $client = new Client(['handler' => $handlerStack]); + + $headers = [ + 'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', + 'Date' => date('D, d M Y h:i:s') . ' GMT', + 'Content-Type' => 'application/activity+json', + 'User-Agent' => 'PixelFedBot - https://pixelfed.org' + ]; + + $response = $client->post($url, [ + 'options' => [ + 'allow_redirects' => false, + 'verify' => true, + 'timeout' => 30 + ], + 'headers' => $headers, + 'body' => $body + ]); + + return $response->getBody(); + } + + +} \ No newline at end of file