diff --git a/lib/api.dart b/lib/api.dart index 7058e9eb..71af9cbe 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -6,6 +6,7 @@ import "package:flutter/foundation.dart"; import "package:http/http.dart" as http; import "package:intl/intl.dart"; import "package:inventree/app_colors.dart"; +import "package:inventree/app_settings.dart"; import "package:open_file/open_file.dart"; import "package:cached_network_image/cached_network_image.dart"; @@ -82,7 +83,7 @@ class APIResponse { /* * Custom FileService for caching network images * Requires a custom badCertificateCallback, - * so we can accept "dodgy" certificates + * so we can accept "dodgy" (e.g. self-signed) certificates */ class InvenTreeFileService extends FileService { @@ -142,6 +143,8 @@ class InvenTreeAPI { // Minimum required API version for server static const _minApiVersion = 7; + bool _strictHttps = false; + // Endpoint for requesting an API token static const _URL_GET_TOKEN = "user/token/"; @@ -308,6 +311,9 @@ class InvenTreeAPI { username = username.trim(); password = password.trim(); + // Cache the "strictHttps" setting, so we can use it later without async requirement + _strictHttps = await InvenTreeSettingsManager().getValue(INV_STRICT_HTTPS, false) as bool; + if (address.isEmpty || username.isEmpty || password.isEmpty) { showSnackIcon( L10().incompleteDetails, @@ -620,7 +626,9 @@ class InvenTreeAPI { HttpClientRequest? _request; - var client = createClient(allowBadCert: true); + final bool strictHttps = await InvenTreeSettingsManager().getValue(INV_STRICT_HTTPS, false) as bool; + + var client = createClient(strictHttps: strictHttps); // Attempt to open a connection to the server try { @@ -811,22 +819,22 @@ class InvenTreeAPI { ); } - HttpClient createClient({bool allowBadCert = true}) { + HttpClient createClient({bool strictHttps = false}) { var client = HttpClient(); client.badCertificateCallback = (X509Certificate cert, String host, int port) { - // TODO - Introspection of actual certificate? - if (allowBadCert) { - return true; - } else { + if (strictHttps) { showServerError( L10().serverCertificateError, L10().serverCertificateInvalid, ); return false; } + + // Strict HTTPs not enforced, so we'll ignore the bad cert + return true; }; // Set the connection timeout @@ -874,7 +882,9 @@ class InvenTreeAPI { HttpClientRequest? _request; - var client = createClient(allowBadCert: true); + final bool strictHttps = await InvenTreeSettingsManager().getValue(INV_STRICT_HTTPS, false) as bool; + + var client = createClient(strictHttps: strictHttps); // Attempt to open a connection to the server try { @@ -1113,7 +1123,9 @@ class InvenTreeAPI { CacheManager manager = CacheManager( Config( key, - fileService: InvenTreeFileService(), + fileService: InvenTreeFileService( + strictHttps: _strictHttps, + ), ) ); diff --git a/lib/app_settings.dart b/lib/app_settings.dart index 7d97b9c4..e009b784 100644 --- a/lib/app_settings.dart +++ b/lib/app_settings.dart @@ -22,6 +22,8 @@ const String INV_STOCK_SHOW_HISTORY = "stockShowHistory"; const String INV_REPORT_ERRORS = "reportErrors"; +const String INV_STRICT_HTTPS = "strictHttps"; + class InvenTreeSettingsManager { factory InvenTreeSettingsManager() { diff --git a/lib/l10n b/lib/l10n index 5d2c2ce3..9d44f97d 160000 --- a/lib/l10n +++ b/lib/l10n @@ -1 +1 @@ -Subproject commit 5d2c2ce31b308b30b910ea5e40fbacf988c839af +Subproject commit 9d44f97ded4ff7be3de7f51f305c493c99263508 diff --git a/lib/settings/app_settings.dart b/lib/settings/app_settings.dart index be86c7bf..124246d1 100644 --- a/lib/settings/app_settings.dart +++ b/lib/settings/app_settings.dart @@ -29,6 +29,7 @@ class _InvenTreeAppSettingsState extends State { bool stockShowHistory = false; bool reportErrors = true; + bool strictHttps = false; @override void initState() { @@ -50,6 +51,7 @@ class _InvenTreeAppSettingsState extends State { stockShowHistory = await InvenTreeSettingsManager().getValue(INV_STOCK_SHOW_HISTORY, false) as bool; reportErrors = await InvenTreeSettingsManager().getValue(INV_REPORT_ERRORS, true) as bool; + strictHttps = await InvenTreeSettingsManager().getValue(INV_STRICT_HTTPS, false) as bool; setState(() { }); @@ -163,15 +165,29 @@ class _InvenTreeAppSettingsState extends State { Divider(height: 1), ListTile( title: Text( - L10().errorReporting, + L10().appSettings, style: TextStyle(fontWeight: FontWeight.bold), ), - leading: FaIcon(FontAwesomeIcons.bug), + leading: FaIcon(FontAwesomeIcons.mobile), + ), + ListTile( + title: Text(L10().strictHttps), + subtitle: Text(L10().strictHttpsDetails), + leading: FaIcon(FontAwesomeIcons.lock), + trailing: Switch( + value: strictHttps, + onChanged: (bool value) { + InvenTreeSettingsManager().setValue(INV_STRICT_HTTPS, value); + setState(() { + strictHttps = value; + }); + }, + ), ), ListTile( title: Text(L10().errorReportUpload), subtitle: Text(L10().errorReportUploadDetails), - leading: FaIcon(FontAwesomeIcons.cloudUploadAlt), + leading: FaIcon(FontAwesomeIcons.bug), trailing: Switch( value: reportErrors, onChanged: (bool value) {