CW-423 Use SensitiveClipboard for sensitive Stings (#1013)

* CW-423 Use SensitiveClipboard for sensitive Stings * CW-423 Bump Android Target and Min SDK * CW-423 Use Helper function for sensitive Clipboard

Konstantin Ullrich committed Aug 1, 2023 at 14:52 UTC c68baf72447001490ce691b0143cf6c992dfca65
8 files changed +67 -47
android/app/build.gradle
+2 -2
@@ -45,8 +45,8 @@ android {
45
46 defaultConfig {
47 applicationId appProperties['id']
48 - minSdkVersion 21
49 - targetSdkVersion 31
48 + minSdkVersion 24
49 + targetSdkVersion 33
50 versionCode flutterVersionCode.toInteger()
51 versionName flutterVersionName
52 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
lib/src/screens/backup/backup_page.dart
+20 -20
@@ -1,21 +1,22 @@
1 import 'dart:io';
2 +import 'package:cake_wallet/core/execution_state.dart';
3 +import 'package:cake_wallet/src/screens/base_page.dart';
4 +import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
5 +import 'package:cake_wallet/src/widgets/primary_button.dart';
6 +import 'package:cake_wallet/src/widgets/trail_button.dart';
7 +import 'package:cake_wallet/generated/i18n.dart';
8 import 'package:cake_wallet/palette.dart';
9 +import 'package:cake_wallet/routes.dart';
10 +import 'package:cake_wallet/utils/clipboard_util.dart';
11 import 'package:cake_wallet/utils/exception_handler.dart';
12 import 'package:cake_wallet/utils/share_util.dart';
13 +import 'package:cake_wallet/utils/show_bar.dart';
14 +import 'package:cake_wallet/utils/show_pop_up.dart';
15 +import 'package:cake_wallet/view_model/backup_view_model.dart';
16 import 'package:file_picker/file_picker.dart';
17 import 'package:flutter/material.dart';
18 import 'package:flutter/services.dart';
19 import 'package:flutter_mobx/flutter_mobx.dart';
9 -import 'package:cake_wallet/utils/show_bar.dart';
10 -import 'package:cake_wallet/routes.dart';
11 -import 'package:cake_wallet/generated/i18n.dart';
12 -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
13 -import 'package:cake_wallet/src/widgets/primary_button.dart';
14 -import 'package:cake_wallet/src/widgets/trail_button.dart';
15 -import 'package:cake_wallet/utils/show_pop_up.dart';
16 -import 'package:cake_wallet/view_model/backup_view_model.dart';
17 -import 'package:cake_wallet/core/execution_state.dart';
18 -import 'package:cake_wallet/src/screens/base_page.dart';
20 import 'package:permission_handler/permission_handler.dart';
21
22 class BackupPage extends BasePage {
@@ -52,7 +53,7 @@ class BackupPage extends BasePage {
53 child: Observer(
54 builder: (_) => GestureDetector(
55 onTap: () {
55 - Clipboard.setData(
56 + ClipboardUtil.setSensitiveDataToClipboard(
57 ClipboardData(text: backupViewModelBase.backupPassword));
58 showBar<void>(
59 context,
@@ -75,15 +76,14 @@ class BackupPage extends BasePage {
76 ]))),
77 Positioned(
78 child: Observer(
78 - builder: (_) => LoadingPrimaryButton(
79 - isLoading: backupViewModelBase.state is IsExecutingState,
80 - onPressed: () => onExportBackup(context),
81 - text: S.of(context).export_backup,
82 - color: Theme.of(context)
83 - .accentTextTheme!
84 - .bodyLarge!
85 - .color!,
86 - textColor: Colors.white)),
79 + builder: (_) => LoadingPrimaryButton(
80 + isLoading: backupViewModelBase.state is IsExecutingState,
81 + onPressed: () => onExportBackup(context),
82 + text: S.of(context).export_backup,
83 + color: Theme.of(context).accentTextTheme.bodyLarge!.color!,
84 + textColor: Colors.white,
85 + ),
86 + ),
87 bottom: 24,
88 left: 24,
89 right: 24,
lib/src/screens/seed/pre_seed_page.dart
+6 -6
@@ -1,11 +1,11 @@
1 -import 'package:cake_wallet/utils/responsive_layout_util.dart';
2 -import 'package:cw_core/wallet_type.dart';
1 +import 'package:cake_wallet/src/screens/base_page.dart';
2 +import 'package:cake_wallet/src/widgets/primary_button.dart';
3 +import 'package:cake_wallet/generated/i18n.dart';
4 import 'package:cake_wallet/routes.dart';
5 import 'package:cake_wallet/themes/theme_base.dart';
6 +import 'package:cake_wallet/utils/responsive_layout_util.dart';
7 +import 'package:cw_core/wallet_type.dart';
8 import 'package:flutter/material.dart';
6 -import 'package:cake_wallet/generated/i18n.dart';
7 -import 'package:cake_wallet/src/widgets/primary_button.dart';
8 -import 'package:cake_wallet/src/screens/base_page.dart';
9
10 class PreSeedPage extends BasePage {
11 PreSeedPage(this.type)
@@ -61,7 +61,7 @@ class PreSeedPage extends BasePage {
61 onPressed: () =>
62 Navigator.of(context).popAndPushNamed(Routes.seed, arguments: true),
63 text: S.of(context).pre_seed_button_text,
64 - color: Theme.of(context).accentTextTheme!.bodyLarge!.color!,
64 + color: Theme.of(context).accentTextTheme.bodyLarge!.color!,
65 textColor: Colors.white)
66 ],
67 ),
lib/src/screens/seed/wallet_seed_page.dart
+3 -3
@@ -1,6 +1,7 @@
1 import 'package:cake_wallet/palette.dart';
2 import 'package:cake_wallet/themes/theme_base.dart';
3 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
4 +import 'package:cake_wallet/utils/clipboard_util.dart';
5 import 'package:cake_wallet/utils/share_util.dart';
6 import 'package:cake_wallet/utils/responsive_layout_util.dart';
7 import 'package:cake_wallet/utils/show_bar.dart';
@@ -92,8 +93,7 @@ class WalletSeedPage extends BasePage {
93 mainAxisAlignment: MainAxisAlignment.spaceBetween,
94 children: <Widget>[
95 ConstrainedBox(
95 - constraints:
96 - BoxConstraints(maxHeight: MediaQuery.of(context).size.height * 0.3),
96 + constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.height * 0.3),
97 child: AspectRatio(aspectRatio: 1, child: image),
98 ),
99 Observer(builder: (_) {
@@ -159,7 +159,7 @@ class WalletSeedPage extends BasePage {
159 child: Builder(
160 builder: (context) => PrimaryButton(
161 onPressed: () {
162 - Clipboard.setData(
162 + ClipboardUtil.setSensitiveDataToClipboard(
163 ClipboardData(text: walletSeedViewModel.seed));
164 showBar<void>(context, S.of(context).copied_to_clipboard);
165 },
lib/src/screens/setup_2fa/setup_2fa_qr_page.dart
+11 -8
@@ -1,16 +1,18 @@
1 import 'package:cake_wallet/core/totp_request_details.dart';
2 -import 'package:flutter/material.dart';
3 -import 'package:flutter/services.dart';
4 -import 'package:cake_wallet/generated/i18n.dart';
5 -import 'package:cake_wallet/routes.dart';
2 import 'package:cake_wallet/src/screens/base_page.dart';
3 import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart';
4 +import 'package:cake_wallet/src/widgets/primary_button.dart';
5 +import 'package:cake_wallet/src/widgets/standard_list.dart';
6 +import 'package:cake_wallet/generated/i18n.dart';
7 +import 'package:cake_wallet/palette.dart';
8 +import 'package:cake_wallet/routes.dart';
9 +import 'package:cake_wallet/utils/clipboard_util.dart';
10 import 'package:cake_wallet/utils/show_bar.dart';
11 import 'package:cake_wallet/view_model/set_up_2fa_viewmodel.dart';
12 +import 'package:flutter/material.dart';
13 +import 'package:flutter/services.dart';
14 import 'package:qr_flutter/qr_flutter.dart' as qr;
11 -import '../../../palette.dart';
12 -import '../../widgets/primary_button.dart';
13 -import '../../widgets/standard_list.dart';
15 +
16
17 class Setup2FAQRPage extends BasePage {
18 Setup2FAQRPage({required this.setup2FAViewModel});
@@ -106,7 +108,8 @@ class Setup2FAQRPage extends BasePage {
108 height: 32,
109 child: InkWell(
110 onTap: () {
109 - Clipboard.setData(ClipboardData(text: '${setup2FAViewModel.secretKey}'));
111 + ClipboardUtil.setSensitiveDataToClipboard(
112 + ClipboardData(text: '${setup2FAViewModel.secretKey}'));
113 showBar<void>(context, S.of(context).copied_to_clipboard);
114 },
115 child: Container(
lib/src/screens/wallet_keys/wallet_keys_page.dart
+9 -8
@@ -1,16 +1,17 @@
1 import 'package:auto_size_text/auto_size_text.dart';
2 import 'package:cake_wallet/entities/qr_view_data.dart';
3 +import 'package:cake_wallet/src/screens/base_page.dart';
4 +import 'package:cake_wallet/src/widgets/list_row.dart';
5 import 'package:cake_wallet/src/widgets/section_divider.dart';
6 +import 'package:cake_wallet/generated/i18n.dart';
7 +import 'package:cake_wallet/routes.dart';
8 +import 'package:cake_wallet/utils/clipboard_util.dart';
9 import 'package:cake_wallet/utils/show_bar.dart';
10 +import 'package:cake_wallet/view_model/wallet_keys_view_model.dart';
11 import 'package:device_display_brightness/device_display_brightness.dart';
12 import 'package:flutter/material.dart';
13 import 'package:flutter/services.dart';
14 import 'package:flutter_mobx/flutter_mobx.dart';
9 -import 'package:cake_wallet/generated/i18n.dart';
10 -import 'package:cake_wallet/src/screens/base_page.dart';
11 -import 'package:cake_wallet/src/widgets/list_row.dart';
12 -import 'package:cake_wallet/view_model/wallet_keys_view_model.dart';
13 -import 'package:cake_wallet/routes.dart';
15 import 'package:qr_flutter/qr_flutter.dart';
16
17 class WalletKeysPage extends BasePage {
@@ -56,7 +57,7 @@ class WalletKeysPage extends BasePage {
57 width: double.infinity,
58 decoration: BoxDecoration(
59 borderRadius: BorderRadius.circular(12.0),
59 - color: Theme.of(context).accentTextTheme!.bodySmall!.color!,
60 + color: Theme.of(context).accentTextTheme.bodySmall!.color!,
61 ),
62 child: Center(
63 child: Padding(
@@ -84,7 +85,7 @@ class WalletKeysPage extends BasePage {
85 separatorBuilder: (context, index) => Container(
86 height: 1,
87 padding: EdgeInsets.only(left: 24),
87 - color: Theme.of(context).accentTextTheme!.titleLarge!.backgroundColor!,
88 + color: Theme.of(context).accentTextTheme.titleLarge!.backgroundColor!,
89 child: const SectionDivider(),
90 ),
91 itemCount: walletKeysViewModel.items.length,
@@ -93,7 +94,7 @@ class WalletKeysPage extends BasePage {
94
95 return GestureDetector(
96 onTap: () {
96 - Clipboard.setData(ClipboardData(text: item.value));
97 + ClipboardUtil.setSensitiveDataToClipboard(ClipboardData(text: item.value));
98 showBar<void>(context, S.of(context).copied_key_to_clipboard(item.title));
99 },
100 child: ListRow(
lib/utils/clipboard_util.dart new
+15
@@ -0,0 +1,15 @@
1 +import 'package:flutter/services.dart';
2 +
3 +import 'package:cake_wallet/utils/device_info.dart';
4 +import 'package:sensitive_clipboard/sensitive_clipboard.dart';
5 +
6 +class ClipboardUtil {
7 + static Future<void> setSensitiveDataToClipboard(ClipboardData data) async {
8 + if (DeviceInfo.instance.isMobile) {
9 + await SensitiveClipboard.copy(data.text);
10 + return;
11 + }
12 +
13 + return Clipboard.setData(data);
14 + }
15 +}
pubspec_base.yaml
+1
@@ -81,6 +81,7 @@ dependencies:
81 path_provider_android: 2.0.24
82 shared_preferences_android: 2.0.17
83 url_launcher_android: 6.0.24
84 + sensitive_clipboard: ^1.0.0
85 bitcoin_flutter:
86 git:
87 url: https://github.com/cake-tech/bitcoin_flutter.git