pull/37/head
Kherel 2021-09-15 15:15:54 +02:00
parent 90d64d8f51
commit d0023e5718
26 changed files with 200 additions and 19 deletions

View File

@ -39,6 +39,16 @@
"generate_key": "Generate key", "generate_key": "Generate key",
"generate_key_text": "You can generate ssh key", "generate_key_text": "You can generate ssh key",
"console": "Console", "console": "Console",
"remove": "Remove",
"enable": "Enable",
"ok": "ok",
"continue": "Continue",
"ssh_key_exist_text": "You have generated ssh key",
"yes_delete": "Yes, delete my SSH key",
"share": "Share",
"copy_buffer": "Copy to buffer",
"copied_ssh": "SSH copied to clipboard",
"delete_ssh_text": "Delete SSH key?",
"about_app_page": { "about_app_page": {
"text": "Application version v.{}" "text": "Application version v.{}"
}, },

View File

@ -39,6 +39,16 @@
"create_ssh_key": "Создать ssh ключ", "create_ssh_key": "Создать ssh ключ",
"generate_key": "Сгенерировать ключ", "generate_key": "Сгенерировать ключ",
"generate_key_text": "Вы сможете сгенерировать ключ", "generate_key_text": "Вы сможете сгенерировать ключ",
"remove": "Отключить",
"enable": "Включить",
"ok": "ok",
"continue": "Продолжить",
"ssh_key_exist_text": "У вас уже есть сгенерированный ssk ключ",
"yes_delete": "Да, удалить",
"share": "Поделиться",
"copy_buffer": "Копировать в буфер",
"copied_ssh": "SSH копировано в буфер",
"delete_ssh_text": "Удалить SSH ключ?",
"about_app_page": { "about_app_page": {
"text": "Версия приложения: v.{}" "text": "Версия приложения: v.{}"
}, },

View File

@ -2,6 +2,8 @@ PODS:
- Flutter (1.0.0) - Flutter (1.0.0)
- flutter_secure_storage (3.3.1): - flutter_secure_storage (3.3.1):
- Flutter - Flutter
- local_auth (0.0.1):
- Flutter
- package_info (0.0.1): - package_info (0.0.1):
- Flutter - Flutter
- path_provider (0.0.1): - path_provider (0.0.1):
@ -18,6 +20,7 @@ PODS:
DEPENDENCIES: DEPENDENCIES:
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- local_auth (from `.symlinks/plugins/local_auth/ios`)
- package_info (from `.symlinks/plugins/package_info/ios`) - package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`) - path_provider (from `.symlinks/plugins/path_provider/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`)
@ -30,6 +33,8 @@ EXTERNAL SOURCES:
:path: Flutter :path: Flutter
flutter_secure_storage: flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios" :path: ".symlinks/plugins/flutter_secure_storage/ios"
local_auth:
:path: ".symlinks/plugins/local_auth/ios"
package_info: package_info:
:path: ".symlinks/plugins/package_info/ios" :path: ".symlinks/plugins/package_info/ios"
path_provider: path_provider:
@ -46,6 +51,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68

View File

@ -361,6 +361,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = UVNTKR53DD;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -499,6 +500,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = UVNTKR53DD;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -529,6 +531,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = UVNTKR53DD;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 354 B

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 608 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 B

After

Width:  |  Height:  |  Size: 1007 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 907 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 608 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -24,6 +24,7 @@ class HiveConfig {
var cipher = HiveAesCipher(await getEncriptedKey(BNames.key)); var cipher = HiveAesCipher(await getEncriptedKey(BNames.key));
await Hive.openBox(BNames.appConfig, encryptionCipher: cipher); await Hive.openBox(BNames.appConfig, encryptionCipher: cipher);
var sshCipher = HiveAesCipher(await getEncriptedKey(BNames.sshEnckey)); var sshCipher = HiveAesCipher(await getEncriptedKey(BNames.sshEnckey));
await Hive.openBox(BNames.sshConfig, encryptionCipher: sshCipher); await Hive.openBox(BNames.sshConfig, encryptionCipher: sshCipher);
} }

View File

@ -33,7 +33,7 @@ class ServerApi extends ApiMap {
var client = await getClient(); var client = await getClient();
try { try {
response = await client.get('/serviceStatus'); response = await client.get('/services/status');
res = response.statusCode == HttpStatus.ok; res = response.statusCode == HttpStatus.ok;
} catch (e) { } catch (e) {
res = false; res = false;
@ -49,7 +49,7 @@ class ServerApi extends ApiMap {
var client = await getClient(); var client = await getClient();
try { try {
response = await client.post( response = await client.post(
'/createUser', '/users/create',
options: Options( options: Options(
headers: { headers: {
"X-User": user.login, "X-User": user.login,
@ -78,7 +78,7 @@ class ServerApi extends ApiMap {
var client = await getClient(); var client = await getClient();
try { try {
response = await client.get( response = await client.get(
'/apply', '/system/configuration/apply',
); );
res = response.statusCode == HttpStatus.ok; res = response.statusCode == HttpStatus.ok;

View File

@ -1,5 +1,3 @@
import 'dart:developer';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:pointycastle/pointycastle.dart'; import 'package:pointycastle/pointycastle.dart';
import 'package:rsa_encrypt/rsa_encrypt.dart'; import 'package:rsa_encrypt/rsa_encrypt.dart';
@ -30,4 +28,12 @@ class SSHModel {
savedPrivateKey = _box.get(BNames.sshPrivateKey); savedPrivateKey = _box.get(BNames.sshPrivateKey);
savedPubKey = _box.get(BNames.sshPublicKey); savedPubKey = _box.get(BNames.sshPublicKey);
} }
bool get isSSHKeyGenerated => savedPrivateKey != null && savedPubKey != null;
clear() async {
savedPrivateKey = null;
savedPubKey = null;
await _box.clear();
}
} }

View File

@ -119,7 +119,7 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
], ],
), ),
), ),
// deleteServer(context) deleteServer(context)
], ],
), ),
); );

View File

@ -1,11 +1,16 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:ionicons/ionicons.dart'; import 'package:ionicons/ionicons.dart';
import 'package:selfprivacy/config/brand_colors.dart'; import 'package:selfprivacy/config/brand_colors.dart';
import 'package:selfprivacy/config/brand_theme.dart'; import 'package:selfprivacy/config/brand_theme.dart';
import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/config/text_themes.dart'; import 'package:selfprivacy/config/text_themes.dart';
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
import 'package:selfprivacy/logic/get_it/ssh_helper.dart';
import 'package:selfprivacy/logic/models/job.dart'; import 'package:selfprivacy/logic/models/job.dart';
import 'package:selfprivacy/logic/models/state_types.dart'; import 'package:selfprivacy/logic/models/state_types.dart';
import 'package:selfprivacy/ui/components/action_button/action_button.dart';
import 'package:selfprivacy/ui/components/brand_alert/brand_alert.dart';
import 'package:selfprivacy/ui/components/brand_button/brand_button.dart'; import 'package:selfprivacy/ui/components/brand_button/brand_button.dart';
import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart'; import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart'; import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
@ -17,6 +22,7 @@ import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart';
import 'package:selfprivacy/ui/pages/rootRoute.dart'; import 'package:selfprivacy/ui/pages/rootRoute.dart';
import 'package:selfprivacy/utils/route_transitions/basic.dart'; import 'package:selfprivacy/utils/route_transitions/basic.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:share_plus/share_plus.dart';
import 'about/about.dart'; import 'about/about.dart';
import 'app_settings/app_setting.dart'; import 'app_settings/app_setting.dart';
@ -79,19 +85,66 @@ class MorePage extends StatelessWidget {
title: 'more.create_ssh_key'.tr(), title: 'more.create_ssh_key'.tr(),
iconData: Ionicons.key_outline, iconData: Ionicons.key_outline,
onTap: () { onTap: () {
showDialog<void>( if (getIt<SSHModel>().isSSHKeyGenerated) {
context: context, showDialog<void>(
builder: (BuildContext context) { context: context,
return _MoreDetails( builder: (BuildContext context) {
title: 'more.create_ssh_key'.tr(), return _SSHExitsDetails(
icon: Ionicons.key_outline, onShareTap: () {
onTap: () { Share.share(getIt<SSHModel>().savedPrivateKey!);
jobsCubit.createShhJobIfNotExist(CreateSSHKeyJob()); },
}, onDeleteTap: () {
text: 'more.generate_key_text'.tr(), showDialog(
); context: context,
}, builder: (_) {
); return BrandAlert(
title: 'modals.3'.tr(),
contentText: 'more.delete_ssh_text'.tr(),
acitons: [
ActionButton(
text: 'more.yes_delete'.tr(),
isRed: true,
onPressed: () {
getIt<SSHModel>().clear();
Navigator.of(context).pop();
}),
ActionButton(
text: 'basis.cancel'.tr(),
),
],
);
},
);
},
onCopyTap: () {
Clipboard.setData(ClipboardData(
text: getIt<SSHModel>().savedPrivateKey!));
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('more.copied_ssh'.tr()),
duration: const Duration(seconds: 2),
),
);
},
);
},
);
} else {
showDialog<void>(
context: context,
builder: (BuildContext context) {
return _MoreDetails(
title: 'more.create_ssh_key'.tr(),
icon: Ionicons.key_outline,
onTap: () {
jobsCubit
.createShhJobIfNotExist(CreateSSHKeyJob());
},
text: 'more.generate_key_text'.tr(),
);
},
);
}
}, },
), ),
], ],
@ -103,6 +156,83 @@ class MorePage extends StatelessWidget {
} }
} }
class _SSHExitsDetails extends StatelessWidget {
const _SSHExitsDetails({
Key? key,
required this.onDeleteTap,
required this.onShareTap,
required this.onCopyTap,
}) : super(key: key);
final Function onDeleteTap;
final Function onShareTap;
final Function onCopyTap;
@override
Widget build(BuildContext context) {
var textStyle = body1Style.copyWith(
color: Theme.of(context).brightness == Brightness.dark
? Colors.white
: BrandColors.black);
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
child: SingleChildScrollView(
child: Container(
width: 350,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: paddingH15V30,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(height: 10),
Text(
'more.ssh_key_exist_text'.tr(),
style: textStyle,
),
SizedBox(height: 10),
Container(
child: BrandButton.text(
onPressed: () {
Navigator.of(context).pop();
onShareTap();
},
title: 'more.share'.tr(),
),
),
Container(
alignment: Alignment.centerLeft,
child: BrandButton.text(
onPressed: () {
Navigator.of(context).pop();
onDeleteTap();
},
title: 'basis.delete'.tr(),
),
),
Container(
child: BrandButton.text(
onPressed: () {
Navigator.of(context).pop();
onCopyTap();
},
title: 'more.copy_buffer'.tr(),
),
),
],
),
)
],
),
),
),
);
}
}
class _MoreDetails extends StatelessWidget { class _MoreDetails extends StatelessWidget {
const _MoreDetails({ const _MoreDetails({
Key? key, Key? key,

View File

@ -333,6 +333,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.5" version: "0.6.5"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
flutter_secure_storage: flutter_secure_storage:
dependency: "direct main" dependency: "direct main"
description: description:
@ -469,6 +476,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.1.4" version: "4.1.4"
local_auth:
dependency: "direct main"
description:
name: local_auth
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.7"
logging: logging:
dependency: transitive dependency: transitive
description: description:

View File

@ -38,6 +38,7 @@ dependencies:
pointycastle: ^3.3.2 pointycastle: ^3.3.2
rsa_encrypt: ^2.0.0 rsa_encrypt: ^2.0.0
ssh_key: ^0.7.0 ssh_key: ^0.7.0
local_auth: ^1.1.7
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: