From 0db3960b0e5082ce3b706fa409020e4e19573913 Mon Sep 17 00:00:00 2001 From: Maurice Renck Date: Mon, 11 Nov 2024 09:24:24 +0100 Subject: [PATCH] fix: dependency updates - update of the bluesky api library fixes #15 --- composer.lock | 64 +++---- .../bluesky-api/src/BlueskyApi.php | 164 +++++++++++++----- vendor/composer/installed.php | 14 +- 3 files changed, 157 insertions(+), 85 deletions(-) diff --git a/composer.lock b/composer.lock index 04cfa92..eaa5d05 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "db82c175de414071e06155a0f53e9025", + "content-hash": "bae3b732fb0a4dea06d32466a26af887", "packages": [ { "name": "cjrasmussen/bluesky-api", - "version": "2.1.5", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/cjrasmussen/BlueskyApi.git", - "reference": "1487a71b351e5ec8d34361a3055369c0c39eb4a2" + "reference": "e8f696671955995eb11a1e7817bb83d5feb2a452" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cjrasmussen/BlueskyApi/zipball/1487a71b351e5ec8d34361a3055369c0c39eb4a2", - "reference": "1487a71b351e5ec8d34361a3055369c0c39eb4a2", + "url": "https://api.github.com/repos/cjrasmussen/BlueskyApi/zipball/e8f696671955995eb11a1e7817bb83d5feb2a452", + "reference": "e8f696671955995eb11a1e7817bb83d5feb2a452", "shasum": "" }, "require": { @@ -52,7 +52,7 @@ "issues": "https://github.com/cjrasmussen/BlueskyApi/issues", "source": "https://github.com/cjrasmussen/BlueskyApi" }, - "time": "2024-09-25T17:46:52+00:00" + "time": "2024-09-29T03:45:35+00:00" }, { "name": "getkirby/composer-installer", @@ -891,16 +891,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.12.0", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { @@ -939,7 +939,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { @@ -947,20 +947,20 @@ "type": "tidelift" } ], - "time": "2024-06-12T14:39:25+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { "name": "nikic/php-parser", - "version": "v5.2.0", + "version": "v5.3.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb" + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb", - "reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", "shasum": "" }, "require": { @@ -1003,9 +1003,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.2.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" }, - "time": "2024-09-15T16:40:33+00:00" + "time": "2024-10-08T18:51:32+00:00" }, { "name": "phar-io/manifest", @@ -1529,16 +1529,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.35", + "version": "10.5.38", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "7ac8b4e63f456046dcb4c9787da9382831a1874b" + "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7ac8b4e63f456046dcb4c9787da9382831a1874b", - "reference": "7ac8b4e63f456046dcb4c9787da9382831a1874b", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a86773b9e887a67bc53efa9da9ad6e3f2498c132", + "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132", "shasum": "" }, "require": { @@ -1559,7 +1559,7 @@ "phpunit/php-timer": "^6.0.0", "sebastian/cli-parser": "^2.0.1", "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.2", + "sebastian/comparator": "^5.0.3", "sebastian/diff": "^5.1.1", "sebastian/environment": "^6.1.0", "sebastian/exporter": "^5.1.2", @@ -1610,7 +1610,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.35" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.38" }, "funding": [ { @@ -1626,7 +1626,7 @@ "type": "tidelift" } ], - "time": "2024-09-19T10:52:21+00:00" + "time": "2024-10-28T13:06:21+00:00" }, { "name": "psr/log", @@ -1848,16 +1848,16 @@ }, { "name": "sebastian/comparator", - "version": "5.0.2", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53" + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53", - "reference": "2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", "shasum": "" }, "require": { @@ -1868,7 +1868,7 @@ "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^10.4" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { @@ -1913,7 +1913,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.2" + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" }, "funding": [ { @@ -1921,7 +1921,7 @@ "type": "github" } ], - "time": "2024-08-12T06:03:08+00:00" + "time": "2024-10-18T14:56:07+00:00" }, { "name": "sebastian/complexity", diff --git a/vendor/cjrasmussen/bluesky-api/src/BlueskyApi.php b/vendor/cjrasmussen/bluesky-api/src/BlueskyApi.php index 1359203..4f3bce8 100644 --- a/vendor/cjrasmussen/bluesky-api/src/BlueskyApi.php +++ b/vendor/cjrasmussen/bluesky-api/src/BlueskyApi.php @@ -10,15 +10,13 @@ */ class BlueskyApi { - private ?string $accountDid = null; - private ?string $apiKey = null; - private ?string $refreshToken = null; - private string $apiUri; - private ?array $lastResponseHeader = null; + private string $defaultApiHost; + private ?string $lastResponseHeader = null; + private ?object $activeSession = null; - public function __construct(string $api_uri = 'https://bsky.social/xrpc/') + public function __construct(string $api_host = 'bsky.social') { - $this->apiUri = $api_uri; + $this->defaultApiHost = $this->sanitizeApiHost($api_host); } /** @@ -41,16 +39,31 @@ public function auth(string $handleOrToken, ?string $app_password = null): bool } if ($data) { - $this->accountDid = $data->did; - $this->apiKey = $data->accessJwt; - $this->refreshToken = $data->refreshJwt; - return (bool)$data->did; } return false; } + /** + * Check to see if the current session is active + * + * @return object|null + * @throws JsonException + */ + public function getSession(): ?object + { + $data = $this->request('GET', 'com.atproto.server.getSession'); + + if (empty($data->error)) { + $this->activeSession = $data; + } else { + $this->activeSession = null; + } + + return $data; + } + /** * Check to see if the current session is active * @@ -59,8 +72,26 @@ public function auth(string $handleOrToken, ?string $app_password = null): bool */ public function isSessionActive(): bool { - $data = $this->request('GET', 'com.atproto.server.getSession'); - return (($data !== null) && empty($data->error)); + $this->getSession(); + return ($this->activeSession !== null); + } + + /** + * Get the endpoint URI from the session if available + * + * @return ?string + */ + public function getSessionHost(): ?string + { + if (($this->activeSession) && (is_array($this->activeSession->didDoc->service))) { + foreach ($this->activeSession->didDoc->service AS $service) { + if (!empty($service->serviceEndpoint)) { + return $this->sanitizeApiHost($service->serviceEndpoint); + } + } + } + + return null; } /** @@ -70,7 +101,11 @@ public function isSessionActive(): bool */ public function getAccountDid(): ?string { - return $this->accountDid; + if ($this->activeSession) { + return $this->activeSession->did; + } + + return null; } /** @@ -80,15 +115,15 @@ public function getAccountDid(): ?string */ public function getRefreshToken(): ?string { - return $this->refreshToken; + return $this->activeSession->refreshJwt; } /** - * Get the response headers from the most recent API request + * Get the response header from the most recent API request * - * @return ?array + * @return ?string */ - public function getLastResponseHeader(): ?array + public function getLastResponseHeader(): ?string { return $this->lastResponseHeader; } @@ -101,12 +136,18 @@ public function getLastResponseHeader(): ?array * @param array $args * @param string|null $body * @param string|null $content_type + * @param string|null $endpoint_host + * @param string|null $token * @return ?object * @throws JsonException */ - public function request(string $type, string $request, array $args = [], ?string $body = null, string $content_type = null): ?object + public function request(string $type, string $request, array $args = [], ?string $body = null, ?string $content_type = null, ?string $endpoint_host = null, ?string $token = null): ?object { - $url = $this->apiUri . $request; + if ($endpoint_host) { + $endpoint_host = $this->sanitizeApiHost($endpoint_host); + } + + $url = $this->formatApiUri($endpoint_host ?: $this->getApiHost()) . $request; if (($type === 'GET') && (count($args))) { $url .= '?' . http_build_query($args); @@ -115,10 +156,15 @@ public function request(string $type, string $request, array $args = [], ?string } $headers = []; - if ($this->apiKey) { - $headers[] = 'Authorization: Bearer ' . $this->apiKey; + + if ($token) { + $headers[] = 'Authorization: Bearer ' . $token; + } elseif ($this->activeSession) { + $headers[] = 'Authorization: Bearer ' . $this->activeSession->accessJwt; } + $headers[] = 'Accept: application/json'; + if ($content_type) { $headers[] = 'Content-Type: ' . $content_type; @@ -128,8 +174,6 @@ public function request(string $type, string $request, array $args = [], ?string } } - $this->lastResponseHeader = []; - $c = curl_init(); curl_setopt($c, CURLOPT_URL, $url); @@ -156,7 +200,7 @@ public function request(string $type, string $request, array $args = [], ?string curl_setopt($c, CURLOPT_POSTFIELDS, null); } - curl_setopt($c, CURLOPT_HEADER, 0); + curl_setopt($c, CURLOPT_HEADER, 1); curl_setopt($c, CURLOPT_VERBOSE, 0); curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); curl_setopt($c, CURLOPT_ENCODING, ''); @@ -164,15 +208,18 @@ public function request(string $type, string $request, array $args = [], ?string curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($c, CURLOPT_SSL_VERIFYPEER, 1); - curl_setopt($c, CURLOPT_HEADERFUNCTION, [$this, 'populateLastResponseHeader']); - $data = curl_exec($c); + $response = curl_exec($c); + $header_length = curl_getinfo($c, CURLINFO_HEADER_SIZE); curl_close($c); - if (!$data) { + if (!$response) { return null; } - return json_decode($data, false, 512, JSON_THROW_ON_ERROR); + $this->lastResponseHeader = substr($response, 0, $header_length); + $body = substr($response, $header_length); + + return json_decode($body, false, 512, JSON_THROW_ON_ERROR); } /** @@ -185,7 +232,7 @@ public function request(string $type, string $request, array $args = [], ?string */ private function startNewSession(string $handle, string $app_password): ?object { - $this->apiKey = null; + $this->activeSession = null; $args = [ 'identifier' => $handle, @@ -197,6 +244,8 @@ private function startNewSession(string $handle, string $app_password): ?object throw new RuntimeException($data->message); } + $this->activeSession = $data; + return $data; } @@ -209,38 +258,61 @@ private function startNewSession(string $handle, string $app_password): ?object */ private function refreshSession(string $refresh_token): ?object { - $this->apiKey = $refresh_token; - $data = $this->request('POST', 'com.atproto.server.refreshSession'); - $this->apiKey = null; + $data = $this->request('POST', 'com.atproto.server.refreshSession', [], null, null, null, $refresh_token); if (($data !== null) && (!empty($data->error))) { throw new RuntimeException($data->message); } + $this->activeSession = $data; + return $data; } /** - * Populate an array with data from the + * Determine the appropriate API host to use + * + * @return string + */ + private function getApiHost(): string + { + if ($this->activeSession) { + return $this->getSessionHost(); + } + + return $this->defaultApiHost; + } + + /** + * Sanitize a URI for use as an API host * - * @param $c - cUrl handler, required but not used - * @param string $header - * @return int + * @param string $api_host + * @return string|null */ - private function populateLastResponseHeader($c, string $header): int + private function sanitizeApiHost(string $api_host): ?string { - $header_length = strlen($header); - [$header_name, $header_value] = array_map('trim', explode(':', $header, 2)); + $output = parse_url($api_host, PHP_URL_HOST); - if (!$header_value) { - return $header_length; + if ($output === null) { + $api_host = 'https://' . $api_host; + $output = parse_url($api_host, PHP_URL_HOST); } - if (!array_key_exists($header_name, $this->lastResponseHeader)) { - $this->lastResponseHeader[$header_name] = []; + if ($output === false) { + return null; } - $this->lastResponseHeader[$header_name][] = $header_value; - return $header_length; + return $output; + } + + /** + * Convert the API host into a proper API URI + * + * @param string $api_host + * @return string + */ + private function formatApiUri(string $api_host): string + { + return 'https://' . $api_host . '/xrpc/'; } } diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index e486620..dcfcba2 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -1,8 +1,8 @@ array( 'name' => 'mauricerenck/indieconnector', - 'pretty_version' => '2.1.3', - 'version' => '2.1.3.0', + 'pretty_version' => '2.2.0', + 'version' => '2.2.0.0', 'reference' => NULL, 'type' => 'kirby-plugin', 'install_path' => __DIR__ . '/../../', @@ -11,9 +11,9 @@ ), 'versions' => array( 'cjrasmussen/bluesky-api' => array( - 'pretty_version' => '2.1.5', - 'version' => '2.1.5.0', - 'reference' => '1487a71b351e5ec8d34361a3055369c0c39eb4a2', + 'pretty_version' => '2.3.0', + 'version' => '2.3.0.0', + 'reference' => 'e8f696671955995eb11a1e7817bb83d5feb2a452', 'type' => 'library', 'install_path' => __DIR__ . '/../cjrasmussen/bluesky-api', 'aliases' => array(), @@ -38,8 +38,8 @@ 'dev_requirement' => false, ), 'mauricerenck/indieconnector' => array( - 'pretty_version' => '2.1.3', - 'version' => '2.1.3.0', + 'pretty_version' => '2.2.0', + 'version' => '2.2.0.0', 'reference' => NULL, 'type' => 'kirby-plugin', 'install_path' => __DIR__ . '/../../',