selfprivacy.org.app/lib/logic/cubit/server_installation/server_installation_cubit.dart

675 lines
20 KiB
Dart
Raw Normal View History

2021-01-21 23:01:42 +02:00
import 'dart:async';
2022-05-24 21:55:39 +03:00
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:easy_localization/easy_localization.dart';
2021-01-06 19:35:57 +02:00
import 'package:equatable/equatable.dart';
import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
import 'package:selfprivacy/logic/api_maps/rest_maps/provider_api_settings.dart';
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
import 'package:selfprivacy/logic/models/hive/server_details.dart';
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
import 'package:selfprivacy/logic/models/hive/user.dart';
import 'package:selfprivacy/logic/models/server_basic_info.dart';
2021-01-21 09:35:38 +02:00
2022-06-05 22:36:32 +03:00
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_repository.dart';
2022-02-08 08:59:19 +02:00
2021-03-18 02:55:38 +02:00
export 'package:provider/provider.dart';
2021-01-06 19:35:57 +02:00
part '../server_installation/server_installation_state.dart';
2021-01-06 19:35:57 +02:00
class ServerInstallationCubit extends Cubit<ServerInstallationState> {
2022-05-24 21:55:39 +03:00
ServerInstallationCubit() : super(const ServerInstallationEmpty());
2021-01-06 19:35:57 +02:00
2022-06-05 22:36:32 +03:00
final ServerInstallationRepository repository =
ServerInstallationRepository();
2021-01-06 19:35:57 +02:00
Timer? timer;
2021-03-31 17:33:58 +03:00
Future<void> load() async {
2022-06-05 22:36:32 +03:00
final ServerInstallationState state = await repository.load();
2021-02-16 20:48:15 +02:00
if (state is ServerInstallationFinished) {
2021-02-16 20:48:15 +02:00
emit(state);
} else if (state is ServerInstallationNotFinished) {
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);
2021-10-14 00:49:24 +03:00
} else {
emit(state);
}
} else if (state is ServerInstallationRecovery) {
emit(state);
} else {
throw 'wrong state';
2021-02-16 20:48:15 +02:00
}
}
RegExp getServerProviderApiTokenValidation() =>
repository.serverProviderApiFactory!
.getServerProvider()
.getApiTokenValidation();
RegExp getDnsProviderApiTokenValidation() => repository.dnsProviderApiFactory!
.getDnsProvider()
2022-07-13 14:58:23 +03:00
.getApiTokenValidation();
2022-07-12 15:54:16 +03:00
Future<bool> isServerProviderApiTokenValid(
final String providerToken,
) async =>
2022-07-13 14:58:23 +03:00
repository.serverProviderApiFactory!
.getServerProvider(
settings: const ProviderApiSettings(isWithToken: false),
)
.isApiTokenValid(providerToken);
Future<bool> isDnsProviderApiTokenValid(
final String providerToken,
) async =>
repository.dnsProviderApiFactory!
.getDnsProvider(
settings: const DnsProviderApiSettings(isWithToken: false),
)
2022-07-13 14:58:23 +03:00
.isApiTokenValid(providerToken);
2022-07-12 15:54:16 +03:00
2022-06-05 22:36:32 +03:00
void setHetznerKey(final String hetznerKey) async {
await repository.saveHetznerKey(hetznerKey);
if (state is ServerInstallationRecovery) {
2022-06-05 22:36:32 +03:00
emit(
(state as ServerInstallationRecovery).copyWith(
2022-07-12 15:54:16 +03:00
providerApiToken: hetznerKey,
2022-06-05 22:36:32 +03:00
currentStep: RecoveryStep.serverSelection,
),
);
return;
}
2022-06-05 22:36:32 +03:00
emit(
2022-07-12 15:54:16 +03:00
(state as ServerInstallationNotFinished).copyWith(
providerApiToken: hetznerKey,
),
2022-06-05 22:36:32 +03:00
);
}
2021-02-16 20:48:15 +02:00
2022-06-05 22:36:32 +03:00
void setCloudflareKey(final String cloudFlareKey) async {
if (state is ServerInstallationRecovery) {
setAndValidateCloudflareToken(cloudFlareKey);
return;
}
await repository.saveCloudFlareKey(cloudFlareKey);
2022-06-05 22:36:32 +03:00
emit(
(state as ServerInstallationNotFinished)
.copyWith(cloudFlareKey: cloudFlareKey),
);
}
2022-06-05 22:36:32 +03:00
void setBackblazeKey(final String keyId, final String applicationKey) async {
final BackblazeCredential backblazeCredential = BackblazeCredential(
keyId: keyId,
applicationKey: applicationKey,
);
await repository.saveBackblazeKey(backblazeCredential);
2022-05-23 17:21:34 +03:00
if (state is ServerInstallationRecovery) {
finishRecoveryProcess(backblazeCredential);
2022-05-23 17:21:34 +03:00
return;
}
2022-06-05 22:36:32 +03:00
emit(
(state as ServerInstallationNotFinished)
.copyWith(backblazeCredential: backblazeCredential),
);
}
2022-06-05 22:36:32 +03:00
void setDomain(final ServerDomain serverDomain) async {
await repository.saveDomain(serverDomain);
2022-06-05 22:36:32 +03:00
emit(
(state as ServerInstallationNotFinished)
.copyWith(serverDomain: serverDomain),
);
}
2022-06-05 22:36:32 +03:00
void setRootUser(final User rootUser) async {
await repository.saveRootUser(rootUser);
emit((state as ServerInstallationNotFinished).copyWith(rootUser: rootUser));
}
void createServerAndSetDnsRecords() async {
2022-06-05 22:36:32 +03:00
final ServerInstallationNotFinished stateCopy =
state as ServerInstallationNotFinished;
2022-06-05 22:36:32 +03:00
void onCancel() => emit(
(state as ServerInstallationNotFinished).copyWith(isLoading: false),
);
2022-06-05 22:36:32 +03:00
Future<void> onSuccess(final ServerHostingDetails serverDetails) async {
2022-07-13 14:58:23 +03:00
await repository.createDnsRecords(
serverDetails,
state.serverDomain!,
onCancel: onCancel,
);
2022-06-05 22:36:32 +03:00
emit(
(state as ServerInstallationNotFinished).copyWith(
isLoading: false,
serverDetails: serverDetails,
),
);
2022-05-24 21:55:39 +03:00
runDelayed(startServerIfDnsIsOkay, const Duration(seconds: 30), null);
}
try {
emit((state as ServerInstallationNotFinished).copyWith(isLoading: true));
await repository.createServer(
state.rootUser!,
state.serverDomain!.domainName,
state.cloudFlareKey!,
state.backblazeCredential!,
onCancel: onCancel,
onSuccess: onSuccess,
);
} catch (e) {
2022-05-24 21:55:39 +03:00
emit(stateCopy);
}
}
2021-02-16 20:48:15 +02:00
2022-06-10 00:13:06 +03:00
void startServerIfDnsIsOkay({
final ServerInstallationNotFinished? state,
}) async {
2022-06-05 22:36:32 +03:00
final ServerInstallationNotFinished dataState =
state ?? this.state as ServerInstallationNotFinished;
2021-02-16 20:48:15 +02:00
emit(TimerState(dataState: dataState, isLoading: true));
2021-02-16 20:48:15 +02:00
2022-06-05 22:36:32 +03:00
final String ip4 = dataState.serverDetails!.ip4;
final String domainName = dataState.serverDomain!.domainName;
2021-03-25 10:32:00 +02:00
2022-06-05 22:36:32 +03:00
final Map<String, bool> matches = await repository.isDnsAddressesMatch(
domainName,
ip4,
2022-06-09 19:15:53 +03:00
dataState.dnsMatches ?? {},
2022-06-05 22:36:32 +03:00
);
2022-06-05 22:36:32 +03:00
if (matches.values.every((final bool value) => value)) {
2022-07-12 15:54:16 +03:00
final ServerHostingDetails? server = await repository.startServer(
dataState.serverDetails!,
);
2022-07-12 15:54:16 +03:00
if (server == null) {
final ServerInstallationNotFinished newState = dataState.copyWith(
isLoading: false,
dnsMatches: matches,
);
emit(newState);
runDelayed(
startServerIfDnsIsOkay,
const Duration(seconds: 30),
newState,
);
return;
}
await repository.saveServerDetails(server);
await repository.saveIsServerStarted(true);
2021-02-16 20:48:15 +02:00
2022-06-05 22:36:32 +03:00
final ServerInstallationNotFinished newState = dataState.copyWith(
isServerStarted: true,
isLoading: false,
serverDetails: server,
);
2022-06-05 22:36:32 +03:00
emit(newState);
2022-05-24 21:55:39 +03:00
runDelayed(
2022-06-05 22:36:32 +03:00
resetServerIfServerIsOkay,
const Duration(seconds: 60),
newState,
);
2021-02-16 20:48:15 +02:00
} else {
2022-06-05 22:36:32 +03:00
final ServerInstallationNotFinished newState = dataState.copyWith(
isLoading: false,
dnsMatches: matches,
);
2022-06-05 22:36:32 +03:00
emit(newState);
2022-05-24 21:55:39 +03:00
runDelayed(
2022-06-05 22:36:32 +03:00
startServerIfDnsIsOkay,
const Duration(seconds: 30),
newState,
);
2021-02-16 20:48:15 +02:00
}
}
2022-06-05 22:36:32 +03:00
void resetServerIfServerIsOkay({
final ServerInstallationNotFinished? state,
}) async {
final ServerInstallationNotFinished dataState =
state ?? this.state as ServerInstallationNotFinished;
2021-02-16 20:48:15 +02:00
emit(TimerState(dataState: dataState, isLoading: true));
2021-02-16 20:48:15 +02:00
2022-06-05 22:36:32 +03:00
final bool isServerWorking = await repository.isHttpServerWorking();
2021-02-16 20:48:15 +02:00
if (isServerWorking) {
2022-06-05 22:36:32 +03:00
const Duration pauseDuration = Duration(seconds: 30);
emit(
TimerState(
dataState: dataState,
timerStart: DateTime.now(),
isLoading: false,
duration: pauseDuration,
),
);
timer = Timer(pauseDuration, () async {
2022-06-05 22:36:32 +03:00
final ServerHostingDetails hetznerServerDetails =
await repository.restart();
await repository.saveIsServerResetedFirstTime(true);
await repository.saveServerDetails(hetznerServerDetails);
2022-06-05 22:36:32 +03:00
final ServerInstallationNotFinished newState = dataState.copyWith(
isServerResetedFirstTime: true,
serverDetails: hetznerServerDetails,
isLoading: false,
);
2022-06-05 22:36:32 +03:00
emit(newState);
runDelayed(oneMoreReset, const Duration(seconds: 60), newState);
});
2021-03-31 14:37:39 +03:00
} else {
2022-06-05 22:36:32 +03:00
runDelayed(
resetServerIfServerIsOkay,
const Duration(seconds: 60),
dataState,
);
2021-03-31 14:37:39 +03:00
}
}
2022-06-05 22:36:32 +03:00
void oneMoreReset({final ServerInstallationNotFinished? state}) async {
final ServerInstallationNotFinished dataState =
state ?? this.state as ServerInstallationNotFinished;
2021-03-31 14:37:39 +03:00
emit(TimerState(dataState: dataState, isLoading: true));
2021-03-31 14:37:39 +03:00
2022-06-05 22:36:32 +03:00
final bool isServerWorking = await repository.isHttpServerWorking();
2021-03-31 14:37:39 +03:00
if (isServerWorking) {
2022-06-05 22:36:32 +03:00
const Duration pauseDuration = Duration(seconds: 30);
emit(
TimerState(
dataState: dataState,
timerStart: DateTime.now(),
isLoading: false,
duration: pauseDuration,
),
);
timer = Timer(pauseDuration, () async {
2022-06-05 22:36:32 +03:00
final ServerHostingDetails hetznerServerDetails =
await repository.restart();
await repository.saveIsServerResetedSecondTime(true);
await repository.saveServerDetails(hetznerServerDetails);
2022-06-05 22:36:32 +03:00
final ServerInstallationNotFinished newState = dataState.copyWith(
isServerResetedSecondTime: true,
serverDetails: hetznerServerDetails,
isLoading: false,
);
emit(newState);
runDelayed(
finishCheckIfServerIsOkay,
const Duration(seconds: 60),
newState,
);
});
2021-02-16 20:48:15 +02:00
} else {
2022-06-05 22:36:32 +03:00
runDelayed(oneMoreReset, const Duration(seconds: 60), dataState);
2021-02-16 20:48:15 +02:00
}
}
void finishCheckIfServerIsOkay({
2022-06-05 22:36:32 +03:00
final ServerInstallationNotFinished? state,
2021-02-16 20:48:15 +02:00
}) async {
2022-06-05 22:36:32 +03:00
final ServerInstallationNotFinished dataState =
state ?? this.state as ServerInstallationNotFinished;
2021-02-16 20:48:15 +02:00
emit(TimerState(dataState: dataState, isLoading: true));
2021-02-16 20:48:15 +02:00
2022-06-05 22:36:32 +03:00
final bool isServerWorking = await repository.isHttpServerWorking();
2021-02-16 20:48:15 +02:00
if (isServerWorking) {
await repository.createDkimRecord(dataState.serverDomain!);
await repository.saveHasFinalChecked(true);
2021-03-25 10:32:00 +02:00
emit(dataState.finish());
2021-02-16 20:48:15 +02:00
} else {
2022-05-24 21:55:39 +03:00
runDelayed(
2022-06-05 22:36:32 +03:00
finishCheckIfServerIsOkay,
const Duration(seconds: 60),
dataState,
);
2021-02-16 20:48:15 +02:00
}
2021-01-06 19:35:57 +02:00
}
2022-06-05 22:36:32 +03:00
void runDelayed(
final void Function() work,
final Duration delay,
final ServerInstallationNotFinished? state,
) async {
final ServerInstallationNotFinished dataState =
state ?? this.state as ServerInstallationNotFinished;
2022-06-05 22:36:32 +03:00
emit(
TimerState(
dataState: dataState,
timerStart: DateTime.now(),
duration: delay,
isLoading: false,
),
);
timer = Timer(delay, work);
}
2022-06-05 22:36:32 +03:00
void submitDomainForAccessRecovery(final String domain) async {
final ServerDomain serverDomain = ServerDomain(
domainName: domain,
2022-05-24 21:55:39 +03:00
provider: DnsProvider.unknown,
zoneId: '',
);
2022-06-05 22:36:32 +03:00
final ServerRecoveryCapabilities recoveryCapabilities =
await repository.getRecoveryCapabilities(serverDomain);
await repository.saveDomain(serverDomain);
2022-05-31 02:06:08 +03:00
await repository.saveIsRecoveringServer(true);
2022-06-05 22:36:32 +03:00
emit(
ServerInstallationRecovery(
serverDomain: serverDomain,
recoveryCapabilities: recoveryCapabilities,
currentStep: RecoveryStep.selecting,
),
);
}
2022-06-05 22:36:32 +03:00
void tryToRecover(
2022-06-10 00:13:06 +03:00
final String token,
final ServerRecoveryMethods method,
) async {
2022-06-05 22:36:32 +03:00
final ServerInstallationRecovery dataState =
state as ServerInstallationRecovery;
final ServerDomain? serverDomain = dataState.serverDomain;
if (serverDomain == null) {
return;
}
try {
Future<ServerHostingDetails> Function(
2022-06-05 22:36:32 +03:00
ServerDomain,
String,
ServerRecoveryCapabilities,
) recoveryFunction;
switch (method) {
case ServerRecoveryMethods.newDeviceKey:
recoveryFunction = repository.authorizeByNewDeviceKey;
break;
case ServerRecoveryMethods.recoveryKey:
recoveryFunction = repository.authorizeByRecoveryKey;
break;
case ServerRecoveryMethods.oldToken:
recoveryFunction = repository.authorizeByApiToken;
break;
default:
throw Exception('Unknown recovery method');
}
2022-06-05 22:36:32 +03:00
final ServerHostingDetails serverDetails = await recoveryFunction(
serverDomain,
token,
dataState.recoveryCapabilities,
);
await repository.saveServerDetails(serverDetails);
2022-06-05 22:36:32 +03:00
emit(
dataState.copyWith(
serverDetails: serverDetails,
currentStep: RecoveryStep.hetznerToken,
),
);
} on ServerAuthorizationException {
getIt<NavigationService>()
.showSnackBar('recovering.authorization_failed'.tr());
return;
} on IpNotFoundException {
getIt<NavigationService>()
.showSnackBar('recovering.domain_recover_error'.tr());
return;
}
}
void revertRecoveryStep() {
2022-06-10 00:13:06 +03:00
if (state is ServerInstallationEmpty) {
return;
}
2022-06-05 22:36:32 +03:00
final ServerInstallationRecovery dataState =
state as ServerInstallationRecovery;
switch (dataState.currentStep) {
2022-05-24 21:55:39 +03:00
case RecoveryStep.selecting:
repository.deleteDomain();
2022-05-24 21:55:39 +03:00
emit(const ServerInstallationEmpty());
break;
2022-05-24 21:55:39 +03:00
case RecoveryStep.recoveryKey:
case RecoveryStep.newDeviceKey:
case RecoveryStep.oldToken:
2022-06-05 22:36:32 +03:00
emit(
dataState.copyWith(
currentStep: RecoveryStep.selecting,
),
);
break;
2022-06-15 06:23:54 +03:00
case RecoveryStep.cloudflareToken:
repository.deleteServerDetails();
emit(
dataState.copyWith(
currentStep: RecoveryStep.serverSelection,
),
);
break;
// We won't revert steps after client is authorized
default:
break;
}
}
2022-06-05 22:36:32 +03:00
void selectRecoveryMethod(final ServerRecoveryMethods method) {
final ServerInstallationRecovery dataState =
state as ServerInstallationRecovery;
switch (method) {
case ServerRecoveryMethods.newDeviceKey:
2022-06-05 22:36:32 +03:00
emit(
dataState.copyWith(
currentStep: RecoveryStep.newDeviceKey,
),
);
break;
case ServerRecoveryMethods.recoveryKey:
2022-06-05 22:36:32 +03:00
emit(
dataState.copyWith(
currentStep: RecoveryStep.recoveryKey,
),
);
break;
case ServerRecoveryMethods.oldToken:
2022-06-05 22:36:32 +03:00
emit(
dataState.copyWith(
currentStep: RecoveryStep.oldToken,
),
);
break;
}
}
Future<List<ServerBasicInfoWithValidators>>
getServersOnHetznerAccount() async {
2022-06-05 22:36:32 +03:00
final ServerInstallationRecovery dataState =
state as ServerInstallationRecovery;
final List<ServerBasicInfo> servers =
2022-07-12 15:54:16 +03:00
await repository.getServersOnProviderAccount();
2022-06-05 22:36:32 +03:00
final Iterable<ServerBasicInfoWithValidators> validated = servers.map(
(final ServerBasicInfo server) =>
ServerBasicInfoWithValidators.fromServerBasicInfo(
serverBasicInfo: server,
isIpValid: server.ip == dataState.serverDetails?.ip4,
isReverseDnsValid:
server.reverseDns == dataState.serverDomain?.domainName,
),
);
return validated.toList();
}
2022-06-05 22:36:32 +03:00
Future<void> setServerId(final ServerBasicInfo server) async {
final ServerInstallationRecovery dataState =
state as ServerInstallationRecovery;
final ServerDomain? serverDomain = dataState.serverDomain;
if (serverDomain == null) {
return;
}
2022-06-05 22:36:32 +03:00
final ServerHostingDetails serverDetails = ServerHostingDetails(
ip4: server.ip,
id: server.id,
createTime: server.created,
volume: ServerVolume(
id: server.volumeId,
2022-05-24 21:55:39 +03:00
name: 'recovered_volume',
2022-06-28 21:06:52 +03:00
sizeByte: 0,
2022-06-27 10:07:11 +03:00
serverId: server.id,
),
apiToken: dataState.serverDetails!.apiToken,
2022-05-24 21:55:39 +03:00
provider: ServerProvider.hetzner,
);
await repository.saveDomain(serverDomain);
await repository.saveServerDetails(serverDetails);
2022-06-05 22:36:32 +03:00
emit(
dataState.copyWith(
serverDetails: serverDetails,
currentStep: RecoveryStep.cloudflareToken,
),
);
}
2022-06-05 22:36:32 +03:00
Future<void> setAndValidateCloudflareToken(final String token) async {
final ServerInstallationRecovery dataState =
state as ServerInstallationRecovery;
final ServerDomain? serverDomain = dataState.serverDomain;
2022-05-23 17:21:34 +03:00
if (serverDomain == null) {
return;
}
2022-06-05 22:36:32 +03:00
final String? zoneId =
await repository.getDomainId(token, serverDomain.domainName);
2022-05-23 17:21:34 +03:00
if (zoneId == null) {
getIt<NavigationService>()
.showSnackBar('recovering.domain_not_available_on_token'.tr());
return;
}
2022-06-05 22:36:32 +03:00
await repository.saveDomain(
ServerDomain(
2022-05-23 17:21:34 +03:00
domainName: serverDomain.domainName,
zoneId: zoneId,
2022-05-24 21:55:39 +03:00
provider: DnsProvider.cloudflare,
2022-05-23 17:21:34 +03:00
),
2022-06-05 22:36:32 +03:00
);
await repository.saveCloudFlareKey(token);
emit(
dataState.copyWith(
serverDomain: ServerDomain(
domainName: serverDomain.domainName,
zoneId: zoneId,
provider: DnsProvider.cloudflare,
),
cloudFlareKey: token,
currentStep: RecoveryStep.backblazeToken,
),
);
2022-05-23 17:21:34 +03:00
}
2022-06-05 22:36:32 +03:00
void finishRecoveryProcess(
2022-06-10 00:13:06 +03:00
final BackblazeCredential backblazeCredential,
) async {
await repository.saveIsServerStarted(true);
await repository.saveIsServerResetedFirstTime(true);
await repository.saveIsServerResetedSecondTime(true);
await repository.saveHasFinalChecked(true);
2022-05-31 02:06:08 +03:00
await repository.saveIsRecoveringServer(false);
2022-06-05 22:36:32 +03:00
final User mainUser = await repository.getMainUser();
2022-05-31 17:30:35 +03:00
await repository.saveRootUser(mainUser);
2022-06-05 22:36:32 +03:00
final ServerInstallationRecovery updatedState =
(state as ServerInstallationRecovery).copyWith(
backblazeCredential: backblazeCredential,
rootUser: mainUser,
);
emit(updatedState.finish());
}
@override
2022-06-05 22:36:32 +03:00
void onChange(final Change<ServerInstallationState> change) {
super.onChange(change);
print('================================');
print('ServerInstallationState changed!');
print('Current type: ${change.nextState.runtimeType}');
2022-07-12 15:54:16 +03:00
print('Hetzner key: ${change.nextState.providerApiToken}');
print('Cloudflare key: ${change.nextState.cloudFlareKey}');
print('Domain: ${change.nextState.serverDomain}');
print('BackblazeCredential: ${change.nextState.backblazeCredential}');
if (change.nextState is ServerInstallationRecovery) {
print(
2022-06-05 22:36:32 +03:00
'Recovery Step: ${(change.nextState as ServerInstallationRecovery).currentStep}',
);
print(
2022-06-05 22:36:32 +03:00
'Recovery Capabilities: ${(change.nextState as ServerInstallationRecovery).recoveryCapabilities}',
);
}
if (change.nextState is TimerState) {
print('Timer: ${(change.nextState as TimerState).duration}');
}
}
2021-02-03 21:51:07 +02:00
void clearAppConfig() {
2021-03-30 20:38:40 +03:00
closeTimer();
2021-08-29 16:54:28 +03:00
2021-02-03 21:51:07 +02:00
repository.clearAppConfig();
2022-05-24 21:55:39 +03:00
emit(const ServerInstallationEmpty());
2021-01-06 19:35:57 +02:00
}
2021-04-22 21:04:24 +03:00
Future<void> serverDelete() async {
closeTimer();
2021-08-29 16:54:28 +03:00
if (state.serverDetails != null) {
await repository.deleteServer(state.serverDomain!);
2021-04-22 21:04:24 +03:00
}
2022-05-31 17:30:35 +03:00
await repository.deleteServerRelatedRecords();
2022-06-05 22:36:32 +03:00
emit(
ServerInstallationNotFinished(
2022-07-12 15:54:16 +03:00
providerApiToken: state.providerApiToken,
2022-06-05 22:36:32 +03:00
serverDomain: state.serverDomain,
cloudFlareKey: state.cloudFlareKey,
backblazeCredential: state.backblazeCredential,
rootUser: state.rootUser,
serverDetails: null,
isServerStarted: false,
isServerResetedFirstTime: false,
isServerResetedSecondTime: false,
isLoading: false,
dnsMatches: null,
),
);
2021-04-22 21:04:24 +03:00
}
2022-05-24 21:55:39 +03:00
@override
2022-06-05 22:36:32 +03:00
Future<void> close() {
2021-03-30 20:38:40 +03:00
closeTimer();
2021-02-16 20:48:15 +02:00
return super.close();
}
2021-03-30 20:38:40 +03:00
void closeTimer() {
2021-03-15 17:39:44 +02:00
if (timer != null && timer!.isActive) {
timer!.cancel();
2021-02-16 20:48:15 +02:00
}
2021-02-03 21:51:07 +02:00
}
2021-01-06 19:35:57 +02:00
}