diff --git a/assets/images/pics/myprofile.png b/assets/images/pics/myprofile.png new file mode 100644 index 00000000..d1f1f3d0 Binary files /dev/null and b/assets/images/pics/myprofile.png differ diff --git a/assets/images/pics/permissions.png b/assets/images/pics/permissions.png new file mode 100644 index 00000000..4b9dd3f7 Binary files /dev/null and b/assets/images/pics/permissions.png differ diff --git a/assets/markdown/how_cloudflare-ru.md b/assets/markdown/how_cloudflare-ru.md index 7da91f77..d6cc0072 100644 --- a/assets/markdown/how_cloudflare-ru.md +++ b/assets/markdown/how_cloudflare-ru.md @@ -1,11 +1,14 @@ ### Как получить Cloudflare API Token 1. Переходим по [ссылке](https://dash.cloudflare.com/) и авторизуемся в ранее созданном аккаунте. https://dash.cloudflare.com/ -В правом углу кликаем на иконку профиля (человечек в кружочке). Для мобильной версии сайта, в верхнем левом углу, нажимаем кнопку **Меню** (три горизонтальных полоски), в выпавшем меню, ищем пункт **My Profile**. +2. В правом верхнем углу кликаем на иконку профиля (для мобильной версии сайта: в верхнем левом углу нажимаем кнопку **Меню** с тремя горизонтальными полосками). В выпавшем меню кликаем на пункт **My Profile**. +![My profile](resource:assets/images/pics/myprofile.png) 3. Нам предлагается на выбор, четыре категории настройки: **Preferences**, **Authentication**, **API Tokens**, **Sessions**. Выбираем **API Tokens**. 4. Самым первым пунктом видим кнопку **Create Token**. С полной уверенностью в себе и желанием обрести приватность, нажимаем на неё. 5. Спускаемся в самый низ и видим поле **Create Custom Token** и кнопку **Get Started** с правой стороны. Нажимаем. 6. В поле **Token Name** даём своему токену имя. Можете покреативить и отнестись к этому как к наименованию домашнего зверька :) -7. Далее, у нас **Permissions**. В первом поле выбираем Zone. Во втором поле, по центру, выбираем **DNS**. В последнем поле выбираем **Edit**. +7. Далее, у нас **Permissions**. В первом поле выбираем **Zone**. Во втором поле, по центру, выбираем **DNS**. В последнем поле выбираем **Edit**. +8. Нажимаем на синюю надпись снизу **+ Add more** (сразу же под левым полем которое мы заполняли ранее). Вуаля, у нас появились новые поля. Заполняем по аналогии с предыдущим пунктом, в первом поле выбираем **Zone**, во-втором тоже **Zone**. А уже в третьем нажимаем на **Read**. Давайте сверим с тем, что у вас получилось: +![Permissions](resource:assets/images/pics/permissions.png) 8. Далее смотрим на **Zone Resources**. Под этой надписью есть строка с двумя полями. В первом должно быть **Include**, а во втором — **Specific Zone**. Как только Вы выберите **Specific Zone**, справа появится ещё одно поле. В нём выбираем наш домен. 9. Листаем в самый низ и нажимаем на синюю кнопку **Continue to Summary**. 10. Проверяем, всё ли мы правильно выбрали. Должна присутствовать подобная строка: ваш.домен — **DNS:Edit, Zone:Read**. diff --git a/assets/translations/en.json b/assets/translations/en.json index 708da384..53fb30d9 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -303,7 +303,7 @@ "22": "Create master account", "23": "Enter a nickname and strong password", "finish": "Everything is initialized", - "checks": "Checks have been completed \n{} ouf of {}" + "checks": "Checks have been completed \n{} out of {}" }, "recovering": { "recovery_main_header": "Connect to an existing server", diff --git a/lib/logic/api_maps/rest_maps/server.dart b/lib/logic/api_maps/rest_maps/server.dart index 4139d3e2..b16d46d3 100644 --- a/lib/logic/api_maps/rest_maps/server.dart +++ b/lib/logic/api_maps/rest_maps/server.dart @@ -46,7 +46,10 @@ class ServerApi extends ApiMap { @override BaseOptions get options { - BaseOptions options = BaseOptions(); + BaseOptions options = BaseOptions( + connectTimeout: 10000, + receiveTimeout: 10000, + ); if (isWithToken) { final ServerDomain? serverDomain = getIt().serverDomain; @@ -55,6 +58,8 @@ class ServerApi extends ApiMap { options = BaseOptions( baseUrl: 'https://api.$domainName', + connectTimeout: 10000, + receiveTimeout: 10000, headers: { 'Authorization': 'Bearer $apiToken', }, @@ -64,6 +69,8 @@ class ServerApi extends ApiMap { if (overrideDomain != null) { options = BaseOptions( baseUrl: 'https://api.$overrideDomain', + connectTimeout: 10000, + receiveTimeout: 10000, headers: customToken != null ? {'Authorization': 'Bearer $customToken'} : null, @@ -618,7 +625,7 @@ class ServerApi extends ApiMap { } } - Future getDkim() async { + Future getDkim() async { Response response; final Dio client = await getClient(); @@ -626,13 +633,13 @@ class ServerApi extends ApiMap { response = await client.get('/services/mailserver/dkim'); } on DioError catch (e) { print(e.message); - return null; + throw Exception('No DKIM key found'); } finally { close(client); } if (response.statusCode == null) { - return null; + throw Exception('No DKIM key found'); } if (response.statusCode == HttpStatus.notFound || response.data == null) { @@ -640,7 +647,7 @@ class ServerApi extends ApiMap { } if (response.statusCode != HttpStatus.ok) { - return ''; + throw Exception('No DKIM key found'); } final Codec base64toString = utf8.fuse(base64); diff --git a/lib/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart b/lib/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart index 098db0f9..c28bfa5f 100644 --- a/lib/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart +++ b/lib/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart @@ -298,10 +298,6 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi { dataBase: newVolume, ); - if (details == null) { - deleteVolume(newVolume.id); - } - return details; } @@ -347,6 +343,8 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi { print('Decoded data: $data'); ServerHostingDetails? serverDetails; + DioError? hetznerError; + bool success = false; try { final Response serverCreateResponse = await client.post( @@ -362,16 +360,25 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi { apiToken: apiToken, provider: ServerProvider.hetzner, ); + success = true; } on DioError catch (e) { print(e); - deleteVolume(dataBase.id); - rethrow; + hetznerError = e; } catch (e) { print(e); } finally { client.close(); } + if (!success) { + await Future.delayed(const Duration(seconds: 10)); + await deleteVolume(dbId); + } + + if (hetznerError != null) { + throw hetznerError; + } + return serverDetails; } diff --git a/lib/logic/cubit/forms/user/ssh_form_cubit.dart b/lib/logic/cubit/forms/user/ssh_form_cubit.dart index ba38a642..b6493ee7 100644 --- a/lib/logic/cubit/forms/user/ssh_form_cubit.dart +++ b/lib/logic/cubit/forms/user/ssh_form_cubit.dart @@ -41,7 +41,8 @@ class SshFormCubit extends FormCubit { @override FutureOr onSubmit() { print(key.state.isValid); - jobsCubit.addJob(CreateSSHKeyJob(user: user, publicKey: key.state.value)); + jobsCubit + .addJob(CreateSSHKeyJob(user: user, publicKey: key.state.value.trim())); } late FieldCubit key; diff --git a/lib/logic/cubit/server_installation/server_installation_cubit.dart b/lib/logic/cubit/server_installation/server_installation_cubit.dart index c17c1ff2..a1b15e32 100644 --- a/lib/logic/cubit/server_installation/server_installation_cubit.dart +++ b/lib/logic/cubit/server_installation/server_installation_cubit.dart @@ -197,24 +197,10 @@ class ServerInstallationCubit extends Cubit { ); if (matches.values.every((final bool value) => value)) { - final ServerHostingDetails? server = await repository.startServer( + final ServerHostingDetails server = await repository.startServer( dataState.serverDetails!, ); - if (server == null) { - final ServerInstallationNotFinished newState = dataState.copyWith( - isLoading: false, - dnsMatches: matches, - ); - emit(newState); - runDelayed( - startServerIfDnsIsOkay, - const Duration(seconds: 30), - newState, - ); - return; - } - await repository.saveServerDetails(server); await repository.saveIsServerStarted(true); @@ -340,10 +326,22 @@ class ServerInstallationCubit extends Cubit { final bool isServerWorking = await repository.isHttpServerWorking(); if (isServerWorking) { - await repository.createDkimRecord(dataState.serverDomain!); - await repository.saveHasFinalChecked(true); - - emit(dataState.finish()); + bool dkimCreated = true; + try { + await repository.createDkimRecord(dataState.serverDomain!); + } catch (e) { + dkimCreated = false; + } + if (dkimCreated) { + await repository.saveHasFinalChecked(true); + emit(dataState.finish()); + } else { + runDelayed( + finishCheckIfServerIsOkay, + const Duration(seconds: 60), + dataState, + ); + } } else { runDelayed( finishCheckIfServerIsOkay, diff --git a/lib/logic/cubit/server_installation/server_installation_repository.dart b/lib/logic/cubit/server_installation/server_installation_repository.dart index f09599eb..e19b61ff 100644 --- a/lib/logic/cubit/server_installation/server_installation_repository.dart +++ b/lib/logic/cubit/server_installation/server_installation_repository.dart @@ -151,10 +151,10 @@ class ServerInstallationRepository { usersBox.clear(); } - Future startServer( + Future startServer( final ServerHostingDetails hetznerServer, ) async { - ServerHostingDetails? serverDetails; + ServerHostingDetails serverDetails; final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(); serverDetails = await api.powerOn(); @@ -359,20 +359,20 @@ class ServerInstallationRepository { dnsProviderApiFactory!.getDnsProvider(); final ServerApi api = ServerApi(); - final String? dkimRecordString = await api.getDkim(); + String dkimRecordString = ''; + try { + dkimRecordString = await api.getDkim(); + } catch (e) { + print(e); + rethrow; + } - await dnsProviderApi.setDkim(dkimRecordString ?? '', cloudFlareDomain); + await dnsProviderApi.setDkim(dkimRecordString, cloudFlareDomain); } Future isHttpServerWorking() async { final ServerApi api = ServerApi(); - final bool isHttpServerWorking = await api.isHttpServerWorking(); - try { - await api.getDkim(); - } catch (e) { - return false; - } - return isHttpServerWorking; + return api.isHttpServerWorking(); } Future restart() async { diff --git a/lib/logic/cubit/server_installation/server_installation_state.dart b/lib/logic/cubit/server_installation/server_installation_state.dart index 5bb59275..bb04c07d 100644 --- a/lib/logic/cubit/server_installation/server_installation_state.dart +++ b/lib/logic/cubit/server_installation/server_installation_state.dart @@ -35,11 +35,11 @@ abstract class ServerInstallationState extends Equatable { final bool isServerResetedFirstTime; final bool isServerResetedSecondTime; - bool get isProviderFilled => providerApiToken != null; - bool get isCloudFlareFilled => cloudFlareKey != null; - bool get isBackblazeFilled => backblazeCredential != null; - bool get isDomainFilled => serverDomain != null; - bool get isUserFilled => rootUser != null; + bool get isServerProviderFilled => providerApiToken != null; + bool get isDnsProviderFilled => cloudFlareKey != null; + bool get isBackupsProviderFilled => backblazeCredential != null; + bool get isDomainSelected => serverDomain != null; + bool get isPrimaryUserFilled => rootUser != null; bool get isServerCreated => serverDetails != null; bool get isFullyInitilized => _fulfilementList.every((final el) => el!); @@ -58,11 +58,11 @@ abstract class ServerInstallationState extends Equatable { List get _fulfilementList { final List res = [ - isProviderFilled, - isCloudFlareFilled, - isBackblazeFilled, - isDomainFilled, - isUserFilled, + isServerProviderFilled, + isDnsProviderFilled, + isBackupsProviderFilled, + isDomainSelected, + isPrimaryUserFilled, isServerCreated, isServerStarted, isServerResetedFirstTime, diff --git a/lib/ui/pages/setup/initializing.dart b/lib/ui/pages/setup/initializing.dart index b4a504b8..2cde89ce 100644 --- a/lib/ui/pages/setup/initializing.dart +++ b/lib/ui/pages/setup/initializing.dart @@ -42,7 +42,7 @@ class InitializingPage extends StatelessWidget { () => _stepCheck(cubit), () => _stepCheck(cubit), () => _stepCheck(cubit), - () => Center(child: Text('initializing.finish'.tr())) + () => _stepCheck(cubit) ][cubit.state.progress.index](); return BlocListener( @@ -60,7 +60,7 @@ class InitializingPage extends StatelessWidget { children: [ Padding( padding: paddingH15V0.copyWith(top: 10, bottom: 10), - child: cubit.state.isFullyInitilized + child: cubit.state is ServerInstallationFinished ? const SizedBox( height: 80, ) diff --git a/lib/utils/ui_helpers.dart b/lib/utils/ui_helpers.dart index c34721e1..f4d58a05 100644 --- a/lib/utils/ui_helpers.dart +++ b/lib/utils/ui_helpers.dart @@ -4,5 +4,5 @@ import 'package:selfprivacy/logic/cubit/server_installation/server_installation_ class UiHelpers { static String getDomainName(final ServerInstallationState config) => - config.isDomainFilled ? config.serverDomain!.domainName : 'example.com'; + config.isDomainSelected ? config.serverDomain!.domainName : 'example.com'; } diff --git a/pubspec.lock b/pubspec.lock index e40f6b5c..cb308ae6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -29,6 +29,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.3.1" + asn1lib: + dependency: transitive + description: + name: asn1lib + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" async: dependency: transitive description: @@ -77,7 +84,7 @@ packages: name: build_config url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.0.0" build_daemon: dependency: transitive description: @@ -98,7 +105,7 @@ packages: name: build_runner url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "2.1.11" build_runner_core: dependency: transitive description: @@ -168,14 +175,14 @@ packages: name: connectivity_plus url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.3.5" connectivity_plus_linux: dependency: transitive description: name: connectivity_plus_linux url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.3.1" connectivity_plus_macos: dependency: transitive description: @@ -196,7 +203,7 @@ packages: name: connectivity_plus_web url: "https://pub.dartlang.org" source: hosted - version: "1.2.3" + version: "1.2.2" connectivity_plus_windows: dependency: transitive description: @@ -239,6 +246,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" dart_style: dependency: transitive description: @@ -252,14 +266,14 @@ packages: name: dbus url: "https://pub.dartlang.org" source: hosted - version: "0.5.4" + version: "0.7.3" device_info_plus: dependency: "direct main" description: name: device_info_plus url: "https://pub.dartlang.org" source: hosted - version: "4.0.1" + version: "3.2.3" device_info_plus_linux: dependency: transitive description: @@ -294,7 +308,7 @@ packages: name: device_info_plus_windows url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "2.1.1" dio: dependency: "direct main" description: @@ -308,7 +322,7 @@ packages: name: dynamic_color url: "https://pub.dartlang.org" source: hosted - version: "1.4.0" + version: "1.2.2" easy_localization: dependency: "direct main" description: @@ -357,7 +371,7 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "1.2.1" file: dependency: transitive description: @@ -573,7 +587,7 @@ packages: name: graphql_codegen url: "https://pub.dartlang.org" source: hosted - version: "0.10.2" + version: "0.9.0" graphql_codegen_config: dependency: transitive description: @@ -608,7 +622,7 @@ packages: name: hive url: "https://pub.dartlang.org" source: hosted - version: "2.2.3" + version: "2.1.0" hive_flutter: dependency: "direct main" description: @@ -622,7 +636,7 @@ packages: name: hive_generator url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" + version: "1.1.2" http: dependency: transitive description: @@ -685,14 +699,14 @@ packages: name: json_annotation url: "https://pub.dartlang.org" source: hosted - version: "4.6.0" + version: "4.5.0" json_serializable: dependency: "direct dev" description: name: json_serializable url: "https://pub.dartlang.org" source: hosted - version: "6.3.1" + version: "6.2.0" lints: dependency: transitive description: @@ -804,7 +818,7 @@ packages: name: nm url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.5.0" node_preamble: dependency: transitive description: @@ -867,7 +881,7 @@ packages: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.1.7" + version: "2.1.6" path_provider_macos: dependency: transitive description: @@ -888,14 +902,7 @@ packages: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.11.1" + version: "2.0.6" petitparser: dependency: transitive description: @@ -966,6 +973,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" recase: dependency: transitive description: @@ -979,7 +993,7 @@ packages: name: rxdart url: "https://pub.dartlang.org" source: hosted - version: "0.27.5" + version: "0.27.4" share_plus: dependency: "direct main" description: @@ -1146,6 +1160,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.2" + ssh_key: + dependency: "direct main" + description: + name: ssh_key + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.1" stack_trace: dependency: transitive description: @@ -1230,6 +1251,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + tuple: + dependency: transitive + description: + name: tuple + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" typed_data: dependency: transitive description: @@ -1376,7 +1404,7 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.7.0" + version: "2.6.1" xdg_directories: dependency: transitive description: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 1feb1b08..070eb3b5 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,7 +7,6 @@ #include "generated_plugin_registrant.h" #include -#include #include #include #include @@ -15,8 +14,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { ConnectivityPlusWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); - DynamicColorPluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("DynamicColorPluginCApi")); FlutterSecureStorageWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); SystemThemePluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index fa5d72de..a26e37b0 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,7 +4,6 @@ list(APPEND FLUTTER_PLUGIN_LIST connectivity_plus_windows - dynamic_color flutter_secure_storage_windows system_theme url_launcher_windows