mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-23 09:16:54 +00:00
Refactor infrastructure: cubits and endpoints
Co-authored-by: Inex Code <inex.code@selfprivacy.org>
This commit is contained in:
parent
01b1f7462d
commit
4a42733d31
12
android/app/src/main/res/drawable-v21/launch_background.xml
Normal file
12
android/app/src/main/res/drawable-v21/launch_background.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="?android:colorBackground" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
18
android/app/src/main/res/values-night/styles.xml
Normal file
18
android/app/src/main/res/values-night/styles.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
Flutter draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -5,7 +5,7 @@ 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/cloudflare_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/server_details.dart';
|
||||
import 'package:selfprivacy/logic/models/user.dart';
|
||||
|
||||
|
@ -14,7 +14,7 @@ class HiveConfig {
|
|||
await Hive.initFlutter();
|
||||
Hive.registerAdapter(UserAdapter());
|
||||
Hive.registerAdapter(HetznerServerDetailsAdapter());
|
||||
Hive.registerAdapter(CloudFlareDomainAdapter());
|
||||
Hive.registerAdapter(ServerDomainAdapter());
|
||||
Hive.registerAdapter(BackblazeCredentialAdapter());
|
||||
Hive.registerAdapter(BackblazeBucketAdapter());
|
||||
Hive.registerAdapter(HetznerDataBaseAdapter());
|
||||
|
@ -56,13 +56,14 @@ class BNames {
|
|||
static String key = 'key';
|
||||
static String sshEnckey = 'sshEngkey';
|
||||
|
||||
static String cloudFlareDomain = 'cloudFlareDomain';
|
||||
static String hasFinalChecked = 'hasFinalChecked';
|
||||
static String isServerStarted = 'isServerStarted';
|
||||
|
||||
static String serverDomain = 'cloudFlareDomain';
|
||||
static String hetznerKey = 'hetznerKey';
|
||||
static String cloudFlareKey = 'cloudFlareKey';
|
||||
static String rootUser = 'rootUser';
|
||||
static String hetznerServer = 'hetznerServer';
|
||||
static String hasFinalChecked = 'hasFinalChecked';
|
||||
static String isServerStarted = 'isServerStarted';
|
||||
static String serverDetails = 'hetznerServer';
|
||||
static String backblazeKey = 'backblazeKey';
|
||||
static String backblazeBucket = 'backblazeBucket';
|
||||
static String isLoading = 'isLoading';
|
||||
|
@ -71,5 +72,4 @@ class BNames {
|
|||
static String sshConfig = 'sshConfig';
|
||||
static String sshPrivateKey = "sshPrivateKey";
|
||||
static String sshPublicKey = "sshPublicKey";
|
||||
static String serverDomain = "serverDomain";
|
||||
}
|
||||
|
|
|
@ -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/cloudflare_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/dns_records.dart';
|
||||
|
||||
class CloudflareApi extends ApiMap {
|
||||
|
@ -63,7 +63,7 @@ class CloudflareApi extends ApiMap {
|
|||
|
||||
Future<void> removeSimilarRecords({
|
||||
String? ip4,
|
||||
required CloudFlareDomain cloudFlareDomain,
|
||||
required ServerDomain cloudFlareDomain,
|
||||
}) async {
|
||||
var domainName = cloudFlareDomain.domainName;
|
||||
var domainZoneId = cloudFlareDomain.zoneId;
|
||||
|
@ -89,7 +89,7 @@ class CloudflareApi extends ApiMap {
|
|||
}
|
||||
|
||||
Future<List<DnsRecord>> getDnsRecords({
|
||||
required CloudFlareDomain cloudFlareDomain,
|
||||
required ServerDomain cloudFlareDomain,
|
||||
}) async {
|
||||
var domainName = cloudFlareDomain.domainName;
|
||||
var domainZoneId = cloudFlareDomain.zoneId;
|
||||
|
@ -120,7 +120,7 @@ class CloudflareApi extends ApiMap {
|
|||
|
||||
Future<void> createMultipleDnsRecords({
|
||||
String? ip4,
|
||||
required CloudFlareDomain cloudFlareDomain,
|
||||
required ServerDomain cloudFlareDomain,
|
||||
}) async {
|
||||
var domainName = cloudFlareDomain.domainName;
|
||||
var domainZoneId = cloudFlareDomain.zoneId;
|
||||
|
@ -186,7 +186,7 @@ class CloudflareApi extends ApiMap {
|
|||
}
|
||||
|
||||
Future<void> setDkim(
|
||||
String dkimRecordString, CloudFlareDomain cloudFlareDomain) async {
|
||||
String dkimRecordString, ServerDomain cloudFlareDomain) async {
|
||||
final domainZoneId = cloudFlareDomain.zoneId;
|
||||
final url = '$rootAddress/zones/$domainZoneId/dns_records';
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ class HetznerApi extends ApiMap {
|
|||
return server == null;
|
||||
}
|
||||
|
||||
Future<HetznerDataBase> createVolume() async {
|
||||
Future<ServerVolume> createVolume() async {
|
||||
var client = await getClient();
|
||||
Response dbCreateResponse = await client.post(
|
||||
'/volumes',
|
||||
|
@ -82,17 +82,17 @@ class HetznerApi extends ApiMap {
|
|||
},
|
||||
);
|
||||
var dbId = dbCreateResponse.data['volume']['id'];
|
||||
return HetznerDataBase(
|
||||
return ServerVolume(
|
||||
id: dbId,
|
||||
name: dbCreateResponse.data['volume']['name'],
|
||||
);
|
||||
}
|
||||
|
||||
Future<HetznerServerDetails> createServer({
|
||||
Future<ServerHostingDetails> createServer({
|
||||
required String cloudFlareKey,
|
||||
required User rootUser,
|
||||
required String domainName,
|
||||
required HetznerDataBase dataBase,
|
||||
required ServerVolume dataBase,
|
||||
}) async {
|
||||
var client = await getClient();
|
||||
|
||||
|
@ -136,7 +136,7 @@ class HetznerApi extends ApiMap {
|
|||
|
||||
print(serverCreateResponse.data);
|
||||
client.close();
|
||||
return HetznerServerDetails(
|
||||
return ServerHostingDetails(
|
||||
id: serverCreateResponse.data['server']['id'],
|
||||
ip4: serverCreateResponse.data['server']['public_net']['ipv4']['ip'],
|
||||
createTime: DateTime.now(),
|
||||
|
@ -189,8 +189,8 @@ class HetznerApi extends ApiMap {
|
|||
close(client);
|
||||
}
|
||||
|
||||
Future<HetznerServerDetails> reset() async {
|
||||
var server = getIt<ApiConfigModel>().hetznerServer!;
|
||||
Future<ServerHostingDetails> reset() async {
|
||||
var server = getIt<ApiConfigModel>().serverDetails!;
|
||||
|
||||
var client = await getClient();
|
||||
await client.post('/servers/${server.id}/actions/reset');
|
||||
|
@ -199,8 +199,8 @@ class HetznerApi extends ApiMap {
|
|||
return server.copyWith(startTime: DateTime.now());
|
||||
}
|
||||
|
||||
Future<HetznerServerDetails> powerOn() async {
|
||||
var server = getIt<ApiConfigModel>().hetznerServer!;
|
||||
Future<ServerHostingDetails> powerOn() async {
|
||||
var server = getIt<ApiConfigModel>().serverDetails!;
|
||||
|
||||
var client = await getClient();
|
||||
await client.post('/servers/${server.id}/actions/poweron');
|
||||
|
@ -211,7 +211,7 @@ class HetznerApi extends ApiMap {
|
|||
|
||||
Future<Map<String, dynamic>> getMetrics(
|
||||
DateTime start, DateTime end, String type) async {
|
||||
var hetznerServer = getIt<ApiConfigModel>().hetznerServer;
|
||||
var hetznerServer = getIt<ApiConfigModel>().serverDetails;
|
||||
var client = await getClient();
|
||||
|
||||
Map<String, dynamic> queryParameters = {
|
||||
|
@ -228,7 +228,7 @@ class HetznerApi extends ApiMap {
|
|||
}
|
||||
|
||||
Future<HetznerServerInfo> getInfo() async {
|
||||
var hetznerServer = getIt<ApiConfigModel>().hetznerServer;
|
||||
var hetznerServer = getIt<ApiConfigModel>().serverDetails;
|
||||
var client = await getClient();
|
||||
Response response = await client.get('/servers/${hetznerServer!.id}');
|
||||
close(client);
|
||||
|
@ -240,7 +240,7 @@ class HetznerApi extends ApiMap {
|
|||
required String ip4,
|
||||
required String domainName,
|
||||
}) async {
|
||||
var hetznerServer = getIt<ApiConfigModel>().hetznerServer;
|
||||
var hetznerServer = getIt<ApiConfigModel>().serverDetails;
|
||||
var client = await getClient();
|
||||
await client.post(
|
||||
'/servers/${hetznerServer!.id}/actions/change_dns_ptr',
|
||||
|
|
|
@ -33,65 +33,68 @@ class ApiResponse<D> {
|
|||
class ServerApi extends ApiMap {
|
||||
bool hasLogger;
|
||||
bool isWithToken;
|
||||
String? overrideDomain;
|
||||
|
||||
ServerApi({this.hasLogger = false, this.isWithToken = true});
|
||||
ServerApi(
|
||||
{this.hasLogger = false, this.isWithToken = true, this.overrideDomain});
|
||||
|
||||
BaseOptions get options {
|
||||
var options = BaseOptions();
|
||||
|
||||
if (isWithToken) {
|
||||
var cloudFlareDomain = getIt<ApiConfigModel>().cloudFlareDomain;
|
||||
var cloudFlareDomain = getIt<ApiConfigModel>().serverDomain;
|
||||
var domainName = cloudFlareDomain!.domainName;
|
||||
var apiToken = getIt<ApiConfigModel>().hetznerServer?.apiToken;
|
||||
var apiToken = getIt<ApiConfigModel>().serverDetails?.apiToken;
|
||||
|
||||
options = BaseOptions(baseUrl: 'https://api.$domainName', headers: {
|
||||
'Authorization': 'Bearer $apiToken',
|
||||
});
|
||||
}
|
||||
|
||||
if (overrideDomain != null) {
|
||||
options = BaseOptions(baseUrl: 'https://api.$overrideDomain');
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
Future<String?> getApiVersion() async {
|
||||
Response response;
|
||||
|
||||
var client = await getClient();
|
||||
String? apiVersion = null;
|
||||
|
||||
try {
|
||||
response = await client.get('/api/version');
|
||||
apiVersion = response.data['version'];
|
||||
} on DioError catch (e) {
|
||||
print(e.message);
|
||||
} finally {
|
||||
close(client);
|
||||
return apiVersion;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> isHttpServerWorking() async {
|
||||
bool res;
|
||||
bool res = false;
|
||||
Response response;
|
||||
|
||||
var client = await getClient();
|
||||
try {
|
||||
response = await client.get(
|
||||
'/services/status',
|
||||
options: Options(
|
||||
contentType: 'application/json',
|
||||
receiveDataWhenStatusError: true,
|
||||
followRedirects: false,
|
||||
validateStatus: (status) {
|
||||
return (status != null) &&
|
||||
(status < HttpStatus.internalServerError);
|
||||
}),
|
||||
);
|
||||
response = await client.get('/services/status');
|
||||
res = response.statusCode == HttpStatus.ok;
|
||||
} catch (e) {
|
||||
res = false;
|
||||
} on DioError catch (e) {
|
||||
print(e.message);
|
||||
} finally {
|
||||
close(client);
|
||||
return res;
|
||||
}
|
||||
close(client);
|
||||
return res;
|
||||
}
|
||||
|
||||
Future<ApiResponse<User>> createUser(User user) async {
|
||||
var client = await getClient();
|
||||
|
||||
var makeErrorApiReponse = (int status) {
|
||||
return ApiResponse(
|
||||
statusCode: status,
|
||||
data: User(
|
||||
login: user.login,
|
||||
password: user.password,
|
||||
isFoundOnServer: false,
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
late Response<dynamic> response;
|
||||
Response response;
|
||||
|
||||
try {
|
||||
response = await client.post(
|
||||
|
@ -100,68 +103,75 @@ class ServerApi extends ApiMap {
|
|||
'username': user.login,
|
||||
'password': user.password,
|
||||
},
|
||||
options: Options(
|
||||
contentType: 'application/json',
|
||||
receiveDataWhenStatusError: true,
|
||||
followRedirects: false,
|
||||
validateStatus: (status) {
|
||||
return (status != null) &&
|
||||
(status < HttpStatus.internalServerError);
|
||||
}),
|
||||
);
|
||||
} catch (e) {
|
||||
return makeErrorApiReponse(HttpStatus.internalServerError);
|
||||
} on DioError catch (e) {
|
||||
print(e.message);
|
||||
return ApiResponse(
|
||||
errorMessage: e.error.toString(),
|
||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
||||
data: User(
|
||||
login: user.login,
|
||||
password: user.password,
|
||||
isFoundOnServer: false,
|
||||
),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
if ((response.statusCode != null) &&
|
||||
(response.statusCode == HttpStatus.created)) {
|
||||
return ApiResponse(
|
||||
statusCode: response.statusCode!,
|
||||
data: User(
|
||||
login: user.login,
|
||||
password: user.password,
|
||||
isFoundOnServer: true,
|
||||
),
|
||||
);
|
||||
bool isFoundOnServer = false;
|
||||
int statusCode = 0;
|
||||
|
||||
final bool isUserCreated = (response.statusCode != null) &&
|
||||
(response.statusCode == HttpStatus.created);
|
||||
|
||||
if (isUserCreated) {
|
||||
isFoundOnServer = true;
|
||||
statusCode = response.statusCode!;
|
||||
} else {
|
||||
print(response.statusCode.toString() +
|
||||
": " +
|
||||
(response.statusMessage ?? ""));
|
||||
return makeErrorApiReponse(
|
||||
response.statusCode ?? HttpStatus.internalServerError);
|
||||
isFoundOnServer = false;
|
||||
statusCode = HttpStatus.notAcceptable;
|
||||
}
|
||||
|
||||
return ApiResponse(
|
||||
statusCode: statusCode,
|
||||
data: User(
|
||||
login: user.login,
|
||||
password: user.password,
|
||||
isFoundOnServer: isFoundOnServer,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<ApiResponse<List<String>>> getUsersList() async {
|
||||
List<String> res = [];
|
||||
Response response;
|
||||
String? message;
|
||||
int code = 0;
|
||||
|
||||
var client = await getClient();
|
||||
response = await client.get(
|
||||
'/users',
|
||||
options: Options(
|
||||
contentType: 'application/json',
|
||||
receiveDataWhenStatusError: true,
|
||||
followRedirects: false,
|
||||
validateStatus: (status) {
|
||||
return (status != null) &&
|
||||
(status < HttpStatus.internalServerError);
|
||||
}),
|
||||
);
|
||||
try {
|
||||
response = await client.get('/users');
|
||||
for (var user in response.data) {
|
||||
res.add(user.toString());
|
||||
}
|
||||
} on DioError catch (e) {
|
||||
print(e.message);
|
||||
message = e.message;
|
||||
code = e.response?.statusCode ?? HttpStatus.internalServerError;
|
||||
res = [];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
message = e.toString();
|
||||
code = HttpStatus.internalServerError;
|
||||
res = [];
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
close(client);
|
||||
return ApiResponse<List<String>>(
|
||||
statusCode: response.statusCode ?? HttpStatus.internalServerError,
|
||||
return ApiResponse(
|
||||
errorMessage: message,
|
||||
statusCode: code,
|
||||
data: res,
|
||||
);
|
||||
}
|
||||
|
@ -170,22 +180,23 @@ class ServerApi extends ApiMap {
|
|||
Response response;
|
||||
|
||||
var client = await getClient();
|
||||
response = await client.post(
|
||||
'/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);
|
||||
}),
|
||||
);
|
||||
try {
|
||||
response = await client.post(
|
||||
'/services/ssh/keys/${user.login}',
|
||||
data: {
|
||||
'public_key': sshKey,
|
||||
},
|
||||
);
|
||||
} on DioError catch (e) {
|
||||
print(e.message);
|
||||
return ApiResponse(
|
||||
data: null,
|
||||
errorMessage: e.message,
|
||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
close(client);
|
||||
return ApiResponse<void>(
|
||||
statusCode: response.statusCode ?? HttpStatus.internalServerError,
|
||||
data: null,
|
||||
|
|
|
@ -5,7 +5,7 @@ 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/cloudflare_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/server_details.dart';
|
||||
import 'package:selfprivacy/logic/models/user.dart';
|
||||
|
||||
|
@ -15,35 +15,6 @@ export 'package:provider/provider.dart';
|
|||
|
||||
part 'app_config_state.dart';
|
||||
|
||||
/// Initializing steps:
|
||||
///
|
||||
/// The set phase.
|
||||
/// 1.1. Hetzner key |setHetznerKey
|
||||
/// 1.2. Cloudflare key |setCloudflareKey
|
||||
/// 1.3. Backblaze Id + Key |setBackblazeKey
|
||||
/// 1.4. Set Domain address |setDomain
|
||||
/// 1.5. Set Root user name password |setRootUser
|
||||
/// 1.6. Set Create server ans set DNS-Records |createServerAndSetDnsRecords
|
||||
/// (without start)
|
||||
///
|
||||
/// The check phase.
|
||||
///
|
||||
/// 2.1. a. wait 60sec checkDnsAndStartServer |startServerIfDnsIsOkay
|
||||
/// b. checkDns
|
||||
/// c. if dns is okay start server
|
||||
///
|
||||
/// 2.2. a. wait 60sec |resetServerIfServerIsOkay
|
||||
/// b. checkServer
|
||||
/// c. if server is ok wait 30 sec
|
||||
/// d. reset server
|
||||
///
|
||||
/// 2.3. a. wait 60sec |oneMoreReset()
|
||||
/// d. reset server
|
||||
///
|
||||
/// 2.4. a. wait 30sec |finishCheckIfServerIsOkay
|
||||
/// b. checkServer
|
||||
/// c. if server is okay set that fully checked
|
||||
|
||||
class AppConfigCubit extends Cubit<AppConfigState> {
|
||||
AppConfigCubit() : super(AppConfigEmpty());
|
||||
|
||||
|
@ -55,180 +26,142 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
if (state is AppConfigFinished) {
|
||||
emit(state);
|
||||
} else if (state is AppConfigNotFinished) {
|
||||
if (state.progress == 6) {
|
||||
startServerIfDnsIsOkay(state: state, isImmediate: true);
|
||||
} else if (state.progress == 7) {
|
||||
resetServerIfServerIsOkay(state: state, isImmediate: true);
|
||||
} else if (state.progress == 8) {
|
||||
oneMoreReset(state: state, isImmediate: true);
|
||||
} else if (state.progress == 9) {
|
||||
finishCheckIfServerIsOkay(state: state, isImmediate: true);
|
||||
if (state.progress == ServerSetupProgress.serverCreated) {
|
||||
startServerIfDnsIsOkay(state: state);
|
||||
} else if (state.progress == ServerSetupProgress.serverStarted) {
|
||||
resetServerIfServerIsOkay(state: state);
|
||||
} else if (state.progress == ServerSetupProgress.serverResetedFirstTime) {
|
||||
oneMoreReset(state: state);
|
||||
} else if (state.progress ==
|
||||
ServerSetupProgress.serverResetedSecondTime) {
|
||||
finishCheckIfServerIsOkay(state: state);
|
||||
} else {
|
||||
emit(state);
|
||||
}
|
||||
} else if (state is AppConfigRecovery) {
|
||||
emit(state);
|
||||
} else {
|
||||
throw 'wrong state';
|
||||
}
|
||||
}
|
||||
|
||||
void startServerIfDnsIsOkay({
|
||||
AppConfigNotFinished? state,
|
||||
bool isImmediate = false,
|
||||
}) async {
|
||||
state = state ?? this.state as AppConfigNotFinished;
|
||||
void runDelayed(
|
||||
void Function() work, Duration delay, AppConfigNotFinished? state) async {
|
||||
final dataState = state ?? this.state as AppConfigNotFinished;
|
||||
|
||||
final work = () async {
|
||||
emit(TimerState(dataState: state!, isLoading: true));
|
||||
emit(TimerState(
|
||||
dataState: dataState,
|
||||
timerStart: DateTime.now(),
|
||||
duration: delay,
|
||||
isLoading: false,
|
||||
));
|
||||
timer = Timer(delay, work);
|
||||
}
|
||||
|
||||
var ip4 = state.hetznerServer!.ip4;
|
||||
var domainName = state.cloudFlareDomain!.domainName;
|
||||
void startServerIfDnsIsOkay({AppConfigNotFinished? state}) async {
|
||||
final dataState = state ?? this.state as AppConfigNotFinished;
|
||||
|
||||
var matches = await repository.isDnsAddressesMatch(
|
||||
domainName, ip4, state.dnsMatches);
|
||||
emit(TimerState(dataState: dataState, isLoading: true));
|
||||
|
||||
if (matches.values.every((value) => value)) {
|
||||
var server = await repository.startServer(
|
||||
state.hetznerServer!,
|
||||
);
|
||||
await repository.saveServerDetails(server);
|
||||
await repository.saveIsServerStarted(true);
|
||||
var ip4 = dataState.serverDetails!.ip4;
|
||||
var domainName = dataState.serverDomain!.domainName;
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
isServerStarted: true,
|
||||
isLoading: false,
|
||||
hetznerServer: server,
|
||||
),
|
||||
);
|
||||
resetServerIfServerIsOkay();
|
||||
} else {
|
||||
emit(
|
||||
state.copyWith(
|
||||
isLoading: false,
|
||||
dnsMatches: matches,
|
||||
),
|
||||
);
|
||||
startServerIfDnsIsOkay();
|
||||
}
|
||||
};
|
||||
var matches = await repository.isDnsAddressesMatch(
|
||||
domainName, ip4, dataState.dnsMatches);
|
||||
|
||||
if (isImmediate) {
|
||||
work();
|
||||
if (matches.values.every((value) => value)) {
|
||||
var server = await repository.startServer(
|
||||
dataState.serverDetails!,
|
||||
);
|
||||
await repository.saveServerDetails(server);
|
||||
await repository.saveIsServerStarted(true);
|
||||
|
||||
emit(
|
||||
dataState.copyWith(
|
||||
isServerStarted: true,
|
||||
isLoading: false,
|
||||
serverDetails: server,
|
||||
),
|
||||
);
|
||||
runDelayed(resetServerIfServerIsOkay, Duration(seconds: 60), dataState);
|
||||
} else {
|
||||
var pauseDuration = Duration(seconds: 30);
|
||||
emit(TimerState(
|
||||
dataState: state,
|
||||
timerStart: DateTime.now(),
|
||||
duration: pauseDuration,
|
||||
isLoading: false,
|
||||
));
|
||||
timer = Timer(pauseDuration, work);
|
||||
emit(
|
||||
dataState.copyWith(
|
||||
isLoading: false,
|
||||
dnsMatches: matches,
|
||||
),
|
||||
);
|
||||
runDelayed(startServerIfDnsIsOkay, Duration(seconds: 30), dataState);
|
||||
}
|
||||
}
|
||||
|
||||
void oneMoreReset({
|
||||
AppConfigNotFinished? state,
|
||||
bool isImmediate = false,
|
||||
}) async {
|
||||
var dataState = state ?? this.state as AppConfigNotFinished;
|
||||
void oneMoreReset({AppConfigNotFinished? state}) async {
|
||||
final dataState = state ?? this.state as AppConfigNotFinished;
|
||||
|
||||
var work = () async {
|
||||
emit(TimerState(dataState: dataState, isLoading: true));
|
||||
emit(TimerState(dataState: dataState, isLoading: true));
|
||||
|
||||
var isServerWorking = await repository.isHttpServerWorking();
|
||||
var isServerWorking = await repository.isHttpServerWorking();
|
||||
|
||||
if (isServerWorking) {
|
||||
var pauseDuration = Duration(seconds: 30);
|
||||
emit(TimerState(
|
||||
dataState: dataState,
|
||||
timerStart: DateTime.now(),
|
||||
isLoading: false,
|
||||
duration: pauseDuration,
|
||||
));
|
||||
timer = Timer(pauseDuration, () async {
|
||||
var hetznerServerDetails = await repository.restart();
|
||||
await repository.saveIsServerResetedSecondTime(true);
|
||||
await repository.saveServerDetails(hetznerServerDetails);
|
||||
if (isServerWorking) {
|
||||
var pauseDuration = Duration(seconds: 30);
|
||||
emit(TimerState(
|
||||
dataState: dataState,
|
||||
timerStart: DateTime.now(),
|
||||
isLoading: false,
|
||||
duration: pauseDuration,
|
||||
));
|
||||
timer = Timer(pauseDuration, () async {
|
||||
var hetznerServerDetails = await repository.restart();
|
||||
await repository.saveIsServerResetedSecondTime(true);
|
||||
await repository.saveServerDetails(hetznerServerDetails);
|
||||
|
||||
emit(
|
||||
dataState.copyWith(
|
||||
isServerResetedSecondTime: true,
|
||||
hetznerServer: hetznerServerDetails,
|
||||
isLoading: false,
|
||||
),
|
||||
);
|
||||
finishCheckIfServerIsOkay();
|
||||
});
|
||||
} else {
|
||||
oneMoreReset();
|
||||
}
|
||||
};
|
||||
if (isImmediate) {
|
||||
work();
|
||||
emit(
|
||||
dataState.copyWith(
|
||||
isServerResetedSecondTime: true,
|
||||
serverDetails: hetznerServerDetails,
|
||||
isLoading: false,
|
||||
),
|
||||
);
|
||||
runDelayed(finishCheckIfServerIsOkay, Duration(seconds: 60), dataState);
|
||||
});
|
||||
} else {
|
||||
var pauseDuration = Duration(seconds: 60);
|
||||
emit(
|
||||
TimerState(
|
||||
dataState: dataState,
|
||||
timerStart: DateTime.now(),
|
||||
duration: pauseDuration,
|
||||
isLoading: false,
|
||||
),
|
||||
);
|
||||
timer = Timer(pauseDuration, work);
|
||||
runDelayed(oneMoreReset, Duration(seconds: 60), dataState);
|
||||
}
|
||||
}
|
||||
|
||||
void resetServerIfServerIsOkay({
|
||||
AppConfigNotFinished? state,
|
||||
bool isImmediate = false,
|
||||
}) async {
|
||||
var dataState = state ?? this.state as AppConfigNotFinished;
|
||||
final dataState = state ?? this.state as AppConfigNotFinished;
|
||||
|
||||
var work = () async {
|
||||
emit(TimerState(dataState: dataState, isLoading: true));
|
||||
emit(TimerState(dataState: dataState, isLoading: true));
|
||||
|
||||
var isServerWorking = await repository.isHttpServerWorking();
|
||||
var isServerWorking = await repository.isHttpServerWorking();
|
||||
|
||||
if (isServerWorking) {
|
||||
var pauseDuration = Duration(seconds: 30);
|
||||
emit(TimerState(
|
||||
dataState: dataState,
|
||||
timerStart: DateTime.now(),
|
||||
isLoading: false,
|
||||
duration: pauseDuration,
|
||||
));
|
||||
timer = Timer(pauseDuration, () async {
|
||||
var hetznerServerDetails = await repository.restart();
|
||||
await repository.saveIsServerResetedFirstTime(true);
|
||||
await repository.saveServerDetails(hetznerServerDetails);
|
||||
if (isServerWorking) {
|
||||
var pauseDuration = Duration(seconds: 30);
|
||||
emit(TimerState(
|
||||
dataState: dataState,
|
||||
timerStart: DateTime.now(),
|
||||
isLoading: false,
|
||||
duration: pauseDuration,
|
||||
));
|
||||
timer = Timer(pauseDuration, () async {
|
||||
var hetznerServerDetails = await repository.restart();
|
||||
await repository.saveIsServerResetedFirstTime(true);
|
||||
await repository.saveServerDetails(hetznerServerDetails);
|
||||
|
||||
emit(
|
||||
dataState.copyWith(
|
||||
isServerResetedFirstTime: true,
|
||||
hetznerServer: hetznerServerDetails,
|
||||
isLoading: false,
|
||||
),
|
||||
);
|
||||
oneMoreReset();
|
||||
});
|
||||
} else {
|
||||
resetServerIfServerIsOkay();
|
||||
}
|
||||
};
|
||||
if (isImmediate) {
|
||||
work();
|
||||
emit(
|
||||
dataState.copyWith(
|
||||
isServerResetedFirstTime: true,
|
||||
serverDetails: hetznerServerDetails,
|
||||
isLoading: false,
|
||||
),
|
||||
);
|
||||
runDelayed(oneMoreReset, Duration(seconds: 60), dataState);
|
||||
});
|
||||
} else {
|
||||
var pauseDuration = Duration(seconds: 60);
|
||||
emit(
|
||||
TimerState(
|
||||
dataState: dataState,
|
||||
timerStart: DateTime.now(),
|
||||
duration: pauseDuration,
|
||||
isLoading: false,
|
||||
),
|
||||
);
|
||||
timer = Timer(pauseDuration, work);
|
||||
runDelayed(resetServerIfServerIsOkay, Duration(seconds: 60), dataState);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,37 +169,20 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
|
||||
void finishCheckIfServerIsOkay({
|
||||
AppConfigNotFinished? state,
|
||||
bool isImmediate = false,
|
||||
}) async {
|
||||
state = state ?? this.state as AppConfigNotFinished;
|
||||
final dataState = state ?? this.state as AppConfigNotFinished;
|
||||
|
||||
var work = () async {
|
||||
emit(TimerState(dataState: state!, isLoading: true));
|
||||
emit(TimerState(dataState: dataState, isLoading: true));
|
||||
|
||||
var isServerWorking = await repository.isHttpServerWorking();
|
||||
var isServerWorking = await repository.isHttpServerWorking();
|
||||
|
||||
if (isServerWorking) {
|
||||
await repository.createDkimRecord(state.cloudFlareDomain!);
|
||||
await repository.saveHasFinalChecked(true);
|
||||
if (isServerWorking) {
|
||||
await repository.createDkimRecord(dataState.serverDomain!);
|
||||
await repository.saveHasFinalChecked(true);
|
||||
|
||||
emit(state.finish());
|
||||
} else {
|
||||
finishCheckIfServerIsOkay();
|
||||
}
|
||||
};
|
||||
if (isImmediate) {
|
||||
work();
|
||||
emit(dataState.finish());
|
||||
} else {
|
||||
var pauseDuration = Duration(seconds: 60);
|
||||
emit(
|
||||
TimerState(
|
||||
dataState: state,
|
||||
timerStart: DateTime.now(),
|
||||
duration: pauseDuration,
|
||||
isLoading: false,
|
||||
),
|
||||
);
|
||||
timer = Timer(pauseDuration, work);
|
||||
runDelayed(finishCheckIfServerIsOkay, Duration(seconds: 60), dataState);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,18 +196,18 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
Future<void> serverDelete() async {
|
||||
closeTimer();
|
||||
|
||||
if (state.hetznerServer != null) {
|
||||
await repository.deleteServer(state.cloudFlareDomain!);
|
||||
if (state.serverDetails != null) {
|
||||
await repository.deleteServer(state.serverDomain!);
|
||||
await getIt<SSHModel>().clear();
|
||||
}
|
||||
await repository.deleteRecords();
|
||||
emit(AppConfigNotFinished(
|
||||
hetznerKey: state.hetznerKey,
|
||||
cloudFlareDomain: state.cloudFlareDomain,
|
||||
serverDomain: state.serverDomain,
|
||||
cloudFlareKey: state.cloudFlareKey,
|
||||
backblazeCredential: state.backblazeCredential,
|
||||
rootUser: state.rootUser,
|
||||
hetznerServer: null,
|
||||
serverDetails: null,
|
||||
isServerStarted: false,
|
||||
isServerResetedFirstTime: false,
|
||||
isServerResetedSecondTime: false,
|
||||
|
@ -321,10 +237,9 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
.copyWith(backblazeCredential: backblazeCredential));
|
||||
}
|
||||
|
||||
void setDomain(CloudFlareDomain cloudFlareDomain) async {
|
||||
await repository.saveDomain(cloudFlareDomain);
|
||||
emit((state as AppConfigNotFinished)
|
||||
.copyWith(cloudFlareDomain: cloudFlareDomain));
|
||||
void setDomain(ServerDomain serverDomain) async {
|
||||
await repository.saveDomain(serverDomain);
|
||||
emit((state as AppConfigNotFinished).copyWith(serverDomain: serverDomain));
|
||||
}
|
||||
|
||||
void setRootUser(User rootUser) async {
|
||||
|
@ -334,17 +249,17 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
|
||||
void createServerAndSetDnsRecords() async {
|
||||
AppConfigNotFinished _stateCopy = state as AppConfigNotFinished;
|
||||
var onSuccess = (HetznerServerDetails serverDetails) async {
|
||||
var onSuccess = (ServerHostingDetails serverDetails) async {
|
||||
await repository.createDnsRecords(
|
||||
serverDetails.ip4,
|
||||
state.cloudFlareDomain!,
|
||||
state.serverDomain!,
|
||||
);
|
||||
|
||||
emit((state as AppConfigNotFinished).copyWith(
|
||||
isLoading: false,
|
||||
hetznerServer: serverDetails,
|
||||
serverDetails: serverDetails,
|
||||
));
|
||||
startServerIfDnsIsOkay();
|
||||
runDelayed(startServerIfDnsIsOkay, Duration(seconds: 30), null);
|
||||
};
|
||||
|
||||
var onCancel =
|
||||
|
@ -354,7 +269,7 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
emit((state as AppConfigNotFinished).copyWith(isLoading: true));
|
||||
await repository.createServer(
|
||||
state.rootUser!,
|
||||
state.cloudFlareDomain!.domainName,
|
||||
state.serverDomain!.domainName,
|
||||
state.cloudFlareKey!,
|
||||
state.backblazeCredential!,
|
||||
onCancel: onCancel,
|
||||
|
|
|
@ -8,7 +8,7 @@ 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/cloudflare_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/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';
|
||||
|
@ -21,14 +21,19 @@ class AppConfigRepository {
|
|||
Box box = Hive.box(BNames.appConfig);
|
||||
|
||||
Future<AppConfigState> load() async {
|
||||
late AppConfigState res;
|
||||
final hetznerToken = getIt<ApiConfigModel>().hetznerKey;
|
||||
final cloudflareToken = getIt<ApiConfigModel>().cloudFlareKey;
|
||||
final serverDomain = getIt<ApiConfigModel>().serverDomain;
|
||||
final backblazeCredential = getIt<ApiConfigModel>().backblazeCredential;
|
||||
final serverDetails = getIt<ApiConfigModel>().serverDetails;
|
||||
|
||||
if (box.get(BNames.hasFinalChecked, defaultValue: false)) {
|
||||
res = AppConfigFinished(
|
||||
hetznerKey: getIt<ApiConfigModel>().hetznerKey!,
|
||||
cloudFlareKey: getIt<ApiConfigModel>().cloudFlareKey!,
|
||||
cloudFlareDomain: getIt<ApiConfigModel>().cloudFlareDomain!,
|
||||
backblazeCredential: getIt<ApiConfigModel>().backblazeCredential!,
|
||||
hetznerServer: getIt<ApiConfigModel>().hetznerServer!,
|
||||
return AppConfigFinished(
|
||||
hetznerKey: hetznerToken!,
|
||||
cloudFlareKey: cloudflareToken!,
|
||||
serverDomain: serverDomain!,
|
||||
backblazeCredential: backblazeCredential!,
|
||||
serverDetails: serverDetails!,
|
||||
rootUser: box.get(BNames.rootUser),
|
||||
isServerStarted: box.get(BNames.isServerStarted, defaultValue: false),
|
||||
isServerResetedFirstTime:
|
||||
|
@ -36,33 +41,62 @@ class AppConfigRepository {
|
|||
isServerResetedSecondTime:
|
||||
box.get(BNames.isServerResetedSecondTime, defaultValue: false),
|
||||
);
|
||||
} else {
|
||||
res = AppConfigNotFinished(
|
||||
hetznerKey: getIt<ApiConfigModel>().hetznerKey,
|
||||
cloudFlareKey: getIt<ApiConfigModel>().cloudFlareKey,
|
||||
cloudFlareDomain: getIt<ApiConfigModel>().cloudFlareDomain,
|
||||
backblazeCredential: getIt<ApiConfigModel>().backblazeCredential,
|
||||
hetznerServer: getIt<ApiConfigModel>().hetznerServer,
|
||||
rootUser: box.get(BNames.rootUser),
|
||||
isServerStarted: box.get(BNames.isServerStarted, defaultValue: false),
|
||||
isServerResetedFirstTime:
|
||||
box.get(BNames.isServerResetedFirstTime, defaultValue: false),
|
||||
isServerResetedSecondTime:
|
||||
box.get(BNames.isServerResetedSecondTime, defaultValue: false),
|
||||
isLoading: box.get(BNames.isLoading, defaultValue: false),
|
||||
dnsMatches: null,
|
||||
);
|
||||
}
|
||||
|
||||
return res;
|
||||
if (getIt<ApiConfigModel>().serverDomain?.provider == DnsProvider.Unknown) {
|
||||
return AppConfigRecovery(
|
||||
hetznerKey: hetznerToken,
|
||||
cloudFlareKey: cloudflareToken,
|
||||
serverDomain: serverDomain,
|
||||
backblazeCredential: backblazeCredential,
|
||||
serverDetails: serverDetails,
|
||||
rootUser: box.get(BNames.rootUser),
|
||||
currentStep: getCurrentRecoveryStep(
|
||||
hetznerToken, cloudflareToken, serverDomain!, serverDetails),
|
||||
);
|
||||
}
|
||||
|
||||
return AppConfigNotFinished(
|
||||
hetznerKey: hetznerToken,
|
||||
cloudFlareKey: cloudflareToken,
|
||||
serverDomain: serverDomain,
|
||||
backblazeCredential: backblazeCredential,
|
||||
serverDetails: serverDetails,
|
||||
rootUser: box.get(BNames.rootUser),
|
||||
isServerStarted: box.get(BNames.isServerStarted, defaultValue: false),
|
||||
isServerResetedFirstTime:
|
||||
box.get(BNames.isServerResetedFirstTime, defaultValue: false),
|
||||
isServerResetedSecondTime:
|
||||
box.get(BNames.isServerResetedSecondTime, defaultValue: false),
|
||||
isLoading: box.get(BNames.isLoading, defaultValue: false),
|
||||
dnsMatches: null,
|
||||
);
|
||||
}
|
||||
|
||||
RecoveryStep getCurrentRecoveryStep(
|
||||
String? hetznerToken,
|
||||
String? cloudflareToken,
|
||||
ServerDomain serverDomain,
|
||||
ServerHostingDetails? serverDetails,
|
||||
) {
|
||||
if (serverDetails != null) {
|
||||
if (hetznerToken != null) {
|
||||
if (cloudflareToken != null) {
|
||||
return RecoveryStep.BackblazeToken;
|
||||
}
|
||||
return RecoveryStep.CloudflareToken;
|
||||
}
|
||||
return RecoveryStep.HetznerToken;
|
||||
}
|
||||
return RecoveryStep.Selecting;
|
||||
}
|
||||
|
||||
void clearAppConfig() {
|
||||
box.clear();
|
||||
}
|
||||
|
||||
Future<HetznerServerDetails> startServer(
|
||||
HetznerServerDetails hetznerServer,
|
||||
Future<ServerHostingDetails> startServer(
|
||||
ServerHostingDetails hetznerServer,
|
||||
) async {
|
||||
var hetznerApi = HetznerApi();
|
||||
var serverDetails = await hetznerApi.powerOn();
|
||||
|
@ -122,11 +156,11 @@ class AppConfigRepository {
|
|||
String cloudFlareKey,
|
||||
BackblazeCredential backblazeCredential, {
|
||||
required void Function() onCancel,
|
||||
required Future<void> Function(HetznerServerDetails serverDetails)
|
||||
required Future<void> Function(ServerHostingDetails serverDetails)
|
||||
onSuccess,
|
||||
}) async {
|
||||
var hetznerApi = HetznerApi();
|
||||
late HetznerDataBase dataBase;
|
||||
late ServerVolume dataBase;
|
||||
|
||||
try {
|
||||
dataBase = await hetznerApi.createVolume();
|
||||
|
@ -180,7 +214,7 @@ class AppConfigRepository {
|
|||
|
||||
Future<void> createDnsRecords(
|
||||
String ip4,
|
||||
CloudFlareDomain cloudFlareDomain,
|
||||
ServerDomain cloudFlareDomain,
|
||||
) async {
|
||||
var cloudflareApi = CloudflareApi();
|
||||
|
||||
|
@ -200,7 +234,7 @@ class AppConfigRepository {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> createDkimRecord(CloudFlareDomain cloudFlareDomain) async {
|
||||
Future<void> createDkimRecord(ServerDomain cloudFlareDomain) async {
|
||||
var cloudflareApi = CloudflareApi();
|
||||
var api = ServerApi();
|
||||
|
||||
|
@ -220,17 +254,17 @@ class AppConfigRepository {
|
|||
return isHttpServerWorking;
|
||||
}
|
||||
|
||||
Future<HetznerServerDetails> restart() async {
|
||||
Future<ServerHostingDetails> restart() async {
|
||||
var hetznerApi = HetznerApi();
|
||||
return await hetznerApi.reset();
|
||||
}
|
||||
|
||||
Future<HetznerServerDetails> powerOn() async {
|
||||
Future<ServerHostingDetails> powerOn() async {
|
||||
var hetznerApi = HetznerApi();
|
||||
return await hetznerApi.powerOn();
|
||||
}
|
||||
|
||||
Future<void> saveServerDetails(HetznerServerDetails serverDetails) async {
|
||||
Future<void> saveServerDetails(ServerHostingDetails serverDetails) async {
|
||||
await getIt<ApiConfigModel>().storeServerDetails(serverDetails);
|
||||
}
|
||||
|
||||
|
@ -239,10 +273,6 @@ class AppConfigRepository {
|
|||
await getIt<ApiConfigModel>().storeHetznerKey(key);
|
||||
}
|
||||
|
||||
Future<void> saveServerDomain(String domain) async {
|
||||
await getIt<ApiConfigModel>().storeServerDomain(domain);
|
||||
}
|
||||
|
||||
Future<void> saveBackblazeKey(BackblazeCredential backblazeCredential) async {
|
||||
await getIt<ApiConfigModel>().storeBackblazeCredential(backblazeCredential);
|
||||
}
|
||||
|
@ -251,8 +281,8 @@ class AppConfigRepository {
|
|||
await getIt<ApiConfigModel>().storeCloudFlareKey(key);
|
||||
}
|
||||
|
||||
Future<void> saveDomain(CloudFlareDomain cloudFlareDomain) async {
|
||||
await getIt<ApiConfigModel>().storeCloudFlareDomain(cloudFlareDomain);
|
||||
Future<void> saveDomain(ServerDomain serverDomain) async {
|
||||
await getIt<ApiConfigModel>().storeServerDomain(serverDomain);
|
||||
}
|
||||
|
||||
Future<void> saveIsServerStarted(bool value) async {
|
||||
|
@ -275,12 +305,12 @@ class AppConfigRepository {
|
|||
await box.put(BNames.hasFinalChecked, value);
|
||||
}
|
||||
|
||||
Future<void> deleteServer(CloudFlareDomain cloudFlareDomain) async {
|
||||
Future<void> deleteServer(ServerDomain serverDomain) async {
|
||||
var hetznerApi = HetznerApi();
|
||||
var cloudFlare = CloudflareApi();
|
||||
|
||||
await hetznerApi.deleteSelfprivacyServerAndAllVolumes(
|
||||
domainName: cloudFlareDomain.domainName,
|
||||
domainName: serverDomain.domainName,
|
||||
);
|
||||
|
||||
await box.put(BNames.hasFinalChecked, false);
|
||||
|
@ -288,14 +318,14 @@ class AppConfigRepository {
|
|||
await box.put(BNames.isServerResetedFirstTime, false);
|
||||
await box.put(BNames.isServerResetedSecondTime, false);
|
||||
await box.put(BNames.isLoading, false);
|
||||
await box.put(BNames.hetznerServer, null);
|
||||
await box.put(BNames.serverDetails, null);
|
||||
|
||||
await cloudFlare.removeSimilarRecords(cloudFlareDomain: cloudFlareDomain);
|
||||
await cloudFlare.removeSimilarRecords(cloudFlareDomain: serverDomain);
|
||||
}
|
||||
|
||||
Future<void> deleteRecords() async {
|
||||
await box.deleteAll([
|
||||
BNames.hetznerServer,
|
||||
BNames.serverDetails,
|
||||
BNames.isServerStarted,
|
||||
BNames.isServerResetedFirstTime,
|
||||
BNames.isServerResetedSecondTime,
|
||||
|
|
|
@ -5,9 +5,9 @@ abstract class AppConfigState extends Equatable {
|
|||
required this.hetznerKey,
|
||||
required this.cloudFlareKey,
|
||||
required this.backblazeCredential,
|
||||
required this.cloudFlareDomain,
|
||||
required this.serverDomain,
|
||||
required this.rootUser,
|
||||
required this.hetznerServer,
|
||||
required this.serverDetails,
|
||||
required this.isServerStarted,
|
||||
required this.isServerResetedFirstTime,
|
||||
required this.isServerResetedSecondTime,
|
||||
|
@ -18,9 +18,9 @@ abstract class AppConfigState extends Equatable {
|
|||
hetznerKey,
|
||||
cloudFlareKey,
|
||||
backblazeCredential,
|
||||
cloudFlareDomain,
|
||||
serverDomain,
|
||||
rootUser,
|
||||
hetznerServer,
|
||||
serverDetails,
|
||||
isServerStarted,
|
||||
isServerResetedFirstTime,
|
||||
];
|
||||
|
@ -28,9 +28,9 @@ abstract class AppConfigState extends Equatable {
|
|||
final String? hetznerKey;
|
||||
final String? cloudFlareKey;
|
||||
final BackblazeCredential? backblazeCredential;
|
||||
final CloudFlareDomain? cloudFlareDomain;
|
||||
final ServerDomain? serverDomain;
|
||||
final User? rootUser;
|
||||
final HetznerServerDetails? hetznerServer;
|
||||
final ServerHostingDetails? serverDetails;
|
||||
final bool isServerStarted;
|
||||
final bool isServerResetedFirstTime;
|
||||
final bool isServerResetedSecondTime;
|
||||
|
@ -38,17 +38,18 @@ abstract class AppConfigState extends Equatable {
|
|||
bool get isHetznerFilled => hetznerKey != null;
|
||||
bool get isCloudFlareFilled => cloudFlareKey != null;
|
||||
bool get isBackblazeFilled => backblazeCredential != null;
|
||||
bool get isDomainFilled => cloudFlareDomain != null;
|
||||
bool get isDomainFilled => serverDomain != null;
|
||||
bool get isUserFilled => rootUser != null;
|
||||
bool get isServerCreated => hetznerServer != null;
|
||||
bool get isServerCreated => serverDetails != null;
|
||||
|
||||
bool get isFullyInitilized => _fulfilementList.every((el) => el!);
|
||||
int get progress => _fulfilementList.where((el) => el!).length;
|
||||
ServerSetupProgress get progress =>
|
||||
ServerSetupProgress.values[_fulfilementList.where((el) => el!).length];
|
||||
|
||||
int get porgressBar {
|
||||
if (progress < 6) {
|
||||
return progress;
|
||||
} else if (progress < 10) {
|
||||
if (progress.index < 6) {
|
||||
return progress.index;
|
||||
} else if (progress.index < 10) {
|
||||
return 6;
|
||||
} else {
|
||||
return 7;
|
||||
|
@ -82,9 +83,9 @@ class TimerState extends AppConfigNotFinished {
|
|||
hetznerKey: dataState.hetznerKey,
|
||||
cloudFlareKey: dataState.cloudFlareKey,
|
||||
backblazeCredential: dataState.backblazeCredential,
|
||||
cloudFlareDomain: dataState.cloudFlareDomain,
|
||||
serverDomain: dataState.serverDomain,
|
||||
rootUser: dataState.rootUser,
|
||||
hetznerServer: dataState.hetznerServer,
|
||||
serverDetails: dataState.serverDetails,
|
||||
isServerStarted: dataState.isServerStarted,
|
||||
isServerResetedFirstTime: dataState.isServerResetedFirstTime,
|
||||
isServerResetedSecondTime: dataState.isServerResetedSecondTime,
|
||||
|
@ -104,6 +105,19 @@ class TimerState extends AppConfigNotFinished {
|
|||
];
|
||||
}
|
||||
|
||||
enum ServerSetupProgress {
|
||||
nothingYet,
|
||||
hetznerFilled,
|
||||
cloudFlareFilled,
|
||||
backblazeFilled,
|
||||
domainFilled,
|
||||
userFilled,
|
||||
serverCreated,
|
||||
serverStarted,
|
||||
serverResetedFirstTime,
|
||||
serverResetedSecondTime,
|
||||
}
|
||||
|
||||
class AppConfigNotFinished extends AppConfigState {
|
||||
final bool isLoading;
|
||||
final Map<String, bool>? dnsMatches;
|
||||
|
@ -112,9 +126,9 @@ class AppConfigNotFinished extends AppConfigState {
|
|||
String? hetznerKey,
|
||||
String? cloudFlareKey,
|
||||
BackblazeCredential? backblazeCredential,
|
||||
CloudFlareDomain? cloudFlareDomain,
|
||||
ServerDomain? serverDomain,
|
||||
User? rootUser,
|
||||
HetznerServerDetails? hetznerServer,
|
||||
ServerHostingDetails? serverDetails,
|
||||
required bool isServerStarted,
|
||||
required bool isServerResetedFirstTime,
|
||||
required bool isServerResetedSecondTime,
|
||||
|
@ -124,9 +138,9 @@ class AppConfigNotFinished extends AppConfigState {
|
|||
hetznerKey: hetznerKey,
|
||||
cloudFlareKey: cloudFlareKey,
|
||||
backblazeCredential: backblazeCredential,
|
||||
cloudFlareDomain: cloudFlareDomain,
|
||||
serverDomain: serverDomain,
|
||||
rootUser: rootUser,
|
||||
hetznerServer: hetznerServer,
|
||||
serverDetails: serverDetails,
|
||||
isServerStarted: isServerStarted,
|
||||
isServerResetedFirstTime: isServerResetedFirstTime,
|
||||
isServerResetedSecondTime: isServerResetedSecondTime,
|
||||
|
@ -137,9 +151,9 @@ class AppConfigNotFinished extends AppConfigState {
|
|||
hetznerKey,
|
||||
cloudFlareKey,
|
||||
backblazeCredential,
|
||||
cloudFlareDomain,
|
||||
serverDomain,
|
||||
rootUser,
|
||||
hetznerServer,
|
||||
serverDetails,
|
||||
isServerStarted,
|
||||
isServerResetedFirstTime,
|
||||
isLoading,
|
||||
|
@ -150,9 +164,9 @@ class AppConfigNotFinished extends AppConfigState {
|
|||
String? hetznerKey,
|
||||
String? cloudFlareKey,
|
||||
BackblazeCredential? backblazeCredential,
|
||||
CloudFlareDomain? cloudFlareDomain,
|
||||
ServerDomain? serverDomain,
|
||||
User? rootUser,
|
||||
HetznerServerDetails? hetznerServer,
|
||||
ServerHostingDetails? serverDetails,
|
||||
bool? isServerStarted,
|
||||
bool? isServerResetedFirstTime,
|
||||
bool? isServerResetedSecondTime,
|
||||
|
@ -163,9 +177,9 @@ class AppConfigNotFinished extends AppConfigState {
|
|||
hetznerKey: hetznerKey ?? this.hetznerKey,
|
||||
cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey,
|
||||
backblazeCredential: backblazeCredential ?? this.backblazeCredential,
|
||||
cloudFlareDomain: cloudFlareDomain ?? this.cloudFlareDomain,
|
||||
serverDomain: serverDomain ?? this.serverDomain,
|
||||
rootUser: rootUser ?? this.rootUser,
|
||||
hetznerServer: hetznerServer ?? this.hetznerServer,
|
||||
serverDetails: serverDetails ?? this.serverDetails,
|
||||
isServerStarted: isServerStarted ?? this.isServerStarted,
|
||||
isServerResetedFirstTime:
|
||||
isServerResetedFirstTime ?? this.isServerResetedFirstTime,
|
||||
|
@ -179,9 +193,9 @@ class AppConfigNotFinished extends AppConfigState {
|
|||
hetznerKey: hetznerKey!,
|
||||
cloudFlareKey: cloudFlareKey!,
|
||||
backblazeCredential: backblazeCredential!,
|
||||
cloudFlareDomain: cloudFlareDomain!,
|
||||
serverDomain: serverDomain!,
|
||||
rootUser: rootUser!,
|
||||
hetznerServer: hetznerServer!,
|
||||
serverDetails: serverDetails!,
|
||||
isServerStarted: isServerStarted,
|
||||
isServerResetedFirstTime: isServerResetedFirstTime,
|
||||
isServerResetedSecondTime: isServerResetedSecondTime,
|
||||
|
@ -194,9 +208,9 @@ class AppConfigEmpty extends AppConfigNotFinished {
|
|||
hetznerKey: null,
|
||||
cloudFlareKey: null,
|
||||
backblazeCredential: null,
|
||||
cloudFlareDomain: null,
|
||||
serverDomain: null,
|
||||
rootUser: null,
|
||||
hetznerServer: null,
|
||||
serverDetails: null,
|
||||
isServerStarted: false,
|
||||
isServerResetedFirstTime: false,
|
||||
isServerResetedSecondTime: false,
|
||||
|
@ -210,9 +224,9 @@ class AppConfigFinished extends AppConfigState {
|
|||
required String hetznerKey,
|
||||
required String cloudFlareKey,
|
||||
required BackblazeCredential backblazeCredential,
|
||||
required CloudFlareDomain cloudFlareDomain,
|
||||
required ServerDomain serverDomain,
|
||||
required User rootUser,
|
||||
required HetznerServerDetails hetznerServer,
|
||||
required ServerHostingDetails serverDetails,
|
||||
required bool isServerStarted,
|
||||
required bool isServerResetedFirstTime,
|
||||
required bool isServerResetedSecondTime,
|
||||
|
@ -220,9 +234,9 @@ class AppConfigFinished extends AppConfigState {
|
|||
hetznerKey: hetznerKey,
|
||||
cloudFlareKey: cloudFlareKey,
|
||||
backblazeCredential: backblazeCredential,
|
||||
cloudFlareDomain: cloudFlareDomain,
|
||||
serverDomain: serverDomain,
|
||||
rootUser: rootUser,
|
||||
hetznerServer: hetznerServer,
|
||||
serverDetails: serverDetails,
|
||||
isServerStarted: isServerStarted,
|
||||
isServerResetedFirstTime: isServerResetedFirstTime,
|
||||
isServerResetedSecondTime: isServerResetedSecondTime,
|
||||
|
@ -233,35 +247,45 @@ class AppConfigFinished extends AppConfigState {
|
|||
hetznerKey,
|
||||
cloudFlareKey,
|
||||
backblazeCredential,
|
||||
cloudFlareDomain,
|
||||
serverDomain,
|
||||
rootUser,
|
||||
hetznerServer,
|
||||
serverDetails,
|
||||
isServerStarted,
|
||||
isServerResetedFirstTime,
|
||||
];
|
||||
}
|
||||
|
||||
class AppRecovery extends AppConfigState {
|
||||
const AppRecovery({
|
||||
required String hetznerKey,
|
||||
required String cloudFlareKey,
|
||||
required BackblazeCredential backblazeCredential,
|
||||
required CloudFlareDomain cloudFlareDomain,
|
||||
required User rootUser,
|
||||
required HetznerServerDetails hetznerServer,
|
||||
required bool isServerStarted,
|
||||
required bool isServerResetedFirstTime,
|
||||
required bool isServerResetedSecondTime,
|
||||
enum RecoveryStep {
|
||||
Selecting,
|
||||
RecoveryKey,
|
||||
NewDeviceKey,
|
||||
OldToken,
|
||||
HetznerToken,
|
||||
CloudflareToken,
|
||||
BackblazeToken,
|
||||
}
|
||||
|
||||
class AppConfigRecovery extends AppConfigState {
|
||||
final RecoveryStep currentStep;
|
||||
|
||||
const AppConfigRecovery({
|
||||
String? hetznerKey,
|
||||
String? cloudFlareKey,
|
||||
BackblazeCredential? backblazeCredential,
|
||||
ServerDomain? serverDomain,
|
||||
User? rootUser,
|
||||
ServerHostingDetails? serverDetails,
|
||||
required RecoveryStep this.currentStep,
|
||||
}) : super(
|
||||
hetznerKey: hetznerKey,
|
||||
cloudFlareKey: cloudFlareKey,
|
||||
backblazeCredential: backblazeCredential,
|
||||
cloudFlareDomain: cloudFlareDomain,
|
||||
serverDomain: serverDomain,
|
||||
rootUser: rootUser,
|
||||
hetznerServer: hetznerServer,
|
||||
isServerStarted: isServerStarted,
|
||||
isServerResetedFirstTime: isServerResetedFirstTime,
|
||||
isServerResetedSecondTime: isServerResetedSecondTime,
|
||||
serverDetails: serverDetails,
|
||||
isServerStarted: true,
|
||||
isServerResetedFirstTime: true,
|
||||
isServerResetedSecondTime: true,
|
||||
);
|
||||
|
||||
@override
|
||||
|
@ -269,10 +293,29 @@ class AppRecovery extends AppConfigState {
|
|||
hetznerKey,
|
||||
cloudFlareKey,
|
||||
backblazeCredential,
|
||||
cloudFlareDomain,
|
||||
serverDomain,
|
||||
rootUser,
|
||||
hetznerServer,
|
||||
serverDetails,
|
||||
isServerStarted,
|
||||
isServerResetedFirstTime,
|
||||
currentStep
|
||||
];
|
||||
|
||||
AppConfigRecovery copyWith({
|
||||
String? hetznerKey,
|
||||
String? cloudFlareKey,
|
||||
BackblazeCredential? backblazeCredential,
|
||||
ServerDomain? serverDomain,
|
||||
User? rootUser,
|
||||
ServerHostingDetails? serverDetails,
|
||||
RecoveryStep? currentStep,
|
||||
}) =>
|
||||
AppConfigRecovery(
|
||||
hetznerKey: hetznerKey ?? this.hetznerKey,
|
||||
cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey,
|
||||
backblazeCredential: backblazeCredential ?? this.backblazeCredential,
|
||||
serverDomain: serverDomain ?? this.serverDomain,
|
||||
rootUser: rootUser ?? this.rootUser,
|
||||
serverDetails: serverDetails ?? this.serverDetails,
|
||||
currentStep: currentStep ?? this.currentStep);
|
||||
}
|
||||
|
|
|
@ -85,9 +85,9 @@ class BackupsCubit extends AppConfigDependendCubit<BackupsState> {
|
|||
|
||||
Future<void> createBucket() async {
|
||||
emit(state.copyWith(preventActions: true));
|
||||
final domain = appConfigCubit.state.cloudFlareDomain!.domainName
|
||||
final domain = appConfigCubit.state.serverDomain!.domainName
|
||||
.replaceAll(RegExp(r'[^a-zA-Z0-9]'), '-');
|
||||
final serverId = appConfigCubit.state.hetznerServer!.id;
|
||||
final serverId = appConfigCubit.state.serverDetails!.id;
|
||||
var bucketName = 'selfprivacy-$domain-$serverId';
|
||||
// If bucket name is too long, shorten it
|
||||
if (bucketName.length > 49) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:cubit_form/cubit_form.dart';
|
||||
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/dns_records.dart';
|
||||
|
||||
import '../../api_maps/cloudflare.dart';
|
||||
|
@ -20,11 +20,11 @@ class DnsRecordsCubit extends AppConfigDependendCubit<DnsRecordsState> {
|
|||
emit(DnsRecordsState(
|
||||
dnsState: DnsRecordsStatus.refreshing,
|
||||
dnsRecords: _getDesiredDnsRecords(
|
||||
appConfigCubit.state.cloudFlareDomain?.domainName, "", "")));
|
||||
appConfigCubit.state.serverDomain?.domainName, "", "")));
|
||||
print('Loading DNS status');
|
||||
if (appConfigCubit.state is AppConfigFinished) {
|
||||
final CloudFlareDomain? domain = appConfigCubit.state.cloudFlareDomain;
|
||||
final String? ipAddress = appConfigCubit.state.hetznerServer?.ip4;
|
||||
final ServerDomain? domain = appConfigCubit.state.serverDomain;
|
||||
final String? ipAddress = appConfigCubit.state.serverDetails?.ip4;
|
||||
if (domain != null && ipAddress != null) {
|
||||
final List<DnsRecord> records =
|
||||
await cloudflare.getDnsRecords(cloudFlareDomain: domain);
|
||||
|
@ -95,8 +95,8 @@ class DnsRecordsCubit extends AppConfigDependendCubit<DnsRecordsState> {
|
|||
|
||||
Future<void> fix() async {
|
||||
emit(state.copyWith(dnsState: DnsRecordsStatus.refreshing));
|
||||
final CloudFlareDomain? domain = appConfigCubit.state.cloudFlareDomain;
|
||||
final String? ipAddress = appConfigCubit.state.hetznerServer?.ip4;
|
||||
final ServerDomain? domain = appConfigCubit.state.serverDomain;
|
||||
final String? ipAddress = appConfigCubit.state.serverDetails?.ip4;
|
||||
final String? dkimPublicKey = await api.getDkim();
|
||||
await cloudflare.removeSimilarRecords(cloudFlareDomain: domain!);
|
||||
await cloudflare.createMultipleDnsRecords(
|
||||
|
|
|
@ -52,5 +52,14 @@ class FieldCubitFactory {
|
|||
);
|
||||
}
|
||||
|
||||
FieldCubit<String> createServerDomainField() {
|
||||
return FieldCubit(
|
||||
initalValue: '',
|
||||
validations: [
|
||||
RequiredStringValidation('validations.required'.tr()),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
final BuildContext context;
|
||||
}
|
||||
|
|
|
@ -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/cloudflare_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/server_domain.dart';
|
||||
|
||||
class DomainSetupCubit extends Cubit<DomainSetupState> {
|
||||
DomainSetupCubit(this.initializingCubit) : super(Initial());
|
||||
|
@ -36,9 +36,10 @@ class DomainSetupCubit extends Cubit<DomainSetupState> {
|
|||
|
||||
var zoneId = await api.getZoneId(domainName);
|
||||
|
||||
var domain = CloudFlareDomain(
|
||||
var domain = ServerDomain(
|
||||
domainName: domainName,
|
||||
zoneId: zoneId,
|
||||
provider: DnsProvider.Cloudflare,
|
||||
);
|
||||
|
||||
initializingCubit.setDomain(domain);
|
||||
|
|
|
@ -1,51 +1,32 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cubit_form/cubit_form.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/hetzner.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/validations/validations.dart';
|
||||
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
||||
import 'package:selfprivacy/logic/models/server_domain.dart';
|
||||
|
||||
class RecoveryDomainFormCubit extends FormCubit {
|
||||
RecoveryDomainFormCubit(this.initializingCubit) {
|
||||
var regExp = RegExp(r"\s+|[-!$%^&*()@+|~=`{}\[\]:<>?,.\/]");
|
||||
apiKey = FieldCubit(
|
||||
initalValue: '',
|
||||
validations: [
|
||||
RequiredStringValidation('validations.required'.tr()),
|
||||
ValidationModel<String>(
|
||||
(s) => regExp.hasMatch(s), 'validations.key_format'.tr()),
|
||||
LengthStringNotEqualValidation(64)
|
||||
],
|
||||
);
|
||||
RecoveryDomainFormCubit(
|
||||
this.initializingCubit, final FieldCubitFactory fieldFactory) {
|
||||
serverDomainField = fieldFactory.createServerDomainField();
|
||||
|
||||
super.addFields([apiKey]);
|
||||
super.addFields([serverDomainField]);
|
||||
}
|
||||
|
||||
@override
|
||||
FutureOr<void> onSubmit() async {
|
||||
initializingCubit.setHetznerKey(apiKey.state.value);
|
||||
initializingCubit.setDomain(ServerDomain(
|
||||
domainName: serverDomainField.state.value,
|
||||
provider: DnsProvider.Unknown,
|
||||
zoneId: ""));
|
||||
}
|
||||
|
||||
// @override
|
||||
// FutureOr<bool> asyncValidation() async {
|
||||
// ; //var client =
|
||||
// }
|
||||
|
||||
final AppConfigCubit initializingCubit;
|
||||
|
||||
late final FieldCubit<String> apiKey;
|
||||
|
||||
@override
|
||||
FutureOr<bool> asyncValidation() async {
|
||||
late bool isKeyValid;
|
||||
HetznerApi apiClient = HetznerApi(isWithToken: false);
|
||||
|
||||
try {
|
||||
isKeyValid = await apiClient.isValid(apiKey.state.value);
|
||||
} catch (e) {
|
||||
addError(e);
|
||||
}
|
||||
|
||||
if (!isKeyValid) {
|
||||
apiKey.setError('bad key');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
late final FieldCubit<String> serverDomainField;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class ServerDetailsCubit extends Cubit<ServerDetailsState> {
|
|||
ServerDetailsRepository repository = ServerDetailsRepository();
|
||||
|
||||
void check() async {
|
||||
var isReadyToCheck = getIt<ApiConfigModel>().hetznerServer != null;
|
||||
var isReadyToCheck = getIt<ApiConfigModel>().serverDetails != null;
|
||||
if (isReadyToCheck) {
|
||||
emit(ServerDetailsLoading());
|
||||
var data = await repository.load();
|
||||
|
|
|
@ -2,26 +2,24 @@ 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/cloudflare_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/server_details.dart';
|
||||
|
||||
class ApiConfigModel {
|
||||
Box _box = Hive.box(BNames.appConfig);
|
||||
|
||||
HetznerServerDetails? get hetznerServer => _hetznerServer;
|
||||
ServerHostingDetails? get serverDetails => _serverDetails;
|
||||
String? get hetznerKey => _hetznerKey;
|
||||
String? get cloudFlareKey => _cloudFlareKey;
|
||||
String? get serverDomain => _serverDomain;
|
||||
BackblazeCredential? get backblazeCredential => _backblazeCredential;
|
||||
CloudFlareDomain? get cloudFlareDomain => _cloudFlareDomain;
|
||||
ServerDomain? get serverDomain => _serverDomain;
|
||||
BackblazeBucket? get backblazeBucket => _backblazeBucket;
|
||||
|
||||
String? _hetznerKey;
|
||||
String? _cloudFlareKey;
|
||||
String? _serverDomain;
|
||||
HetznerServerDetails? _hetznerServer;
|
||||
ServerHostingDetails? _serverDetails;
|
||||
BackblazeCredential? _backblazeCredential;
|
||||
CloudFlareDomain? _cloudFlareDomain;
|
||||
ServerDomain? _serverDomain;
|
||||
BackblazeBucket? _backblazeBucket;
|
||||
|
||||
Future<void> storeHetznerKey(String value) async {
|
||||
|
@ -34,25 +32,20 @@ class ApiConfigModel {
|
|||
_cloudFlareKey = value;
|
||||
}
|
||||
|
||||
Future<void> storeServerDomain(String value) async {
|
||||
await _box.put(BNames.serverDomain, value);
|
||||
_serverDomain = value;
|
||||
}
|
||||
|
||||
Future<void> storeBackblazeCredential(BackblazeCredential value) async {
|
||||
await _box.put(BNames.backblazeKey, value);
|
||||
|
||||
_backblazeCredential = value;
|
||||
}
|
||||
|
||||
Future<void> storeCloudFlareDomain(CloudFlareDomain value) async {
|
||||
await _box.put(BNames.cloudFlareDomain, value);
|
||||
_cloudFlareDomain = value;
|
||||
Future<void> storeServerDomain(ServerDomain value) async {
|
||||
await _box.put(BNames.serverDomain, value);
|
||||
_serverDomain = value;
|
||||
}
|
||||
|
||||
Future<void> storeServerDetails(HetznerServerDetails value) async {
|
||||
await _box.put(BNames.hetznerServer, value);
|
||||
_hetznerServer = value;
|
||||
Future<void> storeServerDetails(ServerHostingDetails value) async {
|
||||
await _box.put(BNames.serverDetails, value);
|
||||
_serverDetails = value;
|
||||
}
|
||||
|
||||
Future<void> storeBackblazeBucket(BackblazeBucket value) async {
|
||||
|
@ -64,8 +57,8 @@ class ApiConfigModel {
|
|||
_hetznerKey = null;
|
||||
_cloudFlareKey = null;
|
||||
_backblazeCredential = null;
|
||||
_cloudFlareDomain = null;
|
||||
_hetznerServer = null;
|
||||
_serverDomain = null;
|
||||
_serverDetails = null;
|
||||
_backblazeBucket = null;
|
||||
}
|
||||
|
||||
|
@ -74,8 +67,8 @@ class ApiConfigModel {
|
|||
|
||||
_cloudFlareKey = _box.get(BNames.cloudFlareKey);
|
||||
_backblazeCredential = _box.get(BNames.backblazeKey);
|
||||
_cloudFlareDomain = _box.get(BNames.cloudFlareDomain);
|
||||
_hetznerServer = _box.get(BNames.hetznerServer);
|
||||
_serverDomain = _box.get(BNames.serverDomain);
|
||||
_serverDetails = _box.get(BNames.serverDetails);
|
||||
_backblazeBucket = _box.get(BNames.backblazeBucket);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ import 'package:hive/hive.dart';
|
|||
part 'server_details.g.dart';
|
||||
|
||||
@HiveType(typeId: 2)
|
||||
class HetznerServerDetails {
|
||||
HetznerServerDetails({
|
||||
class ServerHostingDetails {
|
||||
ServerHostingDetails({
|
||||
required this.ip4,
|
||||
required this.id,
|
||||
required this.createTime,
|
||||
|
@ -26,13 +26,13 @@ class HetznerServerDetails {
|
|||
final DateTime? startTime;
|
||||
|
||||
@HiveField(4)
|
||||
final HetznerDataBase dataBase;
|
||||
final ServerVolume dataBase;
|
||||
|
||||
@HiveField(5)
|
||||
final String apiToken;
|
||||
|
||||
HetznerServerDetails copyWith({DateTime? startTime}) {
|
||||
return HetznerServerDetails(
|
||||
ServerHostingDetails copyWith({DateTime? startTime}) {
|
||||
return ServerHostingDetails(
|
||||
startTime: startTime ?? this.startTime,
|
||||
createTime: createTime,
|
||||
id: id,
|
||||
|
@ -46,8 +46,8 @@ class HetznerServerDetails {
|
|||
}
|
||||
|
||||
@HiveType(typeId: 5)
|
||||
class HetznerDataBase {
|
||||
HetznerDataBase({
|
||||
class ServerVolume {
|
||||
ServerVolume({
|
||||
required this.id,
|
||||
required this.name,
|
||||
});
|
||||
|
|
|
@ -6,28 +6,28 @@ part of 'server_details.dart';
|
|||
// TypeAdapterGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class HetznerServerDetailsAdapter extends TypeAdapter<HetznerServerDetails> {
|
||||
class HetznerServerDetailsAdapter extends TypeAdapter<ServerHostingDetails> {
|
||||
@override
|
||||
final int typeId = 2;
|
||||
|
||||
@override
|
||||
HetznerServerDetails read(BinaryReader reader) {
|
||||
ServerHostingDetails read(BinaryReader reader) {
|
||||
final numOfFields = reader.readByte();
|
||||
final fields = <int, dynamic>{
|
||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return HetznerServerDetails(
|
||||
return ServerHostingDetails(
|
||||
ip4: fields[0] as String,
|
||||
id: fields[1] as int,
|
||||
createTime: fields[3] as DateTime?,
|
||||
dataBase: fields[4] as HetznerDataBase,
|
||||
dataBase: fields[4] as ServerVolume,
|
||||
apiToken: fields[5] as String,
|
||||
startTime: fields[2] as DateTime?,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, HetznerServerDetails obj) {
|
||||
void write(BinaryWriter writer, ServerHostingDetails obj) {
|
||||
writer
|
||||
..writeByte(6)
|
||||
..writeByte(0)
|
||||
|
@ -55,24 +55,24 @@ class HetznerServerDetailsAdapter extends TypeAdapter<HetznerServerDetails> {
|
|||
typeId == other.typeId;
|
||||
}
|
||||
|
||||
class HetznerDataBaseAdapter extends TypeAdapter<HetznerDataBase> {
|
||||
class HetznerDataBaseAdapter extends TypeAdapter<ServerVolume> {
|
||||
@override
|
||||
final int typeId = 5;
|
||||
|
||||
@override
|
||||
HetznerDataBase read(BinaryReader reader) {
|
||||
ServerVolume read(BinaryReader reader) {
|
||||
final numOfFields = reader.readByte();
|
||||
final fields = <int, dynamic>{
|
||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return HetznerDataBase(
|
||||
return ServerVolume(
|
||||
id: fields[1] as int,
|
||||
name: fields[2] as String,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, HetznerDataBase obj) {
|
||||
void write(BinaryWriter writer, ServerVolume obj) {
|
||||
writer
|
||||
..writeByte(2)
|
||||
..writeByte(1)
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'cloudflare_domain.g.dart';
|
||||
part 'server_domain.g.dart';
|
||||
|
||||
enum DnsProvider {
|
||||
Unknown,
|
||||
Cloudflare,
|
||||
}
|
||||
|
||||
@HiveType(typeId: 3)
|
||||
class CloudFlareDomain {
|
||||
CloudFlareDomain({
|
||||
class ServerDomain {
|
||||
ServerDomain({
|
||||
required this.domainName,
|
||||
required this.zoneId,
|
||||
required this.provider,
|
||||
});
|
||||
|
||||
@HiveField(0)
|
||||
|
@ -15,6 +21,9 @@ class CloudFlareDomain {
|
|||
@HiveField(1)
|
||||
final String zoneId;
|
||||
|
||||
@HiveField(2, defaultValue: DnsProvider.Cloudflare)
|
||||
final DnsProvider provider;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '$domainName: $zoneId';
|
|
@ -1,35 +1,39 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'cloudflare_domain.dart';
|
||||
part of 'server_domain.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// TypeAdapterGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class CloudFlareDomainAdapter extends TypeAdapter<CloudFlareDomain> {
|
||||
class ServerDomainAdapter extends TypeAdapter<ServerDomain> {
|
||||
@override
|
||||
final int typeId = 3;
|
||||
|
||||
@override
|
||||
CloudFlareDomain read(BinaryReader reader) {
|
||||
ServerDomain read(BinaryReader reader) {
|
||||
final numOfFields = reader.readByte();
|
||||
final fields = <int, dynamic>{
|
||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return CloudFlareDomain(
|
||||
return ServerDomain(
|
||||
domainName: fields[0] as String,
|
||||
zoneId: fields[1] as String,
|
||||
provider:
|
||||
fields[2] == null ? DnsProvider.Cloudflare : fields[2] as DnsProvider,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, CloudFlareDomain obj) {
|
||||
void write(BinaryWriter writer, ServerDomain obj) {
|
||||
writer
|
||||
..writeByte(2)
|
||||
..writeByte(3)
|
||||
..writeByte(0)
|
||||
..write(obj.domainName)
|
||||
..writeByte(1)
|
||||
..write(obj.zoneId);
|
||||
..write(obj.zoneId)
|
||||
..writeByte(2)
|
||||
..write(obj.provider);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -38,7 +42,7 @@ class CloudFlareDomainAdapter extends TypeAdapter<CloudFlareDomain> {
|
|||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is CloudFlareDomainAdapter &&
|
||||
other is ServerDomainAdapter &&
|
||||
runtimeType == other.runtimeType &&
|
||||
typeId == other.typeId;
|
||||
}
|
|
@ -63,7 +63,7 @@ class _DnsDetailsPageState extends State<DnsDetailsPage> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var isReady = context.watch<AppConfigCubit>().state is AppConfigFinished;
|
||||
final domain = getIt<ApiConfigModel>().cloudFlareDomain?.domainName ?? '';
|
||||
final domain = getIt<ApiConfigModel>().serverDomain?.domainName ?? '';
|
||||
var dnsCubit = context.watch<DnsRecordsCubit>().state;
|
||||
|
||||
print(dnsCubit.dnsState);
|
||||
|
|
|
@ -129,7 +129,7 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
|
|||
|
||||
Widget deleteServer(BuildContext context) {
|
||||
var isDisabled =
|
||||
context.watch<AppConfigCubit>().state.hetznerServer == null;
|
||||
context.watch<AppConfigCubit>().state.serverDetails == null;
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 20, bottom: 5),
|
||||
decoration: BoxDecoration(
|
||||
|
|
|
@ -100,7 +100,7 @@ class _Card extends StatelessWidget {
|
|||
AppConfigState appConfig = context.watch<AppConfigCubit>().state;
|
||||
|
||||
var domainName =
|
||||
appConfig.isDomainFilled ? appConfig.cloudFlareDomain!.domainName : '';
|
||||
appConfig.isDomainFilled ? appConfig.serverDomain!.domainName : '';
|
||||
|
||||
switch (provider.type) {
|
||||
case ProviderType.server:
|
||||
|
|
|
@ -1,75 +1,48 @@
|
|||
import 'package:cubit_form/cubit_form.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.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/cubit/forms/setup/recovering/recovery_domain_form_cubit.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_button/brand_button.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart';
|
||||
|
||||
class RecoveryDomain extends StatefulWidget {
|
||||
@override
|
||||
State<RecoveryDomain> createState() => _RecoveryDomainState();
|
||||
}
|
||||
|
||||
class _RecoveryDomainState extends State<RecoveryDomain> {
|
||||
class RecoveryDomain extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BrandHeroScreen(
|
||||
children: [
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "recovering.domain_recover_placeholder".tr(),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
BrandButton.rised(
|
||||
onPressed: () {},
|
||||
text: "more.continue".tr(),
|
||||
),
|
||||
],
|
||||
heroTitle: "recovering.recovery_main_header".tr(),
|
||||
heroSubtitle: "recovering.domain_recovery_description".tr(),
|
||||
hasBackButton: true,
|
||||
hasFlashButton: false,
|
||||
heroIcon: Icons.link,
|
||||
);
|
||||
}
|
||||
}
|
||||
var appConfig = context.watch<AppConfigCubit>();
|
||||
|
||||
/*class RecoveryDomain extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: PreferredSize(
|
||||
preferredSize: Size.fromHeight(52),
|
||||
child: BrandHeader(hasBackButton: true),
|
||||
),
|
||||
body: ListView(
|
||||
padding: EdgeInsets.all(16),
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
RecoveryDomainFormCubit(appConfig, FieldCubitFactory(context)),
|
||||
child: Builder(builder: (context) {
|
||||
var formCubitState = context.watch<RecoveryDomainFormCubit>().state;
|
||||
|
||||
return BrandHeroScreen(
|
||||
children: [
|
||||
Text(
|
||||
"recovering.recovery_main_header".tr(),
|
||||
style: Theme.of(context).textTheme.headlineMedium,
|
||||
),
|
||||
SizedBox(height: 18),
|
||||
Text(
|
||||
"recovering.domain_recovery_description".tr(),
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
SizedBox(height: 18),
|
||||
TextField(
|
||||
CubitFormTextField(
|
||||
formFieldCubit:
|
||||
context.read<RecoveryDomainFormCubit>().serverDomainField,
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "recovering.domain_recover_placeholder".tr(),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 18),
|
||||
SizedBox(height: 16),
|
||||
BrandButton.rised(
|
||||
onPressed: () {},
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () => context.read<RecoveryDomainFormCubit>().trySubmit(),
|
||||
text: "more.continue".tr(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
heroTitle: "recovering.recovery_main_header".tr(),
|
||||
heroSubtitle: "recovering.domain_recovery_description".tr(),
|
||||
hasBackButton: true,
|
||||
hasFlashButton: false,
|
||||
heroIcon: Icons.link,
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
|||
/// it's ui helpers use only for ui components, don't use for logic components.
|
||||
|
||||
class UiHelpers {
|
||||
static String getDomainName(AppConfigState config) => config.isDomainFilled
|
||||
? config.cloudFlareDomain!.domainName
|
||||
: 'example.com';
|
||||
static String getDomainName(AppConfigState config) =>
|
||||
config.isDomainFilled ? config.serverDomain!.domainName : 'example.com';
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue