From 129c1bb4c6cbd91279e50fe488533a427633957b Mon Sep 17 00:00:00 2001 From: NaiJi Date: Sat, 14 May 2022 05:54:40 +0300 Subject: [PATCH] Refactor infrastructure Co-authored-by: Inex Code --- lib/config/hive_config.dart | 14 +- lib/logic/api_maps/backblaze.dart | 2 +- lib/logic/api_maps/cloudflare.dart | 4 +- lib/logic/api_maps/hetzner.dart | 9 +- lib/logic/api_maps/server.dart | 939 ++++++++---------- .../cubit/app_config/app_config_cubit.dart | 160 +-- .../app_config/app_config_repository.dart | 12 +- lib/logic/cubit/backups/backups_cubit.dart | 4 +- .../cubit/dns_records/dns_records_cubit.dart | 4 +- .../initializing/backblaze_form_cubit.dart | 2 +- .../setup/initializing/domain_cloudflare.dart | 2 +- .../initializing/root_user_form_cubit.dart | 2 +- .../recovery_domain_form_cubit.dart | 2 +- .../cubit/forms/user/ssh_form_cubit.dart | 2 +- .../cubit/forms/user/user_form_cubit.dart | 2 +- .../server_detailed_info_cubit.dart | 4 +- .../server_detailed_info_repository.dart | 4 +- lib/logic/cubit/users/users_cubit.dart | 2 +- lib/logic/get_it/api_config.dart | 8 +- lib/logic/models/hive/README.md | 13 + .../models/{ => hive}/backblaze_bucket.dart | 0 .../models/{ => hive}/backblaze_bucket.g.dart | 0 .../{ => hive}/backblaze_credential.dart | 0 .../{ => hive}/backblaze_credential.g.dart | 0 .../models/{ => hive}/server_details.dart | 19 +- .../models/{ => hive}/server_details.g.dart | 60 +- .../models/{ => hive}/server_domain.dart | 13 +- .../models/{ => hive}/server_domain.g.dart | 39 + lib/logic/models/{ => hive}/user.dart | 0 lib/logic/models/{ => hive}/user.g.dart | 0 lib/logic/models/job.dart | 2 +- lib/logic/models/{ => json}/api_token.dart | 0 lib/logic/models/{ => json}/api_token.g.dart | 0 .../{ => json}/auto_upgrade_settings.dart | 0 .../{ => json}/auto_upgrade_settings.g.dart | 0 lib/logic/models/{ => json}/backup.dart | 0 lib/logic/models/{ => json}/backup.g.dart | 0 lib/logic/models/{ => json}/device_token.dart | 0 .../models/{ => json}/device_token.g.dart | 0 lib/logic/models/{ => json}/dns_records.dart | 0 .../models/{ => json}/dns_records.g.dart | 0 .../{ => json}/hetzner_server_info.dart | 0 .../{ => json}/hetzner_server_info.g.dart | 0 .../{ => json}/recovery_token_status.dart | 0 .../{ => json}/recovery_token_status.g.dart | 0 .../{ => json}/server_configurations.dart | 0 .../{ => json}/server_configurations.g.dart | 0 .../pages/backup_details/backup_details.dart | 2 +- lib/ui/pages/setup/initializing.dart | 2 +- lib/ui/pages/ssh_keys/ssh_keys.dart | 2 +- lib/ui/pages/users/users.dart | 2 +- 51 files changed, 690 insertions(+), 642 deletions(-) create mode 100644 lib/logic/models/hive/README.md rename lib/logic/models/{ => hive}/backblaze_bucket.dart (100%) rename lib/logic/models/{ => hive}/backblaze_bucket.g.dart (100%) rename lib/logic/models/{ => hive}/backblaze_credential.dart (100%) rename lib/logic/models/{ => hive}/backblaze_credential.g.dart (100%) rename lib/logic/models/{ => hive}/server_details.dart (74%) rename lib/logic/models/{ => hive}/server_details.g.dart (60%) rename lib/logic/models/{ => hive}/server_domain.dart (90%) rename lib/logic/models/{ => hive}/server_domain.g.dart (60%) rename lib/logic/models/{ => hive}/user.dart (100%) rename lib/logic/models/{ => hive}/user.g.dart (100%) rename lib/logic/models/{ => json}/api_token.dart (100%) rename lib/logic/models/{ => json}/api_token.g.dart (100%) rename lib/logic/models/{ => json}/auto_upgrade_settings.dart (100%) rename lib/logic/models/{ => json}/auto_upgrade_settings.g.dart (100%) rename lib/logic/models/{ => json}/backup.dart (100%) rename lib/logic/models/{ => json}/backup.g.dart (100%) rename lib/logic/models/{ => json}/device_token.dart (100%) rename lib/logic/models/{ => json}/device_token.g.dart (100%) rename lib/logic/models/{ => json}/dns_records.dart (100%) rename lib/logic/models/{ => json}/dns_records.g.dart (100%) rename lib/logic/models/{ => json}/hetzner_server_info.dart (100%) rename lib/logic/models/{ => json}/hetzner_server_info.g.dart (100%) rename lib/logic/models/{ => json}/recovery_token_status.dart (100%) rename lib/logic/models/{ => json}/recovery_token_status.g.dart (100%) rename lib/logic/models/{ => json}/server_configurations.dart (100%) rename lib/logic/models/{ => json}/server_configurations.g.dart (100%) diff --git a/lib/config/hive_config.dart b/lib/config/hive_config.dart index 3eeb1219..e5ef6927 100644 --- a/lib/config/hive_config.dart +++ b/lib/config/hive_config.dart @@ -3,21 +3,21 @@ import 'dart:typed_data'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:hive_flutter/hive_flutter.dart'; -import 'package:selfprivacy/logic/models/backblaze_bucket.dart'; -import 'package:selfprivacy/logic/models/backblaze_credential.dart'; -import 'package:selfprivacy/logic/models/server_domain.dart'; -import 'package:selfprivacy/logic/models/server_details.dart'; -import 'package:selfprivacy/logic/models/user.dart'; +import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart'; +import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart'; +import 'package:selfprivacy/logic/models/hive/server_domain.dart'; +import 'package:selfprivacy/logic/models/hive/server_details.dart'; +import 'package:selfprivacy/logic/models/hive/user.dart'; class HiveConfig { static Future init() async { await Hive.initFlutter(); Hive.registerAdapter(UserAdapter()); - Hive.registerAdapter(HetznerServerDetailsAdapter()); + Hive.registerAdapter(ServerHostingDetailsAdapter()); Hive.registerAdapter(ServerDomainAdapter()); Hive.registerAdapter(BackblazeCredentialAdapter()); Hive.registerAdapter(BackblazeBucketAdapter()); - Hive.registerAdapter(HetznerDataBaseAdapter()); + Hive.registerAdapter(ServerVolumeAdapter()); await Hive.openBox(BNames.appSettings); await Hive.openBox(BNames.users); diff --git a/lib/logic/api_maps/backblaze.dart b/lib/logic/api_maps/backblaze.dart index 6a56788c..678ec333 100644 --- a/lib/logic/api_maps/backblaze.dart +++ b/lib/logic/api_maps/backblaze.dart @@ -3,7 +3,7 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/api_maps/api_map.dart'; -import 'package:selfprivacy/logic/models/backblaze_credential.dart'; +import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart'; class BackblazeApiAuth { BackblazeApiAuth({required this.authorizationToken, required this.apiUrl}); diff --git a/lib/logic/api_maps/cloudflare.dart b/lib/logic/api_maps/cloudflare.dart index 5b81fdba..9da5ecee 100644 --- a/lib/logic/api_maps/cloudflare.dart +++ b/lib/logic/api_maps/cloudflare.dart @@ -3,8 +3,8 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/api_maps/api_map.dart'; -import 'package:selfprivacy/logic/models/server_domain.dart'; -import 'package:selfprivacy/logic/models/dns_records.dart'; +import 'package:selfprivacy/logic/models/hive/server_domain.dart'; +import 'package:selfprivacy/logic/models/json/dns_records.dart'; class CloudflareApi extends ApiMap { CloudflareApi({this.hasLogger = false, this.isWithToken = true}); diff --git a/lib/logic/api_maps/hetzner.dart b/lib/logic/api_maps/hetzner.dart index 304650f2..2256f9e5 100644 --- a/lib/logic/api_maps/hetzner.dart +++ b/lib/logic/api_maps/hetzner.dart @@ -4,9 +4,9 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/api_maps/api_map.dart'; -import 'package:selfprivacy/logic/models/hetzner_server_info.dart'; -import 'package:selfprivacy/logic/models/server_details.dart'; -import 'package:selfprivacy/logic/models/user.dart'; +import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart'; +import 'package:selfprivacy/logic/models/hive/server_details.dart'; +import 'package:selfprivacy/logic/models/hive/user.dart'; import 'package:selfprivacy/utils/password_generator.dart'; class HetznerApi extends ApiMap { @@ -140,8 +140,9 @@ class HetznerApi extends ApiMap { id: serverCreateResponse.data['server']['id'], ip4: serverCreateResponse.data['server']['public_net']['ipv4']['ip'], createTime: DateTime.now(), - dataBase: dataBase, + volume: dataBase, apiToken: apiToken, + provider: ServerProvider.Hetzner, ); } diff --git a/lib/logic/api_maps/server.dart b/lib/logic/api_maps/server.dart index 74c2137f..27c0f5c2 100644 --- a/lib/logic/api_maps/server.dart +++ b/lib/logic/api_maps/server.dart @@ -5,14 +5,15 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/common_enum/common_enum.dart'; -import 'package:selfprivacy/logic/models/api_token.dart'; -import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart'; -import 'package:selfprivacy/logic/models/backblaze_bucket.dart'; -import 'package:selfprivacy/logic/models/backup.dart'; -import 'package:selfprivacy/logic/models/recovery_token_status.dart'; -import 'package:selfprivacy/logic/models/device_token.dart'; +import 'package:selfprivacy/logic/models/json/api_token.dart'; +import 'package:selfprivacy/logic/models/json/auto_upgrade_settings.dart'; +import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart'; +import 'package:selfprivacy/logic/models/json/backup.dart'; +import 'package:selfprivacy/logic/models/json/recovery_token_status.dart'; +import 'package:selfprivacy/logic/models/json/device_token.dart'; import 'package:selfprivacy/logic/models/timezone_settings.dart'; -import 'package:selfprivacy/logic/models/user.dart'; +import 'package:selfprivacy/logic/models/hive/user.dart'; +import 'package:timezone/browser.dart'; import 'api_map.dart'; @@ -92,10 +93,9 @@ class ServerApi extends ApiMap { } Future> createUser(User user) async { - var client = await getClient(); - Response response; + var client = await getClient(); try { response = await client.post( '/users', @@ -120,21 +120,21 @@ class ServerApi extends ApiMap { } bool isFoundOnServer = false; - int statusCode = 0; + int code = 0; final bool isUserCreated = (response.statusCode != null) && (response.statusCode == HttpStatus.created); if (isUserCreated) { isFoundOnServer = true; - statusCode = response.statusCode!; + code = response.statusCode!; } else { isFoundOnServer = false; - statusCode = HttpStatus.notAcceptable; + code = HttpStatus.notAcceptable; } return ApiResponse( - statusCode: statusCode, + statusCode: code, data: User( login: user.login, password: user.password, @@ -146,8 +146,6 @@ class ServerApi extends ApiMap { Future>> getUsersList() async { List res = []; Response response; - String? message; - int code = 0; var client = await getClient(); try { @@ -157,27 +155,32 @@ class ServerApi extends ApiMap { } } on DioError catch (e) { print(e.message); - message = e.message; - code = e.response?.statusCode ?? HttpStatus.internalServerError; - res = []; + return ApiResponse( + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: [], + ); } catch (e) { print(e); - message = e.toString(); - code = HttpStatus.internalServerError; - res = []; + return ApiResponse( + errorMessage: e.toString(), + statusCode: HttpStatus.internalServerError, + data: [], + ); } finally { close(client); } + final int code = response.statusCode ?? HttpStatus.internalServerError; + return ApiResponse( - errorMessage: message, statusCode: code, data: res, ); } Future> addUserSshKey(User user, String sshKey) async { - Response response; + late Response response; var client = await getClient(); try { @@ -189,47 +192,48 @@ class ServerApi extends ApiMap { ); } on DioError catch (e) { print(e.message); - return ApiResponse( - data: null, - errorMessage: e.message, - statusCode: e.response?.statusCode ?? HttpStatus.internalServerError); + return ApiResponse( + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: null, + ); } finally { close(client); } + final int code = response.statusCode ?? HttpStatus.internalServerError; + return ApiResponse( - statusCode: response.statusCode ?? HttpStatus.internalServerError, + statusCode: code, data: null, - errorMessage: response.data?.containsKey('error') ?? false - ? response.data['error'] - : null, ); } Future> addRootSshKey(String ssh) async { - Response response; + late Response response; var client = await getClient(); - response = await client.put( - '/services/ssh/key/send', - data: {"public_key": ssh}, - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); + try { + response = await client.put( + '/services/ssh/key/send', + data: {"public_key": ssh}, + ); + } on DioError catch (e) { + print(e.message); + return ApiResponse( + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: null, + ); + } finally { + close(client); + } + + final int code = response.statusCode ?? HttpStatus.internalServerError; return ApiResponse( - statusCode: response.statusCode ?? HttpStatus.internalServerError, + statusCode: code, data: null, - errorMessage: response.data?.containsKey('error') ?? false - ? response.data['error'] - : null, ); } @@ -238,27 +242,30 @@ class ServerApi extends ApiMap { Response response; var client = await getClient(); - response = await client.get( - '/services/ssh/keys/${user.login}', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); try { + response = await client.get('/services/ssh/keys/${user.login}'); res = (response.data as List).map((e) => e as String).toList(); + } on DioError catch (e) { + print(e.message); + return ApiResponse>( + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: [], + ); } catch (e) { - print(e); - res = []; + return ApiResponse>( + errorMessage: e.toString(), + statusCode: HttpStatus.internalServerError, + data: [], + ); + } finally { + close(client); } - close(client); + final int code = response.statusCode ?? HttpStatus.internalServerError; + return ApiResponse>( - statusCode: response.statusCode ?? HttpStatus.internalServerError, + statusCode: code, data: res, errorMessage: response.data is List ? null @@ -272,22 +279,26 @@ class ServerApi extends ApiMap { Response response; var client = await getClient(); - response = await client.delete( - '/services/ssh/keys/${user.login}', - data: {"public_key": sshKey}, - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); + try { + response = await client.delete( + '/services/ssh/keys/${user.login}', + data: {"public_key": sshKey}, + ); + } on DioError catch (e) { + print(e.message); + return ApiResponse( + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: null, + ); + } finally { + close(client); + } + + final int code = response.statusCode ?? HttpStatus.internalServerError; return ApiResponse( - statusCode: response.statusCode ?? HttpStatus.internalServerError, + statusCode: code, data: null, errorMessage: response.data?.containsKey('error') ?? false ? response.data['error'] @@ -296,95 +307,69 @@ class ServerApi extends ApiMap { } Future deleteUser(User user) async { - bool res; + bool res = false; Response response; var client = await getClient(); try { - response = await client.delete( - '/users/${user.login}', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); + response = await client.delete('/users/${user.login}'); res = response.statusCode == HttpStatus.ok || response.statusCode == HttpStatus.notFound; - } catch (e) { - print(e); + } on DioError catch (e) { + print(e.message); res = false; + } finally { + close(client); + return res; } - - close(client); - return res; } String get rootAddress => throw UnimplementedError('not used in with implementation'); Future apply() async { - bool res; + bool res = false; Response response; var client = await getClient(); try { - response = await client.get( - '/system/configuration/apply', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - + response = await client.get('/system/configuration/apply'); res = response.statusCode == HttpStatus.ok; - } catch (e) { - print(e); + } on DioError catch (e) { + print(e.message); res = false; + } finally { + close(client); + return res; } - - close(client); - return res; } Future switchService(ServiceTypes type, bool needToTurnOn) async { var client = await getClient(); - client.post( - '/services/${type.url}/${needToTurnOn ? 'enable' : 'disable'}', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); + try { + client.post( + '/services/${type.url}/${needToTurnOn ? 'enable' : 'disable'}', + ); + } on DioError catch (e) { + print(e.message); + } finally { + close(client); + } } Future> servicesPowerCheck() async { - var client = await getClient(); - Response response = await client.get( - '/services/status', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); + Response response; + + var client = await getClient(); + try { + response = await client.get('/services/status'); + } on DioError catch (e) { + print(e.message); + return {}; + } finally { + close(client); + } - close(client); return { ServiceTypes.passwordManager: response.data['bitwarden'] == 0, ServiceTypes.git: response.data['gitea'] == 0, @@ -396,225 +381,189 @@ class ServerApi extends ApiMap { Future uploadBackblazeConfig(BackblazeBucket bucket) async { var client = await getClient(); - client.put( - '/services/restic/backblaze/config', - data: { - 'accountId': bucket.applicationKeyId, - 'accountKey': bucket.applicationKey, - 'bucket': bucket.bucketName, - }, - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); + try { + client.put( + '/services/restic/backblaze/config', + data: { + 'accountId': bucket.applicationKeyId, + 'accountKey': bucket.applicationKey, + 'bucket': bucket.bucketName, + }, + ); + } on DioError catch (e) { + print(e.message); + } finally { + close(client); + } } Future startBackup() async { var client = await getClient(); - client.put( - '/services/restic/backup/create', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); + try { + client.put('/services/restic/backup/create'); + } on DioError catch (e) { + print(e.message); + } finally { + close(client); + } } Future> getBackups() async { Response response; + List backups = []; var client = await getClient(); try { - response = await client.get( - '/services/restic/backup/list', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - return response.data.map((e) => Backup.fromJson(e)).toList(); + response = await client.get('/services/restic/backup/list'); + backups = response.data.map((e) => Backup.fromJson(e)).toList(); + } on DioError catch (e) { + print(e.message); } catch (e) { print(e); + } finally { + close(client); + return backups; } - close(client); - return []; } Future getBackupStatus() async { Response response; - - var client = await getClient(); - try { - response = await client.get( - '/services/restic/backup/status', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - return BackupStatus.fromJson(response.data); - } catch (e) { - print(e); - } - close(client); - - return BackupStatus( + BackupStatus status = BackupStatus( status: BackupStatusEnum.error, errorMessage: 'Network error', progress: 0, ); + + var client = await getClient(); + try { + response = await client.get('/services/restic/backup/status'); + status = BackupStatus.fromJson(response.data); + } on DioError catch (e) { + print(e.message); + } finally { + close(client); + return status; + } } Future forceBackupListReload() async { var client = await getClient(); - client.get( - '/services/restic/backup/reload', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); + try { + client.get('/services/restic/backup/reload'); + } on DioError catch (e) { + print(e.message); + } finally { + close(client); + } } Future restoreBackup(String backupId) async { var client = await getClient(); - client.put( - '/services/restic/backup/restore', - data: {'backupId': backupId}, - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); + try { + client.put( + '/services/restic/backup/restore', + data: {'backupId': backupId}, + ); + } on DioError catch (e) { + print(e.message); + } finally { + close(client); + } } Future pullConfigurationUpdate() async { + Response response; + bool result = false; + var client = await getClient(); - Response response = await client.get( - '/system/configuration/pull', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); - return response.statusCode == HttpStatus.ok; + try { + response = await client.get('/system/configuration/pull'); + result = (response.statusCode != null) + ? (response.statusCode == HttpStatus.ok) + : false; + } on DioError catch (e) { + print(e.message); + } finally { + close(client); + return result; + } } Future reboot() async { + Response response; + bool result = false; + var client = await getClient(); - Response response = await client.get( - '/system/reboot', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); - return response.statusCode == HttpStatus.ok; + try { + response = await client.get('/system/reboot'); + result = (response.statusCode != null) + ? (response.statusCode == HttpStatus.ok) + : false; + } on DioError catch (e) { + print(e.message); + } finally { + close(client); + return result; + } } Future upgrade() async { + Response response; + bool result = false; + var client = await getClient(); - Response response = await client.get( - '/system/configuration/upgrade', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); - return response.statusCode == HttpStatus.ok; + try { + response = await client.get('/system/configuration/upgrade'); + result = (response.statusCode != null) + ? (response.statusCode == HttpStatus.ok) + : false; + } on DioError catch (e) { + print(e.message); + } finally { + close(client); + return result; + } } Future getAutoUpgradeSettings() async { - var client = await getClient(); - Response response = await client.get( - '/system/configuration/autoUpgrade', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), + Response response; + AutoUpgradeSettings settings = AutoUpgradeSettings( + enable: false, + allowReboot: false, ); - close(client); - return AutoUpgradeSettings.fromJson(response.data); + + var client = await getClient(); + try { + response = await client.get('/system/configuration/autoUpgrade'); + if (response.data != null) { + settings = AutoUpgradeSettings.fromJson(response.data); + } + } on DioError catch (e) { + print(e.message); + } finally { + close(client); + return settings; + } } Future updateAutoUpgradeSettings(AutoUpgradeSettings settings) async { var client = await getClient(); - await client.put( - '/system/configuration/autoUpgrade', - data: settings.toJson(), - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); + try { + await client.put( + '/system/configuration/autoUpgrade', + data: settings.toJson(), + ); + } on DioError catch (e) { + print(e.message); + } finally { + close(client); + } } Future getServerTimezone() async { + // I am not sure how to initialize TimeZoneSettings with default value... var client = await getClient(); - Response response = await client.get( - '/system/configuration/timezone', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); + Response response = await client.get('/system/configuration/timezone'); close(client); return TimeZoneSettings.fromString(response.data); @@ -622,35 +571,30 @@ class ServerApi extends ApiMap { Future updateServerTimezone(TimeZoneSettings settings) async { var client = await getClient(); - await client.put( - '/system/configuration/timezone', - data: settings.toJson(), - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); + try { + await client.put( + '/system/configuration/timezone', + data: settings.toString(), + ); + } on DioError catch (e) { + print(e.message); + } finally { + close(client); + } } Future getDkim() async { + Response response; + var client = await getClient(); - Response response = await client.get( - '/services/mailserver/dkim', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - close(client); + try { + response = await client.get('/services/mailserver/dkim'); + } on DioError catch (e) { + print(e.message); + return null; + } finally { + close(client); + } if (response.statusCode == null) { return null; @@ -674,241 +618,232 @@ class ServerApi extends ApiMap { } Future> getRecoveryTokenStatus() async { - var client = await getClient(); - Response response = await client.get( - '/auth/recovery_token', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - client.close(); + Response response; - if (response.statusCode != null) { + var client = await getClient(); + try { + response = await client.get('/auth/recovery_token'); + } on DioError catch (e) { + print(e.message); return ApiResponse( - statusCode: response.statusCode!, - data: response.data != null - ? response.data.fromJson(response.data) - : null); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: RecoveryTokenStatus(exists: false, valid: false)); + } finally { + close(client); } + final int code = response.statusCode ?? HttpStatus.internalServerError; + return ApiResponse( - statusCode: HttpStatus.internalServerError, - data: RecoveryTokenStatus(exists: false, valid: false)); + statusCode: code, + data: response.data != null + ? response.data.fromJson(response.data) + : null); } Future> generateRecoveryToken( DateTime expiration, int uses) async { - var client = await getClient(); - Response response = await client.post( - '/auth/recovery_token', - data: { - 'expiration': expiration.toIso8601String(), - 'uses': uses, - }, - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - client.close(); + Response response; - if (response.statusCode != null) { + var client = await getClient(); + try { + response = await client.post( + '/auth/recovery_token', + data: { + 'expiration': expiration.toIso8601String(), + 'uses': uses, + }, + ); + } on DioError catch (e) { + print(e.message); return ApiResponse( - statusCode: response.statusCode!, - data: response.data != null ? response.data["token"] : ''); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: ""); + } finally { + close(client); } - return ApiResponse(statusCode: HttpStatus.internalServerError, data: ''); + final int code = response.statusCode ?? HttpStatus.internalServerError; + + return ApiResponse( + statusCode: code, + data: response.data != null ? response.data["token"] : ''); } Future> useRecoveryToken(DeviceToken token) async { - var client = await getClient(); - Response response = await client.post( - '/auth/recovery_token/use', - data: { - 'token': token.token, - 'device': token.device, - }, - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - client.close(); + Response response; - if (response.statusCode != null) { + var client = await getClient(); + try { + response = await client.post( + '/auth/recovery_token/use', + data: { + 'token': token.token, + 'device': token.device, + }, + ); + } on DioError catch (e) { + print(e.message); return ApiResponse( - statusCode: response.statusCode!, - data: response.data != null ? response.data["token"] : ''); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: ""); + } finally { + client.close(); } - return ApiResponse(statusCode: HttpStatus.internalServerError, data: ''); + final int code = response.statusCode ?? HttpStatus.internalServerError; + + return ApiResponse( + statusCode: code, + data: response.data != null ? response.data["token"] : ''); } Future> authorizeDevice(DeviceToken token) async { - var client = await getClient(); - Response response = await client.post( - '/auth/new_device/authorize', - data: { - 'token': token.token, - 'device': token.device, - }, - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - client.close(); + Response response; - if (response.statusCode != null) { + var client = await getClient(); + try { + response = await client.post( + '/auth/new_device/authorize', + data: { + 'token': token.token, + 'device': token.device, + }, + ); + } on DioError catch (e) { + print(e.message); return ApiResponse( - statusCode: response.statusCode!, - data: response.data != null ? response.data : ''); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: ""); + } finally { + client.close(); } - return ApiResponse(statusCode: HttpStatus.internalServerError, data: ''); + final int code = response.statusCode ?? HttpStatus.internalServerError; + + return ApiResponse( + statusCode: code, data: response.data != null ? response.data : ''); } Future> createDeviceToken() async { - var client = await getClient(); - Response response = await client.post( - '/auth/new_device', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - client.close(); + Response response; - if (response.statusCode != null) { + var client = await getClient(); + try { + response = await client.post('/auth/new_device'); + } on DioError catch (e) { + print(e.message); return ApiResponse( - statusCode: response.statusCode!, - data: response.data != null ? response.data["token"] : ''); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: ""); + } finally { + client.close(); } - return ApiResponse(statusCode: HttpStatus.internalServerError, data: ''); + final int code = response.statusCode ?? HttpStatus.internalServerError; + + return ApiResponse( + statusCode: code, + data: response.data != null ? response.data["token"] : ''); } Future> deleteDeviceToken() async { - var client = await getClient(); - Response response = await client.delete( - '/auth/new_device', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - client.close(); + Response response; - if (response.statusCode != null) { + var client = await getClient(); + try { + response = await client.delete('/auth/new_device'); + } on DioError catch (e) { + print(e.message); return ApiResponse( - statusCode: response.statusCode!, - data: response.data != null ? response.data : ''); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: ""); + } finally { + client.close(); } - return ApiResponse(statusCode: HttpStatus.internalServerError, data: ''); + final int code = response.statusCode ?? HttpStatus.internalServerError; + + return ApiResponse( + statusCode: code, data: response.data != null ? response.data : ''); } Future>> getApiTokens() async { - var client = await getClient(); - Response response = await client.get( - '/auth/tokens', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - client.close(); + Response response; - if (response.statusCode != null) { + var client = await getClient(); + try { + response = await client.get('/auth/tokens'); + } on DioError catch (e) { + print(e.message); return ApiResponse( - statusCode: response.statusCode!, - data: (response.data != null) - ? response.data - .map((e) => ApiToken.fromJson(e)) - .toList() - : []); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: []); + } finally { + client.close(); } - return ApiResponse(statusCode: HttpStatus.internalServerError, data: []); + final int code = response.statusCode ?? HttpStatus.internalServerError; + + return ApiResponse( + statusCode: code, + data: (response.data != null) + ? response.data.map((e) => ApiToken.fromJson(e)).toList() + : []); } Future> refreshCurrentApiToken() async { - var client = await getClient(); - Response response = await client.post( - '/auth/tokens', - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - client.close(); + Response response; - if (response.statusCode != null) { + var client = await getClient(); + try { + response = await client.post('/auth/tokens'); + } on DioError catch (e) { + print(e.message); return ApiResponse( - statusCode: response.statusCode!, - data: (response.data != null) ? response.data["token"] : ''); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: ""); + } finally { + client.close(); } - return ApiResponse(statusCode: HttpStatus.internalServerError, data: ''); + final int code = response.statusCode ?? HttpStatus.internalServerError; + + return ApiResponse( + statusCode: code, + data: response.data != null ? response.data["token"] : ''); } Future> deleteApiToken(String device) async { + Response response; var client = await getClient(); - Response response = await client.delete( - '/auth/tokens', - data: { - 'device': device, - }, - options: Options( - contentType: 'application/json', - receiveDataWhenStatusError: true, - followRedirects: false, - validateStatus: (status) { - return (status != null) && - (status < HttpStatus.internalServerError); - }), - ); - client.close(); - - if (response.statusCode != null) { - return ApiResponse(statusCode: response.statusCode!, data: null); + try { + response = await client.delete( + '/auth/tokens', + data: { + 'device': device, + }, + ); + } on DioError catch (e) { + print(e.message); + return ApiResponse( + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: null); + } finally { + client.close(); } - return ApiResponse(statusCode: HttpStatus.internalServerError, data: null); + final int code = response.statusCode ?? HttpStatus.internalServerError; + return ApiResponse(statusCode: code, data: null); } } diff --git a/lib/logic/cubit/app_config/app_config_cubit.dart b/lib/logic/cubit/app_config/app_config_cubit.dart index 030e4afe..f430f458 100644 --- a/lib/logic/cubit/app_config/app_config_cubit.dart +++ b/lib/logic/cubit/app_config/app_config_cubit.dart @@ -4,10 +4,10 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/get_it/ssh.dart'; -import 'package:selfprivacy/logic/models/backblaze_credential.dart'; -import 'package:selfprivacy/logic/models/server_domain.dart'; -import 'package:selfprivacy/logic/models/server_details.dart'; -import 'package:selfprivacy/logic/models/user.dart'; +import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart'; +import 'package:selfprivacy/logic/models/hive/server_domain.dart'; +import 'package:selfprivacy/logic/models/hive/server_details.dart'; +import 'package:selfprivacy/logic/models/hive/user.dart'; import 'app_config_repository.dart'; @@ -20,6 +20,8 @@ class AppConfigCubit extends Cubit { final repository = AppConfigRepository(); + Timer? timer; + Future load() async { var state = await repository.load(); @@ -45,17 +47,68 @@ class AppConfigCubit extends Cubit { } } - void runDelayed( - void Function() work, Duration delay, AppConfigNotFinished? state) async { - final dataState = state ?? this.state as AppConfigNotFinished; + void setHetznerKey(String hetznerKey) async { + await repository.saveHetznerKey(hetznerKey); + emit((state as AppConfigNotFinished).copyWith(hetznerKey: hetznerKey)); + } - emit(TimerState( - dataState: dataState, - timerStart: DateTime.now(), - duration: delay, - isLoading: false, - )); - timer = Timer(delay, work); + void setCloudflareKey(String cloudFlareKey) async { + await repository.saveCloudFlareKey(cloudFlareKey); + emit( + (state as AppConfigNotFinished).copyWith(cloudFlareKey: cloudFlareKey)); + } + + void setBackblazeKey(String keyId, String applicationKey) async { + var backblazeCredential = BackblazeCredential( + keyId: keyId, + applicationKey: applicationKey, + ); + await repository.saveBackblazeKey(backblazeCredential); + emit((state as AppConfigNotFinished) + .copyWith(backblazeCredential: backblazeCredential)); + } + + void setDomain(ServerDomain serverDomain) async { + await repository.saveDomain(serverDomain); + emit((state as AppConfigNotFinished).copyWith(serverDomain: serverDomain)); + } + + void setRootUser(User rootUser) async { + await repository.saveRootUser(rootUser); + emit((state as AppConfigNotFinished).copyWith(rootUser: rootUser)); + } + + void createServerAndSetDnsRecords() async { + AppConfigNotFinished _stateCopy = state as AppConfigNotFinished; + var onSuccess = (ServerHostingDetails serverDetails) async { + await repository.createDnsRecords( + serverDetails.ip4, + state.serverDomain!, + ); + + emit((state as AppConfigNotFinished).copyWith( + isLoading: false, + serverDetails: serverDetails, + )); + runDelayed(startServerIfDnsIsOkay, Duration(seconds: 30), null); + }; + + var onCancel = + () => emit((state as AppConfigNotFinished).copyWith(isLoading: false)); + + try { + emit((state as AppConfigNotFinished).copyWith(isLoading: true)); + await repository.createServer( + state.rootUser!, + state.serverDomain!.domainName, + state.cloudFlareKey!, + state.backblazeCredential!, + onCancel: onCancel, + onSuccess: onSuccess, + ); + } catch (e) { + emit(_stateCopy); + } } void startServerIfDnsIsOkay({AppConfigNotFinished? state}) async { @@ -165,8 +218,6 @@ class AppConfigCubit extends Cubit { } } - Timer? timer; - void finishCheckIfServerIsOkay({ AppConfigNotFinished? state, }) async { @@ -186,6 +237,19 @@ class AppConfigCubit extends Cubit { } } + void runDelayed( + void Function() work, Duration delay, AppConfigNotFinished? state) async { + final dataState = state ?? this.state as AppConfigNotFinished; + + emit(TimerState( + dataState: dataState, + timerStart: DateTime.now(), + duration: delay, + isLoading: false, + )); + timer = Timer(delay, work); + } + void clearAppConfig() { closeTimer(); @@ -216,70 +280,6 @@ class AppConfigCubit extends Cubit { )); } - void setHetznerKey(String hetznerKey) async { - await repository.saveHetznerKey(hetznerKey); - emit((state as AppConfigNotFinished).copyWith(hetznerKey: hetznerKey)); - } - - void setCloudflareKey(String cloudFlareKey) async { - await repository.saveCloudFlareKey(cloudFlareKey); - emit( - (state as AppConfigNotFinished).copyWith(cloudFlareKey: cloudFlareKey)); - } - - void setBackblazeKey(String keyId, String applicationKey) async { - var backblazeCredential = BackblazeCredential( - keyId: keyId, - applicationKey: applicationKey, - ); - await repository.saveBackblazeKey(backblazeCredential); - emit((state as AppConfigNotFinished) - .copyWith(backblazeCredential: backblazeCredential)); - } - - void setDomain(ServerDomain serverDomain) async { - await repository.saveDomain(serverDomain); - emit((state as AppConfigNotFinished).copyWith(serverDomain: serverDomain)); - } - - void setRootUser(User rootUser) async { - await repository.saveRootUser(rootUser); - emit((state as AppConfigNotFinished).copyWith(rootUser: rootUser)); - } - - void createServerAndSetDnsRecords() async { - AppConfigNotFinished _stateCopy = state as AppConfigNotFinished; - var onSuccess = (ServerHostingDetails serverDetails) async { - await repository.createDnsRecords( - serverDetails.ip4, - state.serverDomain!, - ); - - emit((state as AppConfigNotFinished).copyWith( - isLoading: false, - serverDetails: serverDetails, - )); - runDelayed(startServerIfDnsIsOkay, Duration(seconds: 30), null); - }; - - var onCancel = - () => emit((state as AppConfigNotFinished).copyWith(isLoading: false)); - - try { - emit((state as AppConfigNotFinished).copyWith(isLoading: true)); - await repository.createServer( - state.rootUser!, - state.serverDomain!.domainName, - state.cloudFlareKey!, - state.backblazeCredential!, - onCancel: onCancel, - onSuccess: onSuccess, - ); - } catch (e) { - emit(_stateCopy); - } - } - close() { closeTimer(); return super.close(); diff --git a/lib/logic/cubit/app_config/app_config_repository.dart b/lib/logic/cubit/app_config/app_config_repository.dart index 363f1134..28c27db6 100644 --- a/lib/logic/cubit/app_config/app_config_repository.dart +++ b/lib/logic/cubit/app_config/app_config_repository.dart @@ -7,11 +7,11 @@ import 'package:selfprivacy/config/hive_config.dart'; import 'package:selfprivacy/logic/api_maps/cloudflare.dart'; import 'package:selfprivacy/logic/api_maps/hetzner.dart'; import 'package:selfprivacy/logic/api_maps/server.dart'; -import 'package:selfprivacy/logic/models/backblaze_credential.dart'; -import 'package:selfprivacy/logic/models/server_domain.dart'; +import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart'; +import 'package:selfprivacy/logic/models/hive/server_domain.dart'; import 'package:selfprivacy/logic/models/message.dart'; -import 'package:selfprivacy/logic/models/server_details.dart'; -import 'package:selfprivacy/logic/models/user.dart'; +import 'package:selfprivacy/logic/models/hive/server_details.dart'; +import 'package:selfprivacy/logic/models/hive/user.dart'; import 'package:selfprivacy/ui/components/action_button/action_button.dart'; import 'package:selfprivacy/ui/components/brand_alert/brand_alert.dart'; @@ -51,7 +51,7 @@ class AppConfigRepository { backblazeCredential: backblazeCredential, serverDetails: serverDetails, rootUser: box.get(BNames.rootUser), - currentStep: getCurrentRecoveryStep( + currentStep: _getCurrentRecoveryStep( hetznerToken, cloudflareToken, serverDomain!, serverDetails), ); } @@ -73,7 +73,7 @@ class AppConfigRepository { ); } - RecoveryStep getCurrentRecoveryStep( + RecoveryStep _getCurrentRecoveryStep( String? hetznerToken, String? cloudflareToken, ServerDomain serverDomain, diff --git a/lib/logic/cubit/backups/backups_cubit.dart b/lib/logic/cubit/backups/backups_cubit.dart index a867dc87..8617f587 100644 --- a/lib/logic/cubit/backups/backups_cubit.dart +++ b/lib/logic/cubit/backups/backups_cubit.dart @@ -5,8 +5,8 @@ import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/api_maps/backblaze.dart'; import 'package:selfprivacy/logic/api_maps/server.dart'; import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart'; -import 'package:selfprivacy/logic/models/backblaze_bucket.dart'; -import 'package:selfprivacy/logic/models/backup.dart'; +import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart'; +import 'package:selfprivacy/logic/models/json/backup.dart'; part 'backups_state.dart'; diff --git a/lib/logic/cubit/dns_records/dns_records_cubit.dart b/lib/logic/cubit/dns_records/dns_records_cubit.dart index 8efc7bfc..e32ca7ff 100644 --- a/lib/logic/cubit/dns_records/dns_records_cubit.dart +++ b/lib/logic/cubit/dns_records/dns_records_cubit.dart @@ -1,7 +1,7 @@ import 'package:cubit_form/cubit_form.dart'; import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart'; -import 'package:selfprivacy/logic/models/server_domain.dart'; -import 'package:selfprivacy/logic/models/dns_records.dart'; +import 'package:selfprivacy/logic/models/hive/server_domain.dart'; +import 'package:selfprivacy/logic/models/json/dns_records.dart'; import '../../api_maps/cloudflare.dart'; import '../../api_maps/server.dart'; diff --git a/lib/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart b/lib/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart index d8777fa8..7eb43c24 100644 --- a/lib/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart +++ b/lib/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; import 'package:selfprivacy/logic/api_maps/backblaze.dart'; import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; -import 'package:selfprivacy/logic/models/backblaze_credential.dart'; +import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart'; import 'package:easy_localization/easy_localization.dart'; class BackblazeFormCubit extends FormCubit { diff --git a/lib/logic/cubit/forms/setup/initializing/domain_cloudflare.dart b/lib/logic/cubit/forms/setup/initializing/domain_cloudflare.dart index 1582a4cf..828d9b86 100644 --- a/lib/logic/cubit/forms/setup/initializing/domain_cloudflare.dart +++ b/lib/logic/cubit/forms/setup/initializing/domain_cloudflare.dart @@ -1,7 +1,7 @@ import 'package:cubit_form/cubit_form.dart'; import 'package:selfprivacy/logic/api_maps/cloudflare.dart'; import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; -import 'package:selfprivacy/logic/models/server_domain.dart'; +import 'package:selfprivacy/logic/models/hive/server_domain.dart'; class DomainSetupCubit extends Cubit { DomainSetupCubit(this.initializingCubit) : super(Initial()); diff --git a/lib/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart b/lib/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart index 102d7ac7..6d8b55c0 100644 --- a/lib/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart +++ b/lib/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart @@ -3,7 +3,7 @@ import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart'; -import 'package:selfprivacy/logic/models/user.dart'; +import 'package:selfprivacy/logic/models/hive/user.dart'; class RootUserFormCubit extends FormCubit { RootUserFormCubit( diff --git a/lib/logic/cubit/forms/setup/recovering/recovery_domain_form_cubit.dart b/lib/logic/cubit/forms/setup/recovering/recovery_domain_form_cubit.dart index 1b56b610..b592f5e1 100644 --- a/lib/logic/cubit/forms/setup/recovering/recovery_domain_form_cubit.dart +++ b/lib/logic/cubit/forms/setup/recovering/recovery_domain_form_cubit.dart @@ -4,7 +4,7 @@ import 'package:cubit_form/cubit_form.dart'; import 'package:selfprivacy/logic/api_maps/server.dart'; import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart'; -import 'package:selfprivacy/logic/models/server_domain.dart'; +import 'package:selfprivacy/logic/models/hive/server_domain.dart'; class RecoveryDomainFormCubit extends FormCubit { RecoveryDomainFormCubit( diff --git a/lib/logic/cubit/forms/user/ssh_form_cubit.dart b/lib/logic/cubit/forms/user/ssh_form_cubit.dart index d51cac6b..47bf2994 100644 --- a/lib/logic/cubit/forms/user/ssh_form_cubit.dart +++ b/lib/logic/cubit/forms/user/ssh_form_cubit.dart @@ -4,7 +4,7 @@ import 'package:cubit_form/cubit_form.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; import 'package:selfprivacy/logic/models/job.dart'; -import 'package:selfprivacy/logic/models/user.dart'; +import 'package:selfprivacy/logic/models/hive/user.dart'; class SshFormCubit extends FormCubit { SshFormCubit({ diff --git a/lib/logic/cubit/forms/user/user_form_cubit.dart b/lib/logic/cubit/forms/user/user_form_cubit.dart index b65cfb47..c877ff3f 100644 --- a/lib/logic/cubit/forms/user/user_form_cubit.dart +++ b/lib/logic/cubit/forms/user/user_form_cubit.dart @@ -4,7 +4,7 @@ import 'package:cubit_form/cubit_form.dart'; import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart'; import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; import 'package:selfprivacy/logic/models/job.dart'; -import 'package:selfprivacy/logic/models/user.dart'; +import 'package:selfprivacy/logic/models/hive/user.dart'; import 'package:selfprivacy/utils/password_generator.dart'; class UserFormCubit extends FormCubit { diff --git a/lib/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart b/lib/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart index 86aae1a9..86b44be7 100644 --- a/lib/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart +++ b/lib/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart @@ -2,8 +2,8 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/cubit/server_detailed_info/server_detailed_info_repository.dart'; -import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart'; -import 'package:selfprivacy/logic/models/hetzner_server_info.dart'; +import 'package:selfprivacy/logic/models/json/auto_upgrade_settings.dart'; +import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart'; import 'package:selfprivacy/logic/models/timezone_settings.dart'; part 'server_detailed_info_state.dart'; diff --git a/lib/logic/cubit/server_detailed_info/server_detailed_info_repository.dart b/lib/logic/cubit/server_detailed_info/server_detailed_info_repository.dart index a5d6c07e..ee407da5 100644 --- a/lib/logic/cubit/server_detailed_info/server_detailed_info_repository.dart +++ b/lib/logic/cubit/server_detailed_info/server_detailed_info_repository.dart @@ -1,7 +1,7 @@ import 'package:selfprivacy/logic/api_maps/hetzner.dart'; import 'package:selfprivacy/logic/api_maps/server.dart'; -import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart'; -import 'package:selfprivacy/logic/models/hetzner_server_info.dart'; +import 'package:selfprivacy/logic/models/json/auto_upgrade_settings.dart'; +import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart'; import 'package:selfprivacy/logic/models/timezone_settings.dart'; class ServerDetailsRepository { diff --git a/lib/logic/cubit/users/users_cubit.dart b/lib/logic/cubit/users/users_cubit.dart index 0fd27064..22dabb46 100644 --- a/lib/logic/cubit/users/users_cubit.dart +++ b/lib/logic/cubit/users/users_cubit.dart @@ -2,7 +2,7 @@ import 'package:bloc/bloc.dart'; import 'package:hive/hive.dart'; import 'package:selfprivacy/config/hive_config.dart'; import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart'; -import 'package:selfprivacy/logic/models/user.dart'; +import 'package:selfprivacy/logic/models/hive/user.dart'; import '../../api_maps/server.dart'; diff --git a/lib/logic/get_it/api_config.dart b/lib/logic/get_it/api_config.dart index 6ab1b564..1dc5ce7d 100644 --- a/lib/logic/get_it/api_config.dart +++ b/lib/logic/get_it/api_config.dart @@ -1,9 +1,9 @@ import 'package:hive/hive.dart'; import 'package:selfprivacy/config/hive_config.dart'; -import 'package:selfprivacy/logic/models/backblaze_bucket.dart'; -import 'package:selfprivacy/logic/models/backblaze_credential.dart'; -import 'package:selfprivacy/logic/models/server_domain.dart'; -import 'package:selfprivacy/logic/models/server_details.dart'; +import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart'; +import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart'; +import 'package:selfprivacy/logic/models/hive/server_domain.dart'; +import 'package:selfprivacy/logic/models/hive/server_details.dart'; class ApiConfigModel { Box _box = Hive.box(BNames.appConfig); diff --git a/lib/logic/models/hive/README.md b/lib/logic/models/hive/README.md new file mode 100644 index 00000000..afdd6276 --- /dev/null +++ b/lib/logic/models/hive/README.md @@ -0,0 +1,13 @@ +# Registered Hive Types + +1. User +2. ServerHostingDetails +3. ServerDomain +4. BackblazeCredential +5. ServerVolume +6. BackblazeBucket + + +## Enums +100. DnsProvider +101. ServerProvider \ No newline at end of file diff --git a/lib/logic/models/backblaze_bucket.dart b/lib/logic/models/hive/backblaze_bucket.dart similarity index 100% rename from lib/logic/models/backblaze_bucket.dart rename to lib/logic/models/hive/backblaze_bucket.dart diff --git a/lib/logic/models/backblaze_bucket.g.dart b/lib/logic/models/hive/backblaze_bucket.g.dart similarity index 100% rename from lib/logic/models/backblaze_bucket.g.dart rename to lib/logic/models/hive/backblaze_bucket.g.dart diff --git a/lib/logic/models/backblaze_credential.dart b/lib/logic/models/hive/backblaze_credential.dart similarity index 100% rename from lib/logic/models/backblaze_credential.dart rename to lib/logic/models/hive/backblaze_credential.dart diff --git a/lib/logic/models/backblaze_credential.g.dart b/lib/logic/models/hive/backblaze_credential.g.dart similarity index 100% rename from lib/logic/models/backblaze_credential.g.dart rename to lib/logic/models/hive/backblaze_credential.g.dart diff --git a/lib/logic/models/server_details.dart b/lib/logic/models/hive/server_details.dart similarity index 74% rename from lib/logic/models/server_details.dart rename to lib/logic/models/hive/server_details.dart index d12c1b36..e9bb5f38 100644 --- a/lib/logic/models/server_details.dart +++ b/lib/logic/models/hive/server_details.dart @@ -8,8 +8,9 @@ class ServerHostingDetails { required this.ip4, required this.id, required this.createTime, - required this.dataBase, + required this.volume, required this.apiToken, + required this.provider, this.startTime, }); @@ -26,19 +27,23 @@ class ServerHostingDetails { final DateTime? startTime; @HiveField(4) - final ServerVolume dataBase; + final ServerVolume volume; @HiveField(5) final String apiToken; + @HiveField(6, defaultValue: ServerProvider.Hetzner) + final ServerProvider provider; + ServerHostingDetails copyWith({DateTime? startTime}) { return ServerHostingDetails( startTime: startTime ?? this.startTime, createTime: createTime, id: id, ip4: ip4, - dataBase: dataBase, + volume: volume, apiToken: apiToken, + provider: provider, ); } @@ -57,3 +62,11 @@ class ServerVolume { @HiveField(2) String name; } + +@HiveType(typeId: 101) +enum ServerProvider { + @HiveField(0) + Unknown, + @HiveField(1) + Hetzner, +} diff --git a/lib/logic/models/server_details.g.dart b/lib/logic/models/hive/server_details.g.dart similarity index 60% rename from lib/logic/models/server_details.g.dart rename to lib/logic/models/hive/server_details.g.dart index 61252506..f52e6b37 100644 --- a/lib/logic/models/server_details.g.dart +++ b/lib/logic/models/hive/server_details.g.dart @@ -6,7 +6,7 @@ part of 'server_details.dart'; // TypeAdapterGenerator // ************************************************************************** -class HetznerServerDetailsAdapter extends TypeAdapter { +class ServerHostingDetailsAdapter extends TypeAdapter { @override final int typeId = 2; @@ -20,8 +20,11 @@ class HetznerServerDetailsAdapter extends TypeAdapter { ip4: fields[0] as String, id: fields[1] as int, createTime: fields[3] as DateTime?, - dataBase: fields[4] as ServerVolume, + volume: fields[4] as ServerVolume, apiToken: fields[5] as String, + provider: fields[6] == null + ? ServerProvider.Hetzner + : fields[6] as ServerProvider, startTime: fields[2] as DateTime?, ); } @@ -29,7 +32,7 @@ class HetznerServerDetailsAdapter extends TypeAdapter { @override void write(BinaryWriter writer, ServerHostingDetails obj) { writer - ..writeByte(6) + ..writeByte(7) ..writeByte(0) ..write(obj.ip4) ..writeByte(1) @@ -39,9 +42,11 @@ class HetznerServerDetailsAdapter extends TypeAdapter { ..writeByte(2) ..write(obj.startTime) ..writeByte(4) - ..write(obj.dataBase) + ..write(obj.volume) ..writeByte(5) - ..write(obj.apiToken); + ..write(obj.apiToken) + ..writeByte(6) + ..write(obj.provider); } @override @@ -50,12 +55,12 @@ class HetznerServerDetailsAdapter extends TypeAdapter { @override bool operator ==(Object other) => identical(this, other) || - other is HetznerServerDetailsAdapter && + other is ServerHostingDetailsAdapter && runtimeType == other.runtimeType && typeId == other.typeId; } -class HetznerDataBaseAdapter extends TypeAdapter { +class ServerVolumeAdapter extends TypeAdapter { @override final int typeId = 5; @@ -87,7 +92,46 @@ class HetznerDataBaseAdapter extends TypeAdapter { @override bool operator ==(Object other) => identical(this, other) || - other is HetznerDataBaseAdapter && + other is ServerVolumeAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +class ServerProviderAdapter extends TypeAdapter { + @override + final int typeId = 101; + + @override + ServerProvider read(BinaryReader reader) { + switch (reader.readByte()) { + case 0: + return ServerProvider.Unknown; + case 1: + return ServerProvider.Hetzner; + default: + return ServerProvider.Unknown; + } + } + + @override + void write(BinaryWriter writer, ServerProvider obj) { + switch (obj) { + case ServerProvider.Unknown: + writer.writeByte(0); + break; + case ServerProvider.Hetzner: + writer.writeByte(1); + break; + } + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is ServerProviderAdapter && runtimeType == other.runtimeType && typeId == other.typeId; } diff --git a/lib/logic/models/server_domain.dart b/lib/logic/models/hive/server_domain.dart similarity index 90% rename from lib/logic/models/server_domain.dart rename to lib/logic/models/hive/server_domain.dart index 81525d2f..ab60019e 100644 --- a/lib/logic/models/server_domain.dart +++ b/lib/logic/models/hive/server_domain.dart @@ -2,11 +2,6 @@ import 'package:hive/hive.dart'; part 'server_domain.g.dart'; -enum DnsProvider { - Unknown, - Cloudflare, -} - @HiveType(typeId: 3) class ServerDomain { ServerDomain({ @@ -29,3 +24,11 @@ class ServerDomain { return '$domainName: $zoneId'; } } + +@HiveType(typeId: 100) +enum DnsProvider { + @HiveField(0) + Unknown, + @HiveField(1) + Cloudflare, +} diff --git a/lib/logic/models/server_domain.g.dart b/lib/logic/models/hive/server_domain.g.dart similarity index 60% rename from lib/logic/models/server_domain.g.dart rename to lib/logic/models/hive/server_domain.g.dart index c154fba1..7a3eb4de 100644 --- a/lib/logic/models/server_domain.g.dart +++ b/lib/logic/models/hive/server_domain.g.dart @@ -46,3 +46,42 @@ class ServerDomainAdapter extends TypeAdapter { runtimeType == other.runtimeType && typeId == other.typeId; } + +class DnsProviderAdapter extends TypeAdapter { + @override + final int typeId = 100; + + @override + DnsProvider read(BinaryReader reader) { + switch (reader.readByte()) { + case 0: + return DnsProvider.Unknown; + case 1: + return DnsProvider.Cloudflare; + default: + return DnsProvider.Unknown; + } + } + + @override + void write(BinaryWriter writer, DnsProvider obj) { + switch (obj) { + case DnsProvider.Unknown: + writer.writeByte(0); + break; + case DnsProvider.Cloudflare: + writer.writeByte(1); + break; + } + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is DnsProviderAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} diff --git a/lib/logic/models/user.dart b/lib/logic/models/hive/user.dart similarity index 100% rename from lib/logic/models/user.dart rename to lib/logic/models/hive/user.dart diff --git a/lib/logic/models/user.g.dart b/lib/logic/models/hive/user.g.dart similarity index 100% rename from lib/logic/models/user.g.dart rename to lib/logic/models/hive/user.g.dart diff --git a/lib/logic/models/job.dart b/lib/logic/models/job.dart index 698cd1fb..38ef2022 100644 --- a/lib/logic/models/job.dart +++ b/lib/logic/models/job.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:selfprivacy/logic/common_enum/common_enum.dart'; import 'package:selfprivacy/utils/password_generator.dart'; -import 'user.dart'; +import 'hive/user.dart'; @immutable class Job extends Equatable { diff --git a/lib/logic/models/api_token.dart b/lib/logic/models/json/api_token.dart similarity index 100% rename from lib/logic/models/api_token.dart rename to lib/logic/models/json/api_token.dart diff --git a/lib/logic/models/api_token.g.dart b/lib/logic/models/json/api_token.g.dart similarity index 100% rename from lib/logic/models/api_token.g.dart rename to lib/logic/models/json/api_token.g.dart diff --git a/lib/logic/models/auto_upgrade_settings.dart b/lib/logic/models/json/auto_upgrade_settings.dart similarity index 100% rename from lib/logic/models/auto_upgrade_settings.dart rename to lib/logic/models/json/auto_upgrade_settings.dart diff --git a/lib/logic/models/auto_upgrade_settings.g.dart b/lib/logic/models/json/auto_upgrade_settings.g.dart similarity index 100% rename from lib/logic/models/auto_upgrade_settings.g.dart rename to lib/logic/models/json/auto_upgrade_settings.g.dart diff --git a/lib/logic/models/backup.dart b/lib/logic/models/json/backup.dart similarity index 100% rename from lib/logic/models/backup.dart rename to lib/logic/models/json/backup.dart diff --git a/lib/logic/models/backup.g.dart b/lib/logic/models/json/backup.g.dart similarity index 100% rename from lib/logic/models/backup.g.dart rename to lib/logic/models/json/backup.g.dart diff --git a/lib/logic/models/device_token.dart b/lib/logic/models/json/device_token.dart similarity index 100% rename from lib/logic/models/device_token.dart rename to lib/logic/models/json/device_token.dart diff --git a/lib/logic/models/device_token.g.dart b/lib/logic/models/json/device_token.g.dart similarity index 100% rename from lib/logic/models/device_token.g.dart rename to lib/logic/models/json/device_token.g.dart diff --git a/lib/logic/models/dns_records.dart b/lib/logic/models/json/dns_records.dart similarity index 100% rename from lib/logic/models/dns_records.dart rename to lib/logic/models/json/dns_records.dart diff --git a/lib/logic/models/dns_records.g.dart b/lib/logic/models/json/dns_records.g.dart similarity index 100% rename from lib/logic/models/dns_records.g.dart rename to lib/logic/models/json/dns_records.g.dart diff --git a/lib/logic/models/hetzner_server_info.dart b/lib/logic/models/json/hetzner_server_info.dart similarity index 100% rename from lib/logic/models/hetzner_server_info.dart rename to lib/logic/models/json/hetzner_server_info.dart diff --git a/lib/logic/models/hetzner_server_info.g.dart b/lib/logic/models/json/hetzner_server_info.g.dart similarity index 100% rename from lib/logic/models/hetzner_server_info.g.dart rename to lib/logic/models/json/hetzner_server_info.g.dart diff --git a/lib/logic/models/recovery_token_status.dart b/lib/logic/models/json/recovery_token_status.dart similarity index 100% rename from lib/logic/models/recovery_token_status.dart rename to lib/logic/models/json/recovery_token_status.dart diff --git a/lib/logic/models/recovery_token_status.g.dart b/lib/logic/models/json/recovery_token_status.g.dart similarity index 100% rename from lib/logic/models/recovery_token_status.g.dart rename to lib/logic/models/json/recovery_token_status.g.dart diff --git a/lib/logic/models/server_configurations.dart b/lib/logic/models/json/server_configurations.dart similarity index 100% rename from lib/logic/models/server_configurations.dart rename to lib/logic/models/json/server_configurations.dart diff --git a/lib/logic/models/server_configurations.g.dart b/lib/logic/models/json/server_configurations.g.dart similarity index 100% rename from lib/logic/models/server_configurations.g.dart rename to lib/logic/models/json/server_configurations.g.dart diff --git a/lib/ui/pages/backup_details/backup_details.dart b/lib/ui/pages/backup_details/backup_details.dart index 3040d1aa..a3562095 100644 --- a/lib/ui/pages/backup_details/backup_details.dart +++ b/lib/ui/pages/backup_details/backup_details.dart @@ -4,7 +4,7 @@ import 'package:selfprivacy/config/brand_colors.dart'; import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart'; -import 'package:selfprivacy/logic/models/backup.dart'; +import 'package:selfprivacy/logic/models/json/backup.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'; diff --git a/lib/ui/pages/setup/initializing.dart b/lib/ui/pages/setup/initializing.dart index d64d7c3b..5048aa57 100644 --- a/lib/ui/pages/setup/initializing.dart +++ b/lib/ui/pages/setup/initializing.dart @@ -35,7 +35,7 @@ class InitializingPage extends StatelessWidget { () => _stepCheck(cubit), () => _stepCheck(cubit), () => Container(child: Center(child: Text('initializing.finish'.tr()))) - ][cubit.state.progress](); + ][cubit.state.progress.index](); return BlocListener( listener: (context, state) { if (cubit.state is AppConfigFinished) { diff --git a/lib/ui/pages/ssh_keys/ssh_keys.dart b/lib/ui/pages/ssh_keys/ssh_keys.dart index b67087c6..3967bf65 100644 --- a/lib/ui/pages/ssh_keys/ssh_keys.dart +++ b/lib/ui/pages/ssh_keys/ssh_keys.dart @@ -11,7 +11,7 @@ import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; import '../../../config/brand_colors.dart'; import '../../../config/brand_theme.dart'; import '../../../logic/cubit/jobs/jobs_cubit.dart'; -import '../../../logic/models/user.dart'; +import '../../../logic/models/hive/user.dart'; import '../../components/brand_button/brand_button.dart'; import '../../components/brand_header/brand_header.dart'; diff --git a/lib/ui/pages/users/users.dart b/lib/ui/pages/users/users.dart index 013f65b0..7110f986 100644 --- a/lib/ui/pages/users/users.dart +++ b/lib/ui/pages/users/users.dart @@ -11,7 +11,7 @@ import 'package:selfprivacy/logic/cubit/forms/user/user_form_cubit.dart'; import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; import 'package:selfprivacy/logic/cubit/users/users_cubit.dart'; import 'package:selfprivacy/logic/models/job.dart'; -import 'package:selfprivacy/logic/models/user.dart'; +import 'package:selfprivacy/logic/models/hive/user.dart'; import 'package:selfprivacy/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart'; import 'package:selfprivacy/ui/components/brand_button/brand_button.dart'; import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';