/** * Are any updates available? * * @param string $supplier * @param string $packageName * @param string $minVersion * @param string $apiEndpoint * * @return UpdateInfo[] * * @throws \Airship\Alerts\Hail\NoAPIResponse */ public function updateCheck(string $supplier = '', string $packageName = '', string $minVersion = '', string $apiEndpoint = 'version') : array { if (empty($supplier)) { $supplier = $this->supplier->getName(); } $channelsConfigured = $this->supplier->getChannels(); if (empty($channelsConfigured)) { throw new NoAPIResponse(\trk('errors.hail.no_channel_configured')); } foreach ($channelsConfigured as $channelName) { $channel = $this->getChannel($channelName); $publicKey = $channel->getPublicKey(); foreach ($channel->getAllURLs() as $ch) { try { $response = $this->hail->postSignedJSON($ch . API::get($apiEndpoint), $publicKey, ['type' => $this->type, 'supplier' => $supplier, 'package' => $packageName, 'minimum' => $minVersion]); if ($response['status'] === 'error') { $this->log($response['error'], LogLevel::ERROR, ['response' => $response, 'channel' => $ch, 'supplier' => $supplier, 'type' => $this->type, 'package' => $packageName]); continue; } $updates = []; foreach ($response['versions'] as $update) { $updates[] = new UpdateInfo($update, $ch, $publicKey, $supplier, $packageName); } if (empty($updates)) { $this->log('No updates found.', LogLevel::DEBUG, ['type' => \get_class($this), 'supplier' => $supplier, 'package' => $packageName, 'channelName' => $channelName, 'channel' => $ch]); return []; } return $this->sortUpdatesByVersion(...$updates); } catch (SignatureFailed $ex) { // Log? Definitely suppress, however. $this->log('Automatic update - signature failure. (' . \get_class($ex) . ')', LogLevel::ALERT, ['exception' => \Airship\throwableToArray($ex), 'channelName' => $channelName, 'channel' => $ch]); } catch (TransferException $ex) { // Log? Definitely suppress, however. $this->log('Automatic update failure. (' . \get_class($ex) . ')', LogLevel::WARNING, ['exception' => \Airship\throwableToArray($ex), 'channelName' => $channelName, 'channel' => $ch]); } } } throw new NoAPIResponse(\trk('errors.hail.no_channel_responded')); }
/** * Get metadata about the package we're installing. * * @param string $minVersion * @return array * @throws NoAPIResponse */ public function getPackageData(string $minVersion = '') : array { $channelsConfigured = $this->supplier->getChannels(); if (empty($channelsConfigured)) { throw new NoAPIResponse(\trk('errors.hail.no_channel_configured', $this->supplier->getName())); } /** * HTTP POST arguments */ $args = ['type' => $this->type, 'supplier' => $this->supplier->getName(), 'package' => $this->package]; if (!empty($minVersion)) { $args['minimum'] = $minVersion; } /** * Let's try each of the channels this supplier * belongs to. This should in most cases only * run once. */ foreach ($channelsConfigured as $channel) { $chan = $this->getChannel($channel); $publicKey = $chan->getPublicKey(); // Iterate through all the available Channel URLs. // If the channel supports Tor, and we have tor-only // mode enabled, it will prioritize those URLs. foreach ($chan->getAllURLs() as $ch) { try { $result = $this->hail->postSignedJSON($ch . API::get('version'), $publicKey, $args); // Add the channel to this data... $result['channel'] = $ch; $result['minimum'] = (string) ($minVersion ?? '0.0.0'); return $result; } catch (TransferException $ex) { $this->log('This channel URL did not respond.', LogLevel::INFO, ['channel' => $channel, 'url' => $ch, 'exception' => \Airship\throwableToArray($ex)]); } catch (SignatureFailed $ex) { $this->log('Channel signature validation failed', LogLevel::WARNING, ['channel' => $channel, 'url' => $ch, 'exception' => \Airship\throwableToArray($ex)]); } // If we didn't return a result, we'll continue onto the next URL } } throw new NoAPIResponse(\trk('errors.hail.no_channel_responded')); }