diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 7555f88..fd4ace3 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -21,7 +21,9 @@ android:label="Vikunja" android:name="${applicationName}" android:icon="@mipmap/ic_launcher" - android:usesCleartextTraffic="true"> + android:networkSecurityConfig="@xml/network_security_config" + > + - \ No newline at end of file + diff --git a/android/app/src/main/res/xml/network_security_config.xml b/android/app/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..8a76775 --- /dev/null +++ b/android/app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/lib/api/client.dart b/lib/api/client.dart index bf8c66c..2d7b3d3 100644 --- a/lib/api/client.dart +++ b/lib/api/client.dart @@ -1,9 +1,11 @@ -import 'dart:async'; import 'dart:convert'; import 'dart:core'; import 'dart:io'; +import 'package:cronet_http/cronet_http.dart' as cronet_http; +import 'package:cupertino_http/cupertino_http.dart' as cupertino_http; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; +import 'package:http/io_client.dart' as io_client; import 'package:vikunja_app/api/response.dart'; import 'package:vikunja_app/components/string_extension.dart'; import 'package:vikunja_app/global.dart'; @@ -25,16 +27,42 @@ class Client { String? post_body; - bool operator ==(dynamic otherClient) { + @override + bool operator ==(Object otherClient) { + if (otherClient is! Client) return false; return otherClient._token == _token; } - Client(this.global_scaffold_key, - {String? token, String? base, bool authenticated = false}) { - configure(token: token, base: base, authenticated: authenticated); + Client( + this.global_scaffold_key, { + String? token, + String? base, + bool authenticated = false, + }) { + configure( + token: token, + base: base, + authenticated: authenticated, + ); + } + + http.Client get httpClient { + if (Platform.isAndroid) { + final engine = cronet_http.CronetEngine.build( + cacheMode: cronet_http.CacheMode.memory, cacheMaxSize: 1000000); + return cronet_http.CronetClient.fromCronetEngine(engine); + } + if (Platform.isIOS || Platform.isMacOS) { + final config = + cupertino_http.URLSessionConfiguration.ephemeralSessionConfiguration() + ..cache = + cupertino_http.URLCache.withCapacity(memoryCapacity: 1000000); + return cupertino_http.CupertinoClient.fromSessionConfiguration(config); + } + return io_client.IOClient(); } - void reload_ignore_certs(bool? val) { + void reloadIgnoreCerts(bool? val) { ignoreCertificates = val ?? false; HttpOverrides.global = new IgnoreCertHttpOverrides(ignoreCertificates); if (global_scaffold_key == null || @@ -47,7 +75,7 @@ class Client { get _headers => { 'Authorization': _token != '' ? 'Bearer $_token' : '', 'Content-Type': 'application/json', - 'User-Agent': 'Vikunja Mobile App' + 'User-Agent': 'Vikunja Mobile App', }; get headers => _headers; @@ -55,7 +83,11 @@ class Client { @override int get hashCode => _token.hashCode; - void configure({String? token, String? base, bool? authenticated}) { + void configure({ + String? token, + String? base, + bool? authenticated, + }) { if (token != null) _token = token; if (base != null) { base = base.replaceAll(" ", ""); @@ -66,7 +98,6 @@ class Client { } void reset() { - _token = _base = ''; authenticated = false; } @@ -85,14 +116,14 @@ class Client { queryParameters: queryParameters, fragment: uri.fragment); - return http + return httpClient .get(uri, headers: _headers) .then(_handleResponse) .onError((error, stackTrace) => _handleError(error, stackTrace)); } Future delete(String url) { - return http + return httpClient .delete( '${this.base}$url'.toUri()!, headers: _headers, @@ -102,7 +133,7 @@ class Client { } Future post(String url, {dynamic body}) { - return http + return httpClient .post( '${this.base}$url'.toUri()!, headers: _headers, @@ -113,7 +144,7 @@ class Client { } Future put(String url, {dynamic body}) { - return http + return httpClient .put( '${this.base}$url'.toUri()!, headers: _headers, @@ -183,7 +214,7 @@ class Client { } Response? _handleResponse(http.Response response) { - Error? error = _handleResponseErrors(response); + _handleResponseErrors(response); return Response( _decoder.convert(response.body), response.statusCode, response.headers); } diff --git a/lib/global.dart b/lib/global.dart index d82d657..4bcc7eb 100644 --- a/lib/global.dart +++ b/lib/global.dart @@ -120,7 +120,7 @@ class VikunjaGlobalState extends State { _client = Client(snackbarKey); settingsManager .getIgnoreCertificates() - .then((value) => client.reload_ignore_certs(value == "1")); + .then((value) => client.reloadIgnoreCerts(value == "1")); _newUserService = UserAPIService(client); _loadCurrentUser(); tz.initializeTimeZones(); diff --git a/lib/main.dart b/lib/main.dart index a808f47..0073576 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -52,7 +52,7 @@ void callbackDispatcher() { .getIgnoreCertificates() .then((value) async { print("ignoring: $value"); - client.reload_ignore_certs(value == "1"); + client.reloadIgnoreCerts(value == "1"); TaskAPIService taskService = TaskAPIService(client); NotificationClass nc = NotificationClass(); diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart index b39a69d..b1ddfc9 100644 --- a/lib/pages/settings.dart +++ b/lib/pages/settings.dart @@ -173,7 +173,7 @@ class SettingsPageState extends State { value: ignoreCertificates, onChanged: (value) { setState(() => ignoreCertificates = value); - VikunjaGlobal.of(context).client.reload_ignore_certs(value); + VikunjaGlobal.of(context).client.reloadIgnoreCerts(value); }) : ListTile(title: Text("...")), Divider(), diff --git a/lib/pages/user/login.dart b/lib/pages/user/login.dart index bdcfd61..5d6a6b1 100644 --- a/lib/pages/user/login.dart +++ b/lib/pages/user/login.dart @@ -264,7 +264,7 @@ class _LoginPageState extends State { value: client.ignoreCertificates, onChanged: (value) { setState( - () => client.reload_ignore_certs(value ?? false)); + () => client.reloadIgnoreCerts(value ?? false)); VikunjaGlobal.of(context) .settingsManager .setIgnoreCertificates(value ?? false);