From a21ca91d5f42ee92ad46560869cff6fd58960430 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 21 May 2024 14:22:46 +0200 Subject: [PATCH 01/32] 2 person login --- lib/model/push_request.dart | 15 ++++++-- .../push_request_notifier.dart | 35 +++++++++++-------- lib/utils/identifiers.dart | 1 + .../dialog_widgets/push_request_dialog.dart | 23 ++++++++++++ 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/lib/model/push_request.dart b/lib/model/push_request.dart index 6c7fa0dee..059875117 100644 --- a/lib/model/push_request.dart +++ b/lib/model/push_request.dart @@ -24,6 +24,8 @@ class PushRequest { final String serial; final String signature; final bool? accepted; + final List? answers; + final int? selectedAnswerIndex; const PushRequest({ required this.title, @@ -36,6 +38,8 @@ class PushRequest { this.serial = '', this.signature = '', this.accepted, + this.answers, + this.selectedAnswerIndex, }); PushRequest copyWith({ @@ -49,6 +53,8 @@ class PushRequest { String? serial, String? signature, bool? accepted, + List Function()? answers, + int? Function()? selectedAnswerIndex, }) { return PushRequest( title: title ?? this.title, @@ -61,6 +67,8 @@ class PushRequest { serial: serial ?? this.serial, signature: signature ?? this.signature, accepted: accepted ?? this.accepted, + answers: answers != null ? answers() : this.answers, + selectedAnswerIndex: selectedAnswerIndex != null ? selectedAnswerIndex() : this.selectedAnswerIndex, ); } @@ -75,7 +83,8 @@ class PushRequest { return 'PushRequest{title: $title, question: $question, ' 'id: $id, uri: $uri, _nonce: $nonce, sslVerify: $sslVerify, ' 'expirationDate: $expirationDate, serial: $serial, ' - 'signature: $signature, accepted: $accepted}'; + 'signature: $signature, accepted: $accepted, ' + 'answers: $answers, selectedAnswerIndex: $selectedAnswerIndex}'; } factory PushRequest.fromJson(Map json) => _$PushRequestFromJson(json); @@ -98,6 +107,7 @@ class PushRequest { serial: data[PUSH_REQUEST_SERIAL], expirationDate: DateTime.now().add(const Duration(minutes: 2)), signature: data[PUSH_REQUEST_SIGNATURE], + answers: data[PUSH_REQUEST_ANSWERS], ); } @@ -136,7 +146,8 @@ class PushRequest { '$serial|' '$question|' '$title|' - '${sslVerify ? '1' : '0'}'; + '${sslVerify ? '1' : '0'}' + '${answers != null ? '|require_presence' : ''}'; // Re-add url and sslverify to android legacy tokens: if (token.url == null) { diff --git a/lib/state_notifiers/push_request_notifier.dart b/lib/state_notifiers/push_request_notifier.dart index 67eb6e5f1..60a161e94 100644 --- a/lib/state_notifiers/push_request_notifier.dart +++ b/lib/state_notifiers/push_request_notifier.dart @@ -217,7 +217,7 @@ class PushRequestNotifier extends StateNotifier { /// Accepts a push request and returns true if successful, false if not. /// An accepted push request is removed from the state. /// It should be still in the CustomIntBuffer of the state. - Future accept(PushToken pushToken, PushRequest pushRequest) async { + Future accept(PushToken pushToken, PushRequest pushRequest, {int? selectedAnswerIndex}) async { if (pushRequest.accepted != null) { Logger.warning('The push request is already accepted or declined.', name: 'push_request_notifier.dart#decline'); @@ -225,7 +225,7 @@ class PushRequestNotifier extends StateNotifier { } Logger.info('Decline push request.', name: 'push_request_notifier.dart#decline'); final updated = await _updatePushRequest(pushRequest, (p0) async { - final updated = p0.copyWith(accepted: true); + final updated = p0.copyWith(accepted: true, selectedAnswerIndex: () => selectedAnswerIndex); final success = await _handleReaction(pushRequest: updated, token: pushToken); if (!success) { return p0; @@ -244,7 +244,7 @@ class PushRequestNotifier extends StateNotifier { } Logger.info('Decline push request.', name: 'push_request_notifier.dart#decline'); final updated = await _updatePushRequest(pushRequest, (p0) async { - final updated = p0.copyWith(accepted: false); + final updated = p0.copyWith(accepted: false, selectedAnswerIndex: () => null); final success = await _handleReaction(pushRequest: updated, token: pushToken); if (!success) { return p0; @@ -318,28 +318,35 @@ class PushRequestNotifier extends StateNotifier { Future _handleReaction({required PushRequest pushRequest, required PushToken token}) async { if (pushRequest.accepted == null) return false; Logger.info('Push auth request accepted=${pushRequest.accepted}, sending response to privacyidea', name: 'token_widgets.dart#handleReaction'); - // signature ::= {nonce}|{serial}[|decline] - String msg = '${pushRequest.nonce}|${token.serial}'; - if (pushRequest.accepted! == false) { - msg += '|decline'; - } - String? signature = await _rsaUtils.trySignWithToken(token, msg); - if (signature == null) { - return false; - } // POST https://privacyideaserver/validate/check // nonce= // serial= // signature= // decline=1 (optional) + // answer= (optional) final Map body = { 'nonce': pushRequest.nonce, 'serial': token.serial, - 'signature': signature, }; + // signature ::= {nonce}|{serial}[|decline] + String msg = '${pushRequest.nonce}|${token.serial}'; if (pushRequest.accepted! == false) { - body["decline"] = "1"; + body['decline'] = '1'; + msg += '|decline'; + } + if (pushRequest.answers != null && pushRequest.selectedAnswerIndex != null) { + body['answer'] = pushRequest.answers![pushRequest.selectedAnswerIndex!]; + msg += '|${pushRequest.answers![pushRequest.selectedAnswerIndex!]}'; + } + + String? signature = await _rsaUtils.trySignWithToken(token, msg); + if (signature == null) { + Logger.warning('Failed to sign push request response.', name: 'token_widgets.dart#handleReaction'); + return false; } + + body['signature'] = signature; + Response response; try { response = await _ioClient.doPost(sslVerify: pushRequest.sslVerify, url: pushRequest.uri, body: body); diff --git a/lib/utils/identifiers.dart b/lib/utils/identifiers.dart index e56679f64..3b3811ddc 100644 --- a/lib/utils/identifiers.dart +++ b/lib/utils/identifiers.dart @@ -63,6 +63,7 @@ const String PUSH_REQUEST_QUESTION = 'question'; // 4. const String PUSH_REQUEST_TITLE = 'title'; // 5. const String PUSH_REQUEST_SSL_VERIFY = 'sslverify'; // 6. const String PUSH_REQUEST_SIGNATURE = 'signature'; // 7. +const String PUSH_REQUEST_ANSWERS = 'require_presence'; // 8. const String GLOBAL_SECURE_REPO_PREFIX = 'app_v3_'; diff --git a/lib/widgets/dialog_widgets/push_request_dialog.dart b/lib/widgets/dialog_widgets/push_request_dialog.dart index f3a88453a..663391e86 100644 --- a/lib/widgets/dialog_widgets/push_request_dialog.dart +++ b/lib/widgets/dialog_widgets/push_request_dialog.dart @@ -88,6 +88,29 @@ class _PushRequestDialogState extends ConsumerState { ), SizedBox(height: lineHeight), ], + if (widget.pushRequest.answers != null) + GridView.builder( + shrinkWrap: true, + itemCount: widget.pushRequest.answers!.length, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 3, + ), + itemBuilder: (context, index) { + return PressButton( + onPressed: () { + globalRef?.read(pushRequestProvider.notifier).accept(token, widget.pushRequest, selectedAnswerIndex: index); + Navigator.of(context).pop(); + if (mounted) setState(() => isHandled = true); + }, + child: Text( + widget.pushRequest.answers![index], + style: const TextStyle(fontSize: 16), + textAlign: TextAlign.center, + ), + ); + }, + ), SizedBox( // Accept button height: lineHeight * titleScale * 2 + 16, From 7e3990a931fbbe70cbf63cbd648272335e04460b Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 21 May 2024 17:28:18 +0200 Subject: [PATCH 02/32] migrate app to gradles plugin dsl --- android/app/build.gradle | 21 +++----- android/app/src/main/AndroidManifest.xml | 2 +- .../main/res/drawable/launch_background.xml | 11 ----- .../res/drawable/launch_background.xml | 11 ----- .../res/drawable/launch_background.xml | 11 ----- android/build.gradle | 14 ------ android/settings.gradle | 49 ++++++++++++++++--- ios/Flutter/flutter_export_environment.sh | 14 ------ lib/model/push_request.g.dart | 2 +- lib/model/token_folder.g.dart | 4 +- lib/model/tokens/day_password_token.g.dart | 8 +-- lib/model/tokens/hotp_token.g.dart | 8 +-- lib/model/tokens/push_token.g.dart | 4 +- lib/model/tokens/steam_token.g.dart | 4 +- lib/model/tokens/totp_token.g.dart | 8 +-- lib/model/version.g.dart | 6 +-- lib/utils/custom_int_buffer.g.dart | 2 +- lib/utils/firebase_utils.dart | 2 +- pubspec.lock | 24 ++++----- pubspec.yaml | 6 +-- 20 files changed, 88 insertions(+), 123 deletions(-) delete mode 100644 android/app/src/main/res/drawable/launch_background.xml delete mode 100644 android/app/src/netknights/res/drawable/launch_background.xml delete mode 100644 android/app/src/netknights_debug/res/drawable/launch_background.xml delete mode 100755 ios/Flutter/flutter_export_environment.sh diff --git a/android/app/build.gradle b/android/app/build.gradle index 3bc83ed63..858f3b0eb 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,3 +1,9 @@ +plugins { + id "com.android.application" + id "kotlin-android" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,10 +12,6 @@ if (localPropertiesFile.exists()) { } } -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { @@ -21,11 +23,6 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -apply plugin: 'com.android.application' -apply plugin: 'com.google.gms.google-services' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - def keystorePropertiesNetknights = new Properties() def keystorePropertiesFileNetknights = rootProject.file('app/src/netknights/key.properties') if (keystorePropertiesFileNetknights.exists()) { @@ -49,7 +46,7 @@ android { defaultConfig { applicationId "it.netknights.piauthenticator" - minSdkVersion 21 + minSdkVersion 24 targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -122,7 +119,3 @@ android { flutter { source '../..' } - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index e784db90e..ba5f579be 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -17,7 +17,7 @@ + android:maxSdkVersion="28" /> - - - - You can insert your own image assets here - - - - --> diff --git a/android/app/src/netknights/res/drawable/launch_background.xml b/android/app/src/netknights/res/drawable/launch_background.xml deleted file mode 100644 index d00d47bf2..000000000 --- a/android/app/src/netknights/res/drawable/launch_background.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - You can insert your own image assets here - - - - --> diff --git a/android/app/src/netknights_debug/res/drawable/launch_background.xml b/android/app/src/netknights_debug/res/drawable/launch_background.xml deleted file mode 100644 index d00d47bf2..000000000 --- a/android/app/src/netknights_debug/res/drawable/launch_background.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - You can insert your own image assets here - - - - --> diff --git a/android/build.gradle b/android/build.gradle index e2355144d..bc157bd1a 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,17 +1,3 @@ -buildscript { - ext.kotlin_version = '1.8.0' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.gms:google-services:4.3.15' - } -} - allprojects { repositories { google() diff --git a/android/settings.gradle b/android/settings.gradle index 44e62bcf0..349d5215b 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,11 +1,44 @@ -include ':app' -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "7.4.2" apply false + id "org.jetbrains.kotlin.android" version "1.8.0" apply false +} + +include ":app" + + + + + + + +// include ':app' + +// def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +// def properties = new Properties() + +// assert localPropertiesFile.exists() +// localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +// def flutterSdkPath = properties.getProperty("flutter.sdk") +// assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +// apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/ios/Flutter/flutter_export_environment.sh b/ios/Flutter/flutter_export_environment.sh deleted file mode 100755 index f8c05ec23..000000000 --- a/ios/Flutter/flutter_export_environment.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=/Users/frankmerkel/src/flutter" -export "FLUTTER_APPLICATION_PATH=/Users/frankmerkel/Documents/GitHub/pi-authenticator" -export "COCOAPODS_PARALLEL_CODE_SIGN=true" -export "FLUTTER_TARGET=/Users/frankmerkel/Documents/GitHub/pi-authenticator/lib/mains/main_netknights.dart" -export "FLUTTER_BUILD_DIR=build" -export "FLUTTER_BUILD_NAME=4.4.0" -export "FLUTTER_BUILD_NUMBER=404001" -export "DART_OBFUSCATION=false" -export "TRACK_WIDGET_CREATION=true" -export "TREE_SHAKE_ICONS=false" -export "PACKAGE_CONFIG=/Users/frankmerkel/Documents/GitHub/pi-authenticator/.dart_tool/package_config.json" -export "FLAVOR=netknights" diff --git a/lib/model/push_request.g.dart b/lib/model/push_request.g.dart index a9ecce588..5d2b4d409 100644 --- a/lib/model/push_request.g.dart +++ b/lib/model/push_request.g.dart @@ -12,7 +12,7 @@ PushRequest _$PushRequestFromJson(Map json) => PushRequest( uri: Uri.parse(json['uri'] as String), nonce: json['nonce'] as String, sslVerify: json['sslVerify'] as bool, - id: json['id'] as int, + id: (json['id'] as num).toInt(), expirationDate: DateTime.parse(json['expirationDate'] as String), serial: json['serial'] as String? ?? '', signature: json['signature'] as String? ?? '', diff --git a/lib/model/token_folder.g.dart b/lib/model/token_folder.g.dart index a7ebd95c2..cb98515b6 100644 --- a/lib/model/token_folder.g.dart +++ b/lib/model/token_folder.g.dart @@ -8,10 +8,10 @@ part of 'token_folder.dart'; TokenFolder _$TokenFolderFromJson(Map json) => TokenFolder( label: json['label'] as String, - folderId: json['folderId'] as int, + folderId: (json['folderId'] as num).toInt(), isExpanded: json['isExpanded'] as bool? ?? true, isLocked: json['isLocked'] as bool? ?? false, - sortIndex: json['sortIndex'] as int?, + sortIndex: (json['sortIndex'] as num?)?.toInt(), ); Map _$TokenFolderToJson(TokenFolder instance) => diff --git a/lib/model/tokens/day_password_token.g.dart b/lib/model/tokens/day_password_token.g.dart index ebbb0e7d0..e85e5172e 100644 --- a/lib/model/tokens/day_password_token.g.dart +++ b/lib/model/tokens/day_password_token.g.dart @@ -8,18 +8,18 @@ part of 'day_password_token.dart'; DayPasswordToken _$DayPasswordTokenFromJson(Map json) => DayPasswordToken( - period: Duration(microseconds: json['period'] as int), + period: Duration(microseconds: (json['period'] as num).toInt()), id: json['id'] as String, algorithm: $enumDecode(_$AlgorithmsEnumMap, json['algorithm']), - digits: json['digits'] as int, + digits: (json['digits'] as num).toInt(), secret: json['secret'] as String, viewMode: $enumDecodeNullable( _$DayPasswordTokenViewModeEnumMap, json['viewMode']) ?? DayPasswordTokenViewMode.VALIDFOR, type: json['type'] as String?, tokenImage: json['tokenImage'] as String?, - sortIndex: json['sortIndex'] as int?, - folderId: json['folderId'] as int?, + sortIndex: (json['sortIndex'] as num?)?.toInt(), + folderId: (json['folderId'] as num?)?.toInt(), pin: json['pin'] as bool?, isLocked: json['isLocked'] as bool?, isHidden: json['isHidden'] as bool?, diff --git a/lib/model/tokens/hotp_token.g.dart b/lib/model/tokens/hotp_token.g.dart index b8ef1d22d..0d2a99bd4 100644 --- a/lib/model/tokens/hotp_token.g.dart +++ b/lib/model/tokens/hotp_token.g.dart @@ -7,18 +7,18 @@ part of 'hotp_token.dart'; // ************************************************************************** HOTPToken _$HOTPTokenFromJson(Map json) => HOTPToken( - counter: json['counter'] as int? ?? 0, + counter: (json['counter'] as num?)?.toInt() ?? 0, id: json['id'] as String, algorithm: $enumDecode(_$AlgorithmsEnumMap, json['algorithm']), - digits: json['digits'] as int, + digits: (json['digits'] as num).toInt(), secret: json['secret'] as String, type: json['type'] as String?, tokenImage: json['tokenImage'] as String?, pin: json['pin'] as bool?, isLocked: json['isLocked'] as bool?, isHidden: json['isHidden'] as bool?, - sortIndex: json['sortIndex'] as int?, - folderId: json['folderId'] as int?, + sortIndex: (json['sortIndex'] as num?)?.toInt(), + folderId: (json['folderId'] as num?)?.toInt(), origin: json['origin'] == null ? null : TokenOriginData.fromJson(json['origin'] as Map), diff --git a/lib/model/tokens/push_token.g.dart b/lib/model/tokens/push_token.g.dart index 2f3acccfa..a651a9c71 100644 --- a/lib/model/tokens/push_token.g.dart +++ b/lib/model/tokens/push_token.g.dart @@ -26,8 +26,8 @@ PushToken _$PushTokenFromJson(Map json) => PushToken( _$PushTokenRollOutStateEnumMap, json['rolloutState']), type: json['type'] as String?, tokenImage: json['tokenImage'] as String?, - sortIndex: json['sortIndex'] as int?, - folderId: json['folderId'] as int?, + sortIndex: (json['sortIndex'] as num?)?.toInt(), + folderId: (json['folderId'] as num?)?.toInt(), pin: json['pin'] as bool?, isLocked: json['isLocked'] as bool?, isHidden: json['isHidden'] as bool?, diff --git a/lib/model/tokens/steam_token.g.dart b/lib/model/tokens/steam_token.g.dart index 68a5d14ab..d104764d6 100644 --- a/lib/model/tokens/steam_token.g.dart +++ b/lib/model/tokens/steam_token.g.dart @@ -14,8 +14,8 @@ SteamToken _$SteamTokenFromJson(Map json) => SteamToken( pin: json['pin'] as bool?, isLocked: json['isLocked'] as bool?, isHidden: json['isHidden'] as bool?, - sortIndex: json['sortIndex'] as int?, - folderId: json['folderId'] as int?, + sortIndex: (json['sortIndex'] as num?)?.toInt(), + folderId: (json['folderId'] as num?)?.toInt(), origin: json['origin'] == null ? null : TokenOriginData.fromJson(json['origin'] as Map), diff --git a/lib/model/tokens/totp_token.g.dart b/lib/model/tokens/totp_token.g.dart index 70e4b229b..86924f6c7 100644 --- a/lib/model/tokens/totp_token.g.dart +++ b/lib/model/tokens/totp_token.g.dart @@ -7,18 +7,18 @@ part of 'totp_token.dart'; // ************************************************************************** TOTPToken _$TOTPTokenFromJson(Map json) => TOTPToken( - period: json['period'] as int, + period: (json['period'] as num).toInt(), id: json['id'] as String, algorithm: $enumDecode(_$AlgorithmsEnumMap, json['algorithm']), - digits: json['digits'] as int, + digits: (json['digits'] as num).toInt(), secret: json['secret'] as String, type: json['type'] as String?, tokenImage: json['tokenImage'] as String?, pin: json['pin'] as bool?, isLocked: json['isLocked'] as bool?, isHidden: json['isHidden'] as bool?, - sortIndex: json['sortIndex'] as int?, - folderId: json['folderId'] as int?, + sortIndex: (json['sortIndex'] as num?)?.toInt(), + folderId: (json['folderId'] as num?)?.toInt(), origin: json['origin'] == null ? null : TokenOriginData.fromJson(json['origin'] as Map), diff --git a/lib/model/version.g.dart b/lib/model/version.g.dart index 8e28376b3..6acf48107 100644 --- a/lib/model/version.g.dart +++ b/lib/model/version.g.dart @@ -7,9 +7,9 @@ part of 'version.dart'; // ************************************************************************** Version _$VersionFromJson(Map json) => Version( - json['major'] as int, - json['minor'] as int, - json['patch'] as int, + (json['major'] as num).toInt(), + (json['minor'] as num).toInt(), + (json['patch'] as num).toInt(), ); Map _$VersionToJson(Version instance) => { diff --git a/lib/utils/custom_int_buffer.g.dart b/lib/utils/custom_int_buffer.g.dart index d38cf3d06..ee8663450 100644 --- a/lib/utils/custom_int_buffer.g.dart +++ b/lib/utils/custom_int_buffer.g.dart @@ -8,7 +8,7 @@ part of 'custom_int_buffer.dart'; CustomIntBuffer _$CustomIntBufferFromJson(Map json) => CustomIntBuffer( - maxSize: json['maxSize'] as int? ?? 100, + maxSize: (json['maxSize'] as num?)?.toInt() ?? 100, ); Map _$CustomIntBufferToJson(CustomIntBuffer instance) => diff --git a/lib/utils/firebase_utils.dart b/lib/utils/firebase_utils.dart index a0e011ae1..fc37f3510 100644 --- a/lib/utils/firebase_utils.dart +++ b/lib/utils/firebase_utils.dart @@ -34,7 +34,7 @@ class FirebaseUtils { } _initialized = true; Logger.info('Initializing Firebase', name: 'firebase_utils.dart#initFirebase'); - final app = await Firebase.initializeApp(); + final app = await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); await app.setAutomaticDataCollectionEnabled(false); Logger.warning('Automatic data collection: ${app.isAutomaticDataCollectionEnabled}', name: 'firebase_utils.dart#initFirebase'); try { diff --git a/pubspec.lock b/pubspec.lock index 59b3a6f5b..d91c970e3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -149,18 +149,18 @@ packages: dependency: "direct main" description: name: camera - sha256: "9499cbc2e51d8eb0beadc158b288380037618ce4e30c9acbc4fae1ac3ecb5797" + sha256: cf8ed1789aa244392cfc49d13e97879700476ba641c92500e01f630e109c0f6c url: "https://pub.dev" source: hosted - version: "0.10.5+9" - camera_android: + version: "0.11.0" + camera_android_camerax: dependency: transitive description: - name: camera_android - sha256: "7b0aba6398afa8475e2bc9115d976efb49cf8db781e922572d443795c04a4f4f" + name: camera_android_camerax + sha256: "59967e6d80df9d682a33b86f228cc524e6b52d6184b84f6ac62151dd98bd1ea0" url: "https://pub.dev" source: hosted - version: "0.10.9+1" + version: "0.6.5+2" camera_avfoundation: dependency: transitive description: @@ -519,10 +519,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "4.0.0" flutter_local_notifications: dependency: "direct main" description: @@ -800,10 +800,10 @@ packages: dependency: transitive description: name: lints - sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "4.0.0" local_auth: dependency: "direct main" description: @@ -960,10 +960,10 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "2c582551839386fa7ddbc7770658be7c0f87f388a4bff72066478f597c34d17f" + sha256: b93d8b4d624b4ea19b0a5a208b2d6eff06004bc3ce74c06040b120eeadd00ce0 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "8.0.0" package_info_plus_platform_interface: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 2fccb2787..c55b1f54c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -56,7 +56,7 @@ dependencies: shared_preferences: ^2.2.0 flutter_secure_storage: ^9.0.0 # Info - package_info_plus: ^7.0.0 + package_info_plus: ^8.0.0 device_info_plus: ^10.0.1 # URI uni_links: ^0.5.1 @@ -76,7 +76,7 @@ dependencies: easy_dynamic_theme: ^2.2.0 flutter_slidable: ^3.0.0 expandable: ^5.0.1 - camera: ^0.10.5+9 + camera: ^0.11.0 firebase_messaging: ^14.7.19 collection: ^1.18.0 crypto: ^3.0.3 @@ -96,7 +96,7 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - flutter_lints: ^3.0.0 + flutter_lints: ^4.0.0 mockito: ^5.4.2 test: ^1.24.1 From 0096a3ddf30de20639a690fea506c0333e19be98 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Fri, 24 May 2024 10:35:52 +0200 Subject: [PATCH 03/32] 2 person login --- lib/model/push_request.g.dart | 7 +- lib/model/token_folder.g.dart | 4 +- lib/model/tokens/day_password_token.g.dart | 8 +- lib/model/tokens/hotp_token.g.dart | 8 +- lib/model/tokens/push_token.g.dart | 4 +- lib/model/tokens/steam_token.g.dart | 4 +- lib/model/tokens/totp_token.g.dart | 8 +- lib/model/version.g.dart | 6 +- lib/utils/custom_int_buffer.g.dart | 2 +- .../customization/theme_customization.dart | 18 +- .../labeled_dropdown_button.dart | 2 +- lib/views/feedback_view/feedback_view.dart | 2 +- .../main_view_widgets/no_token_screen.dart | 4 +- .../actions/edit_push_token_action.dart | 4 +- .../rollout_failed_widget.dart | 2 +- .../dialogs/select_export_type_dialog.dart | 4 +- .../dialogs/select_tokens_dialog.dart | 2 +- .../settings_group_error_log.dart | 2 +- .../settings_group_general.dart | 8 +- .../settings_group_import_export_tokens.dart | 4 +- .../settings_group_language.dart | 80 ++-- .../settings_group_push_token.dart | 6 +- .../settings_groups/settings_group_theme.dart | 6 +- .../settings_view_widgets/logging_menu.dart | 2 +- .../dialog_widgets/patch_notes_dialog.dart | 2 +- .../dialog_widgets/push_request_dialog.dart | 409 +++++++++++------- lib/widgets/press_button.dart | 15 +- pubspec.yaml | 2 +- 28 files changed, 359 insertions(+), 266 deletions(-) diff --git a/lib/model/push_request.g.dart b/lib/model/push_request.g.dart index a9ecce588..09a704276 100644 --- a/lib/model/push_request.g.dart +++ b/lib/model/push_request.g.dart @@ -12,11 +12,14 @@ PushRequest _$PushRequestFromJson(Map json) => PushRequest( uri: Uri.parse(json['uri'] as String), nonce: json['nonce'] as String, sslVerify: json['sslVerify'] as bool, - id: json['id'] as int, + id: (json['id'] as num).toInt(), expirationDate: DateTime.parse(json['expirationDate'] as String), serial: json['serial'] as String? ?? '', signature: json['signature'] as String? ?? '', accepted: json['accepted'] as bool?, + answers: + (json['answers'] as List?)?.map((e) => e as String).toList(), + selectedAnswerIndex: (json['selectedAnswerIndex'] as num?)?.toInt(), ); Map _$PushRequestToJson(PushRequest instance) => @@ -31,4 +34,6 @@ Map _$PushRequestToJson(PushRequest instance) => 'serial': instance.serial, 'signature': instance.signature, 'accepted': instance.accepted, + 'answers': instance.answers, + 'selectedAnswerIndex': instance.selectedAnswerIndex, }; diff --git a/lib/model/token_folder.g.dart b/lib/model/token_folder.g.dart index a7ebd95c2..cb98515b6 100644 --- a/lib/model/token_folder.g.dart +++ b/lib/model/token_folder.g.dart @@ -8,10 +8,10 @@ part of 'token_folder.dart'; TokenFolder _$TokenFolderFromJson(Map json) => TokenFolder( label: json['label'] as String, - folderId: json['folderId'] as int, + folderId: (json['folderId'] as num).toInt(), isExpanded: json['isExpanded'] as bool? ?? true, isLocked: json['isLocked'] as bool? ?? false, - sortIndex: json['sortIndex'] as int?, + sortIndex: (json['sortIndex'] as num?)?.toInt(), ); Map _$TokenFolderToJson(TokenFolder instance) => diff --git a/lib/model/tokens/day_password_token.g.dart b/lib/model/tokens/day_password_token.g.dart index ebbb0e7d0..e85e5172e 100644 --- a/lib/model/tokens/day_password_token.g.dart +++ b/lib/model/tokens/day_password_token.g.dart @@ -8,18 +8,18 @@ part of 'day_password_token.dart'; DayPasswordToken _$DayPasswordTokenFromJson(Map json) => DayPasswordToken( - period: Duration(microseconds: json['period'] as int), + period: Duration(microseconds: (json['period'] as num).toInt()), id: json['id'] as String, algorithm: $enumDecode(_$AlgorithmsEnumMap, json['algorithm']), - digits: json['digits'] as int, + digits: (json['digits'] as num).toInt(), secret: json['secret'] as String, viewMode: $enumDecodeNullable( _$DayPasswordTokenViewModeEnumMap, json['viewMode']) ?? DayPasswordTokenViewMode.VALIDFOR, type: json['type'] as String?, tokenImage: json['tokenImage'] as String?, - sortIndex: json['sortIndex'] as int?, - folderId: json['folderId'] as int?, + sortIndex: (json['sortIndex'] as num?)?.toInt(), + folderId: (json['folderId'] as num?)?.toInt(), pin: json['pin'] as bool?, isLocked: json['isLocked'] as bool?, isHidden: json['isHidden'] as bool?, diff --git a/lib/model/tokens/hotp_token.g.dart b/lib/model/tokens/hotp_token.g.dart index b8ef1d22d..0d2a99bd4 100644 --- a/lib/model/tokens/hotp_token.g.dart +++ b/lib/model/tokens/hotp_token.g.dart @@ -7,18 +7,18 @@ part of 'hotp_token.dart'; // ************************************************************************** HOTPToken _$HOTPTokenFromJson(Map json) => HOTPToken( - counter: json['counter'] as int? ?? 0, + counter: (json['counter'] as num?)?.toInt() ?? 0, id: json['id'] as String, algorithm: $enumDecode(_$AlgorithmsEnumMap, json['algorithm']), - digits: json['digits'] as int, + digits: (json['digits'] as num).toInt(), secret: json['secret'] as String, type: json['type'] as String?, tokenImage: json['tokenImage'] as String?, pin: json['pin'] as bool?, isLocked: json['isLocked'] as bool?, isHidden: json['isHidden'] as bool?, - sortIndex: json['sortIndex'] as int?, - folderId: json['folderId'] as int?, + sortIndex: (json['sortIndex'] as num?)?.toInt(), + folderId: (json['folderId'] as num?)?.toInt(), origin: json['origin'] == null ? null : TokenOriginData.fromJson(json['origin'] as Map), diff --git a/lib/model/tokens/push_token.g.dart b/lib/model/tokens/push_token.g.dart index 2f3acccfa..a651a9c71 100644 --- a/lib/model/tokens/push_token.g.dart +++ b/lib/model/tokens/push_token.g.dart @@ -26,8 +26,8 @@ PushToken _$PushTokenFromJson(Map json) => PushToken( _$PushTokenRollOutStateEnumMap, json['rolloutState']), type: json['type'] as String?, tokenImage: json['tokenImage'] as String?, - sortIndex: json['sortIndex'] as int?, - folderId: json['folderId'] as int?, + sortIndex: (json['sortIndex'] as num?)?.toInt(), + folderId: (json['folderId'] as num?)?.toInt(), pin: json['pin'] as bool?, isLocked: json['isLocked'] as bool?, isHidden: json['isHidden'] as bool?, diff --git a/lib/model/tokens/steam_token.g.dart b/lib/model/tokens/steam_token.g.dart index 68a5d14ab..d104764d6 100644 --- a/lib/model/tokens/steam_token.g.dart +++ b/lib/model/tokens/steam_token.g.dart @@ -14,8 +14,8 @@ SteamToken _$SteamTokenFromJson(Map json) => SteamToken( pin: json['pin'] as bool?, isLocked: json['isLocked'] as bool?, isHidden: json['isHidden'] as bool?, - sortIndex: json['sortIndex'] as int?, - folderId: json['folderId'] as int?, + sortIndex: (json['sortIndex'] as num?)?.toInt(), + folderId: (json['folderId'] as num?)?.toInt(), origin: json['origin'] == null ? null : TokenOriginData.fromJson(json['origin'] as Map), diff --git a/lib/model/tokens/totp_token.g.dart b/lib/model/tokens/totp_token.g.dart index 70e4b229b..86924f6c7 100644 --- a/lib/model/tokens/totp_token.g.dart +++ b/lib/model/tokens/totp_token.g.dart @@ -7,18 +7,18 @@ part of 'totp_token.dart'; // ************************************************************************** TOTPToken _$TOTPTokenFromJson(Map json) => TOTPToken( - period: json['period'] as int, + period: (json['period'] as num).toInt(), id: json['id'] as String, algorithm: $enumDecode(_$AlgorithmsEnumMap, json['algorithm']), - digits: json['digits'] as int, + digits: (json['digits'] as num).toInt(), secret: json['secret'] as String, type: json['type'] as String?, tokenImage: json['tokenImage'] as String?, pin: json['pin'] as bool?, isLocked: json['isLocked'] as bool?, isHidden: json['isHidden'] as bool?, - sortIndex: json['sortIndex'] as int?, - folderId: json['folderId'] as int?, + sortIndex: (json['sortIndex'] as num?)?.toInt(), + folderId: (json['folderId'] as num?)?.toInt(), origin: json['origin'] == null ? null : TokenOriginData.fromJson(json['origin'] as Map), diff --git a/lib/model/version.g.dart b/lib/model/version.g.dart index 8e28376b3..6acf48107 100644 --- a/lib/model/version.g.dart +++ b/lib/model/version.g.dart @@ -7,9 +7,9 @@ part of 'version.dart'; // ************************************************************************** Version _$VersionFromJson(Map json) => Version( - json['major'] as int, - json['minor'] as int, - json['patch'] as int, + (json['major'] as num).toInt(), + (json['minor'] as num).toInt(), + (json['patch'] as num).toInt(), ); Map _$VersionToJson(Version instance) => { diff --git a/lib/utils/custom_int_buffer.g.dart b/lib/utils/custom_int_buffer.g.dart index d38cf3d06..ee8663450 100644 --- a/lib/utils/custom_int_buffer.g.dart +++ b/lib/utils/custom_int_buffer.g.dart @@ -8,7 +8,7 @@ part of 'custom_int_buffer.dart'; CustomIntBuffer _$CustomIntBufferFromJson(Map json) => CustomIntBuffer( - maxSize: json['maxSize'] as int? ?? 100, + maxSize: (json['maxSize'] as num?)?.toInt() ?? 100, ); Map _$CustomIntBufferToJson(CustomIntBuffer instance) => diff --git a/lib/utils/customization/theme_customization.dart b/lib/utils/customization/theme_customization.dart index 93818c883..361ea661d 100644 --- a/lib/utils/customization/theme_customization.dart +++ b/lib/utils/customization/theme_customization.dart @@ -265,18 +265,20 @@ class ThemeCustomization { primaryColor: primaryColor, canvasColor: backgroundColor, textTheme: const TextTheme().copyWith( - bodyLarge: TextStyle(color: foregroundColor), - bodyMedium: TextStyle(color: foregroundColor), - titleMedium: TextStyle(color: foregroundColor), - titleSmall: TextStyle(color: foregroundColor), + bodyLarge: TextStyle(color: foregroundColor, fontSize: 18), + bodyMedium: TextStyle(color: foregroundColor, fontSize: 16), + bodySmall: TextStyle(color: subtitleColor, fontSize: 14), + titleLarge: TextStyle(color: primaryColor), + titleMedium: TextStyle(color: primaryColor), + titleSmall: TextStyle(color: primaryColor), displayLarge: TextStyle(color: foregroundColor), displayMedium: TextStyle(color: foregroundColor), displaySmall: TextStyle(color: foregroundColor), - headlineMedium: TextStyle(color: foregroundColor), - headlineSmall: TextStyle(color: foregroundColor), - titleLarge: TextStyle(color: primaryColor), - bodySmall: TextStyle(color: subtitleColor), + headlineMedium: TextStyle(color: primaryColor), + headlineLarge: TextStyle(color: primaryColor), + headlineSmall: TextStyle(color: primaryColor), labelLarge: TextStyle(color: foregroundColor), + labelMedium: TextStyle(color: foregroundColor), labelSmall: TextStyle(color: foregroundColor), ), iconButtonTheme: IconButtonThemeData( diff --git a/lib/views/add_token_manually_view/add_token_manually_view_widgets/labeled_dropdown_button.dart b/lib/views/add_token_manually_view/add_token_manually_view_widgets/labeled_dropdown_button.dart index 10a387e23..822d58eb7 100644 --- a/lib/views/add_token_manually_view/add_token_manually_view_widgets/labeled_dropdown_button.dart +++ b/lib/views/add_token_manually_view/add_token_manually_view_widgets/labeled_dropdown_button.dart @@ -50,7 +50,7 @@ class _LabeledDropdownButtonState extends State> { child: Text( '${value is Enum ? value.name : value}' '${widget.postFix}', - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, overflow: TextOverflow.fade, softWrap: false, ), diff --git a/lib/views/feedback_view/feedback_view.dart b/lib/views/feedback_view/feedback_view.dart index 8faeb446c..03f57451e 100644 --- a/lib/views/feedback_view/feedback_view.dart +++ b/lib/views/feedback_view/feedback_view.dart @@ -73,7 +73,7 @@ class _FeedbackViewState extends State { children: [ Text( AppLocalizations.of(context)!.feedbackDescription, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, textAlign: TextAlign.justify, ), const SizedBox(height: 16), diff --git a/lib/views/main_view/main_view_widgets/no_token_screen.dart b/lib/views/main_view/main_view_widgets/no_token_screen.dart index ba0635593..3f97a6e42 100644 --- a/lib/views/main_view/main_view_widgets/no_token_screen.dart +++ b/lib/views/main_view/main_view_widgets/no_token_screen.dart @@ -22,7 +22,7 @@ class NoTokenScreen extends StatelessWidget { ), Text( AppLocalizations.of(context)!.noResultText1, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, overflow: TextOverflow.fade, softWrap: false, ), @@ -32,7 +32,7 @@ class NoTokenScreen extends StatelessWidget { ), Text( AppLocalizations.of(context)!.noResultText2, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, overflow: TextOverflow.fade, softWrap: false, ) diff --git a/lib/views/main_view/main_view_widgets/token_widgets/push_token_widgets/actions/edit_push_token_action.dart b/lib/views/main_view/main_view_widgets/token_widgets/push_token_widgets/actions/edit_push_token_action.dart index ee6f49281..7e1df7177 100644 --- a/lib/views/main_view/main_view_widgets/token_widgets/push_token_widgets/actions/edit_push_token_action.dart +++ b/lib/views/main_view/main_view_widgets/token_widgets/push_token_widgets/actions/edit_push_token_action.dart @@ -139,7 +139,7 @@ class EditPushTokenAction extends TokenAction { ExpansionTile( title: Text( AppLocalizations.of(context)!.publicKey, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, overflow: TextOverflow.fade, softWrap: false, ), @@ -154,7 +154,7 @@ class EditPushTokenAction extends TokenAction { ExpansionTile( title: Text( AppLocalizations.of(context)!.firebaseToken, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, overflow: TextOverflow.fade, softWrap: false, ), diff --git a/lib/views/main_view/main_view_widgets/token_widgets/push_token_widgets/rollout_failed_widget.dart b/lib/views/main_view/main_view_widgets/token_widgets/push_token_widgets/rollout_failed_widget.dart index 1d8109319..7d32f54a9 100644 --- a/lib/views/main_view/main_view_widgets/token_widgets/push_token_widgets/rollout_failed_widget.dart +++ b/lib/views/main_view/main_view_widgets/token_widgets/push_token_widgets/rollout_failed_widget.dart @@ -26,7 +26,7 @@ class RolloutFailedWidget extends StatelessWidget { child: FittedBox( child: Text( token.rolloutState.rolloutMsg(localizations), - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, textAlign: TextAlign.center, ), ), diff --git a/lib/views/settings_view/settings_groups/import_export_tokens_widgets/dialogs/select_export_type_dialog.dart b/lib/views/settings_view/settings_groups/import_export_tokens_widgets/dialogs/select_export_type_dialog.dart index 556e37fb0..52eed0795 100644 --- a/lib/views/settings_view/settings_groups/import_export_tokens_widgets/dialogs/select_export_type_dialog.dart +++ b/lib/views/settings_view/settings_groups/import_export_tokens_widgets/dialogs/select_export_type_dialog.dart @@ -17,12 +17,12 @@ class SelectExportTypeDialog extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ SettingsListTileButton( - title: Text(AppLocalizations.of(context)!.toFile, style: Theme.of(context).textTheme.titleMedium), + title: Text(AppLocalizations.of(context)!.toFile, style: Theme.of(context).textTheme.bodyMedium), onPressed: () async => _selectTokensDialog(context), icon: const Icon(Icons.file_present, size: 24), ), SettingsListTileButton( - title: Text(AppLocalizations.of(context)!.asQrCode, style: Theme.of(context).textTheme.titleMedium), + title: Text(AppLocalizations.of(context)!.asQrCode, style: Theme.of(context).textTheme.bodyMedium), onPressed: () async => _selectTokenDialog(context), icon: const Icon(Icons.qr_code, size: 24)), ], diff --git a/lib/views/settings_view/settings_groups/import_export_tokens_widgets/dialogs/select_tokens_dialog.dart b/lib/views/settings_view/settings_groups/import_export_tokens_widgets/dialogs/select_tokens_dialog.dart index 4351536f6..7b8315a4f 100644 --- a/lib/views/settings_view/settings_groups/import_export_tokens_widgets/dialogs/select_tokens_dialog.dart +++ b/lib/views/settings_view/settings_groups/import_export_tokens_widgets/dialogs/select_tokens_dialog.dart @@ -33,7 +33,7 @@ class _SelectTokensDialogState extends ConsumerState { ? Text( AppLocalizations.of(context)!.noTokensToExport, textAlign: TextAlign.center, - style: Theme.of(context).textTheme.titleMedium?.copyWith(color: Theme.of(context).colorScheme.secondary), + style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Theme.of(context).colorScheme.secondary), ) : Column( mainAxisSize: MainAxisSize.min, diff --git a/lib/views/settings_view/settings_groups/settings_group_error_log.dart b/lib/views/settings_view/settings_groups/settings_group_error_log.dart index 8d7e1a9f3..9536bb269 100644 --- a/lib/views/settings_view/settings_groups/settings_group_error_log.dart +++ b/lib/views/settings_view/settings_groups/settings_group_error_log.dart @@ -14,7 +14,7 @@ class SettingsGroupErrorLog extends StatelessWidget { ListTile( title: Text( AppLocalizations.of(context)!.logMenu, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, overflow: TextOverflow.fade, softWrap: false, ), diff --git a/lib/views/settings_view/settings_groups/settings_group_general.dart b/lib/views/settings_view/settings_groups/settings_group_general.dart index bf37cf33d..c879ec942 100644 --- a/lib/views/settings_view/settings_groups/settings_group_general.dart +++ b/lib/views/settings_view/settings_groups/settings_group_general.dart @@ -26,7 +26,7 @@ class SettingsGroupGeneral extends StatelessWidget { }, title: Text( AppLocalizations.of(context)!.privacyPolicy, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, overflow: TextOverflow.fade, softWrap: false, ), @@ -37,7 +37,7 @@ class SettingsGroupGeneral extends StatelessWidget { }, title: Text( AppLocalizations.of(context)!.licensesAndVersion, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, overflow: TextOverflow.fade, softWrap: false, ), @@ -47,7 +47,7 @@ class SettingsGroupGeneral extends StatelessWidget { title: Text( AppLocalizations.of(context)!.thisAppIsOpenSource, //'This Application is a Open Source Project. Visit us on GitHub.', - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, maxLines: 2, ), icon: const Icon(SimpleIcons.github), @@ -58,7 +58,7 @@ class SettingsGroupGeneral extends StatelessWidget { }, title: Text( 'Feedback', - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, overflow: TextOverflow.fade, softWrap: false, ), diff --git a/lib/views/settings_view/settings_groups/settings_group_import_export_tokens.dart b/lib/views/settings_view/settings_groups/settings_group_import_export_tokens.dart index b2ae2b802..bf0d655d3 100644 --- a/lib/views/settings_view/settings_groups/settings_group_import_export_tokens.dart +++ b/lib/views/settings_view/settings_groups/settings_group_import_export_tokens.dart @@ -24,7 +24,7 @@ class _SettingsGroupImportExportTokensState extends ConsumerState SettingsGroup( - title: AppLocalizations.of(context)!.language, - children: [ - SwitchListTile( - title: Text( - AppLocalizations.of(context)!.useDeviceLocaleTitle, - style: Theme.of(context).textTheme.titleMedium, - ), - subtitle: Text( - AppLocalizations.of(context)!.useDeviceLocaleDescription, - overflow: TextOverflow.fade, - ), - value: ref.watch(settingsProvider).useSystemLocale, - onChanged: (value) => ref.read(settingsProvider.notifier).setUseSystemLocale(value)), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: DropdownButton( - disabledHint: Text( - '${ref.watch(settingsProvider).currentLocale}', - style: Theme.of(context).textTheme.titleMedium?.copyWith(color: Colors.grey), - overflow: TextOverflow.fade, - softWrap: false, - ), - isExpanded: true, - value: ref.watch(settingsProvider).currentLocale, - items: AppLocalizations.supportedLocales.map>((Locale itemLocale) { - return DropdownMenuItem( - value: itemLocale, - child: Text( - '$itemLocale', - overflow: TextOverflow.fade, - softWrap: false, - ), - ); - }).toList(), - onChanged: ref.watch(settingsProvider).useSystemLocale ? null : (value) => ref.read(settingsProvider.notifier).setLocalePreference(value!), + Widget build(BuildContext context, WidgetRef ref) { + final localizations = AppLocalizations.of(context)!; + return SettingsGroup( + title: localizations.language, + children: [ + SwitchListTile( + title: Text( + localizations.useDeviceLocaleTitle, + style: Theme.of(context).textTheme.bodyMedium, ), + subtitle: Text( + localizations.useDeviceLocaleDescription, + overflow: TextOverflow.fade, + ), + value: ref.watch(settingsProvider).useSystemLocale, + onChanged: (value) => ref.read(settingsProvider.notifier).setUseSystemLocale(value)), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: DropdownButton( + disabledHint: Text( + '${ref.watch(settingsProvider).currentLocale}', + style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.grey), + overflow: TextOverflow.fade, + softWrap: false, + ), + isExpanded: true, + value: ref.watch(settingsProvider).currentLocale, + items: AppLocalizations.supportedLocales.map>((Locale itemLocale) { + return DropdownMenuItem( + value: itemLocale, + child: Text( + '$itemLocale', + overflow: TextOverflow.fade, + style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: ref.watch(settingsProvider).useSystemLocale ? Colors.grey : null), + softWrap: false, + ), + ); + }).toList(), + onChanged: ref.watch(settingsProvider).useSystemLocale ? null : (value) => ref.read(settingsProvider.notifier).setLocalePreference(value!), ), - ], - ); + ), + ], + ); + } } diff --git a/lib/views/settings_view/settings_groups/settings_group_push_token.dart b/lib/views/settings_view/settings_groups/settings_group_push_token.dart index 4ca61c79f..c3979df0f 100644 --- a/lib/views/settings_view/settings_groups/settings_group_push_token.dart +++ b/lib/views/settings_view/settings_groups/settings_group_push_token.dart @@ -24,7 +24,7 @@ class SettingsGroupPushToken extends ConsumerWidget { ListTile( title: Text( AppLocalizations.of(context)!.synchronizePushTokens, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, ), subtitle: Text( AppLocalizations.of(context)!.synchronizesTokensWithServer, @@ -54,7 +54,7 @@ class SettingsGroupPushToken extends ConsumerWidget { children: [ TextSpan( text: AppLocalizations.of(context)!.enablePolling, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, ), // Add clickable icon to inform user of unsupported push tokens (for polling) WidgetSpan( @@ -89,7 +89,7 @@ class SettingsGroupPushToken extends ConsumerWidget { children: [ TextSpan( text: AppLocalizations.of(context)!.hidePushTokens, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, ), ], ), diff --git a/lib/views/settings_view/settings_groups/settings_group_theme.dart b/lib/views/settings_view/settings_groups/settings_group_theme.dart index aca058ea2..77d32c44d 100644 --- a/lib/views/settings_view/settings_groups/settings_group_theme.dart +++ b/lib/views/settings_view/settings_groups/settings_group_theme.dart @@ -15,7 +15,7 @@ class SettingsGroupTheme extends StatelessWidget { RadioListTile( title: Text( AppLocalizations.of(context)!.lightTheme, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, overflow: TextOverflow.fade, softWrap: false, ), @@ -30,7 +30,7 @@ class SettingsGroupTheme extends StatelessWidget { RadioListTile( title: Text( AppLocalizations.of(context)!.darkTheme, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, overflow: TextOverflow.fade, softWrap: false, ), @@ -45,7 +45,7 @@ class SettingsGroupTheme extends StatelessWidget { RadioListTile( title: Text( AppLocalizations.of(context)!.systemTheme, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, ), value: ThemeMode.system, groupValue: EasyDynamicTheme.of(context).themeMode, diff --git a/lib/views/settings_view/settings_view_widgets/logging_menu.dart b/lib/views/settings_view/settings_view_widgets/logging_menu.dart index 00e7924f6..466f4f08a 100644 --- a/lib/views/settings_view/settings_view_widgets/logging_menu.dart +++ b/lib/views/settings_view/settings_view_widgets/logging_menu.dart @@ -30,7 +30,7 @@ class LoggingMenu extends ConsumerWidget { ListTile( title: Text( AppLocalizations.of(context)!.verboseLogging, - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, textAlign: TextAlign.center, ), contentPadding: const EdgeInsets.all(0), diff --git a/lib/widgets/dialog_widgets/patch_notes_dialog.dart b/lib/widgets/dialog_widgets/patch_notes_dialog.dart index 288bbc726..8283e9f55 100644 --- a/lib/widgets/dialog_widgets/patch_notes_dialog.dart +++ b/lib/widgets/dialog_widgets/patch_notes_dialog.dart @@ -39,7 +39,7 @@ class PatchNotesDialog extends StatelessWidget { children: [ Text( '${localizations.version}: ${version.toString()}', - style: Theme.of(context).textTheme.titleMedium, + style: Theme.of(context).textTheme.bodyMedium, ), const SizedBox(height: 16), ...newNotes[version]!.entries.map( diff --git a/lib/widgets/dialog_widgets/push_request_dialog.dart b/lib/widgets/dialog_widgets/push_request_dialog.dart index 663391e86..edef10a3b 100644 --- a/lib/widgets/dialog_widgets/push_request_dialog.dart +++ b/lib/widgets/dialog_widgets/push_request_dialog.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -21,9 +23,14 @@ class PushRequestDialog extends ConsumerStatefulWidget { } class _PushRequestDialogState extends ConsumerState { - static const titleScale = 1.35; - static const questionScale = 1.1; double get lineHeight => Theme.of(context).textTheme.titleLarge?.fontSize ?? 16; + double get spacerHeight => lineHeight * 0.5; + + MaterialStateProperty get buttonShape => MaterialStateProperty.all( + Theme.of(context).elevatedButtonTheme.style?.shape?.resolve({})?.copyWith( + side: BorderSide(color: Theme.of(context).colorScheme.onPrimary, width: 2.5), + ), + ); bool isHandled = false; bool dialogIsOpen = false; @@ -44,83 +51,111 @@ class _PushRequestDialogState extends ConsumerState { @override Widget build(BuildContext context) { - final lineHeight = this.lineHeight; + final spacerHeight = this.spacerHeight; final question = widget.pushRequest.question; final token = ref.watch(tokenProvider).getTokenBySerial(widget.pushRequest.serial); + final localizations = AppLocalizations.of(context)!; if (token == null) { WidgetsBinding.instance.addPostFrameCallback((_) async { - if (mounted) { - ref.read(pushRequestProvider.notifier).remove(widget.pushRequest); - } + if (mounted) ref.read(pushRequestProvider.notifier).remove(widget.pushRequest); }); } + final test = [ + '42', + '0#', + '69', + '13', + '37', + ]; return isHandled || token == null ? const SizedBox() : Container( color: Colors.transparent, child: DefaultDialog( + scrollable: false, title: Text( - AppLocalizations.of(context)!.authenticationRequest, - style: Theme.of(context).textTheme.titleLarge!, + localizations.authenticationRequest, + style: Theme.of(context).textTheme.headlineMedium!, textAlign: TextAlign.center, - textScaler: const TextScaler.linear(titleScale), ), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( - AppLocalizations.of(context)!.requestInfo( + localizations.requestInfo( token.issuer, token.label, ), - style: Theme.of(context).textTheme.bodyLarge?.copyWith(fontSize: Theme.of(context).textTheme.titleMedium?.fontSize), - textScaler: const TextScaler.linear(questionScale), + style: Theme.of(context).textTheme.bodyLarge!, textAlign: TextAlign.center, ), - SizedBox(height: lineHeight), + SizedBox(height: spacerHeight), ...[ Text( question, - style: Theme.of(context).textTheme.bodyLarge?.copyWith(fontSize: Theme.of(context).textTheme.titleMedium?.fontSize), - textScaler: const TextScaler.linear(questionScale), + style: Theme.of(context).textTheme.bodyLarge!, textAlign: TextAlign.center, ), - SizedBox(height: lineHeight), + SizedBox(height: spacerHeight), ], - if (widget.pushRequest.answers != null) - GridView.builder( - shrinkWrap: true, - itemCount: widget.pushRequest.answers!.length, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - childAspectRatio: 3, - ), - itemBuilder: (context, index) { - return PressButton( - onPressed: () { - globalRef?.read(pushRequestProvider.notifier).accept(token, widget.pushRequest, selectedAnswerIndex: index); - Navigator.of(context).pop(); + widget.pushRequest.answers == null + ? AnswerSelectionWidget( + onAnswerSelected: (p0) { + globalRef?.read(pushRequestProvider.notifier).accept(token, widget.pushRequest, selectedAnswerIndex: p0); if (mounted) setState(() => isHandled = true); }, - child: Text( - widget.pushRequest.answers![index], - style: const TextStyle(fontSize: 16), - textAlign: TextAlign.center, + possibleAnswers: test, + ) + : SizedBox( + // Accept button + child: PressButton( + style: ButtonStyle(shape: buttonShape), + onPressed: () async { + if (token.isLocked && await lockAuth(localizedReason: localizations.authToAcceptPushRequest) == false) { + return; + } + globalRef?.read(pushRequestProvider.notifier).accept(token, widget.pushRequest); + if (mounted) setState(() => isHandled = true); + }, + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: spacerHeight), + child: Text( + localizations.accept, + style: Theme.of(context).textTheme.headlineMedium?.copyWith(color: Theme.of(context).colorScheme.onPrimary), + textAlign: TextAlign.center, + maxLines: 1, + ), + ), + Icon( + Icons.check_outlined, + size: Theme.of(context).textTheme.headlineMedium?.fontSize ?? 16, + ), + ], + ), ), - ); - }, - ), + ), SizedBox( - // Accept button - height: lineHeight * titleScale * 2 + 16, + // Decline button child: PressButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + Theme.of(context).colorScheme.errorContainer, + ), + shape: buttonShape, + ), onPressed: () async { - if (token.isLocked && await lockAuth(localizedReason: AppLocalizations.of(context)!.authToAcceptPushRequest) == false) { + if (token.isLocked && await lockAuth(localizedReason: localizations.authToDeclinePushRequest) == false) { return; } - globalRef?.read(pushRequestProvider.notifier).accept(token, widget.pushRequest); - if (mounted) setState(() => isHandled = true); + dialogIsOpen = true; + await _showConfirmationDialog(token); + dialogIsOpen = false; }, child: Row( mainAxisSize: MainAxisSize.max, @@ -128,151 +163,197 @@ class _PushRequestDialogState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - AppLocalizations.of(context)!.accept, - style: Theme.of(context).textTheme.titleLarge?.copyWith(color: Theme.of(context).colorScheme.onPrimary), - textScaler: const TextScaler.linear(titleScale), + localizations.decline, + style: Theme.of(context).textTheme.headlineMedium?.copyWith(color: Theme.of(context).colorScheme.onPrimary), textAlign: TextAlign.center, - maxLines: 1, ), Icon( - Icons.check_outlined, - size: lineHeight * titleScale, + Icons.close_outlined, + size: Theme.of(context).textTheme.headlineMedium?.fontSize ?? 16, ), ], ), ), ), - SizedBox(height: lineHeight * 0.5), - SizedBox( - // Decline button - height: lineHeight * titleScale + 16, - child: PressButton( - style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Theme.of(context).colorScheme.errorContainer)), - onPressed: () async { - if (token.isLocked && await lockAuth(localizedReason: AppLocalizations.of(context)!.authToDeclinePushRequest) == false) { - return; - } - dialogIsOpen = true; - await _showConfirmationDialog(token); - dialogIsOpen = false; + SizedBox(height: spacerHeight), + ], + ), + ), + ); + } + + Future _showConfirmationDialog(PushToken pushToken) { + final localizations = AppLocalizations.of(context)!; + return showDialog( + useRootNavigator: false, + context: globalNavigatorKey.currentContext!, + builder: (BuildContext context) { + final spacerHeight = this.spacerHeight; + return DefaultDialog( + title: Text( + localizations.authenticationRequest, + style: Theme.of(context).textTheme.titleLarge!, + textAlign: TextAlign.center, + ), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + localizations.requestTriggerdByUserQuestion, + style: Theme.of(context).textTheme.bodyLarge?.copyWith(fontSize: Theme.of(context).textTheme.titleMedium?.fontSize), + textAlign: TextAlign.center, + ), + SizedBox(height: spacerHeight), + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + const Expanded(child: SizedBox()), + Expanded( + flex: 6, + child: PressButton( + style: ButtonStyle(shape: buttonShape), + onPressed: () { + globalRef?.read(pushRequestProvider.notifier).decline(pushToken, widget.pushRequest); + Navigator.of(context).pop(); + if (mounted) setState(() => isHandled = true); }, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.center, + child: Column( + mainAxisSize: MainAxisSize.min, children: [ Text( - AppLocalizations.of(context)!.decline, - style: Theme.of(context).textTheme.titleLarge?.copyWith(color: Theme.of(context).colorScheme.onPrimary), - textScaler: const TextScaler.linear(titleScale), + localizations.yes, + style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: Theme.of(context).colorScheme.onPrimary), textAlign: TextAlign.center, ), - Icon(Icons.close_outlined, size: lineHeight * titleScale), + FittedBox( + fit: BoxFit.scaleDown, + child: Text( + localizations.butDiscardIt, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onPrimary.mixWith(Colors.grey.shade800), + ), + textAlign: TextAlign.center, + softWrap: false, + ), + ), ], - )), - ), - ], - ), + ), + ), + ), + const Expanded(flex: 2, child: SizedBox()), + Expanded( + flex: 6, + child: PressButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(Theme.of(context).colorScheme.errorContainer), + shape: buttonShape, + ), + onPressed: () { + //TODO: Notify issuer + globalRef?.read(pushRequestProvider.notifier).decline(pushToken, widget.pushRequest); + Navigator.of(context).pop(); + if (mounted) setState(() => isHandled = true); + }, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + localizations.no, + style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: Theme.of(context).colorScheme.onPrimary), + textAlign: TextAlign.center, + ), + Text( + localizations.declineIt, + style: + Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).colorScheme.onPrimary.mixWith(Colors.grey.shade800)), + textAlign: TextAlign.center, + softWrap: false, + ), + ], + ), + ), + ), + const Expanded(child: SizedBox()), + ], + ), + ], ), ); + }); } +} - Future _showConfirmationDialog(PushToken pushToken) => showDialog( - useRootNavigator: false, - context: globalNavigatorKey.currentContext!, - builder: (BuildContext context) { - final lineHeight = this.lineHeight; - return DefaultDialog( - title: Text( - AppLocalizations.of(context)!.authenticationRequest, - style: Theme.of(context).textTheme.titleLarge!, - textAlign: TextAlign.center, - textScaler: const TextScaler.linear(titleScale), - ), - content: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Text( - AppLocalizations.of(context)!.requestTriggerdByUserQuestion, - style: Theme.of(context).textTheme.bodyLarge?.copyWith(fontSize: Theme.of(context).textTheme.titleMedium?.fontSize), - textScaler: const TextScaler.linear(questionScale), - textAlign: TextAlign.center, - ), - SizedBox(height: lineHeight), - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - const Expanded(child: SizedBox()), - Expanded( - flex: 6, - child: PressButton( - onPressed: () { - globalRef?.read(pushRequestProvider.notifier).decline(pushToken, widget.pushRequest); - Navigator.of(context).pop(); - if (mounted) setState(() => isHandled = true); - }, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - AppLocalizations.of(context)!.yes, - style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: Theme.of(context).colorScheme.onPrimary), - textScaler: const TextScaler.linear(titleScale), - textAlign: TextAlign.center, - ), - FittedBox( - fit: BoxFit.scaleDown, - child: Text( - AppLocalizations.of(context)!.butDiscardIt, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onPrimary.mixWith(Colors.grey.shade800), - ), - textAlign: TextAlign.center, - softWrap: false, - ), - ), - ], +class AnswerSelectionWidget extends StatefulWidget { + final List possibleAnswers; + final void Function(int) onAnswerSelected; + const AnswerSelectionWidget({required this.possibleAnswers, super.key, required this.onAnswerSelected}); + + @override + State> createState() => _AnswerSelectionWidgetState(); +} + +class _AnswerSelectionWidgetState extends State> { + double get lineHeight => Theme.of(context).textTheme.titleLarge?.fontSize ?? 16; + double get spacerHeight => lineHeight * 0.5; + @override + Widget build(BuildContext context) { + final children = []; + final possibleAnswers = widget.possibleAnswers.toList(); + const numPerRow = 3; + var answersHandled = 0; + var numRow = 0; + while (possibleAnswers.length > answersHandled) { + final maxThisRow = possibleAnswers.length - answersHandled == numPerRow + 1 + ? min(possibleAnswers.length - answersHandled, (numPerRow / 2).ceil()) + : min(possibleAnswers.length - answersHandled, numPerRow); + numRow++; + print('NumRow: $numRow'); + print('asd.length: ${possibleAnswers.length}'); + print('maxThisRow: $maxThisRow'); + children.add( + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + if (maxThisRow != numPerRow) const Expanded(child: SizedBox()), + for (var i = answersHandled; i < answersHandled + maxThisRow; i++, answersHandled++) + Expanded( + flex: 4, + child: PressButton( + style: ButtonStyle( + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(999), + side: BorderSide( + color: Theme.of(context).colorScheme.onPrimary, + width: 2.5, + ), ), ), ), - const Expanded(flex: 2, child: SizedBox()), - Expanded( - flex: 6, - child: PressButton( - style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Theme.of(context).colorScheme.errorContainer)), - onPressed: () { - //TODO: Notify issuer - globalRef?.read(pushRequestProvider.notifier).decline(pushToken, widget.pushRequest); - Navigator.of(context).pop(); - if (mounted) setState(() => isHandled = true); - }, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - AppLocalizations.of(context)!.no, - style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: Theme.of(context).colorScheme.onPrimary), - textScaler: const TextScaler.linear(titleScale), - textAlign: TextAlign.center, - ), - Text( - AppLocalizations.of(context)!.declineIt, - style: - Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).colorScheme.onPrimary.mixWith(Colors.grey.shade800)), - textAlign: TextAlign.center, - softWrap: false, - ), - ], - ), + onPressed: () => widget.onAnswerSelected(i), + child: Padding( + padding: EdgeInsets.all(spacerHeight), + child: Text( + possibleAnswers[i].toString(), + style: Theme.of(context).textTheme.headlineMedium?.copyWith(color: Theme.of(context).colorScheme.onPrimary), + textAlign: TextAlign.center, ), ), - const Expanded(child: SizedBox()), - ], + ), ), - ], - ), - ); - }); + if (maxThisRow != numPerRow) const Expanded(child: SizedBox()), + ], + ), + ); + } + + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: children, + ); + } } diff --git a/lib/widgets/press_button.dart b/lib/widgets/press_button.dart index a03dd7c7f..fb2dcbc5f 100644 --- a/lib/widgets/press_button.dart +++ b/lib/widgets/press_button.dart @@ -32,11 +32,12 @@ class _PressButtonState extends State { } @override - Widget build(BuildContext context) { - return ElevatedButton( - onPressed: isPressable ? press : null, - style: widget.style?.merge(Theme.of(context).elevatedButtonTheme.style), - child: widget.child, - ); - } + Widget build(BuildContext context) => Padding( + padding: Theme.of(context).elevatedButtonTheme.style?.padding?.resolve({}) ?? const EdgeInsets.all(0), + child: ElevatedButton( + onPressed: isPressable ? press : null, + style: widget.style?.merge(Theme.of(context).elevatedButtonTheme.style) ?? Theme.of(context).elevatedButtonTheme.style, + child: widget.child, + ), + ); } diff --git a/pubspec.yaml b/pubspec.yaml index 2fccb2787..319e0db63 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -32,7 +32,7 @@ dependencies: flutter_local_notifications: ^17.0.0 home_widget: ^0.5.0 image: ^4.1.6 - json_annotation: ^4.8.1 + json_annotation: ^4.9.0 local_auth: ^2.1.6 local_auth_android: ^1.0.37 local_auth_darwin: ^1.2.2 From e0b941f93c3828780eaa3b8f610874736c02ca50 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Fri, 24 May 2024 14:36:07 +0200 Subject: [PATCH 04/32] migrate app to gradles plugin dsl --- .gitignore | 4 + android/app/build.gradle | 5 +- android/settings.gradle | 5 +- lib/mains/main_netknights.dart | 6 + lib/utils/firebase_utils.dart | 4 +- lib/utils/riverpod_providers.dart | 9 +- pubspec.lock | 200 ++++++++++++++++-------------- pubspec.yaml | 5 +- 8 files changed, 135 insertions(+), 103 deletions(-) diff --git a/.gitignore b/.gitignore index 2fae39ee8..94f48e0de 100644 --- a/.gitignore +++ b/.gitignore @@ -891,3 +891,7 @@ DerivedData/ lib/l10n/untranslated.txt *.jks ios/Flutter/flutter_export_environment.sh + +# Firebase +firebase_options.dart +firebase.json diff --git a/android/app/build.gradle b/android/app/build.gradle index 858f3b0eb..01b1028ad 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,5 +1,8 @@ plugins { id "com.android.application" + // START: FlutterFire Configuration + id 'com.google.gms.google-services' + // END: FlutterFire Configuration id "kotlin-android" id "dev.flutter.flutter-gradle-plugin" } @@ -46,7 +49,7 @@ android { defaultConfig { applicationId "it.netknights.piauthenticator" - minSdkVersion 24 + minSdkVersion 21 targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/android/settings.gradle b/android/settings.gradle index 349d5215b..8e55d5a8d 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -19,7 +19,10 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "7.4.2" apply false + id "com.android.application" version "7.3.0" apply false + // START: FlutterFire Configuration + id "com.google.gms.google-services" version "4.3.15" apply false + // END: FlutterFire Configuration id "org.jetbrains.kotlin.android" version "1.8.0" apply false } diff --git a/lib/mains/main_netknights.dart b/lib/mains/main_netknights.dart index 82661d394..bf56c7135 100644 --- a/lib/mains/main_netknights.dart +++ b/lib/mains/main_netknights.dart @@ -20,8 +20,10 @@ */ import 'package:easy_dynamic_theme/easy_dynamic_theme.dart'; +import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:privacyidea_authenticator/firebase_options.dart'; import 'package:privacyidea_authenticator/l10n/app_localizations.dart'; import 'package:privacyidea_authenticator/utils/customization/application_customization.dart'; import 'package:privacyidea_authenticator/utils/globals.dart'; @@ -48,6 +50,10 @@ void main() async { WidgetsFlutterBinding.ensureInitialized(); await HomeWidgetUtils().registerInteractivityCallback(homeWidgetBackgroundCallback); await HomeWidgetUtils().setAppGroupId(appGroupId); + final app = await Firebase.initializeApp(options: NetknightsFirebaseOptions.currentPlatform); + await app.setAutomaticDataCollectionEnabled(false); + Logger.warning('Automatic data collection: ${app.isAutomaticDataCollectionEnabled}', name: 'firebase_utils.dart#initFirebase'); + runApp(AppWrapper(child: PrivacyIDEAAuthenticator(ApplicationCustomization.defaultCustomization))); }); } diff --git a/lib/utils/firebase_utils.dart b/lib/utils/firebase_utils.dart index fc37f3510..6c1c7d01f 100644 --- a/lib/utils/firebase_utils.dart +++ b/lib/utils/firebase_utils.dart @@ -34,9 +34,7 @@ class FirebaseUtils { } _initialized = true; Logger.info('Initializing Firebase', name: 'firebase_utils.dart#initFirebase'); - final app = await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); - await app.setAutomaticDataCollectionEnabled(false); - Logger.warning('Automatic data collection: ${app.isAutomaticDataCollectionEnabled}', name: 'firebase_utils.dart#initFirebase'); + try { // await FirebaseMessaging.instance.requestPermission(); } on FirebaseException catch (e, s) { diff --git a/lib/utils/riverpod_providers.dart b/lib/utils/riverpod_providers.dart index f8ff04328..89c18c1c1 100644 --- a/lib/utils/riverpod_providers.dart +++ b/lib/utils/riverpod_providers.dart @@ -1,9 +1,9 @@ import 'dart:developer'; +import 'package:app_links/app_links.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:uni_links/uni_links.dart'; import '../l10n/app_localizations.dart'; import '../model/extensions/sortable_list.dart'; @@ -34,8 +34,9 @@ import 'logger.dart'; import 'push_provider.dart'; import 'riverpod_state_listener.dart'; -// Never use globalRef to .watch() a provider. only use it to .read() a provider -// Otherwise the whole app will rebuild on every state change of the provider +/// Never use globalRef to .watch() a provider. only use it to .read() a provider +/// +/// Otherwise the whole app will rebuild on every state change of the provider WidgetRef? globalRef; final tokenProvider = StateNotifierProvider( @@ -104,7 +105,7 @@ final deeplinkProvider = StateNotifierProvider( (ref) { Logger.info("New DeeplinkNotifier created", name: 'deeplinkProvider'); return DeeplinkNotifier(sources: [ - DeeplinkSource(name: 'uni_links', stream: uriLinkStream, initialUri: getInitialUri()), + DeeplinkSource(name: 'uni_links', stream: AppLinks().uriLinkStream, initialUri: AppLinks().getInitialLink()), DeeplinkSource( name: 'home_widget', stream: HomeWidgetUtils().widgetClicked, diff --git a/pubspec.lock b/pubspec.lock index d91c970e3..71c415b1b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "3dee3db3468c5f4640a4e8aa9c1e22561c298976d8c39ed2fdd456a9a3db26e1" + sha256: e4be6711f96d3d4eebe79728897d645b7a5585bbfdd6d534878d202c171266d7 url: "https://pub.dev" source: hosted - version: "1.3.32" + version: "1.3.34" analyzer: dependency: transitive description: @@ -25,6 +25,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.4.1" + app_links: + dependency: "direct main" + description: + name: app_links + sha256: "96e677810b83707ff5e10fac11e4839daa0ea4e0123c35864c092699165eb3db" + url: "https://pub.dev" + source: hosted + version: "6.1.1" app_minimizer: dependency: "direct main" description: @@ -37,10 +45,10 @@ packages: dependency: transitive description: name: archive - sha256: "0763b45fa9294197a2885c8567927e2830ade852e5c896fd4ab7e0e348d0f373" + sha256: "6bd38d335f0954f5fad9c79e614604fbf03a0e5b975923dd001b6ea965ef5b4b" url: "https://pub.dev" source: hosted - version: "3.5.0" + version: "3.6.0" args: dependency: transitive description: @@ -53,10 +61,10 @@ packages: dependency: "direct main" description: name: asn1lib - sha256: c9c85fedbe2188b95133cbe960e16f5f448860f7133330e272edbbca5893ddc6 + sha256: "58082b3f0dca697204dbab0ef9ff208bfaea7767ea771076af9a343488428dda" url: "https://pub.dev" source: hosted - version: "1.5.2" + version: "1.5.3" async: dependency: transitive description: @@ -101,10 +109,10 @@ packages: dependency: transitive description: name: build_daemon - sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1" + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "4.0.2" build_resolvers: dependency: transitive description: @@ -117,10 +125,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22" + sha256: "1414d6d733a85d8ad2f1dfcb3ea7945759e35a123cb99ccfac75d0758f75edfa" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.4.10" build_runner_core: dependency: transitive description: @@ -261,10 +269,10 @@ packages: dependency: transitive description: name: coverage - sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76" + sha256: "3945034e86ea203af7a056d98e98e42a5518fff200d6e8e6647e1886b07e936e" url: "https://pub.dev" source: hosted - version: "1.7.2" + version: "1.8.0" cross_file: dependency: transitive description: @@ -389,18 +397,18 @@ packages: dependency: transitive description: name: file_selector_android - sha256: "1cd66575f063b689e041aec836905ba7be18d76c9f0634d0d75daec825f67095" + sha256: "8bcc3af859e9d47fab9c7dc315537406511a894ab578e198bd8f9ed745ea5a01" url: "https://pub.dev" source: hosted - version: "0.5.0+7" + version: "0.5.1+2" file_selector_ios: dependency: transitive description: name: file_selector_ios - sha256: "0a1196a9c5795858aa315332da2fb5c4bcfdcb312d8a4e27651f765b87904431" + sha256: "38ebf91ecbcfa89a9639a0854ccaed8ab370c75678938eebca7d34184296f0bb" url: "https://pub.dev" source: hosted - version: "0.5.1+9" + version: "0.5.3" file_selector_linux: dependency: transitive description: @@ -413,10 +421,10 @@ packages: dependency: transitive description: name: file_selector_macos - sha256: b15c3da8bd4908b9918111fa486903f5808e388b8d1c559949f584725a6594d6 + sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385 url: "https://pub.dev" source: hosted - version: "0.9.3+3" + version: "0.9.4" file_selector_platform_interface: dependency: transitive description: @@ -445,10 +453,10 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "4aef2a23d0f3265545807d68fbc2f76a6b994ca3c778d88453b99325abd63284" + sha256: "4b5100e2dbc3fe72c2d4241a046d3f01457fe11293283a324f5c52575e3406f8" url: "https://pub.dev" source: hosted - version: "2.30.1" + version: "2.31.1" firebase_core_platform_interface: dependency: transitive description: @@ -461,34 +469,34 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: "67f2fcc600fc78c2f731c370a3a5e6c87ee862e3a2fba6f951eca6d5dafe5c29" + sha256: "43d9e951ac52b87ae9cc38ecdcca1e8fa7b52a1dd26a96085ba41ce5108db8e9" url: "https://pub.dev" source: hosted - version: "2.16.0" + version: "2.17.0" firebase_messaging: dependency: "direct main" description: name: firebase_messaging - sha256: "73a43445a7f8c6e6327f0ec3922b1c99a9f4a0e4896197bfe10a88259f775aad" + sha256: "62c27bd7c9c724b5ee5fd52e06224b8861d6e692f08b3d7bc3ada28552f27d41" url: "https://pub.dev" source: hosted - version: "14.9.1" + version: "14.9.3" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface - sha256: "675527aadccb679c9dfd43a4558690427123ac1e99f03eef5bbce9dc216edc91" + sha256: f73e9fe4bc25307520b714cec39a2e1a625c64511d497964f3e06c5d60146948 url: "https://pub.dev" source: hosted - version: "4.5.34" + version: "4.5.36" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web - sha256: "66deff69307f54fc7a20732b4278af327ae378b86607d5ac877d8f2201fe881e" + sha256: "5ed108929f988d55c497f1456ad5e407501a746869306f058b6d2b2e704790f3" url: "https://pub.dev" source: hosted - version: "3.8.4" + version: "3.8.6" fixnum: dependency: transitive description: @@ -501,10 +509,10 @@ packages: dependency: "direct main" description: name: fluentui_system_icons - sha256: "9bb6c46ff0351f0b20a79bbe5afcaf533af5f06fd8ac22407b57eaee8025004c" + sha256: "5438216388532797b339fcd18c3ebf9c04f4e03123b203dedc98368c0753a1e8" url: "https://pub.dev" source: hosted - version: "1.1.236" + version: "1.1.239" flutter: dependency: "direct main" description: flutter @@ -527,10 +535,10 @@ packages: dependency: "direct main" description: name: flutter_local_notifications - sha256: "8cdc719114ab1c86c64bb7a86d3a679674c3637edd229e3a994797d4a1504ce4" + sha256: "40e6fbd2da7dcc7ed78432c5cdab1559674b4af035fddbfb2f9a8f9c2112fcef" url: "https://pub.dev" source: hosted - version: "17.1.0" + version: "17.1.2" flutter_local_notifications_linux: dependency: transitive description: @@ -580,50 +588,50 @@ packages: dependency: "direct main" description: name: flutter_secure_storage - sha256: ffdbb60130e4665d2af814a0267c481bcf522c41ae2e43caf69fa0146876d685 + sha256: "165164745e6afb5c0e3e3fcc72a012fb9e58496fb26ffb92cf22e16a821e85d0" url: "https://pub.dev" source: hosted - version: "9.0.0" + version: "9.2.2" flutter_secure_storage_linux: dependency: transitive description: name: flutter_secure_storage_linux - sha256: "3d5032e314774ee0e1a7d0a9f5e2793486f0dff2dd9ef5a23f4e3fb2a0ae6a9e" + sha256: "4d91bfc23047422cbcd73ac684bc169859ee766482517c22172c86596bf1464b" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" flutter_secure_storage_macos: dependency: transitive description: name: flutter_secure_storage_macos - sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c + sha256: "1693ab11121a5f925bbea0be725abfcfbbcf36c1e29e571f84a0c0f436147a81" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.1.2" flutter_secure_storage_platform_interface: dependency: transitive description: name: flutter_secure_storage_platform_interface - sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e" + sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8 url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.1.2" flutter_secure_storage_web: dependency: transitive description: name: flutter_secure_storage_web - sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20" + sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9 url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.1" flutter_secure_storage_windows: dependency: transitive description: name: flutter_secure_storage_windows - sha256: "5809c66f9dd3b4b93b0a6e2e8561539405322ee767ac2f64d084e2ab5429d108" + sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709 url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.1.2" flutter_slidable: dependency: "direct main" description: @@ -654,10 +662,10 @@ packages: dependency: transitive description: name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "4.0.0" fuchsia_remote_debug_protocol: dependency: transitive description: flutter @@ -679,6 +687,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.1" + gtk: + dependency: transitive + description: + name: gtk + sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c + url: "https://pub.dev" + source: hosted + version: "2.1.0" hex: dependency: "direct main" description: @@ -691,10 +707,10 @@ packages: dependency: "direct main" description: name: home_widget - sha256: "29565bfee4b32eaf9e7e8b998d504618b779a74b2b1ac62dd4dac7468e66f1a3" + sha256: "2a0fdd6267ff975bd07bedf74686bd5577200f504f5de36527ac1b56bdbe68e3" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.6.0" http: dependency: "direct main" description: @@ -723,10 +739,10 @@ packages: dependency: "direct main" description: name: image - sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e" + sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8" url: "https://pub.dev" source: hosted - version: "4.1.7" + version: "4.2.0" integration_test: dependency: "direct dev" description: flutter @@ -736,10 +752,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" io: dependency: transitive description: @@ -776,26 +792,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.4" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.3" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" lints: dependency: transitive description: @@ -824,10 +840,10 @@ packages: dependency: "direct main" description: name: local_auth_darwin - sha256: "33381a15b0de2279523eca694089393bb146baebdce72a404555d03174ebc1e9" + sha256: e424ebf90d5233452be146d4a7da4bcd7a70278b67791592f3fde1bda8eef9e2 url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.3.1" local_auth_platform_interface: dependency: transitive description: @@ -848,10 +864,10 @@ packages: dependency: "direct main" description: name: logger - sha256: "8c94b8c219e7e50194efc8771cd0e9f10807d8d3e219af473d89b06cc2ee4e04" + sha256: af05cc8714f356fd1f3888fb6741cbe9fbe25cdb6eedbab80e1a6db21047d4a4 url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.0" logging: dependency: transitive description: @@ -864,10 +880,10 @@ packages: dependency: "direct main" description: name: lottie - sha256: ce2bb2605753915080e4ee47f036a64228c88dc7f56f7bc1dbe912d75b55b1e2 + sha256: "6a24ade5d3d918c306bb1c21a6b9a04aab0489d51a2582522eea820b4093b62b" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.2" matcher: dependency: transitive description: @@ -896,10 +912,10 @@ packages: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.0" mime: dependency: transitive description: @@ -1000,10 +1016,10 @@ packages: dependency: transitive description: name: path_provider_foundation - sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" + sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.0" path_provider_linux: dependency: transitive description: @@ -1040,10 +1056,10 @@ packages: dependency: transitive description: name: permission_handler_android - sha256: "1acac6bae58144b442f11e66621c062aead9c99841093c38f5bcdcc24c1c3474" + sha256: "8bb852cd759488893805c3161d0b2b5db55db52f773dbb014420b304055ba2c5" url: "https://pub.dev" source: hosted - version: "12.0.5" + version: "12.0.6" permission_handler_apple: dependency: transitive description: @@ -1111,10 +1127,10 @@ packages: dependency: "direct main" description: name: pointycastle - sha256: "79fbafed02cfdbe85ef3fd06c7f4bc2cbcba0177e61b765264853d4253b21744" + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" url: "https://pub.dev" source: hosted - version: "3.9.0" + version: "3.9.1" pool: dependency: transitive description: @@ -1199,10 +1215,10 @@ packages: dependency: transitive description: name: shared_preferences_foundation - sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" + sha256: "0a8a893bf4fd1152f93fec03a415d11c27c74454d96e2318a7ac38dd18683ab7" url: "https://pub.dev" source: hosted - version: "2.3.5" + version: "2.4.0" shared_preferences_linux: dependency: transitive description: @@ -1388,26 +1404,26 @@ packages: dependency: "direct dev" description: name: test - sha256: a1f7595805820fcc05e5c52e3a231aedd0b72972cb333e8c738a8b1239448b6f + sha256: "7ee446762c2c50b3bd4ea96fe13ffac69919352bd3b4b17bac3f3465edc58073" url: "https://pub.dev" source: hosted - version: "1.24.9" + version: "1.25.2" test_api: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" test_core: dependency: transitive description: name: test_core - sha256: a757b14fc47507060a162cc2530d9a4a2f92f5100a952c7443b5cad5ef5b106a + sha256: "2bc4b4ecddd75309300d8096f781c0e3280ca1ef85beda558d33fcbedc2eead4" url: "https://pub.dev" source: hosted - version: "0.5.9" + version: "0.6.0" timezone: dependency: transitive description: @@ -1468,18 +1484,18 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "360a6ed2027f18b73c8d98e159dda67a61b7f2e0f6ec26e86c3ada33b0621775" + sha256: "17cd5e205ea615e2c6ea7a77323a11712dffa0720a8a90540db57a01347f9ad9" url: "https://pub.dev" source: hosted - version: "6.3.1" + version: "6.3.2" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5" + sha256: "7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89" url: "https://pub.dev" source: hosted - version: "6.2.5" + version: "6.3.0" url_launcher_linux: dependency: transitive description: @@ -1492,10 +1508,10 @@ packages: dependency: transitive description: name: url_launcher_macos - sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234 + sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.2.0" url_launcher_platform_interface: dependency: transitive description: @@ -1540,10 +1556,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.1" watcher: dependency: transitive description: @@ -1588,10 +1604,10 @@ packages: dependency: transitive description: name: win32 - sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb" + sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4 url: "https://pub.dev" source: hosted - version: "5.5.0" + version: "5.5.1" win32_registry: dependency: transitive description: @@ -1633,5 +1649,5 @@ packages: source: hosted version: "0.2.3" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.19.0" + dart: ">=3.4.0 <4.0.0" + flutter: ">=3.20.0-1.2.pre" diff --git a/pubspec.yaml b/pubspec.yaml index c55b1f54c..71d2ee45e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,7 +30,7 @@ dependencies: sdk: flutter app_minimizer: ^1.0.0+2 flutter_local_notifications: ^17.0.0 - home_widget: ^0.5.0 + home_widget: ^0.6.0 image: ^4.1.6 json_annotation: ^4.8.1 local_auth: ^2.1.6 @@ -80,12 +80,13 @@ dependencies: firebase_messaging: ^14.7.19 collection: ^1.18.0 crypto: ^3.0.3 - intl: ^0.18.1 + intl: ^0.19.0 protobuf: ^3.1.0 firebase_core: ^2.27.0 simple_icons: ^10.1.3 path_provider: ^2.1.2 qr_flutter: ^4.1.0 + app_links: ^6.1.1 # file_saver: ^0.2.12 From 378254323153fdb8c8505a0e0bbef0e15ac4a3b6 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Fri, 24 May 2024 14:39:17 +0200 Subject: [PATCH 05/32] migrate app to gradles plugin dsl --- pubspec.lock | 24 ------------------------ pubspec.yaml | 4 +--- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 71c415b1b..3837fcee1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1448,30 +1448,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" - uni_links: - dependency: "direct main" - description: - name: uni_links - sha256: "051098acfc9e26a9fde03b487bef5d3d228ca8f67693480c6f33fd4fbb8e2b6e" - url: "https://pub.dev" - source: hosted - version: "0.5.1" - uni_links_platform_interface: - dependency: transitive - description: - name: uni_links_platform_interface - sha256: "929cf1a71b59e3b7c2d8a2605a9cf7e0b125b13bc858e55083d88c62722d4507" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - uni_links_web: - dependency: transitive - description: - name: uni_links_web - sha256: "7539db908e25f67de2438e33cc1020b30ab94e66720b5677ba6763b25f6394df" - url: "https://pub.dev" - source: hosted - version: "0.1.0" url_launcher: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 71d2ee45e..344e31285 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -59,7 +59,7 @@ dependencies: package_info_plus: ^8.0.0 device_info_plus: ^10.0.1 # URI - uni_links: ^0.5.1 + app_links: ^6.1.1 url_launcher: ^6.0.12 http: ^1.2.0 connectivity_plus: ^6.0.1 @@ -86,8 +86,6 @@ dependencies: simple_icons: ^10.1.3 path_provider: ^2.1.2 qr_flutter: ^4.1.0 - app_links: ^6.1.1 - # file_saver: ^0.2.12 dev_dependencies: From ddd9587c1f0d36a89fcbcc5ddf272bfbf2b97add Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Fri, 24 May 2024 16:47:57 +0200 Subject: [PATCH 06/32] migrate app to gradle plugin dsl --- android/settings.gradle | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/android/settings.gradle b/android/settings.gradle index 8e55d5a8d..286ebc45d 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -26,22 +26,4 @@ plugins { id "org.jetbrains.kotlin.android" version "1.8.0" apply false } -include ":app" - - - - - - - -// include ':app' - -// def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -// def properties = new Properties() - -// assert localPropertiesFile.exists() -// localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } - -// def flutterSdkPath = properties.getProperty("flutter.sdk") -// assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -// apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" +include ":app" \ No newline at end of file From 68d87b88fa25fcf3b511897d929d6fa8ce716f18 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Mon, 27 May 2024 11:14:19 +0200 Subject: [PATCH 07/32] migrate app to gradles plugin dsl --- .github/workflows/flutter_build.yml | 3 +- .github/workflows/flutter_test.yml | 2 +- .github/workflows/test-integration.yaml | 2 +- .gitignore | 2 +- lib/mains/main_netknights.dart | 30 ++++++++--------- .../example/pubspec.lock | 32 +++++++++---------- .../pi-authenticator-legacy/pubspec.lock | 28 ++++++++-------- 7 files changed, 49 insertions(+), 50 deletions(-) diff --git a/.github/workflows/flutter_build.yml b/.github/workflows/flutter_build.yml index 67ae4b7c1..759941266 100644 --- a/.github/workflows/flutter_build.yml +++ b/.github/workflows/flutter_build.yml @@ -27,8 +27,7 @@ jobs: - uses: subosito/flutter-action@v2 with: channel: 'stable' - flutter-version: '3.19.6' - - run: "flutter upgrade" + flutter-version: '3.22.0' - run: "flutter --version" - run: "flutter pub get" - run: "flutter build ios -t 'lib/mains/main_netknights.dart' --debug --flavor netknights --no-codesign" diff --git a/.github/workflows/flutter_test.yml b/.github/workflows/flutter_test.yml index 200b861d4..a637975e6 100644 --- a/.github/workflows/flutter_test.yml +++ b/.github/workflows/flutter_test.yml @@ -19,7 +19,7 @@ jobs: - uses: subosito/flutter-action@v2 with: channel: 'stable' - flutter-version: '3.19.0' + flutter-version: '3.22.0' - run: "flutter --version" - run: flutter pub get - run: flutter test diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index a25fe36b6..2348984d1 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -19,7 +19,7 @@ jobs: - uses: subosito/flutter-action@v2 with: - flutter-version: '3.19.0' + flutter-version: '3.22.0' channel: 'stable' # Run integration test diff --git a/.gitignore b/.gitignore index 94f48e0de..45b8c5a0c 100644 --- a/.gitignore +++ b/.gitignore @@ -893,5 +893,5 @@ lib/l10n/untranslated.txt ios/Flutter/flutter_export_environment.sh # Firebase -firebase_options.dart +*firebase_options.dart firebase.json diff --git a/lib/mains/main_netknights.dart b/lib/mains/main_netknights.dart index bf56c7135..caba769b8 100644 --- a/lib/mains/main_netknights.dart +++ b/lib/mains/main_netknights.dart @@ -23,25 +23,25 @@ import 'package:easy_dynamic_theme/easy_dynamic_theme.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:privacyidea_authenticator/firebase_options.dart'; -import 'package:privacyidea_authenticator/l10n/app_localizations.dart'; -import 'package:privacyidea_authenticator/utils/customization/application_customization.dart'; -import 'package:privacyidea_authenticator/utils/globals.dart'; -import 'package:privacyidea_authenticator/utils/logger.dart'; -import 'package:privacyidea_authenticator/utils/riverpod_providers.dart'; -import 'package:privacyidea_authenticator/views/add_token_manually_view/add_token_manually_view.dart'; -import 'package:privacyidea_authenticator/views/import_tokens_view/import_tokens_view.dart'; -import 'package:privacyidea_authenticator/views/license_view/license_view.dart'; -import 'package:privacyidea_authenticator/views/main_view/main_view.dart'; -import 'package:privacyidea_authenticator/views/push_token_view/push_tokens_view.dart'; -import 'package:privacyidea_authenticator/views/qr_scanner_view/qr_scanner_view.dart'; -import 'package:privacyidea_authenticator/views/settings_view/settings_view.dart'; -import 'package:privacyidea_authenticator/views/splash_screen/splash_screen.dart'; -import 'package:privacyidea_authenticator/widgets/app_wrapper.dart'; +import '../firebase_options/netknights_firebase_options.dart'; +import '../l10n/app_localizations.dart'; import '../model/enums/app_feature.dart'; +import '../utils/customization/application_customization.dart'; +import '../utils/globals.dart'; import '../utils/home_widget_utils.dart'; +import '../utils/logger.dart'; +import '../utils/riverpod_providers.dart'; +import '../views/add_token_manually_view/add_token_manually_view.dart'; import '../views/feedback_view/feedback_view.dart'; +import '../views/import_tokens_view/import_tokens_view.dart'; +import '../views/license_view/license_view.dart'; +import '../views/main_view/main_view.dart'; +import '../views/push_token_view/push_tokens_view.dart'; +import '../views/qr_scanner_view/qr_scanner_view.dart'; +import '../views/settings_view/settings_view.dart'; +import '../views/splash_screen/splash_screen.dart'; +import '../widgets/app_wrapper.dart'; void main() async { Logger.init( diff --git a/local_plugins/pi-authenticator-legacy/example/pubspec.lock b/local_plugins/pi-authenticator-legacy/example/pubspec.lock index 48e72786c..5ad3cb41b 100644 --- a/local_plugins/pi-authenticator-legacy/example/pubspec.lock +++ b/local_plugins/pi-authenticator-legacy/example/pubspec.lock @@ -45,10 +45,10 @@ packages: dependency: "direct main" description: name: cupertino_icons - sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "1.0.8" fake_async: dependency: transitive description: @@ -71,26 +71,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.4" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.3" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" matcher: dependency: transitive description: @@ -111,10 +111,10 @@ packages: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.0" path: dependency: transitive description: @@ -179,10 +179,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" vector_math: dependency: transitive description: @@ -195,10 +195,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.1" sdks: - dart: ">=3.2.0-0 <4.0.0" - flutter: ">=2.0.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/local_plugins/pi-authenticator-legacy/pubspec.lock b/local_plugins/pi-authenticator-legacy/pubspec.lock index e56d812d1..203ecd5c3 100644 --- a/local_plugins/pi-authenticator-legacy/pubspec.lock +++ b/local_plugins/pi-authenticator-legacy/pubspec.lock @@ -63,26 +63,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.4" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.3" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" matcher: dependency: transitive description: @@ -103,10 +103,10 @@ packages: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.0" path: dependency: transitive description: @@ -164,10 +164,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" vector_math: dependency: transitive description: @@ -180,10 +180,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.1" sdks: - dart: ">=3.2.0-0 <4.0.0" - flutter: ">=2.0.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" From 6aa7aea13abc0af79a768ade0271374444af1d07 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Mon, 27 May 2024 11:19:39 +0200 Subject: [PATCH 08/32] Update flutter_build.yml --- .github/workflows/flutter_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flutter_build.yml b/.github/workflows/flutter_build.yml index 43e412844..4c18932ab 100644 --- a/.github/workflows/flutter_build.yml +++ b/.github/workflows/flutter_build.yml @@ -52,7 +52,7 @@ jobs: - uses: subosito/flutter-action@v2 with: channel: 'stable' - flutter-version: '3.19.6' + flutter-version: '3.22.0' - run: 'flutter clean' - run: "flutter --version" - run: "flutter pub get" From 9688761c640260c2193658cda2634a40f3b0d1f1 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Mon, 27 May 2024 12:28:00 +0200 Subject: [PATCH 09/32] migrate app to gradles plugin dsl --- .gitignore | 1 + .../default_firebase_options.dart | 72 +++++++++++++++++++ lib/mains/main_netknights.dart | 7 +- 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 lib/firebase_options/default_firebase_options.dart diff --git a/.gitignore b/.gitignore index 45b8c5a0c..eb3befa03 100644 --- a/.gitignore +++ b/.gitignore @@ -894,4 +894,5 @@ ios/Flutter/flutter_export_environment.sh # Firebase *firebase_options.dart +!default_firebase_options.dart firebase.json diff --git a/lib/firebase_options/default_firebase_options.dart b/lib/firebase_options/default_firebase_options.dart new file mode 100644 index 000000000..eff36320f --- /dev/null +++ b/lib/firebase_options/default_firebase_options.dart @@ -0,0 +1,72 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: type=lint +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Netknights [DefaultFirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatformOf('netknights'), +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions currentPlatformOf(String? app) => switch (app) { + //'netknights' => NetknightsFirebaseOptions.currentPlatform, + _ => defaultCurrentPlatform, + }; + static FirebaseOptions get defaultCurrentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for web - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'DEFAULT_FIREBASE_API_KEY', + appId: 'DEFAULT_FIREBASE_APP_ID', + messagingSenderId: 'DEFAULT_FIREBASE_MESSAGING_SENDER_ID', + projectId: 'DEFAULT_FIREBASE_PROJECT_ID', + storageBucket: 'DEFAULT_FIREBASE_STORAGE_BUCKET', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'DEFAULT_FIREBASE_API_KEY', + appId: 'DEFAULT_FIREBASE_APP_ID', + messagingSenderId: 'DEFAULT_FIREBASE_MESSAGING_SENDER_ID', + projectId: 'DEFAULT_FIREBASE_PROJECT_ID', + storageBucket: 'DEFAULT_FIREBASE_STORAGE_BUCKET', + iosClientId: 'DEFAULT_FIREBASE_IOS_CLIENT_ID', + iosBundleId: 'DEFAULT_FIREBASE_IOS_BUNDLE_ID', + ); +} diff --git a/lib/mains/main_netknights.dart b/lib/mains/main_netknights.dart index caba769b8..b523233d2 100644 --- a/lib/mains/main_netknights.dart +++ b/lib/mains/main_netknights.dart @@ -24,7 +24,7 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import '../firebase_options/netknights_firebase_options.dart'; +import '../firebase_options/default_firebase_options.dart'; import '../l10n/app_localizations.dart'; import '../model/enums/app_feature.dart'; import '../utils/customization/application_customization.dart'; @@ -50,7 +50,10 @@ void main() async { WidgetsFlutterBinding.ensureInitialized(); await HomeWidgetUtils().registerInteractivityCallback(homeWidgetBackgroundCallback); await HomeWidgetUtils().setAppGroupId(appGroupId); - final app = await Firebase.initializeApp(options: NetknightsFirebaseOptions.currentPlatform); + final app = await Firebase.initializeApp( + name: 'netknights', + options: DefaultFirebaseOptions.currentPlatformOf('netknights'), + ); await app.setAutomaticDataCollectionEnabled(false); Logger.warning('Automatic data collection: ${app.isAutomaticDataCollectionEnabled}', name: 'firebase_utils.dart#initFirebase'); From 32f601e0f32980cf54ef82bb6cc0b948f4d2d86a Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Mon, 27 May 2024 15:40:54 +0200 Subject: [PATCH 10/32] 2 person login --- lib/model/push_request.dart | 20 ++++----- lib/model/push_request.g.dart | 12 +++-- .../push_request_notifier.dart | 12 ++--- .../customization/theme_customization.dart | 14 +++--- lib/utils/push_provider.dart | 3 ++ .../rollout_failed_widget.dart | 2 +- .../dialogs/select_tokens_dialog.dart | 2 +- .../dialog_widgets/push_request_dialog.dart | 44 ++++++++----------- 8 files changed, 52 insertions(+), 57 deletions(-) diff --git a/lib/model/push_request.dart b/lib/model/push_request.dart index 059875117..9062bb481 100644 --- a/lib/model/push_request.dart +++ b/lib/model/push_request.dart @@ -24,8 +24,8 @@ class PushRequest { final String serial; final String signature; final bool? accepted; - final List? answers; - final int? selectedAnswerIndex; + final List? possibleAnswers; + final String? selectedAnswer; const PushRequest({ required this.title, @@ -38,8 +38,8 @@ class PushRequest { this.serial = '', this.signature = '', this.accepted, - this.answers, - this.selectedAnswerIndex, + this.possibleAnswers, + this.selectedAnswer, }); PushRequest copyWith({ @@ -54,7 +54,7 @@ class PushRequest { String? signature, bool? accepted, List Function()? answers, - int? Function()? selectedAnswerIndex, + String? Function()? selectedAnswer, }) { return PushRequest( title: title ?? this.title, @@ -67,8 +67,8 @@ class PushRequest { serial: serial ?? this.serial, signature: signature ?? this.signature, accepted: accepted ?? this.accepted, - answers: answers != null ? answers() : this.answers, - selectedAnswerIndex: selectedAnswerIndex != null ? selectedAnswerIndex() : this.selectedAnswerIndex, + possibleAnswers: answers != null ? answers() : this.possibleAnswers, + selectedAnswer: selectedAnswer != null ? selectedAnswer() : this.selectedAnswer, ); } @@ -84,7 +84,7 @@ class PushRequest { 'id: $id, uri: $uri, _nonce: $nonce, sslVerify: $sslVerify, ' 'expirationDate: $expirationDate, serial: $serial, ' 'signature: $signature, accepted: $accepted, ' - 'answers: $answers, selectedAnswerIndex: $selectedAnswerIndex}'; + 'answers: $possibleAnswers, selectedAnswer: $selectedAnswer}'; } factory PushRequest.fromJson(Map json) => _$PushRequestFromJson(json); @@ -107,7 +107,7 @@ class PushRequest { serial: data[PUSH_REQUEST_SERIAL], expirationDate: DateTime.now().add(const Duration(minutes: 2)), signature: data[PUSH_REQUEST_SIGNATURE], - answers: data[PUSH_REQUEST_ANSWERS], + possibleAnswers: data[PUSH_REQUEST_ANSWERS], ); } @@ -147,7 +147,7 @@ class PushRequest { '$question|' '$title|' '${sslVerify ? '1' : '0'}' - '${answers != null ? '|require_presence' : ''}'; + '${possibleAnswers != null ? '|require_presence' : ''}'; // Re-add url and sslverify to android legacy tokens: if (token.url == null) { diff --git a/lib/model/push_request.g.dart b/lib/model/push_request.g.dart index 09a704276..1d6977b67 100644 --- a/lib/model/push_request.g.dart +++ b/lib/model/push_request.g.dart @@ -17,13 +17,11 @@ PushRequest _$PushRequestFromJson(Map json) => PushRequest( serial: json['serial'] as String? ?? '', signature: json['signature'] as String? ?? '', accepted: json['accepted'] as bool?, - answers: - (json['answers'] as List?)?.map((e) => e as String).toList(), - selectedAnswerIndex: (json['selectedAnswerIndex'] as num?)?.toInt(), + possibleAnswers: (json['answers'] as List?)?.map((e) => e as String).toList(), + selectedAnswer: (json['selectedAnswer'] as String?), ); -Map _$PushRequestToJson(PushRequest instance) => - { +Map _$PushRequestToJson(PushRequest instance) => { 'title': instance.title, 'question': instance.question, 'id': instance.id, @@ -34,6 +32,6 @@ Map _$PushRequestToJson(PushRequest instance) => 'serial': instance.serial, 'signature': instance.signature, 'accepted': instance.accepted, - 'answers': instance.answers, - 'selectedAnswerIndex': instance.selectedAnswerIndex, + 'answers': instance.possibleAnswers, + 'selectedAnswer': instance.selectedAnswer, }; diff --git a/lib/state_notifiers/push_request_notifier.dart b/lib/state_notifiers/push_request_notifier.dart index 60a161e94..f9f288842 100644 --- a/lib/state_notifiers/push_request_notifier.dart +++ b/lib/state_notifiers/push_request_notifier.dart @@ -217,7 +217,7 @@ class PushRequestNotifier extends StateNotifier { /// Accepts a push request and returns true if successful, false if not. /// An accepted push request is removed from the state. /// It should be still in the CustomIntBuffer of the state. - Future accept(PushToken pushToken, PushRequest pushRequest, {int? selectedAnswerIndex}) async { + Future accept(PushToken pushToken, PushRequest pushRequest, {String? selectedAnswer}) async { if (pushRequest.accepted != null) { Logger.warning('The push request is already accepted or declined.', name: 'push_request_notifier.dart#decline'); @@ -225,7 +225,7 @@ class PushRequestNotifier extends StateNotifier { } Logger.info('Decline push request.', name: 'push_request_notifier.dart#decline'); final updated = await _updatePushRequest(pushRequest, (p0) async { - final updated = p0.copyWith(accepted: true, selectedAnswerIndex: () => selectedAnswerIndex); + final updated = p0.copyWith(accepted: true, selectedAnswer: () => selectedAnswer); final success = await _handleReaction(pushRequest: updated, token: pushToken); if (!success) { return p0; @@ -244,7 +244,7 @@ class PushRequestNotifier extends StateNotifier { } Logger.info('Decline push request.', name: 'push_request_notifier.dart#decline'); final updated = await _updatePushRequest(pushRequest, (p0) async { - final updated = p0.copyWith(accepted: false, selectedAnswerIndex: () => null); + final updated = p0.copyWith(accepted: false, selectedAnswer: () => null); final success = await _handleReaction(pushRequest: updated, token: pushToken); if (!success) { return p0; @@ -334,9 +334,9 @@ class PushRequestNotifier extends StateNotifier { body['decline'] = '1'; msg += '|decline'; } - if (pushRequest.answers != null && pushRequest.selectedAnswerIndex != null) { - body['answer'] = pushRequest.answers![pushRequest.selectedAnswerIndex!]; - msg += '|${pushRequest.answers![pushRequest.selectedAnswerIndex!]}'; + if (pushRequest.possibleAnswers != null && pushRequest.selectedAnswer != null) { + body['answer'] = pushRequest.selectedAnswer!; + msg += '|${pushRequest.selectedAnswer!}'; } String? signature = await _rsaUtils.trySignWithToken(token, msg); diff --git a/lib/utils/customization/theme_customization.dart b/lib/utils/customization/theme_customization.dart index 361ea661d..7f7ca083d 100644 --- a/lib/utils/customization/theme_customization.dart +++ b/lib/utils/customization/theme_customization.dart @@ -283,7 +283,7 @@ class ThemeCustomization { ), iconButtonTheme: IconButtonThemeData( style: ButtonStyle( - foregroundColor: MaterialStateProperty.all(foregroundColor), + foregroundColor: WidgetStateProperty.all(foregroundColor), ), ), elevatedButtonTheme: ElevatedButtonThemeData( @@ -326,7 +326,7 @@ class ThemeCustomization { navigationBarTheme: const NavigationBarThemeData().copyWith( backgroundColor: navigationBarColor, shadowColor: shadowColor, - iconTheme: MaterialStatePropertyAll(IconThemeData(color: navigationBarIconColor)), + iconTheme: WidgetStatePropertyAll(IconThemeData(color: navigationBarIconColor)), elevation: 3, ), floatingActionButtonTheme: FloatingActionButtonThemeData( @@ -363,8 +363,8 @@ class ThemeCustomization { errorContainer: deleteColor, ), checkboxTheme: CheckboxThemeData( - checkColor: MaterialStateProperty.resolveWith((_) => onPrimary), - fillColor: MaterialStateProperty.resolveWith((Set states) { + checkColor: WidgetStateProperty.resolveWith((_) => onPrimary), + fillColor: WidgetStateProperty.resolveWith((Set states) { if (states.contains(MaterialState.disabled)) { return null; } @@ -375,7 +375,7 @@ class ThemeCustomization { }), ), radioTheme: RadioThemeData( - fillColor: MaterialStateProperty.resolveWith((Set states) { + fillColor: WidgetStateProperty.resolveWith((Set states) { if (states.contains(MaterialState.disabled)) { return null; } @@ -386,7 +386,7 @@ class ThemeCustomization { }), ), switchTheme: SwitchThemeData( - thumbColor: MaterialStateProperty.resolveWith((Set states) { + thumbColor: WidgetStateProperty.resolveWith((Set states) { if (states.contains(MaterialState.disabled)) { return null; } @@ -395,7 +395,7 @@ class ThemeCustomization { } return null; }), - trackColor: MaterialStateProperty.resolveWith((Set states) { + trackColor: WidgetStateProperty.resolveWith((Set states) { if (states.contains(MaterialState.disabled)) { return null; } diff --git a/lib/utils/push_provider.dart b/lib/utils/push_provider.dart index 2e62c5473..68693369a 100644 --- a/lib/utils/push_provider.dart +++ b/lib/utils/push_provider.dart @@ -143,6 +143,9 @@ class PushProvider { Map data; try { data = _getAndValidateDataFromRemoteMessage(remoteMessage); + data.forEach((key, value) { + Logger.info('$key: $value', name: 'push_provider.dart#_foregroundHandler'); + }); } on ArgumentError catch (_) { Logger.info('Try requesting the challenge by polling.', name: 'push_provider.dart#_foregroundHandler'); await pollForChallenges(isManually: true); diff --git a/lib/views/main_view/main_view_widgets/token_widgets/push_token_widgets/rollout_failed_widget.dart b/lib/views/main_view/main_view_widgets/token_widgets/push_token_widgets/rollout_failed_widget.dart index 7d32f54a9..d02c17569 100644 --- a/lib/views/main_view/main_view_widgets/token_widgets/push_token_widgets/rollout_failed_widget.dart +++ b/lib/views/main_view/main_view_widgets/token_widgets/push_token_widgets/rollout_failed_widget.dart @@ -50,7 +50,7 @@ class RolloutFailedWidget extends StatelessWidget { SizedBox( width: width * 0.35, child: PressButton( - style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Theme.of(context).colorScheme.errorContainer)), + style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Theme.of(context).colorScheme.errorContainer)), onPressed: () => _showDialog(), child: Text( localizations.delete, diff --git a/lib/views/settings_view/settings_groups/import_export_tokens_widgets/dialogs/select_tokens_dialog.dart b/lib/views/settings_view/settings_groups/import_export_tokens_widgets/dialogs/select_tokens_dialog.dart index 7b8315a4f..a236a0a14 100644 --- a/lib/views/settings_view/settings_groups/import_export_tokens_widgets/dialogs/select_tokens_dialog.dart +++ b/lib/views/settings_view/settings_groups/import_export_tokens_widgets/dialogs/select_tokens_dialog.dart @@ -76,7 +76,7 @@ class _SelectTokensDialogState extends ConsumerState { child: TextButton( style: _selectedTokens.contains(token) ? ButtonStyle( - backgroundColor: MaterialStateProperty.all(Theme.of(context).colorScheme.secondary.withAlpha(80)), + backgroundColor: WidgetStateProperty.all(Theme.of(context).colorScheme.secondary.withAlpha(80)), ) : null, onPressed: () async { diff --git a/lib/widgets/dialog_widgets/push_request_dialog.dart b/lib/widgets/dialog_widgets/push_request_dialog.dart index edef10a3b..bf1f356c5 100644 --- a/lib/widgets/dialog_widgets/push_request_dialog.dart +++ b/lib/widgets/dialog_widgets/push_request_dialog.dart @@ -26,7 +26,7 @@ class _PushRequestDialogState extends ConsumerState { double get lineHeight => Theme.of(context).textTheme.titleLarge?.fontSize ?? 16; double get spacerHeight => lineHeight * 0.5; - MaterialStateProperty get buttonShape => MaterialStateProperty.all( + WidgetStateProperty get buttonShape => WidgetStateProperty.all( Theme.of(context).elevatedButtonTheme.style?.shape?.resolve({})?.copyWith( side: BorderSide(color: Theme.of(context).colorScheme.onPrimary, width: 2.5), ), @@ -53,6 +53,7 @@ class _PushRequestDialogState extends ConsumerState { Widget build(BuildContext context) { final spacerHeight = this.spacerHeight; final question = widget.pushRequest.question; + final token = ref.watch(tokenProvider).getTokenBySerial(widget.pushRequest.serial); final localizations = AppLocalizations.of(context)!; if (token == null) { @@ -60,13 +61,7 @@ class _PushRequestDialogState extends ConsumerState { if (mounted) ref.read(pushRequestProvider.notifier).remove(widget.pushRequest); }); } - final test = [ - '42', - '0#', - '69', - '13', - '37', - ]; + return isHandled || token == null ? const SizedBox() : Container( @@ -99,13 +94,13 @@ class _PushRequestDialogState extends ConsumerState { ), SizedBox(height: spacerHeight), ], - widget.pushRequest.answers == null + widget.pushRequest.possibleAnswers != null ? AnswerSelectionWidget( - onAnswerSelected: (p0) { - globalRef?.read(pushRequestProvider.notifier).accept(token, widget.pushRequest, selectedAnswerIndex: p0); + onAnswerSelected: (selectedAnswer) { + globalRef?.read(pushRequestProvider.notifier).accept(token, widget.pushRequest, selectedAnswer: selectedAnswer); if (mounted) setState(() => isHandled = true); }, - possibleAnswers: test, + possibleAnswers: widget.pushRequest.possibleAnswers!, ) : SizedBox( // Accept button @@ -144,7 +139,7 @@ class _PushRequestDialogState extends ConsumerState { // Decline button child: PressButton( style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( + backgroundColor: WidgetStateProperty.all( Theme.of(context).colorScheme.errorContainer, ), shape: buttonShape, @@ -247,7 +242,7 @@ class _PushRequestDialogState extends ConsumerState { flex: 6, child: PressButton( style: ButtonStyle( - backgroundColor: MaterialStateProperty.all(Theme.of(context).colorScheme.errorContainer), + backgroundColor: WidgetStateProperty.all(Theme.of(context).colorScheme.errorContainer), shape: buttonShape, ), onPressed: () { @@ -287,7 +282,7 @@ class _PushRequestDialogState extends ConsumerState { class AnswerSelectionWidget extends StatefulWidget { final List possibleAnswers; - final void Function(int) onAnswerSelected; + final void Function(T) onAnswerSelected; const AnswerSelectionWidget({required this.possibleAnswers, super.key, required this.onAnswerSelected}); @override @@ -302,15 +297,14 @@ class _AnswerSelectionWidgetState extends State> { final children = []; final possibleAnswers = widget.possibleAnswers.toList(); const numPerRow = 3; - var answersHandled = 0; var numRow = 0; - while (possibleAnswers.length > answersHandled) { - final maxThisRow = possibleAnswers.length - answersHandled == numPerRow + 1 - ? min(possibleAnswers.length - answersHandled, (numPerRow / 2).ceil()) - : min(possibleAnswers.length - answersHandled, numPerRow); + while (possibleAnswers.isNotEmpty) { + final maxThisRow = possibleAnswers.length == numPerRow + 1 ? min(possibleAnswers.length, (numPerRow / 2).ceil()) : min(possibleAnswers.length, numPerRow); numRow++; + final answersThisRow = possibleAnswers.sublist(0, maxThisRow); + possibleAnswers.removeRange(0, maxThisRow); print('NumRow: $numRow'); - print('asd.length: ${possibleAnswers.length}'); + print('possibleAnswers.length: ${possibleAnswers.length}'); print('maxThisRow: $maxThisRow'); children.add( Row( @@ -318,12 +312,12 @@ class _AnswerSelectionWidgetState extends State> { mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ if (maxThisRow != numPerRow) const Expanded(child: SizedBox()), - for (var i = answersHandled; i < answersHandled + maxThisRow; i++, answersHandled++) + for (final possibleAnswer in answersThisRow) Expanded( flex: 4, child: PressButton( style: ButtonStyle( - shape: MaterialStateProperty.all( + shape: WidgetStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(999), side: BorderSide( @@ -333,11 +327,11 @@ class _AnswerSelectionWidgetState extends State> { ), ), ), - onPressed: () => widget.onAnswerSelected(i), + onPressed: () => widget.onAnswerSelected(possibleAnswer), child: Padding( padding: EdgeInsets.all(spacerHeight), child: Text( - possibleAnswers[i].toString(), + possibleAnswer.toString(), style: Theme.of(context).textTheme.headlineMedium?.copyWith(color: Theme.of(context).colorScheme.onPrimary), textAlign: TextAlign.center, ), From de274744f6de60b9a94cf760e1544d34a35b637d Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Mon, 27 May 2024 17:16:20 +0200 Subject: [PATCH 11/32] 2 person login --- lib/l10n/app_cs.arb | 6 ++- lib/l10n/app_de.arb | 6 ++- lib/l10n/app_en.arb | 4 ++ lib/l10n/app_es.arb | 6 ++- lib/l10n/app_fr.arb | 6 ++- lib/l10n/app_localizations.dart | 6 +++ lib/l10n/app_localizations_cs.dart | 3 ++ lib/l10n/app_localizations_de.dart | 3 ++ lib/l10n/app_localizations_en.dart | 3 ++ lib/l10n/app_localizations_es.dart | 3 ++ lib/l10n/app_localizations_fr.dart | 3 ++ lib/l10n/app_localizations_nl.dart | 3 ++ lib/l10n/app_localizations_pl.dart | 3 ++ lib/l10n/app_nl.arb | 6 ++- lib/l10n/app_pl.arb | 6 ++- .../push_request_notifier.dart | 6 +++ .../dialog_widgets/push_request_dialog.dart | 42 +++++++++++++++---- 17 files changed, 100 insertions(+), 15 deletions(-) diff --git a/lib/l10n/app_cs.arb b/lib/l10n/app_cs.arb index 5a6caa7d6..620cfb3f4 100644 --- a/lib/l10n/app_cs.arb +++ b/lib/l10n/app_cs.arb @@ -635,5 +635,9 @@ "scanThisQrWithNewDevice": "Naskenujte tento QR kód svým novým zařízením pro import žetonu.", "oneMore": "Ještě jeden", "done": "Hotovo", - "confirmPassword": "Potvrďte heslo" + "confirmPassword": "Potvrďte heslo", + "sendPushRequestResponseFailed": "Odpověď se nepodařilo odeslat.", + "@sendPushRequestResponseFailed": { + "description": "Error message when the response to a push request could not be sent." + } } \ No newline at end of file diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 9b32055d6..6d9010d09 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -614,5 +614,9 @@ "scanThisQrWithNewDevice": "Scannen Sie diesen QR-Code mit Ihrem neuen Gerät, um das Token zu importieren.", "oneMore": "Noch eins", "done": "Fertig", - "confirmPassword": "Passwort bestätigen" + "confirmPassword": "Passwort bestätigen", + "sendPushRequestResponseFailed": "Senden der Antwort fehlgeschlagen.", + "@sendPushRequestResponseFailed": { + "description": "Error message when the response to a push request could not be sent." + } } \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 2937cd9e0..649e7d69b 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -657,5 +657,9 @@ "example": "5" } } + }, + "sendPushRequestResponseFailed": "Failed to send the response.", + "@sendPushRequestResponseFailed": { + "description": "Error message when the response to a push request could not be sent." } } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 702a7a056..639a39492 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -631,5 +631,9 @@ "scanThisQrWithNewDevice": "Escanee este código QR con su nuevo dispositivo para importar el token.", "oneMore": "Uno más", "done": "Hecho", - "confirmPassword": "Confirmar contraseña" + "confirmPassword": "Confirmar contraseña", + "sendPushRequestResponseFailed": "No se ha podido enviar la respuesta.", + "@sendPushRequestResponseFailed": { + "description": "Error message when the response to a push request could not be sent." + } } \ No newline at end of file diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index c6962a79d..8768c3253 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -636,5 +636,9 @@ "scanThisQrWithNewDevice": "Scannez ce code QR avec votre nouvel appareil pour importer le jeton.", "oneMore": "Encore un", "done": "Terminé", - "confirmPassword": "Confirmer le mot de passe" + "confirmPassword": "Confirmer le mot de passe", + "sendPushRequestResponseFailed": "Échec de l'envoi de la réponse.", + "@sendPushRequestResponseFailed": { + "description": "Error message when the response to a push request could not be sent." + } } \ No newline at end of file diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index f608e8c83..3f4f45888 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -1668,6 +1668,12 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'The {name} [{value}] is not supported by this version of the app.'** String unsupported(Object name, Object value); + + /// Error message when the response to a push request could not be sent. + /// + /// In en, this message translates to: + /// **'Failed to send the response.'** + String get sendPushRequestResponseFailed; } class _AppLocalizationsDelegate extends LocalizationsDelegate { diff --git a/lib/l10n/app_localizations_cs.dart b/lib/l10n/app_localizations_cs.dart index f5ec56d65..301116cf4 100644 --- a/lib/l10n/app_localizations_cs.dart +++ b/lib/l10n/app_localizations_cs.dart @@ -875,4 +875,7 @@ class AppLocalizationsCs extends AppLocalizations { String unsupported(Object name, Object value) { return 'The $name [$value] is not supported by this version of the app.'; } + + @override + String get sendPushRequestResponseFailed => 'Odpověď se nepodařilo odeslat.'; } diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 5109fb4d8..d41c7b09e 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -875,4 +875,7 @@ class AppLocalizationsDe extends AppLocalizations { String unsupported(Object name, Object value) { return 'The $name [$value] is not supported by this version of the app.'; } + + @override + String get sendPushRequestResponseFailed => 'Senden der Antwort fehlgeschlagen.'; } diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index ca4f6163b..be05f09b7 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -875,4 +875,7 @@ class AppLocalizationsEn extends AppLocalizations { String unsupported(Object name, Object value) { return 'The $name [$value] is not supported by this version of the app.'; } + + @override + String get sendPushRequestResponseFailed => 'Failed to send the response.'; } diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index 046d5d766..9df760cb9 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -875,4 +875,7 @@ class AppLocalizationsEs extends AppLocalizations { String unsupported(Object name, Object value) { return 'The $name [$value] is not supported by this version of the app.'; } + + @override + String get sendPushRequestResponseFailed => 'No se ha podido enviar la respuesta.'; } diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 0b7c478da..b40fa1a6a 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -875,4 +875,7 @@ class AppLocalizationsFr extends AppLocalizations { String unsupported(Object name, Object value) { return 'The $name [$value] is not supported by this version of the app.'; } + + @override + String get sendPushRequestResponseFailed => 'Échec de l\'envoi de la réponse.'; } diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index 372e68eb5..f238a1273 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -875,4 +875,7 @@ class AppLocalizationsNl extends AppLocalizations { String unsupported(Object name, Object value) { return 'The $name [$value] is not supported by this version of the app.'; } + + @override + String get sendPushRequestResponseFailed => 'Het verzenden van het antwoord is mislukt. '; } diff --git a/lib/l10n/app_localizations_pl.dart b/lib/l10n/app_localizations_pl.dart index e9d999ede..6ef9aabba 100644 --- a/lib/l10n/app_localizations_pl.dart +++ b/lib/l10n/app_localizations_pl.dart @@ -875,4 +875,7 @@ class AppLocalizationsPl extends AppLocalizations { String unsupported(Object name, Object value) { return 'The $name [$value] is not supported by this version of the app.'; } + + @override + String get sendPushRequestResponseFailed => 'Nie udało się wysłać odpowiedzi.'; } diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index f335e4b29..8333b1480 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -632,5 +632,9 @@ "scanThisQrWithNewDevice": "Scan deze QR-code met uw nieuwe apparaat om de token te importeren.", "oneMore": "Nog een", "done": "Klaar", - "confirmPassword": "Wachtwoord bevestigen" + "confirmPassword": "Wachtwoord bevestigen", + "sendPushRequestResponseFailed": "Het verzenden van het antwoord is mislukt. ", + "@sendPushRequestResponseFailed": { + "description": "Error message when the response to a push request could not be sent." + } } \ No newline at end of file diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 04681aa25..5c9ead6bc 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -629,5 +629,9 @@ "scanThisQrWithNewDevice": "Zeskanuj ten kod QR za pomocą nowego urządzenia, aby zaimportować token.", "oneMore": "Jeszcze jeden", "done": "Gotowe", - "confirmPassword": "Potwierdź hasło" + "confirmPassword": "Potwierdź hasło", + "sendPushRequestResponseFailed": "Nie udało się wysłać odpowiedzi.", + "@sendPushRequestResponseFailed": { + "description": "Error message when the response to a push request could not be sent." + } } \ No newline at end of file diff --git a/lib/state_notifiers/push_request_notifier.dart b/lib/state_notifiers/push_request_notifier.dart index f9f288842..a4d74266a 100644 --- a/lib/state_notifiers/push_request_notifier.dart +++ b/lib/state_notifiers/push_request_notifier.dart @@ -19,6 +19,7 @@ */ import 'dart:async'; +import 'dart:convert'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:http/http.dart'; @@ -361,6 +362,11 @@ class PushRequestNotifier extends StateNotifier { } } if (response.statusCode != 200) { + final appLocalizations = AppLocalizations.of(await globalContext)!; + globalRef?.read(statusMessageProvider.notifier).state = ( + '${appLocalizations.sendPushRequestResponseFailed}\n${appLocalizations.statusCode(response.statusCode)}', + jsonDecode(response.body)?["result"]?["error"]?["message"], + ); Logger.warning('Sending push request response failed.', name: 'token_widgets.dart#handleReaction'); return false; } diff --git a/lib/widgets/dialog_widgets/push_request_dialog.dart b/lib/widgets/dialog_widgets/push_request_dialog.dart index bf1f356c5..760290829 100644 --- a/lib/widgets/dialog_widgets/push_request_dialog.dart +++ b/lib/widgets/dialog_widgets/push_request_dialog.dart @@ -9,6 +9,7 @@ import '../../model/push_request.dart'; import '../../model/tokens/push_token.dart'; import '../../utils/globals.dart'; import '../../utils/lock_auth.dart'; +import '../../utils/logger.dart'; import '../../utils/riverpod_providers.dart'; import '../press_button.dart'; import 'default_dialog.dart'; @@ -96,8 +97,14 @@ class _PushRequestDialogState extends ConsumerState { ], widget.pushRequest.possibleAnswers != null ? AnswerSelectionWidget( - onAnswerSelected: (selectedAnswer) { - globalRef?.read(pushRequestProvider.notifier).accept(token, widget.pushRequest, selectedAnswer: selectedAnswer); + onAnswerSelected: (selectedAnswer) async { + if (token.isLocked && await lockAuth(localizedReason: localizations.authToAcceptPushRequest) == false) { + return; + } + ref.read(pushRequestProvider.notifier).accept(token, widget.pushRequest, selectedAnswer: selectedAnswer).then((success) { + Logger.info('accept push request success: $success', name: 'push_request_dialog.dart#AnswerSelectionWidget'); + if (!success && mounted) setState(() => isHandled = false); + }); if (mounted) setState(() => isHandled = true); }, possibleAnswers: widget.pushRequest.possibleAnswers!, @@ -110,7 +117,10 @@ class _PushRequestDialogState extends ConsumerState { if (token.isLocked && await lockAuth(localizedReason: localizations.authToAcceptPushRequest) == false) { return; } - globalRef?.read(pushRequestProvider.notifier).accept(token, widget.pushRequest); + ref.read(pushRequestProvider.notifier).accept(token, widget.pushRequest).then((success) { + Logger.info('accept push request success: $success', name: 'push_request_dialog.dart#AnswerSelectionWidget'); + if (!success && mounted) setState(() => isHandled = false); + }); if (mounted) setState(() => isHandled = true); }, child: Row( @@ -209,9 +219,16 @@ class _PushRequestDialogState extends ConsumerState { flex: 6, child: PressButton( style: ButtonStyle(shape: buttonShape), - onPressed: () { - globalRef?.read(pushRequestProvider.notifier).decline(pushToken, widget.pushRequest); - Navigator.of(context).pop(); + onPressed: () async { + if (pushToken.isLocked && await lockAuth(localizedReason: localizations.authToDeclinePushRequest) == false) { + return; + } + + ref.read(pushRequestProvider.notifier).remove(widget.pushRequest).then((success) { + Logger.info('remove push request success: $success', name: 'push_request_dialog.dart#_showConfirmationDialog'); + if (!success && mounted) setState(() => isHandled = false); + }); + if (context.mounted) Navigator.of(context).pop(); if (mounted) setState(() => isHandled = true); }, child: Column( @@ -245,10 +262,17 @@ class _PushRequestDialogState extends ConsumerState { backgroundColor: WidgetStateProperty.all(Theme.of(context).colorScheme.errorContainer), shape: buttonShape, ), - onPressed: () { + onPressed: () async { //TODO: Notify issuer - globalRef?.read(pushRequestProvider.notifier).decline(pushToken, widget.pushRequest); - Navigator.of(context).pop(); + if (pushToken.isLocked && await lockAuth(localizedReason: localizations.authToDeclinePushRequest) == false) { + return; + } + + ref.read(pushRequestProvider.notifier).decline(pushToken, widget.pushRequest).then((success) { + Logger.info('decline push request success: $success', name: 'push_request_dialog.dart#_showConfirmationDialog'); + if (!success && mounted) setState(() => isHandled = false); + }); + if (context.mounted) Navigator.of(context).pop(); if (mounted) setState(() => isHandled = true); }, child: Column( From 8c98acd4ace5e4a64f5f7c76e975efe2e4abe51b Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 28 May 2024 10:03:11 +0200 Subject: [PATCH 12/32] removed debug prints --- lib/model/extensions/sortable_list.dart | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/model/extensions/sortable_list.dart b/lib/model/extensions/sortable_list.dart index 1c32c896b..eee5374b5 100644 --- a/lib/model/extensions/sortable_list.dart +++ b/lib/model/extensions/sortable_list.dart @@ -4,11 +4,6 @@ extension SortableList on List { List get sorted { var list = List.from(this); list.sort((a, b) => a.compareTo(b)); - print('-----------------------------------'); - list.forEach((element) { - print('sorted: ${element.runtimeType} Sortindex: ${element.sortIndex}'); - }); - print('-----------------------------------'); return list; } @@ -25,11 +20,6 @@ extension SortableList on List { list[i] = list[i].copyWith(sortIndex: highestIndex) as T; } } - print('-----------------------------------'); - list.forEach((element) { - print('fillNullIndices: ${element.runtimeType} Sortindex: ${element.sortIndex}'); - }); - print('-----------------------------------'); return list; } @@ -47,11 +37,6 @@ extension SortableList on List { : list.length; list.insert(newIndex, movedItem); list = list.withCurrentSortIndexSet(); - print('-----------------------------------'); - list.forEach((element) { - print('moveBetween: ${element.runtimeType} Sortindex: ${element.sortIndex}'); - }); - print('-----------------------------------'); return list; } From 2cfb06cbffb6fc076731c2ecaf9ce22d65babe61 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 28 May 2024 10:03:38 +0200 Subject: [PATCH 13/32] 2 person login --- lib/model/push_request.dart | 3 +++ lib/utils/push_provider.dart | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/model/push_request.dart b/lib/model/push_request.dart index 9062bb481..13cee7103 100644 --- a/lib/model/push_request.dart +++ b/lib/model/push_request.dart @@ -137,6 +137,9 @@ class PushRequest { if (data[PUSH_REQUEST_SIGNATURE] is! String) { throw ArgumentError('Push request signature is ${data[PUSH_REQUEST_SIGNATURE].runtimeType}. Expected String.'); } + if (data[PUSH_REQUEST_ANSWERS] is! List?) { + throw ArgumentError('Push request answers is ${data[PUSH_REQUEST_ANSWERS].runtimeType}. Expected List or null.'); + } } Future verifySignature(PushToken token, {LegacyUtils legacyUtils = const LegacyUtils(), RsaUtils rsaUtils = const RsaUtils()}) async { diff --git a/lib/utils/push_provider.dart b/lib/utils/push_provider.dart index 68693369a..2e02ef89a 100644 --- a/lib/utils/push_provider.dart +++ b/lib/utils/push_provider.dart @@ -112,6 +112,11 @@ class PushProvider { final Map data; try { data = remoteMessage.data; + Logger.info('----------------------- Remote Message Data ------------------------'); + data.forEach((key, value) { + Logger.info('$key: $value', name: 'push_provider.dart#_foregroundHandler'); + }); + Logger.info('--------------------- Remote Message Data End -----------------------'); PushRequest.verifyData(data); } on ArgumentError catch (e) { Logger.warning('Could not parse push request data.', name: 'push_provider.dart#_getAndValidateDataFromRemoteMessage', error: e, verbose: true); @@ -143,11 +148,8 @@ class PushProvider { Map data; try { data = _getAndValidateDataFromRemoteMessage(remoteMessage); - data.forEach((key, value) { - Logger.info('$key: $value', name: 'push_provider.dart#_foregroundHandler'); - }); } on ArgumentError catch (_) { - Logger.info('Try requesting the challenge by polling.', name: 'push_provider.dart#_foregroundHandler'); + Logger.info('Failed to parse push request data. Trying to poll for challenges.', name: 'push_provider.dart#_foregroundHandler'); await pollForChallenges(isManually: true); return; } @@ -155,8 +157,12 @@ class PushProvider { try { return _handleIncomingRequestForeground(data); } catch (e, s) { - final errorMessage = AppLocalizations.of(globalNavigatorKey.currentContext!)!.unexpectedError; - Logger.error(errorMessage, name: 'push_provider.dart#_foregroundHandler', error: e, stackTrace: s); + Logger.error( + AppLocalizations.of(globalNavigatorKey.currentContext!)!.unexpectedError, + name: 'push_provider.dart#_foregroundHandler', + error: e, + stackTrace: s, + ); } } From 2c89bbc99fbdc4696c99a9d3f33634f5fd66d738 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 28 May 2024 12:20:24 +0200 Subject: [PATCH 14/32] fixed some imports --- lib/mains/main_customizer.dart | 22 ++++++++--------- .../google_authenticator_qr_processor.dart | 4 ++-- .../aegis_import_file_processor.dart | 18 +++++++------- ...thenticator_pro_import_file_processor.dart | 22 ++++++++--------- .../free_otp_plus_import_file_processor.dart | 14 +++++------ .../two_fas_import_file_processor.dart | 6 ++--- lib/repo/secure_token_repository.dart | 12 +++++----- .../push_request_notifier.dart | 24 +++++++++---------- lib/utils/crypto_utils.dart | 2 +- .../application_customization.dart | 2 +- .../customization/theme_customization.dart | 5 ++-- lib/utils/home_widget_utils.dart | 2 +- lib/utils/image_converter.dart | 3 ++- lib/utils/logger.dart | 6 ++--- lib/utils/network_utils.dart | 11 +++++---- lib/utils/push_provider.dart | 4 ++-- lib/utils/rsa_utils.dart | 12 +++++----- lib/utils/utils.dart | 11 ++++++++- .../pages/import_start_page.dart | 12 +++++----- lib/views/main_view/main_view.dart | 2 +- .../qr_scanner_view/qr_scanner_view.dart | 8 +++---- .../update_firebase_token_dialog.dart | 8 +++---- lib/views/splash_screen/splash_screen.dart | 2 +- .../dialog_widgets/two_step_dialog.dart | 8 +++---- 24 files changed, 116 insertions(+), 104 deletions(-) diff --git a/lib/mains/main_customizer.dart b/lib/mains/main_customizer.dart index f11979325..7e31c8ce6 100644 --- a/lib/mains/main_customizer.dart +++ b/lib/mains/main_customizer.dart @@ -22,19 +22,19 @@ import 'package:easy_dynamic_theme/easy_dynamic_theme.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:privacyidea_authenticator/l10n/app_localizations.dart'; -import 'package:privacyidea_authenticator/utils/globals.dart'; -import 'package:privacyidea_authenticator/utils/logger.dart'; -import 'package:privacyidea_authenticator/utils/riverpod_providers.dart'; -import 'package:privacyidea_authenticator/views/add_token_manually_view/add_token_manually_view.dart'; -import 'package:privacyidea_authenticator/views/license_view/license_view.dart'; -import 'package:privacyidea_authenticator/views/main_view/main_view.dart'; -import 'package:privacyidea_authenticator/views/qr_scanner_view/qr_scanner_view.dart'; -import 'package:privacyidea_authenticator/views/settings_view/settings_view.dart'; -import 'package:privacyidea_authenticator/views/splash_screen/splash_screen.dart'; -import 'package:privacyidea_authenticator/widgets/app_wrapper.dart'; +import '../l10n/app_localizations.dart'; import '../model/enums/app_feature.dart'; +import '../utils/globals.dart'; +import '../utils/logger.dart'; +import '../utils/riverpod_providers.dart'; +import '../views/add_token_manually_view/add_token_manually_view.dart'; +import '../views/license_view/license_view.dart'; +import '../views/main_view/main_view.dart'; +import '../views/qr_scanner_view/qr_scanner_view.dart'; +import '../views/settings_view/settings_view.dart'; +import '../views/splash_screen/splash_screen.dart'; +import '../widgets/app_wrapper.dart'; void main() async { Logger.init( diff --git a/lib/processors/scheme_processors/token_import_scheme_processors/google_authenticator_qr_processor.dart b/lib/processors/scheme_processors/token_import_scheme_processors/google_authenticator_qr_processor.dart index b0ee10ba6..0ac271a78 100644 --- a/lib/processors/scheme_processors/token_import_scheme_processors/google_authenticator_qr_processor.dart +++ b/lib/processors/scheme_processors/token_import_scheme_processors/google_authenticator_qr_processor.dart @@ -5,8 +5,8 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:base32/base32.dart'; -import 'package:privacyidea_authenticator/model/extensions/enums/token_origin_source_type.dart'; -import 'package:privacyidea_authenticator/utils/logger.dart'; +import '../../../model/extensions/enums/token_origin_source_type.dart'; +import '../../../utils/logger.dart'; import '../../../model/enums/token_origin_source_type.dart'; import '../../../model/processor_result.dart'; diff --git a/lib/processors/token_import_file_processor/aegis_import_file_processor.dart b/lib/processors/token_import_file_processor/aegis_import_file_processor.dart index f8a093ba5..44943e9b2 100644 --- a/lib/processors/token_import_file_processor/aegis_import_file_processor.dart +++ b/lib/processors/token_import_file_processor/aegis_import_file_processor.dart @@ -8,20 +8,20 @@ import 'package:cryptography/cryptography.dart' as crypto; import 'package:encrypt/encrypt.dart'; import 'package:file_selector/file_selector.dart'; import 'package:pointycastle/export.dart'; -import 'package:privacyidea_authenticator/model/enums/encodings.dart'; -import 'package:privacyidea_authenticator/model/enums/token_origin_source_type.dart'; -import 'package:privacyidea_authenticator/model/enums/token_types.dart'; -import 'package:privacyidea_authenticator/model/extensions/enums/encodings_extension.dart'; -import 'package:privacyidea_authenticator/model/extensions/enums/token_origin_source_type.dart'; -import 'package:privacyidea_authenticator/model/tokens/token.dart'; -import 'package:privacyidea_authenticator/utils/identifiers.dart'; -import 'package:privacyidea_authenticator/utils/logger.dart'; -import 'package:privacyidea_authenticator/utils/token_import_origins.dart'; import '../../l10n/app_localizations.dart'; +import '../../model/enums/encodings.dart'; +import '../../model/enums/token_origin_source_type.dart'; +import '../../model/enums/token_types.dart'; +import '../../model/extensions/enums/encodings_extension.dart'; +import '../../model/extensions/enums/token_origin_source_type.dart'; import '../../model/processor_result.dart'; +import '../../model/tokens/token.dart'; import '../../utils/errors.dart'; import '../../utils/globals.dart'; +import '../../utils/identifiers.dart'; +import '../../utils/logger.dart'; +import '../../utils/token_import_origins.dart'; import '../../utils/utils.dart'; import 'token_import_file_processor_interface.dart'; import 'two_fas_import_file_processor.dart'; diff --git a/lib/processors/token_import_file_processor/authenticator_pro_import_file_processor.dart b/lib/processors/token_import_file_processor/authenticator_pro_import_file_processor.dart index 5ddbe17c8..92ed3bfde 100644 --- a/lib/processors/token_import_file_processor/authenticator_pro_import_file_processor.dart +++ b/lib/processors/token_import_file_processor/authenticator_pro_import_file_processor.dart @@ -4,17 +4,17 @@ import 'dart:convert'; import 'package:cryptography/cryptography.dart'; import 'package:file_selector/file_selector.dart'; -import 'package:privacyidea_authenticator/model/enums/algorithms.dart'; -import 'package:privacyidea_authenticator/model/enums/encodings.dart'; -import 'package:privacyidea_authenticator/model/enums/token_types.dart'; -import 'package:privacyidea_authenticator/model/extensions/enums/encodings_extension.dart'; -import 'package:privacyidea_authenticator/model/extensions/enums/token_origin_source_type.dart'; -import 'package:privacyidea_authenticator/model/tokens/token.dart'; -import 'package:privacyidea_authenticator/processors/scheme_processors/token_import_scheme_processors/otp_auth_processor.dart'; -import 'package:privacyidea_authenticator/processors/token_import_file_processor/two_fas_import_file_processor.dart'; -import 'package:privacyidea_authenticator/utils/identifiers.dart'; -import 'package:privacyidea_authenticator/utils/logger.dart'; -import 'package:privacyidea_authenticator/utils/token_import_origins.dart'; +import '../../model/enums/algorithms.dart'; +import '../../model/enums/encodings.dart'; +import '../../model/enums/token_types.dart'; +import '../../model/extensions/enums/encodings_extension.dart'; +import '../../model/extensions/enums/token_origin_source_type.dart'; +import '../../model/tokens/token.dart'; +import '../../processors/scheme_processors/token_import_scheme_processors/otp_auth_processor.dart'; +import '../../processors/token_import_file_processor/two_fas_import_file_processor.dart'; +import '../../utils/identifiers.dart'; +import '../../utils/logger.dart'; +import '../../utils/token_import_origins.dart'; import '../../l10n/app_localizations.dart'; import '../../model/encryption/aes_encrypted.dart'; diff --git a/lib/processors/token_import_file_processor/free_otp_plus_import_file_processor.dart b/lib/processors/token_import_file_processor/free_otp_plus_import_file_processor.dart index ef3c9a6ef..c99d786ad 100644 --- a/lib/processors/token_import_file_processor/free_otp_plus_import_file_processor.dart +++ b/lib/processors/token_import_file_processor/free_otp_plus_import_file_processor.dart @@ -4,16 +4,16 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:file_selector/file_selector.dart'; -import 'package:privacyidea_authenticator/l10n/app_localizations.dart'; -import 'package:privacyidea_authenticator/model/enums/token_origin_source_type.dart'; -import 'package:privacyidea_authenticator/model/extensions/enums/token_origin_source_type.dart'; -import 'package:privacyidea_authenticator/model/processor_result.dart'; -import 'package:privacyidea_authenticator/model/tokens/token.dart'; -import 'package:privacyidea_authenticator/utils/globals.dart'; -import 'package:privacyidea_authenticator/utils/logger.dart'; +import '../../l10n/app_localizations.dart'; +import '../../model/enums/token_origin_source_type.dart'; +import '../../model/extensions/enums/token_origin_source_type.dart'; +import '../../model/processor_result.dart'; +import '../../model/tokens/token.dart'; import '../../utils/errors.dart'; +import '../../utils/globals.dart'; import '../../utils/identifiers.dart'; +import '../../utils/logger.dart'; import '../../utils/token_import_origins.dart'; import '../scheme_processors/token_import_scheme_processors/free_otp_plus_qr_processor.dart'; import 'token_import_file_processor_interface.dart'; diff --git a/lib/processors/token_import_file_processor/two_fas_import_file_processor.dart b/lib/processors/token_import_file_processor/two_fas_import_file_processor.dart index 2b09f42f4..046fd69ac 100644 --- a/lib/processors/token_import_file_processor/two_fas_import_file_processor.dart +++ b/lib/processors/token_import_file_processor/two_fas_import_file_processor.dart @@ -4,20 +4,20 @@ import 'dart:convert'; import 'package:cryptography/cryptography.dart'; import 'package:file_selector/file_selector.dart'; -import 'package:privacyidea_authenticator/model/extensions/enums/encodings_extension.dart'; -import 'package:privacyidea_authenticator/model/extensions/enums/token_origin_source_type.dart'; -import 'package:privacyidea_authenticator/utils/token_import_origins.dart'; import '../../l10n/app_localizations.dart'; import '../../model/encryption/aes_encrypted.dart'; import '../../model/enums/encodings.dart'; import '../../model/enums/token_origin_source_type.dart'; +import '../../model/extensions/enums/encodings_extension.dart'; +import '../../model/extensions/enums/token_origin_source_type.dart'; import '../../model/processor_result.dart'; import '../../model/tokens/token.dart'; import '../../utils/errors.dart'; import '../../utils/globals.dart'; import '../../utils/identifiers.dart'; import '../../utils/logger.dart'; +import '../../utils/token_import_origins.dart'; import 'token_import_file_processor_interface.dart'; class TwoFasAuthenticatorImportFileProcessor extends TokenImportFileProcessor { diff --git a/lib/repo/secure_token_repository.dart b/lib/repo/secure_token_repository.dart index eb878bfe7..c302554df 100644 --- a/lib/repo/secure_token_repository.dart +++ b/lib/repo/secure_token_repository.dart @@ -27,14 +27,14 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:mutex/mutex.dart'; -import 'package:privacyidea_authenticator/interfaces/repo/token_repository.dart'; -import 'package:privacyidea_authenticator/l10n/app_localizations.dart'; -import 'package:privacyidea_authenticator/model/tokens/token.dart'; -import 'package:privacyidea_authenticator/utils/logger.dart'; -import 'package:privacyidea_authenticator/utils/riverpod_providers.dart'; -import 'package:privacyidea_authenticator/utils/view_utils.dart'; +import '../interfaces/repo/token_repository.dart'; +import '../l10n/app_localizations.dart'; +import '../model/tokens/token.dart'; import '../utils/identifiers.dart'; +import '../utils/logger.dart'; +import '../utils/riverpod_providers.dart'; +import '../utils/view_utils.dart'; import '../views/settings_view/settings_view_widgets/send_error_dialog.dart'; import '../widgets/dialog_widgets/default_dialog.dart'; import '../widgets/dialog_widgets/default_dialog_button.dart'; diff --git a/lib/state_notifiers/push_request_notifier.dart b/lib/state_notifiers/push_request_notifier.dart index a4d74266a..0b05508ad 100644 --- a/lib/state_notifiers/push_request_notifier.dart +++ b/lib/state_notifiers/push_request_notifier.dart @@ -19,25 +19,25 @@ */ import 'dart:async'; -import 'dart:convert'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:http/http.dart'; import 'package:mutex/mutex.dart'; -import 'package:privacyidea_authenticator/interfaces/repo/push_request_repository.dart'; -import 'package:privacyidea_authenticator/l10n/app_localizations.dart'; -import 'package:privacyidea_authenticator/model/push_request.dart'; -import 'package:privacyidea_authenticator/model/tokens/push_token.dart'; -import 'package:privacyidea_authenticator/utils/globals.dart'; -import 'package:privacyidea_authenticator/utils/logger.dart'; -import 'package:privacyidea_authenticator/utils/network_utils.dart'; -import 'package:privacyidea_authenticator/utils/push_provider.dart'; -import 'package:privacyidea_authenticator/utils/riverpod_providers.dart'; -import 'package:privacyidea_authenticator/utils/rsa_utils.dart'; +import '../interfaces/repo/push_request_repository.dart'; +import '../l10n/app_localizations.dart'; +import '../model/push_request.dart'; import '../model/states/push_request_state.dart'; +import '../model/tokens/push_token.dart'; import '../repo/secure_push_request_repository.dart'; import '../utils/custom_int_buffer.dart'; +import '../utils/globals.dart'; +import '../utils/logger.dart'; +import '../utils/network_utils.dart'; +import '../utils/push_provider.dart'; +import '../utils/riverpod_providers.dart'; +import '../utils/rsa_utils.dart'; +import '../utils/utils.dart'; class PushRequestNotifier extends StateNotifier { late final Future initState; @@ -365,7 +365,7 @@ class PushRequestNotifier extends StateNotifier { final appLocalizations = AppLocalizations.of(await globalContext)!; globalRef?.read(statusMessageProvider.notifier).state = ( '${appLocalizations.sendPushRequestResponseFailed}\n${appLocalizations.statusCode(response.statusCode)}', - jsonDecode(response.body)?["result"]?["error"]?["message"], + tryJsonDecode(response.body)?["result"]?["error"]?["message"], ); Logger.warning('Sending push request response failed.', name: 'token_widgets.dart#handleReaction'); return false; diff --git a/lib/utils/crypto_utils.dart b/lib/utils/crypto_utils.dart index 5915edd25..0d708768b 100644 --- a/lib/utils/crypto_utils.dart +++ b/lib/utils/crypto_utils.dart @@ -25,9 +25,9 @@ import 'dart:math' as math; import 'package:base32/base32.dart'; import 'package:flutter/foundation.dart'; import 'package:pointycastle/export.dart'; -import 'package:privacyidea_authenticator/model/extensions/enums/encodings_extension.dart'; import '../model/enums/encodings.dart'; +import '../model/extensions/enums/encodings_extension.dart'; Future pbkdf2({required Uint8List salt, required int iterations, required int keyLength, required Uint8List password}) async { ArgumentError.checkNotNull(salt); diff --git a/lib/utils/customization/application_customization.dart b/lib/utils/customization/application_customization.dart index ee57f2f16..b16fb062f 100644 --- a/lib/utils/customization/application_customization.dart +++ b/lib/utils/customization/application_customization.dart @@ -2,7 +2,7 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:flutter/material.dart'; -import 'package:privacyidea_authenticator/utils/customization/theme_customization.dart'; +import '../../../utils/customization/theme_customization.dart'; import '../../model/enums/app_feature.dart'; diff --git a/lib/utils/customization/theme_customization.dart b/lib/utils/customization/theme_customization.dart index 7f7ca083d..ba22d818a 100644 --- a/lib/utils/customization/theme_customization.dart +++ b/lib/utils/customization/theme_customization.dart @@ -1,8 +1,9 @@ import 'dart:math'; import 'package:flutter/material.dart'; -import 'package:privacyidea_authenticator/utils/customization/action_theme.dart'; -import 'package:privacyidea_authenticator/utils/customization/extended_text_theme.dart'; + +import '../../../utils/customization/action_theme.dart'; +import '../../../utils/customization/extended_text_theme.dart'; class ThemeCustomization { static const ThemeCustomization defaultLightTheme = ThemeCustomization.defaultLightWith(); diff --git a/lib/utils/home_widget_utils.dart b/lib/utils/home_widget_utils.dart index 0319e0653..a979c05c4 100644 --- a/lib/utils/home_widget_utils.dart +++ b/lib/utils/home_widget_utils.dart @@ -7,7 +7,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:home_widget/home_widget.dart'; import 'package:mutex/mutex.dart'; -import 'package:privacyidea_authenticator/utils/customization/theme_customization.dart'; +import '../utils/customization/theme_customization.dart'; import '../interfaces/repo/token_folder_repository.dart'; import '../interfaces/repo/token_repository.dart'; diff --git a/lib/utils/image_converter.dart b/lib/utils/image_converter.dart index c4181945e..aefbb1bcb 100644 --- a/lib/utils/image_converter.dart +++ b/lib/utils/image_converter.dart @@ -5,7 +5,8 @@ import 'dart:ui'; import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import 'package:image/image.dart' as imglib; -import 'package:privacyidea_authenticator/utils/logger.dart'; + +import '../utils/logger.dart'; class ImageConverter { final imglib.Image image; diff --git a/lib/utils/logger.dart b/lib/utils/logger.dart index c5e75431e..53a40e504 100644 --- a/lib/utils/logger.dart +++ b/lib/utils/logger.dart @@ -11,10 +11,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:logger/logger.dart' as printer; import 'package:mutex/mutex.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:privacyidea_authenticator/l10n/app_localizations.dart'; -import 'package:privacyidea_authenticator/utils/app_info_utils.dart'; -import 'package:privacyidea_authenticator/utils/pi_mailer.dart'; +import '../l10n/app_localizations.dart'; +import '../utils/app_info_utils.dart'; +import '../utils/pi_mailer.dart'; import '../views/settings_view/settings_view_widgets/send_error_dialog.dart'; import 'globals.dart'; import 'riverpod_providers.dart'; diff --git a/lib/utils/network_utils.dart b/lib/utils/network_utils.dart index 9d63c4103..143ae09bb 100644 --- a/lib/utils/network_utils.dart +++ b/lib/utils/network_utils.dart @@ -25,11 +25,12 @@ import 'package:flutter/foundation.dart'; import 'package:http/http.dart'; import 'package:http/io_client.dart'; import 'package:package_info_plus/package_info_plus.dart'; -import 'package:privacyidea_authenticator/l10n/app_localizations.dart'; -import 'package:privacyidea_authenticator/utils/globals.dart'; -import 'package:privacyidea_authenticator/utils/logger.dart'; -import 'package:privacyidea_authenticator/utils/riverpod_providers.dart'; -import 'package:privacyidea_authenticator/utils/view_utils.dart'; + +import '../l10n/app_localizations.dart'; +import '../utils/globals.dart'; +import '../utils/logger.dart'; +import '../utils/riverpod_providers.dart'; +import '../utils/view_utils.dart'; class PrivacyIdeaIOClient { const PrivacyIdeaIOClient(); diff --git a/lib/utils/push_provider.dart b/lib/utils/push_provider.dart index 2e02ef89a..3d924e386 100644 --- a/lib/utils/push_provider.dart +++ b/lib/utils/push_provider.dart @@ -26,13 +26,13 @@ import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:http/http.dart'; import 'package:pi_authenticator_legacy/pi_authenticator_legacy.dart'; -import 'package:privacyidea_authenticator/repo/secure_push_request_repository.dart'; -import 'package:privacyidea_authenticator/utils/pi_notifications.dart'; import '../l10n/app_localizations.dart'; import '../model/push_request.dart'; import '../model/tokens/push_token.dart'; +import '../repo/secure_push_request_repository.dart'; import '../repo/secure_token_repository.dart'; +import '../utils/pi_notifications.dart'; import 'firebase_utils.dart'; import 'globals.dart'; import 'logger.dart'; diff --git a/lib/utils/rsa_utils.dart b/lib/utils/rsa_utils.dart index 270215dcb..5ca0105aa 100644 --- a/lib/utils/rsa_utils.dart +++ b/lib/utils/rsa_utils.dart @@ -25,12 +25,12 @@ import 'package:base32/base32.dart'; import 'package:flutter/foundation.dart'; import 'package:pi_authenticator_legacy/pi_authenticator_legacy.dart'; import 'package:pointycastle/export.dart'; -import 'package:privacyidea_authenticator/l10n/app_localizations.dart'; -import 'package:privacyidea_authenticator/model/tokens/push_token.dart'; -import 'package:privacyidea_authenticator/utils/crypto_utils.dart'; -import 'package:privacyidea_authenticator/utils/identifiers.dart'; -import 'package:privacyidea_authenticator/utils/logger.dart'; -import 'package:privacyidea_authenticator/utils/riverpod_providers.dart'; +import '../l10n/app_localizations.dart'; +import '../model/tokens/push_token.dart'; +import '../utils/crypto_utils.dart'; +import '../utils/identifiers.dart'; +import '../utils/logger.dart'; +import '../utils/riverpod_providers.dart'; import 'globals.dart'; diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 740912db2..60f21fdb5 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -26,7 +26,8 @@ import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:permission_handler/permission_handler.dart'; -import 'package:privacyidea_authenticator/utils/logger.dart'; + +import '../utils/logger.dart'; /// Inserts [char] at the position [pos] in the given String ([str]), /// and returns the resulting String. @@ -120,3 +121,11 @@ bool doesThrow(Function() f) { return true; } } + +dynamic tryJsonDecode(String json) { + try { + return jsonDecode(json); + } catch (_) { + return null; + } +} diff --git a/lib/views/import_tokens_view/pages/import_start_page.dart b/lib/views/import_tokens_view/pages/import_start_page.dart index c993a764f..c2f93973e 100644 --- a/lib/views/import_tokens_view/pages/import_start_page.dart +++ b/lib/views/import_tokens_view/pages/import_start_page.dart @@ -5,18 +5,18 @@ import 'dart:isolate'; import 'package:file_selector/file_selector.dart'; import 'package:flutter/material.dart'; import 'package:image/image.dart' as img; -import 'package:privacyidea_authenticator/model/enums/token_import_type.dart'; -import 'package:privacyidea_authenticator/model/enums/token_origin_source_type.dart'; -import 'package:privacyidea_authenticator/model/extensions/enums/token_import_type_extension.dart'; -import 'package:privacyidea_authenticator/model/extensions/enums/token_origin_source_type.dart'; -import 'package:privacyidea_authenticator/model/processor_result.dart'; -import 'package:privacyidea_authenticator/processors/scheme_processors/token_import_scheme_processors/token_import_scheme_processor_interface.dart'; import 'package:zxing2/qrcode.dart'; import '../../../l10n/app_localizations.dart'; +import '../../../model/enums/token_import_type.dart'; +import '../../../model/enums/token_origin_source_type.dart'; +import '../../../model/extensions/enums/token_import_type_extension.dart'; +import '../../../model/extensions/enums/token_origin_source_type.dart'; +import '../../../model/processor_result.dart'; import '../../../model/token_import/token_import_source.dart'; import '../../../model/tokens/token.dart'; import '../../../processors/mixins/token_import_processor.dart'; +import '../../../processors/scheme_processors/token_import_scheme_processors/token_import_scheme_processor_interface.dart'; import '../../../processors/token_import_file_processor/token_import_file_processor_interface.dart'; import '../../../utils/logger.dart'; import '../../qr_scanner_view/qr_scanner_view.dart'; diff --git a/lib/views/main_view/main_view.dart b/lib/views/main_view/main_view.dart index ab1007102..d7c7a862a 100644 --- a/lib/views/main_view/main_view.dart +++ b/lib/views/main_view/main_view.dart @@ -15,7 +15,7 @@ import 'main_view_widgets/main_view_navigation_bar.dart'; import 'main_view_widgets/main_view_tokens_list.dart'; import 'main_view_widgets/main_view_tokens_list_filtered.dart'; -export 'package:privacyidea_authenticator/views/main_view/main_view.dart'; +export '../../views/main_view/main_view.dart'; class MainView extends ConsumerStatefulView { static const routeName = '/mainView'; diff --git a/lib/views/qr_scanner_view/qr_scanner_view.dart b/lib/views/qr_scanner_view/qr_scanner_view.dart index 63edc62dd..8596f32a9 100644 --- a/lib/views/qr_scanner_view/qr_scanner_view.dart +++ b/lib/views/qr_scanner_view/qr_scanner_view.dart @@ -20,12 +20,12 @@ import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; -import 'package:privacyidea_authenticator/l10n/app_localizations.dart'; -import 'package:privacyidea_authenticator/views/view_interface.dart'; -import 'package:privacyidea_authenticator/widgets/dialog_widgets/default_dialog.dart'; -import 'package:privacyidea_authenticator/widgets/dialog_widgets/default_dialog_button.dart'; +import '../../l10n/app_localizations.dart'; import '../../utils/logger.dart'; +import '../../views/view_interface.dart'; +import '../../widgets/dialog_widgets/default_dialog.dart'; +import '../../widgets/dialog_widgets/default_dialog_button.dart'; import 'qr_scanner_view_widgets/qr_scanner_widget.dart'; class QRScannerView extends StatefulView { diff --git a/lib/views/settings_view/settings_view_widgets/update_firebase_token_dialog.dart b/lib/views/settings_view/settings_view_widgets/update_firebase_token_dialog.dart index 5419b74dd..20f2bb288 100644 --- a/lib/views/settings_view/settings_view_widgets/update_firebase_token_dialog.dart +++ b/lib/views/settings_view/settings_view_widgets/update_firebase_token_dialog.dart @@ -20,13 +20,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:privacyidea_authenticator/l10n/app_localizations.dart'; -import 'package:privacyidea_authenticator/utils/logger.dart'; -import 'package:privacyidea_authenticator/utils/riverpod_providers.dart'; -import 'package:privacyidea_authenticator/utils/view_utils.dart'; +import '../../../l10n/app_localizations.dart'; import '../../../model/tokens/push_token.dart'; import '../../../utils/globals.dart'; +import '../../../utils/logger.dart'; +import '../../../utils/riverpod_providers.dart'; +import '../../../utils/view_utils.dart'; import '../../../widgets/dialog_widgets/default_dialog.dart'; class UpdateFirebaseTokenDialog extends ConsumerStatefulWidget { diff --git a/lib/views/splash_screen/splash_screen.dart b/lib/views/splash_screen/splash_screen.dart index c0b2545c5..c13ad8981 100644 --- a/lib/views/splash_screen/splash_screen.dart +++ b/lib/views/splash_screen/splash_screen.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../model/enums/app_feature.dart'; -import '../../utils/customization/application_customization.dart'; import '../../utils/app_info_utils.dart'; +import '../../utils/customization/application_customization.dart'; import '../../utils/home_widget_utils.dart'; import '../../utils/logger.dart'; import '../../utils/riverpod_providers.dart'; diff --git a/lib/widgets/dialog_widgets/two_step_dialog.dart b/lib/widgets/dialog_widgets/two_step_dialog.dart index d87b43d5e..bb7beae82 100644 --- a/lib/widgets/dialog_widgets/two_step_dialog.dart +++ b/lib/widgets/dialog_widgets/two_step_dialog.dart @@ -22,13 +22,13 @@ import 'dart:typed_data'; import 'dart:ui'; import 'package:flutter/material.dart'; -import 'package:privacyidea_authenticator/l10n/app_localizations.dart'; -import 'package:privacyidea_authenticator/utils/crypto_utils.dart'; -import 'package:privacyidea_authenticator/utils/view_utils.dart'; -import 'package:privacyidea_authenticator/widgets/dialog_widgets/default_dialog.dart'; +import '../../l10n/app_localizations.dart'; +import '../../utils/crypto_utils.dart'; import '../../utils/logger.dart'; import '../../utils/utils.dart'; +import '../../utils/view_utils.dart'; +import '../../widgets/dialog_widgets/default_dialog.dart'; import '../widget_keys.dart'; class GenerateTwoStepDialog extends StatelessWidget { From d1d7d486e14acd4de7b4f264028b3123b39d88b6 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 28 May 2024 17:07:58 +0200 Subject: [PATCH 15/32] 2 person login --- lib/model/push_request.dart | 8 +-- lib/utils/push_provider.dart | 6 +-- .../dialog_widgets/push_request_dialog.dart | 53 +++++++++++-------- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/lib/model/push_request.dart b/lib/model/push_request.dart index 13cee7103..4a711c5ce 100644 --- a/lib/model/push_request.dart +++ b/lib/model/push_request.dart @@ -107,7 +107,7 @@ class PushRequest { serial: data[PUSH_REQUEST_SERIAL], expirationDate: DateTime.now().add(const Duration(minutes: 2)), signature: data[PUSH_REQUEST_SIGNATURE], - possibleAnswers: data[PUSH_REQUEST_ANSWERS], + possibleAnswers: data[PUSH_REQUEST_ANSWERS] != null ? (data[PUSH_REQUEST_ANSWERS] as String).split(',') : null, ); } @@ -137,12 +137,13 @@ class PushRequest { if (data[PUSH_REQUEST_SIGNATURE] is! String) { throw ArgumentError('Push request signature is ${data[PUSH_REQUEST_SIGNATURE].runtimeType}. Expected String.'); } - if (data[PUSH_REQUEST_ANSWERS] is! List?) { + if (data[PUSH_REQUEST_ANSWERS] is! String?) { throw ArgumentError('Push request answers is ${data[PUSH_REQUEST_ANSWERS].runtimeType}. Expected List or null.'); } } Future verifySignature(PushToken token, {LegacyUtils legacyUtils = const LegacyUtils(), RsaUtils rsaUtils = const RsaUtils()}) async { + //5NV6KJCFCLNQURT2ZTBRHHGY6FDXOCOR|http://192.168.178.22:5000/ttype/push|PIPU0000E793|Pick a Number!|privacyIDEA|0|["A", "B", "C"] Logger.info('Adding push request to token', name: 'push_request_notifier.dart#newRequest'); String signedData = '$nonce|' '$uri|' @@ -150,7 +151,8 @@ class PushRequest { '$question|' '$title|' '${sslVerify ? '1' : '0'}' - '${possibleAnswers != null ? '|require_presence' : ''}'; + '${possibleAnswers != null ? '|${possibleAnswers!.join(",")}' : ''}'; + Logger.warning('Signed data: $signedData', name: 'push_request_notifier.dart#newRequest'); // Re-add url and sslverify to android legacy tokens: if (token.url == null) { diff --git a/lib/utils/push_provider.dart b/lib/utils/push_provider.dart index 3d924e386..fe7fc07cf 100644 --- a/lib/utils/push_provider.dart +++ b/lib/utils/push_provider.dart @@ -112,11 +112,6 @@ class PushProvider { final Map data; try { data = remoteMessage.data; - Logger.info('----------------------- Remote Message Data ------------------------'); - data.forEach((key, value) { - Logger.info('$key: $value', name: 'push_provider.dart#_foregroundHandler'); - }); - Logger.info('--------------------- Remote Message Data End -----------------------'); PushRequest.verifyData(data); } on ArgumentError catch (e) { Logger.warning('Could not parse push request data.', name: 'push_provider.dart#_getAndValidateDataFromRemoteMessage', error: e, verbose: true); @@ -207,6 +202,7 @@ class PushProvider { Future _handleIncomingRequestForeground(Map data) async { Logger.info('Incoming push challenge.', name: 'push_provider.dart#_handleIncomingRequestForeground'); PushRequest pushRequest = PushRequest.fromMessageData(data); + Logger.info("PushRequest.possibleAnswers: ${pushRequest.possibleAnswers}", name: 'push_provider.dart#_handleIncomingRequestForeground'); Logger.info('Parsing data of push request succeeded.', name: 'push_provider.dart#_handleIncomingRequestForeground'); final pushToken = globalRef?.read(tokenProvider).getTokenBySerial(pushRequest.serial); if (pushToken == null) { diff --git a/lib/widgets/dialog_widgets/push_request_dialog.dart b/lib/widgets/dialog_widgets/push_request_dialog.dart index 760290829..41f625044 100644 --- a/lib/widgets/dialog_widgets/push_request_dialog.dart +++ b/lib/widgets/dialog_widgets/push_request_dialog.dart @@ -96,18 +96,22 @@ class _PushRequestDialogState extends ConsumerState { SizedBox(height: spacerHeight), ], widget.pushRequest.possibleAnswers != null - ? AnswerSelectionWidget( - onAnswerSelected: (selectedAnswer) async { - if (token.isLocked && await lockAuth(localizedReason: localizations.authToAcceptPushRequest) == false) { - return; - } - ref.read(pushRequestProvider.notifier).accept(token, widget.pushRequest, selectedAnswer: selectedAnswer).then((success) { - Logger.info('accept push request success: $success', name: 'push_request_dialog.dart#AnswerSelectionWidget'); - if (!success && mounted) setState(() => isHandled = false); - }); - if (mounted) setState(() => isHandled = true); - }, - possibleAnswers: widget.pushRequest.possibleAnswers!, + ? Flexible( + child: SingleChildScrollView( + child: AnswerSelectionWidget( + onAnswerSelected: (selectedAnswer) async { + if (token.isLocked && await lockAuth(localizedReason: localizations.authToAcceptPushRequest) == false) { + return; + } + ref.read(pushRequestProvider.notifier).accept(token, widget.pushRequest, selectedAnswer: selectedAnswer).then((success) { + Logger.info('accept push request success: $success', name: 'push_request_dialog.dart#AnswerSelectionWidget'); + if (!success && mounted) setState(() => isHandled = false); + }); + if (mounted) setState(() => isHandled = true); + }, + possibleAnswers: widget.pushRequest.possibleAnswers!, + ), + ), ) : SizedBox( // Accept button @@ -320,16 +324,11 @@ class _AnswerSelectionWidgetState extends State> { Widget build(BuildContext context) { final children = []; final possibleAnswers = widget.possibleAnswers.toList(); - const numPerRow = 3; - var numRow = 0; + const numPerRow = 4; while (possibleAnswers.isNotEmpty) { final maxThisRow = possibleAnswers.length == numPerRow + 1 ? min(possibleAnswers.length, (numPerRow / 2).ceil()) : min(possibleAnswers.length, numPerRow); - numRow++; final answersThisRow = possibleAnswers.sublist(0, maxThisRow); possibleAnswers.removeRange(0, maxThisRow); - print('NumRow: $numRow'); - print('possibleAnswers.length: ${possibleAnswers.length}'); - print('maxThisRow: $maxThisRow'); children.add( Row( mainAxisSize: MainAxisSize.max, @@ -353,11 +352,19 @@ class _AnswerSelectionWidgetState extends State> { ), onPressed: () => widget.onAnswerSelected(possibleAnswer), child: Padding( - padding: EdgeInsets.all(spacerHeight), - child: Text( - possibleAnswer.toString(), - style: Theme.of(context).textTheme.headlineMedium?.copyWith(color: Theme.of(context).colorScheme.onPrimary), - textAlign: TextAlign.center, + padding: EdgeInsets.symmetric(vertical: spacerHeight), + child: SizedBox( + height: lineHeight * 2, + child: Center( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text( + possibleAnswer.toString(), + style: Theme.of(context).textTheme.headlineMedium?.copyWith(color: Theme.of(context).colorScheme.onPrimary), + textAlign: TextAlign.center, + ), + ), + ), ), ), ), From d55e94fadd10672ea48317e0a7ab8746d319d613 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 28 May 2024 17:40:39 +0200 Subject: [PATCH 16/32] 2 person login --- .../dialog_widgets/push_request_dialog.dart | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/lib/widgets/dialog_widgets/push_request_dialog.dart b/lib/widgets/dialog_widgets/push_request_dialog.dart index 41f625044..dc0c66ebc 100644 --- a/lib/widgets/dialog_widgets/push_request_dialog.dart +++ b/lib/widgets/dialog_widgets/push_request_dialog.dart @@ -27,7 +27,7 @@ class _PushRequestDialogState extends ConsumerState { double get lineHeight => Theme.of(context).textTheme.titleLarge?.fontSize ?? 16; double get spacerHeight => lineHeight * 0.5; - WidgetStateProperty get buttonShape => WidgetStateProperty.all( + static WidgetStateProperty buttonShape(BuildContext context) => WidgetStateProperty.all( Theme.of(context).elevatedButtonTheme.style?.shape?.resolve({})?.copyWith( side: BorderSide(color: Theme.of(context).colorScheme.onPrimary, width: 2.5), ), @@ -116,7 +116,7 @@ class _PushRequestDialogState extends ConsumerState { : SizedBox( // Accept button child: PressButton( - style: ButtonStyle(shape: buttonShape), + style: ButtonStyle(shape: buttonShape(context)), onPressed: () async { if (token.isLocked && await lockAuth(localizedReason: localizations.authToAcceptPushRequest) == false) { return; @@ -156,7 +156,7 @@ class _PushRequestDialogState extends ConsumerState { backgroundColor: WidgetStateProperty.all( Theme.of(context).colorScheme.errorContainer, ), - shape: buttonShape, + shape: buttonShape(context), ), onPressed: () async { if (token.isLocked && await lockAuth(localizedReason: localizations.authToDeclinePushRequest) == false) { @@ -222,7 +222,7 @@ class _PushRequestDialogState extends ConsumerState { Expanded( flex: 6, child: PressButton( - style: ButtonStyle(shape: buttonShape), + style: ButtonStyle(shape: buttonShape(context)), onPressed: () async { if (pushToken.isLocked && await lockAuth(localizedReason: localizations.authToDeclinePushRequest) == false) { return; @@ -264,7 +264,7 @@ class _PushRequestDialogState extends ConsumerState { child: PressButton( style: ButtonStyle( backgroundColor: WidgetStateProperty.all(Theme.of(context).colorScheme.errorContainer), - shape: buttonShape, + shape: buttonShape(context), ), onPressed: () async { //TODO: Notify issuer @@ -324,32 +324,26 @@ class _AnswerSelectionWidgetState extends State> { Widget build(BuildContext context) { final children = []; final possibleAnswers = widget.possibleAnswers.toList(); - const numPerRow = 4; + final totalAnswersNum = possibleAnswers.length; + const numPerRow = 3; while (possibleAnswers.isNotEmpty) { final maxThisRow = possibleAnswers.length == numPerRow + 1 ? min(possibleAnswers.length, (numPerRow / 2).ceil()) : min(possibleAnswers.length, numPerRow); final answersThisRow = possibleAnswers.sublist(0, maxThisRow); possibleAnswers.removeRange(0, maxThisRow); + final spacer = (maxThisRow != numPerRow && totalAnswersNum > maxThisRow) + ? Expanded(flex: (numPerRow - answersThisRow.length) * answersThisRow.length, child: const SizedBox()) + : const SizedBox(); children.add( Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - if (maxThisRow != numPerRow) const Expanded(child: SizedBox()), + spacer, for (final possibleAnswer in answersThisRow) Expanded( - flex: 4, + flex: answersThisRow.length * 2, child: PressButton( - style: ButtonStyle( - shape: WidgetStateProperty.all( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(999), - side: BorderSide( - color: Theme.of(context).colorScheme.onPrimary, - width: 2.5, - ), - ), - ), - ), + style: ButtonStyle(shape: _PushRequestDialogState.buttonShape(context)), onPressed: () => widget.onAnswerSelected(possibleAnswer), child: Padding( padding: EdgeInsets.symmetric(vertical: spacerHeight), @@ -369,7 +363,7 @@ class _AnswerSelectionWidgetState extends State> { ), ), ), - if (maxThisRow != numPerRow) const Expanded(child: SizedBox()), + spacer, ], ), ); From e242acf3c067f2b2c7ed69f05d01561fcb2ba59c Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Wed, 29 May 2024 11:49:05 +0200 Subject: [PATCH 17/32] 2 person login --- lib/state_notifiers/push_request_notifier.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/state_notifiers/push_request_notifier.dart b/lib/state_notifiers/push_request_notifier.dart index 0b05508ad..937577caf 100644 --- a/lib/state_notifiers/push_request_notifier.dart +++ b/lib/state_notifiers/push_request_notifier.dart @@ -220,11 +220,11 @@ class PushRequestNotifier extends StateNotifier { /// It should be still in the CustomIntBuffer of the state. Future accept(PushToken pushToken, PushRequest pushRequest, {String? selectedAnswer}) async { if (pushRequest.accepted != null) { - Logger.warning('The push request is already accepted or declined.', name: 'push_request_notifier.dart#decline'); + Logger.warning('The push request is already accepted or declined.', name: 'push_request_notifier.dart#accept'); return false; } - Logger.info('Decline push request.', name: 'push_request_notifier.dart#decline'); + Logger.info('Accept push request.', name: 'push_request_notifier.dart#accept'); final updated = await _updatePushRequest(pushRequest, (p0) async { final updated = p0.copyWith(accepted: true, selectedAnswer: () => selectedAnswer); final success = await _handleReaction(pushRequest: updated, token: pushToken); @@ -339,7 +339,7 @@ class PushRequestNotifier extends StateNotifier { body['answer'] = pushRequest.selectedAnswer!; msg += '|${pushRequest.selectedAnswer!}'; } - + Logger.warning('Signature message: $msg', name: 'token_widgets.dart#handleReaction'); String? signature = await _rsaUtils.trySignWithToken(token, msg); if (signature == null) { Logger.warning('Failed to sign push request response.', name: 'token_widgets.dart#handleReaction'); From 9f92cf3596a4debc2bd2060eb65ea26b577fec9a Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Wed, 29 May 2024 12:04:45 +0200 Subject: [PATCH 18/32] Update test-integration.yaml --- .github/workflows/test-integration.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index f8dd73a3b..5c35db750 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -10,7 +10,7 @@ jobs: timeout-minutes: 60 strategy: matrix: - api-level: [21, 30, 34] # [minSdk, most used, newest] + api-level: [30] # [ most used ] steps: - name: Delete unnecessary tools 🔧 uses: jlumbroso/free-disk-space@v1.3.1 @@ -47,4 +47,4 @@ jobs: disable-animations: true disk-size: 6000M heap-size: 600M - script: flutter test integration_test --flavor netknights \ No newline at end of file + script: flutter test integration_test --flavor netknights From c4cdda1a7cf01d2a6b1f0656a988e3ba8c3669fa Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Wed, 29 May 2024 17:36:48 +0200 Subject: [PATCH 19/32] improved logging --- lib/utils/network_utils.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/utils/network_utils.dart b/lib/utils/network_utils.dart index 143ae09bb..c2ecf9768 100644 --- a/lib/utils/network_utils.dart +++ b/lib/utils/network_utils.dart @@ -125,6 +125,7 @@ class PrivacyIdeaIOClient { 'Received unexpected response', name: 'utils.dart#doPost', error: 'Status code: ${response.statusCode}' '\nPosted body: $body' '\nResponse: ${response.body}\n', + stackTrace: StackTrace.current, ); } ioClient.close(); From 957c04197815de6b1868d26466da22bac9ee30cf Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Wed, 29 May 2024 17:37:04 +0200 Subject: [PATCH 20/32] removed wrong log --- lib/repo/secure_token_repository.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/repo/secure_token_repository.dart b/lib/repo/secure_token_repository.dart index c302554df..073ca5145 100644 --- a/lib/repo/secure_token_repository.dart +++ b/lib/repo/secure_token_repository.dart @@ -100,9 +100,6 @@ class SecureTokenRepository implements TokenRepository { } if (valueJson == null || !valueJson.containsKey('type')) { - Logger.warning( - 'Could not deserialize token from secure storage. Value: $value\nserializedToken = $valueJson\ncontainsKey(type) = ${valueJson?.containsKey('type')} ', - name: 'secure_token_repository.dart#loadAllTokens'); // If valueJson is null or does not contain a type, it can't be a token. Skip it. continue; } From 502bbcb4411e6fdb73066cc0bce76593e0c898e4 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Wed, 29 May 2024 17:37:30 +0200 Subject: [PATCH 21/32] fixed minor issue --- lib/state_notifiers/token_notifier.dart | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/state_notifiers/token_notifier.dart b/lib/state_notifiers/token_notifier.dart index d48ff3387..7be86f3e2 100644 --- a/lib/state_notifiers/token_notifier.dart +++ b/lib/state_notifiers/token_notifier.dart @@ -476,19 +476,20 @@ class TokenNotifier extends StateNotifier { // TODO What to do with poll only tokens if google-services is used? Logger.warning('SSLVerify: ${pushToken.sslVerify}', name: 'token_notifier.dart#rolloutPushToken'); + final fbToken = await _firebaseUtils.getFBToken(); Response response = await _ioClient.doPost( sslVerify: pushToken.sslVerify, url: pushToken.url!, body: { 'enrollment_credential': pushToken.enrollmentCredentials, 'serial': pushToken.serial, - 'fbtoken': await _firebaseUtils.getFBToken(), + 'fbtoken': fbToken, 'pubkey': _rsaUtils.serializeRSAPublicKeyPKCS8(pushToken.rsaPublicTokenKey!), }, ); if (response.statusCode == 200) { - pushToken = await _updateToken(pushToken, (p0) => p0.copyWith(rolloutState: PushTokenRollOutState.parsingResponse)); + pushToken = await _updateToken(pushToken, (p0) => p0.copyWith(rolloutState: PushTokenRollOutState.parsingResponse, fbToken: fbToken)); if (pushToken == null) { Logger.warning('Tried to update a token that does not exist.', name: 'token_notifier.dart#rolloutPushToken'); return false; @@ -620,7 +621,10 @@ class TokenNotifier extends StateNotifier { continue; } Response response = await _ioClient.doPost( - sslVerify: p.sslVerify, url: p.url!, body: {'new_fb_token': firebaseToken, 'serial': p.serial, 'timestamp': timestamp, 'signature': signature}); + url: p.url!, + body: {'new_fb_token': firebaseToken, 'serial': p.serial, 'timestamp': timestamp, 'signature': signature}, + sslVerify: p.sslVerify, + ); if (response.statusCode == 200) { Logger.info('Updating firebase token for push token succeeded!', name: 'push_provider.dart#updateFirebaseToken'); _updateToken(p, (p0) => p0.copyWith(fbToken: firebaseToken)); From 624e4188fa5b4d9072f90ca08faccb57722b8467 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Fri, 31 May 2024 11:02:54 +0200 Subject: [PATCH 22/32] 2 person login --- lib/state_notifiers/push_request_notifier.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/state_notifiers/push_request_notifier.dart b/lib/state_notifiers/push_request_notifier.dart index 937577caf..0510025bd 100644 --- a/lib/state_notifiers/push_request_notifier.dart +++ b/lib/state_notifiers/push_request_notifier.dart @@ -324,7 +324,7 @@ class PushRequestNotifier extends StateNotifier { // serial= // signature= // decline=1 (optional) - // answer= (optional) + // presence_answer= (optional) final Map body = { 'nonce': pushRequest.nonce, 'serial': token.serial, @@ -336,7 +336,7 @@ class PushRequestNotifier extends StateNotifier { msg += '|decline'; } if (pushRequest.possibleAnswers != null && pushRequest.selectedAnswer != null) { - body['answer'] = pushRequest.selectedAnswer!; + body['presence_answer'] = pushRequest.selectedAnswer!; msg += '|${pushRequest.selectedAnswer!}'; } Logger.warning('Signature message: $msg', name: 'token_widgets.dart#handleReaction'); From 5cb6976cae12fbe6254cce8aa7fa210c57daf539 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Mon, 3 Jun 2024 09:13:41 +0200 Subject: [PATCH 23/32] Update test-integration.yaml --- .github/workflows/test-integration.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index 5c35db750..cbda802fe 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -44,6 +44,7 @@ jobs: with: api-level: ${{ matrix.api-level }} arch: x86_64 + profile: Nexus 5 disable-animations: true disk-size: 6000M heap-size: 600M From da8770d7861f806c655783d10a9d8a169ed84061 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Mon, 3 Jun 2024 09:48:42 +0200 Subject: [PATCH 24/32] Update test-integration.yaml --- .github/workflows/test-integration.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index cbda802fe..11e37dc12 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -28,16 +28,17 @@ jobs: - name: Set up JDK 17 uses: actions/setup-java@v4 - with: distribution: 'zulu' java-version: 17 + - name: Setup Flutter - uses: subosito/flutter-action@v2 with: flutter-version: '3.22.0' channel: 'stable' - + - run: flutter pub get + # Run integration test - name: Run Integration Tests uses: reactivecircus/android-emulator-runner@v2 From 385f15dc4b084ee03ec55ea427eaa25d5fc34de0 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Mon, 3 Jun 2024 09:51:23 +0200 Subject: [PATCH 25/32] Update test-integration.yaml --- .github/workflows/test-integration.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index 11e37dc12..5d9965791 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -33,7 +33,7 @@ jobs: java-version: 17 - name: Setup Flutter - - uses: subosito/flutter-action@v2 + uses: subosito/flutter-action@v2 with: flutter-version: '3.22.0' channel: 'stable' From 06ca3424251294cf637be2360af5b51e2df2ee27 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:21:01 +0200 Subject: [PATCH 26/32] Update test-integration.yaml --- .github/workflows/test-integration.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index 5d9965791..3ca729adc 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -10,7 +10,7 @@ jobs: timeout-minutes: 60 strategy: matrix: - api-level: [30] # [ most used ] + api-level: [26] # [ most used ] steps: - name: Delete unnecessary tools 🔧 uses: jlumbroso/free-disk-space@v1.3.1 @@ -45,7 +45,7 @@ jobs: with: api-level: ${{ matrix.api-level }} arch: x86_64 - profile: Nexus 5 + profile: Pixel 4 disable-animations: true disk-size: 6000M heap-size: 600M From 592c9830adddf85e40a3236c143c6169c4273174 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:08:43 +0200 Subject: [PATCH 27/32] Update test-integration.yaml --- .github/workflows/test-integration.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index 3ca729adc..e7f881cc2 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -45,7 +45,7 @@ jobs: with: api-level: ${{ matrix.api-level }} arch: x86_64 - profile: Pixel 4 + profile: Nexus 6 disable-animations: true disk-size: 6000M heap-size: 600M From 49e19a3e2c5710b49866e5fee714f521c22e84f6 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 4 Jun 2024 11:48:41 +0200 Subject: [PATCH 28/32] Update test-integration.yaml --- .github/workflows/test-integration.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index e7f881cc2..6787e0dff 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -49,4 +49,4 @@ jobs: disable-animations: true disk-size: 6000M heap-size: 600M - script: flutter test integration_test --flavor netknights + script: flutter test integration_test --flavor netknights --no-enable-impeller From e5dbf8a373c16facb6cacba96a407ed349cb1d8c Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 4 Jun 2024 12:10:10 +0200 Subject: [PATCH 29/32] Update test-integration.yaml --- .github/workflows/test-integration.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index 6787e0dff..6f2452d9c 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -46,7 +46,6 @@ jobs: api-level: ${{ matrix.api-level }} arch: x86_64 profile: Nexus 6 - disable-animations: true disk-size: 6000M heap-size: 600M script: flutter test integration_test --flavor netknights --no-enable-impeller From 57b793b8b037323891ed79a153a5423bbc5fb7da Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 4 Jun 2024 15:16:25 +0200 Subject: [PATCH 30/32] Update test-integration.yaml --- .github/workflows/test-integration.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index 6f2452d9c..605fef9ec 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -46,6 +46,4 @@ jobs: api-level: ${{ matrix.api-level }} arch: x86_64 profile: Nexus 6 - disk-size: 6000M - heap-size: 600M - script: flutter test integration_test --flavor netknights --no-enable-impeller + script: flutter test integration_test --flavor netknights From 8ccfacbc718fa9a37cb53151401b58f8dcfee218 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:14:46 +0200 Subject: [PATCH 31/32] Update test-integration.yaml --- .github/workflows/test-integration.yaml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index 605fef9ec..b408b3e7f 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -12,17 +12,6 @@ jobs: matrix: api-level: [26] # [ most used ] steps: - - name: Delete unnecessary tools 🔧 - uses: jlumbroso/free-disk-space@v1.3.1 - with: - android: false # Don't remove Android tools - tool-cache: true # Remove image tool cache - rm -rf "$AGENT_TOOLSDIRECTORY" - dotnet: true # rm -rf /usr/share/dotnet - haskell: true # rm -rf /opt/ghc... - swap-storage: true # rm -f /mnt/swapfile (4GiB) - docker-images: false # Takes 16s, enable if needed in the future - large-packages: false # includes google-cloud-sdk and it's slow - - name: Checkout uses: actions/checkout@v4 From 60c5d0e5096951670aeee4cc206ec972768caae0 Mon Sep 17 00:00:00 2001 From: Frank Merkel <138444693+frankmer@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:43:51 +0200 Subject: [PATCH 32/32] Update test-integration.yaml --- .github/workflows/test-integration.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index b408b3e7f..80161dd5d 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -12,6 +12,17 @@ jobs: matrix: api-level: [26] # [ most used ] steps: + - name: Delete unnecessary tools 🔧 + uses: jlumbroso/free-disk-space@v1.3.1 + with: + android: false # Don't remove Android tools + tool-cache: false # Don't remove image tool cache - rm -rf "$AGENT_TOOLSDIRECTORY" + dotnet: true # rm -rf /usr/share/dotnet + haskell: true # rm -rf /opt/ghc... + swap-storage: true # rm -f /mnt/swapfile (4GiB) + docker-images: false # Takes 16s, enable if needed in the future + large-packages: false # includes google-cloud-sdk and it's slow + - name: Checkout uses: actions/checkout@v4