From de07fb1b3dcb2e530d8175e7ccc40ab3dceaadbf Mon Sep 17 00:00:00 2001 From: malle-pietje Date: Thu, 28 Nov 2024 14:57:22 +0100 Subject: [PATCH] further finalisation of implementing UniFi API Client version 2.0.X enforce secure cookies when the tool is accessed via HTTPS --- ajax/fetch_collection.php | 8 ++++++-- ajax/fetch_sites.php | 22 +++++++++++++++++++--- ajax/show_api_debug.php | 2 +- composer.json | 1 + index.php | 7 +++++++ js/custom.js | 20 ++++++++++---------- 6 files changed, 44 insertions(+), 16 deletions(-) diff --git a/ajax/fetch_collection.php b/ajax/fetch_collection.php index fe73f51..af65024 100755 --- a/ajax/fetch_collection.php +++ b/ajax/fetch_collection.php @@ -134,6 +134,8 @@ /** * Create an instance of the Unifi API client class, log in to the controller and pull the requested data. + * + * @note the error *messages* are for consumption by the user, not for logging */ try { $unifi_connection = new ApiClient( @@ -152,7 +154,7 @@ } catch (CurlGeneralErrorException $e) { error_log(get_class($e) . ': ' . $e->getMessage()); $results['state'] = 'error'; - $results['message'] = 'We have encountered a general cURL error! Response code: ' . $e->getHttpResponseCode(); + $results['message'] = 'We have encountered a general cURL error: ' . $e->getMessage(); return; } catch (CurlTimeoutException $e) { error_log(get_class($e) . ': ' . $e->getMessage()); @@ -189,7 +191,9 @@ /** * We then determine which method is required and which parameters to pass. - * https://stackoverflow.com/questions/1005857/how-to-call-a-function-from-a-string-stored-in-a-variable + * + * @see https://stackoverflow.com/questions/1005857/how-to-call-a-function-from-a-string-stored-in-a-variable + * @note the error *messages* are for consumption by the user, not for logging */ try { if (count($params) === 0) { diff --git a/ajax/fetch_sites.php b/ajax/fetch_sites.php index 3a52657..d3a5d72 100755 --- a/ajax/fetch_sites.php +++ b/ajax/fetch_sites.php @@ -66,6 +66,8 @@ if (!empty($host) && !empty($port)) { /** * Create an instance of the Unifi API client class, log in to the controller and pull the requested data. + * + * @note the error *messages* are for consumption by the user, not for logging */ try { $unifi_connection = new UniFi_API\Client( @@ -82,7 +84,7 @@ error_log('Exception: ' . get_class($e) . ' - Message: ' . $e->getMessage()); } catch (CurlGeneralErrorException $e) { $results['state'] = 'error'; - $results['message'] = 'We have encountered a general cURL error! Response code: ' . $e->getHttpResponseCode(); + $results['message'] = 'We have encountered a general cURL error: ' . $e->getMessage(); error_log('Exception: ' . get_class($e) . ' - Message: ' . $e->getMessage()); } catch (CurlTimeoutException $e) { $results['state'] = 'error'; @@ -116,6 +118,8 @@ /** * We can safely continue. + * + * @note the error *messages* are for consumption by the user, not for logging */ try { $sites_array = $unifi_connection->list_sites(); @@ -175,8 +179,20 @@ /** * Get the first site from the $results array, just to be sure we use a valid site. */ - $switch_site = $unifi_connection->set_site(($results['data'][0]['site_id'])); - $site_info = $unifi_connection->stat_sysinfo(); + try { + $switch_site = $unifi_connection->set_site(($results['data'][0]['site_id'])); + $site_info = $unifi_connection->stat_sysinfo(); + } catch (InvalidSiteNameException $e) { + $results['state'] = 'error'; + $results['message'] = 'The site name is invalid!'; + error_log('Exception: ' . get_class($e) . ' - Message: ' . $e->getMessage()); + return; + } catch (Exception $e) { + $results['state'] = 'error'; + $results['message'] = 'An Exception was thrown:' . $e->getMessage(); + error_log('Exception: ' . get_class($e) . ' - Message: ' . $e->getMessage()); + return; + } if (!empty($site_info) && isset($site_info[0]->version)) { $_SESSION['controller']['detected_version'] = $site_info[0]->version; diff --git a/ajax/show_api_debug.php b/ajax/show_api_debug.php index 7760762..a308fbc 100755 --- a/ajax/show_api_debug.php +++ b/ajax/show_api_debug.php @@ -72,7 +72,7 @@ exit; } catch (CurlGeneralErrorException $e) { error_log('DEBUG - CurlGeneralErrorException: ' . $e->getMessage()); - echo 'General cURL error! Response code: ' . $e->getHttpResponseCode() . PHP_EOL . PHP_EOL; + echo 'General cURL error: ' . $e->getMessage() . PHP_EOL . PHP_EOL; exit; } catch (CurlTimeoutException $e) { error_log('DEBUG - CurlTimeoutException: ' . $e->getMessage()); diff --git a/composer.json b/composer.json index 935fe7f..8835512 100755 --- a/composer.json +++ b/composer.json @@ -1,4 +1,5 @@ { + "type": "project", "require": { "twig/twig": ">=2.16.1", "kint-php/kint": "3.*", diff --git a/index.php b/index.php index 127b81e..ddeeaf3 100755 --- a/index.php +++ b/index.php @@ -12,6 +12,13 @@ use Twig\Error\SyntaxError; use Twig\Loader\FilesystemLoader; +/** + * If we are using HTTPS, we need to set secure cookies. + */ +if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') { + session_set_cookie_params(0, '/', '', true, true); +} + session_start(); /** diff --git a/js/custom.js b/js/custom.js index 13b2955..f7b8d65 100755 --- a/js/custom.js +++ b/js/custom.js @@ -115,7 +115,7 @@ $('.controller_idx').on('click', function(){ } }, error: function(jqXHR, textStatus, errorThrown) { - console.log(jqXHR); + console.error(jqXHR); controller.idx = ''; controller.full_name = ''; } @@ -219,7 +219,7 @@ function switchCSS(new_theme) { // }, error: function(jqXHR, textStatus, errorThrown) { - console.log(jqXHR); + console.error(jqXHR); } }); } @@ -288,13 +288,13 @@ function fetchSites() { */ updateAboutModal(); } else { - console.log(json.message); + console.error(json.message); $('#site_dropdown > li > div').html(''); renderGeneralErrorAlert(json.message); } }, error: function(jqXHR, textStatus, errorThrown) { - console.log(jqXHR); + console.error(jqXHR); unifi_sites = []; @@ -409,12 +409,12 @@ function fetchCollection() { */ updateAboutModal(); } else { - console.log(json.message); + console.error(json.message); renderGeneralErrorAlert(json.message); } }, error: function(jqXHR, textStatus, errorThrown) { - console.log(jqXHR); + console.error(jqXHR); } }); } @@ -424,7 +424,7 @@ function fetchCollection() { */ function renderGeneralErrorAlert(error_message) { /** - * hide any existings alerts + * hide any existing alerts */ $('.alert_wrapper').addClass('d-none'); @@ -432,7 +432,7 @@ function renderGeneralErrorAlert(error_message) { * render the alert */ $('#general_error_alert_wrapper').removeClass('d-none'); - $('#general_error').html('We encountered the following error: ' + error_message); + $('#general_error').html(error_message); } /** @@ -453,7 +453,7 @@ function updateAboutModal() { $('#span_memory_used').html(json.memory_used); }, error: function(jqXHR, textStatus, errorThrown) { - console.log(jqXHR); + console.error(jqXHR); } }); } @@ -563,7 +563,7 @@ $('#about_modal').on('shown.bs.modal', function (e) { error: function(jqXHR, textStatus, errorThrown) { version_update_span.html('error checking updates'); version_update_span.removeClass('badge-success').addClass('badge-danger'); - console.log(jqXHR); + console.error(jqXHR); } }); })