2021-01-21 21:01:42 +00:00
|
|
|
import 'dart:async';
|
|
|
|
|
2021-01-06 17:35:57 +00:00
|
|
|
import 'package:bloc/bloc.dart';
|
|
|
|
import 'package:equatable/equatable.dart';
|
2021-09-15 14:37:22 +00:00
|
|
|
import 'package:selfprivacy/config/get_it_config.dart';
|
|
|
|
import 'package:selfprivacy/logic/get_it/ssh.dart';
|
2022-05-14 02:54:40 +00:00
|
|
|
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
|
|
|
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
|
|
|
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
|
|
|
import 'package:selfprivacy/logic/models/hive/user.dart';
|
2021-01-21 07:35:38 +00:00
|
|
|
|
|
|
|
import 'app_config_repository.dart';
|
2022-02-08 06:59:19 +00:00
|
|
|
|
2021-03-18 00:55:38 +00:00
|
|
|
export 'package:provider/provider.dart';
|
2021-01-06 17:35:57 +00:00
|
|
|
|
|
|
|
part 'app_config_state.dart';
|
|
|
|
|
|
|
|
class AppConfigCubit extends Cubit<AppConfigState> {
|
2021-09-29 13:08:19 +00:00
|
|
|
AppConfigCubit() : super(AppConfigEmpty());
|
2021-01-06 17:35:57 +00:00
|
|
|
|
2021-01-21 07:35:38 +00:00
|
|
|
final repository = AppConfigRepository();
|
2021-01-06 17:35:57 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
Timer? timer;
|
|
|
|
|
2021-03-31 14:33:58 +00:00
|
|
|
Future<void> load() async {
|
|
|
|
var state = await repository.load();
|
2021-02-16 18:48:15 +00:00
|
|
|
|
2021-09-29 13:08:19 +00:00
|
|
|
if (state is AppConfigFinished) {
|
2021-02-16 18:48:15 +00:00
|
|
|
emit(state);
|
2021-09-29 13:08:19 +00:00
|
|
|
} else if (state is AppConfigNotFinished) {
|
2022-05-13 13:57:56 +00:00
|
|
|
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-13 21:49:24 +00:00
|
|
|
} else {
|
|
|
|
emit(state);
|
2021-09-29 13:08:19 +00:00
|
|
|
}
|
2022-05-13 13:57:56 +00:00
|
|
|
} else if (state is AppConfigRecovery) {
|
|
|
|
emit(state);
|
2021-09-29 13:08:19 +00:00
|
|
|
} else {
|
|
|
|
throw 'wrong state';
|
2021-02-16 18:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
void setHetznerKey(String hetznerKey) async {
|
|
|
|
await repository.saveHetznerKey(hetznerKey);
|
|
|
|
emit((state as AppConfigNotFinished).copyWith(hetznerKey: hetznerKey));
|
|
|
|
}
|
2021-02-16 18:48:15 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
void setCloudflareKey(String cloudFlareKey) async {
|
|
|
|
await repository.saveCloudFlareKey(cloudFlareKey);
|
|
|
|
emit(
|
|
|
|
(state as AppConfigNotFinished).copyWith(cloudFlareKey: cloudFlareKey));
|
|
|
|
}
|
|
|
|
|
|
|
|
void setBackblazeKey(String keyId, String applicationKey) async {
|
|
|
|
var backblazeCredential = BackblazeCredential(
|
|
|
|
keyId: keyId,
|
|
|
|
applicationKey: applicationKey,
|
|
|
|
);
|
|
|
|
await repository.saveBackblazeKey(backblazeCredential);
|
|
|
|
emit((state as AppConfigNotFinished)
|
|
|
|
.copyWith(backblazeCredential: backblazeCredential));
|
|
|
|
}
|
|
|
|
|
|
|
|
void setDomain(ServerDomain serverDomain) async {
|
|
|
|
await repository.saveDomain(serverDomain);
|
|
|
|
emit((state as AppConfigNotFinished).copyWith(serverDomain: serverDomain));
|
|
|
|
}
|
|
|
|
|
|
|
|
void setRootUser(User rootUser) async {
|
|
|
|
await repository.saveRootUser(rootUser);
|
|
|
|
emit((state as AppConfigNotFinished).copyWith(rootUser: rootUser));
|
|
|
|
}
|
|
|
|
|
|
|
|
void createServerAndSetDnsRecords() async {
|
|
|
|
AppConfigNotFinished _stateCopy = state as AppConfigNotFinished;
|
2022-05-16 22:15:16 +00:00
|
|
|
var onCancel =
|
|
|
|
() => emit((state as AppConfigNotFinished).copyWith(isLoading: false));
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
var onSuccess = (ServerHostingDetails serverDetails) async {
|
|
|
|
await repository.createDnsRecords(
|
|
|
|
serverDetails.ip4,
|
|
|
|
state.serverDomain!,
|
2022-05-16 22:15:16 +00:00
|
|
|
onCancel: onCancel,
|
2022-05-14 02:54:40 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
emit((state as AppConfigNotFinished).copyWith(
|
|
|
|
isLoading: false,
|
|
|
|
serverDetails: serverDetails,
|
|
|
|
));
|
|
|
|
runDelayed(startServerIfDnsIsOkay, Duration(seconds: 30), null);
|
|
|
|
};
|
|
|
|
|
|
|
|
try {
|
|
|
|
emit((state as AppConfigNotFinished).copyWith(isLoading: true));
|
|
|
|
await repository.createServer(
|
|
|
|
state.rootUser!,
|
|
|
|
state.serverDomain!.domainName,
|
|
|
|
state.cloudFlareKey!,
|
|
|
|
state.backblazeCredential!,
|
|
|
|
onCancel: onCancel,
|
|
|
|
onSuccess: onSuccess,
|
|
|
|
);
|
|
|
|
} catch (e) {
|
|
|
|
emit(_stateCopy);
|
|
|
|
}
|
2022-05-13 13:57:56 +00:00
|
|
|
}
|
2021-02-16 18:48:15 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
void startServerIfDnsIsOkay({AppConfigNotFinished? state}) async {
|
|
|
|
final dataState = state ?? this.state as AppConfigNotFinished;
|
2021-02-16 18:48:15 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
emit(TimerState(dataState: dataState, isLoading: true));
|
2021-02-16 18:48:15 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
var ip4 = dataState.serverDetails!.ip4;
|
|
|
|
var domainName = dataState.serverDomain!.domainName;
|
2021-03-25 08:32:00 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
var matches = await repository.isDnsAddressesMatch(
|
|
|
|
domainName, ip4, dataState.dnsMatches);
|
|
|
|
|
|
|
|
if (matches.values.every((value) => value)) {
|
|
|
|
var server = await repository.startServer(
|
|
|
|
dataState.serverDetails!,
|
|
|
|
);
|
|
|
|
await repository.saveServerDetails(server);
|
|
|
|
await repository.saveIsServerStarted(true);
|
2021-02-16 18:48:15 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
emit(
|
|
|
|
dataState.copyWith(
|
|
|
|
isServerStarted: true,
|
|
|
|
isLoading: false,
|
|
|
|
serverDetails: server,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
runDelayed(resetServerIfServerIsOkay, Duration(seconds: 60), dataState);
|
2021-02-16 18:48:15 +00:00
|
|
|
} else {
|
2022-05-13 13:57:56 +00:00
|
|
|
emit(
|
|
|
|
dataState.copyWith(
|
|
|
|
isLoading: false,
|
|
|
|
dnsMatches: matches,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
runDelayed(startServerIfDnsIsOkay, Duration(seconds: 30), dataState);
|
2021-02-16 18:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
void oneMoreReset({AppConfigNotFinished? state}) async {
|
|
|
|
final dataState = state ?? this.state as AppConfigNotFinished;
|
2021-02-16 18:48:15 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
emit(TimerState(dataState: dataState, isLoading: true));
|
2021-02-16 18:48:15 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
var isServerWorking = await repository.isHttpServerWorking();
|
2021-02-16 18:48:15 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
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,
|
|
|
|
serverDetails: hetznerServerDetails,
|
|
|
|
isLoading: false,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
runDelayed(finishCheckIfServerIsOkay, Duration(seconds: 60), dataState);
|
|
|
|
});
|
2021-03-31 11:37:39 +00:00
|
|
|
} else {
|
2022-05-13 13:57:56 +00:00
|
|
|
runDelayed(oneMoreReset, Duration(seconds: 60), dataState);
|
2021-03-31 11:37:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void resetServerIfServerIsOkay({
|
2021-09-29 13:08:19 +00:00
|
|
|
AppConfigNotFinished? state,
|
2021-03-31 11:37:39 +00:00
|
|
|
}) async {
|
2022-05-13 13:57:56 +00:00
|
|
|
final dataState = state ?? this.state as AppConfigNotFinished;
|
2021-03-31 11:37:39 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
emit(TimerState(dataState: dataState, isLoading: true));
|
2021-03-31 11:37:39 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
var isServerWorking = await repository.isHttpServerWorking();
|
2021-03-31 11:37:39 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
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,
|
|
|
|
serverDetails: hetznerServerDetails,
|
|
|
|
isLoading: false,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
runDelayed(oneMoreReset, Duration(seconds: 60), dataState);
|
|
|
|
});
|
2021-02-16 18:48:15 +00:00
|
|
|
} else {
|
2022-05-13 13:57:56 +00:00
|
|
|
runDelayed(resetServerIfServerIsOkay, Duration(seconds: 60), dataState);
|
2021-02-16 18:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void finishCheckIfServerIsOkay({
|
2021-09-29 13:08:19 +00:00
|
|
|
AppConfigNotFinished? state,
|
2021-02-16 18:48:15 +00:00
|
|
|
}) async {
|
2022-05-13 13:57:56 +00:00
|
|
|
final dataState = state ?? this.state as AppConfigNotFinished;
|
2021-02-16 18:48:15 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
emit(TimerState(dataState: dataState, isLoading: true));
|
2021-02-16 18:48:15 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
var isServerWorking = await repository.isHttpServerWorking();
|
2021-02-16 18:48:15 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
if (isServerWorking) {
|
|
|
|
await repository.createDkimRecord(dataState.serverDomain!);
|
|
|
|
await repository.saveHasFinalChecked(true);
|
2021-03-25 08:32:00 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
emit(dataState.finish());
|
2021-02-16 18:48:15 +00:00
|
|
|
} else {
|
2022-05-13 13:57:56 +00:00
|
|
|
runDelayed(finishCheckIfServerIsOkay, Duration(seconds: 60), dataState);
|
2021-02-16 18:48:15 +00:00
|
|
|
}
|
2021-01-06 17:35:57 +00:00
|
|
|
}
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
void runDelayed(
|
|
|
|
void Function() work, Duration delay, AppConfigNotFinished? state) async {
|
|
|
|
final dataState = state ?? this.state as AppConfigNotFinished;
|
|
|
|
|
|
|
|
emit(TimerState(
|
|
|
|
dataState: dataState,
|
|
|
|
timerStart: DateTime.now(),
|
|
|
|
duration: delay,
|
|
|
|
isLoading: false,
|
|
|
|
));
|
|
|
|
timer = Timer(delay, work);
|
|
|
|
}
|
|
|
|
|
2021-02-03 19:51:07 +00:00
|
|
|
void clearAppConfig() {
|
2021-03-30 17:38:40 +00:00
|
|
|
closeTimer();
|
2021-08-29 13:54:28 +00:00
|
|
|
|
2021-02-03 19:51:07 +00:00
|
|
|
repository.clearAppConfig();
|
2021-09-29 13:08:19 +00:00
|
|
|
emit(AppConfigEmpty());
|
2021-01-06 17:35:57 +00:00
|
|
|
}
|
|
|
|
|
2021-04-22 18:04:24 +00:00
|
|
|
Future<void> serverDelete() async {
|
|
|
|
closeTimer();
|
2021-08-29 13:54:28 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
if (state.serverDetails != null) {
|
|
|
|
await repository.deleteServer(state.serverDomain!);
|
2021-09-15 14:37:22 +00:00
|
|
|
await getIt<SSHModel>().clear();
|
2021-04-22 18:04:24 +00:00
|
|
|
}
|
|
|
|
await repository.deleteRecords();
|
2021-10-11 21:10:04 +00:00
|
|
|
emit(AppConfigNotFinished(
|
|
|
|
hetznerKey: state.hetznerKey,
|
2022-05-13 13:57:56 +00:00
|
|
|
serverDomain: state.serverDomain,
|
2021-10-11 21:10:04 +00:00
|
|
|
cloudFlareKey: state.cloudFlareKey,
|
|
|
|
backblazeCredential: state.backblazeCredential,
|
|
|
|
rootUser: state.rootUser,
|
2022-05-13 13:57:56 +00:00
|
|
|
serverDetails: null,
|
2021-10-11 21:10:04 +00:00
|
|
|
isServerStarted: false,
|
|
|
|
isServerResetedFirstTime: false,
|
|
|
|
isServerResetedSecondTime: false,
|
|
|
|
isLoading: false,
|
2022-02-08 06:59:19 +00:00
|
|
|
dnsMatches: null,
|
2021-10-11 21:10:04 +00:00
|
|
|
));
|
2021-04-22 18:04:24 +00:00
|
|
|
}
|
|
|
|
|
2021-02-16 18:48:15 +00:00
|
|
|
close() {
|
2021-03-30 17:38:40 +00:00
|
|
|
closeTimer();
|
2021-02-16 18:48:15 +00:00
|
|
|
return super.close();
|
|
|
|
}
|
|
|
|
|
2021-03-30 17:38:40 +00:00
|
|
|
void closeTimer() {
|
2021-03-15 15:39:44 +00:00
|
|
|
if (timer != null && timer!.isActive) {
|
|
|
|
timer!.cancel();
|
2021-02-16 18:48:15 +00:00
|
|
|
}
|
2021-02-03 19:51:07 +00:00
|
|
|
}
|
2021-01-06 17:35:57 +00:00
|
|
|
}
|