mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-11 18:39:45 +00:00
Improve server endpoints, add recovery page
- Handle Dio error codes properly to avoid exceptions - Improve en and ru assets - Improve dns recordings failure handling - Add recovery button to initializing page - Add recovery pages group
This commit is contained in:
parent
31be961dd0
commit
ce3e046f5a
|
@ -21,7 +21,8 @@
|
||||||
"saving": "Saving..",
|
"saving": "Saving..",
|
||||||
"nickname": "Nickname",
|
"nickname": "Nickname",
|
||||||
"loading": "Loading...",
|
"loading": "Loading...",
|
||||||
"later": "I will setup it later",
|
"later": "Skip to setup later",
|
||||||
|
"connect_to_existing": "Connect to existing server",
|
||||||
"reset": "Reset",
|
"reset": "Reset",
|
||||||
"details": "Details",
|
"details": "Details",
|
||||||
"no_data": "No data",
|
"no_data": "No data",
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
"saving": "Сохранение…",
|
"saving": "Сохранение…",
|
||||||
"nickname": "Никнейм",
|
"nickname": "Никнейм",
|
||||||
"loading": "Загрузка",
|
"loading": "Загрузка",
|
||||||
"later": "Настрою потом",
|
"later": "Пропустить и настроить потом",
|
||||||
|
"connect_to_existing": "Подключиться к существующему серверу",
|
||||||
"reset": "Сбросить",
|
"reset": "Сбросить",
|
||||||
"details": "Детальная информация",
|
"details": "Детальная информация",
|
||||||
"no_data": "Нет данных",
|
"no_data": "Нет данных",
|
||||||
|
|
|
@ -58,7 +58,17 @@ class ServerApi extends ApiMap {
|
||||||
|
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
try {
|
try {
|
||||||
response = await client.get('/services/status');
|
response = await client.get(
|
||||||
|
'/services/status',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
res = response.statusCode == HttpStatus.ok;
|
res = response.statusCode == HttpStatus.ok;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
res = false;
|
res = false;
|
||||||
|
@ -129,7 +139,17 @@ class ServerApi extends ApiMap {
|
||||||
Response response;
|
Response response;
|
||||||
|
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
response = await client.get('/users');
|
response = await client.get(
|
||||||
|
'/users',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
try {
|
try {
|
||||||
for (var user in response.data) {
|
for (var user in response.data) {
|
||||||
res.add(user.toString());
|
res.add(user.toString());
|
||||||
|
@ -155,6 +175,14 @@ class ServerApi extends ApiMap {
|
||||||
data: {
|
data: {
|
||||||
'public_key': sshKey,
|
'public_key': sshKey,
|
||||||
},
|
},
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
close(client);
|
close(client);
|
||||||
|
@ -174,6 +202,14 @@ class ServerApi extends ApiMap {
|
||||||
response = await client.put(
|
response = await client.put(
|
||||||
'/services/ssh/key/send',
|
'/services/ssh/key/send',
|
||||||
data: {"public_key": ssh},
|
data: {"public_key": ssh},
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
close(client);
|
close(client);
|
||||||
|
|
||||||
|
@ -191,7 +227,17 @@ class ServerApi extends ApiMap {
|
||||||
Response response;
|
Response response;
|
||||||
|
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
response = await client.get('/services/ssh/keys/${user.login}');
|
response = await client.get(
|
||||||
|
'/services/ssh/keys/${user.login}',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
try {
|
try {
|
||||||
res = (response.data as List<dynamic>).map((e) => e as String).toList();
|
res = (response.data as List<dynamic>).map((e) => e as String).toList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -215,8 +261,18 @@ class ServerApi extends ApiMap {
|
||||||
Response response;
|
Response response;
|
||||||
|
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
response = await client.delete('/services/ssh/keys/${user.login}',
|
response = await client.delete(
|
||||||
data: {"public_key": sshKey});
|
'/services/ssh/keys/${user.login}',
|
||||||
|
data: {"public_key": sshKey},
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
close(client);
|
close(client);
|
||||||
|
|
||||||
return ApiResponse<void>(
|
return ApiResponse<void>(
|
||||||
|
@ -238,7 +294,12 @@ class ServerApi extends ApiMap {
|
||||||
'/users/${user.login}',
|
'/users/${user.login}',
|
||||||
options: Options(
|
options: Options(
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
),
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
res = response.statusCode == HttpStatus.ok ||
|
res = response.statusCode == HttpStatus.ok ||
|
||||||
response.statusCode == HttpStatus.notFound;
|
response.statusCode == HttpStatus.notFound;
|
||||||
|
@ -262,6 +323,14 @@ class ServerApi extends ApiMap {
|
||||||
try {
|
try {
|
||||||
response = await client.get(
|
response = await client.get(
|
||||||
'/system/configuration/apply',
|
'/system/configuration/apply',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
res = response.statusCode == HttpStatus.ok;
|
res = response.statusCode == HttpStatus.ok;
|
||||||
|
@ -276,13 +345,33 @@ class ServerApi extends ApiMap {
|
||||||
|
|
||||||
Future<void> switchService(ServiceTypes type, bool needToTurnOn) async {
|
Future<void> switchService(ServiceTypes type, bool needToTurnOn) async {
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
client.post('/services/${type.url}/${needToTurnOn ? 'enable' : 'disable'}');
|
client.post(
|
||||||
|
'/services/${type.url}/${needToTurnOn ? 'enable' : 'disable'}',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
close(client);
|
close(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<ServiceTypes, bool>> servicesPowerCheck() async {
|
Future<Map<ServiceTypes, bool>> servicesPowerCheck() async {
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
Response response = await client.get('/services/status');
|
Response response = await client.get(
|
||||||
|
'/services/status',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
close(client);
|
close(client);
|
||||||
return {
|
return {
|
||||||
|
@ -303,13 +392,31 @@ class ServerApi extends ApiMap {
|
||||||
'accountKey': bucket.applicationKey,
|
'accountKey': bucket.applicationKey,
|
||||||
'bucket': bucket.bucketName,
|
'bucket': bucket.bucketName,
|
||||||
},
|
},
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
close(client);
|
close(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> startBackup() async {
|
Future<void> startBackup() async {
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
client.put('/services/restic/backup/create');
|
client.put(
|
||||||
|
'/services/restic/backup/create',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
close(client);
|
close(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,6 +427,14 @@ class ServerApi extends ApiMap {
|
||||||
try {
|
try {
|
||||||
response = await client.get(
|
response = await client.get(
|
||||||
'/services/restic/backup/list',
|
'/services/restic/backup/list',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
return response.data.map<Backup>((e) => Backup.fromJson(e)).toList();
|
return response.data.map<Backup>((e) => Backup.fromJson(e)).toList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -336,6 +451,14 @@ class ServerApi extends ApiMap {
|
||||||
try {
|
try {
|
||||||
response = await client.get(
|
response = await client.get(
|
||||||
'/services/restic/backup/status',
|
'/services/restic/backup/status',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
return BackupStatus.fromJson(response.data);
|
return BackupStatus.fromJson(response.data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -352,40 +475,101 @@ class ServerApi extends ApiMap {
|
||||||
|
|
||||||
Future<void> forceBackupListReload() async {
|
Future<void> forceBackupListReload() async {
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
client.get('/services/restic/backup/reload');
|
client.get(
|
||||||
|
'/services/restic/backup/reload',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
close(client);
|
close(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> restoreBackup(String backupId) async {
|
Future<void> restoreBackup(String backupId) async {
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
client.put('/services/restic/backup/restore', data: {'backupId': backupId});
|
client.put(
|
||||||
|
'/services/restic/backup/restore',
|
||||||
|
data: {'backupId': backupId},
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
close(client);
|
close(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> pullConfigurationUpdate() async {
|
Future<bool> pullConfigurationUpdate() async {
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
Response response = await client.get('/system/configuration/pull');
|
Response response = await client.get(
|
||||||
|
'/system/configuration/pull',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
close(client);
|
close(client);
|
||||||
return response.statusCode == HttpStatus.ok;
|
return response.statusCode == HttpStatus.ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> reboot() async {
|
Future<bool> reboot() async {
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
Response response = await client.get('/system/reboot');
|
Response response = await client.get(
|
||||||
|
'/system/reboot',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
close(client);
|
close(client);
|
||||||
return response.statusCode == HttpStatus.ok;
|
return response.statusCode == HttpStatus.ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> upgrade() async {
|
Future<bool> upgrade() async {
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
Response response = await client.get('/system/configuration/upgrade');
|
Response response = await client.get(
|
||||||
|
'/system/configuration/upgrade',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
close(client);
|
close(client);
|
||||||
return response.statusCode == HttpStatus.ok;
|
return response.statusCode == HttpStatus.ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<AutoUpgradeSettings> getAutoUpgradeSettings() async {
|
Future<AutoUpgradeSettings> getAutoUpgradeSettings() async {
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
Response response = await client.get('/system/configuration/autoUpgrade');
|
Response response = await client.get(
|
||||||
|
'/system/configuration/autoUpgrade',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
close(client);
|
close(client);
|
||||||
return AutoUpgradeSettings.fromJson(response.data);
|
return AutoUpgradeSettings.fromJson(response.data);
|
||||||
}
|
}
|
||||||
|
@ -395,13 +579,31 @@ class ServerApi extends ApiMap {
|
||||||
await client.put(
|
await client.put(
|
||||||
'/system/configuration/autoUpgrade',
|
'/system/configuration/autoUpgrade',
|
||||||
data: settings.toJson(),
|
data: settings.toJson(),
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
close(client);
|
close(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<TimeZoneSettings> getServerTimezone() async {
|
Future<TimeZoneSettings> getServerTimezone() async {
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
Response response = await client.get('/system/configuration/timezone');
|
Response response = await client.get(
|
||||||
|
'/system/configuration/timezone',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
close(client);
|
close(client);
|
||||||
|
|
||||||
return TimeZoneSettings.fromString(response.data);
|
return TimeZoneSettings.fromString(response.data);
|
||||||
|
@ -412,20 +614,45 @@ class ServerApi extends ApiMap {
|
||||||
await client.put(
|
await client.put(
|
||||||
'/system/configuration/timezone',
|
'/system/configuration/timezone',
|
||||||
data: settings.toJson(),
|
data: settings.toJson(),
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
close(client);
|
close(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getDkim() async {
|
Future<String?> getDkim() async {
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
Response response = await client.get('/services/mailserver/dkim');
|
Response response = await client.get(
|
||||||
|
'/services/mailserver/dkim',
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
close(client);
|
close(client);
|
||||||
|
|
||||||
// if got 404 raise exception
|
if (response.statusCode == null) {
|
||||||
if (response.statusCode == HttpStatus.notFound) {
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.statusCode == HttpStatus.notFound || response.data == null) {
|
||||||
throw Exception('No DKIM key found');
|
throw Exception('No DKIM key found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response.statusCode != HttpStatus.ok) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
final base64toString = utf8.fuse(base64);
|
final base64toString = utf8.fuse(base64);
|
||||||
|
|
||||||
return base64toString
|
return base64toString
|
||||||
|
|
|
@ -206,7 +206,7 @@ class AppConfigRepository {
|
||||||
|
|
||||||
var dkimRecordString = await api.getDkim();
|
var dkimRecordString = await api.getDkim();
|
||||||
|
|
||||||
await cloudflareApi.setDkim(dkimRecordString, cloudFlareDomain);
|
await cloudflareApi.setDkim(dkimRecordString ?? "", cloudFlareDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> isHttpServerWorking() async {
|
Future<bool> isHttpServerWorking() async {
|
||||||
|
|
|
@ -97,11 +97,11 @@ class DnsRecordsCubit extends AppConfigDependendCubit<DnsRecordsState> {
|
||||||
emit(state.copyWith(dnsState: DnsRecordsStatus.refreshing));
|
emit(state.copyWith(dnsState: DnsRecordsStatus.refreshing));
|
||||||
final CloudFlareDomain? domain = appConfigCubit.state.cloudFlareDomain;
|
final CloudFlareDomain? domain = appConfigCubit.state.cloudFlareDomain;
|
||||||
final String? ipAddress = appConfigCubit.state.hetznerServer?.ip4;
|
final String? ipAddress = appConfigCubit.state.hetznerServer?.ip4;
|
||||||
final dkimPublicKey = await api.getDkim();
|
final String? dkimPublicKey = await api.getDkim();
|
||||||
await cloudflare.removeSimilarRecords(cloudFlareDomain: domain!);
|
await cloudflare.removeSimilarRecords(cloudFlareDomain: domain!);
|
||||||
await cloudflare.createMultipleDnsRecords(
|
await cloudflare.createMultipleDnsRecords(
|
||||||
cloudFlareDomain: domain, ip4: ipAddress);
|
cloudFlareDomain: domain, ip4: ipAddress);
|
||||||
await cloudflare.setDkim(dkimPublicKey, domain);
|
await cloudflare.setDkim(dkimPublicKey ?? "", domain);
|
||||||
await load();
|
await load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:selfprivacy/config/hive_config.dart';
|
import 'package:selfprivacy/config/hive_config.dart';
|
||||||
import 'package:selfprivacy/ui/pages/initializing/initializing.dart';
|
import 'package:selfprivacy/ui/pages/setup/initializing.dart';
|
||||||
import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart';
|
import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart';
|
||||||
import 'package:selfprivacy/ui/pages/rootRoute.dart';
|
import 'package:selfprivacy/ui/pages/rootRoute.dart';
|
||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:selfprivacy/config/brand_colors.dart';
|
import 'package:selfprivacy/config/brand_colors.dart';
|
||||||
import 'package:selfprivacy/config/text_themes.dart';
|
import 'package:selfprivacy/config/text_themes.dart';
|
||||||
import 'package:selfprivacy/ui/pages/initializing/initializing.dart';
|
import 'package:selfprivacy/ui/pages/setup/initializing.dart';
|
||||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
|
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart';
|
import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
||||||
import 'package:selfprivacy/ui/pages/initializing/initializing.dart';
|
import 'package:selfprivacy/ui/pages/setup/initializing.dart';
|
||||||
import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart';
|
import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart';
|
||||||
import 'package:selfprivacy/ui/pages/rootRoute.dart';
|
import 'package:selfprivacy/ui/pages/rootRoute.dart';
|
||||||
import 'package:selfprivacy/ui/pages/ssh_keys/ssh_keys.dart';
|
import 'package:selfprivacy/ui/pages/ssh_keys/ssh_keys.dart';
|
||||||
|
|
|
@ -17,13 +17,14 @@ import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_timer/brand_timer.dart';
|
import 'package:selfprivacy/ui/components/brand_timer/brand_timer.dart';
|
||||||
import 'package:selfprivacy/ui/components/progress_bar/progress_bar.dart';
|
import 'package:selfprivacy/ui/components/progress_bar/progress_bar.dart';
|
||||||
import 'package:selfprivacy/ui/pages/rootRoute.dart';
|
import 'package:selfprivacy/ui/pages/rootRoute.dart';
|
||||||
|
import 'package:selfprivacy/ui/pages/setup/recovering/recovery_domain.dart';
|
||||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||||
|
|
||||||
class InitializingPage extends StatelessWidget {
|
class InitializingPage extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var cubit = context.watch<AppConfigCubit>();
|
var cubit = context.watch<AppConfigCubit>();
|
||||||
var actualPage = [
|
var actualInitializingPage = [
|
||||||
() => _stepHetzner(cubit),
|
() => _stepHetzner(cubit),
|
||||||
() => _stepCloudflare(cubit),
|
() => _stepCloudflare(cubit),
|
||||||
() => _stepBackblaze(cubit),
|
() => _stepBackblaze(cubit),
|
||||||
|
@ -69,7 +70,7 @@ class InitializingPage extends StatelessWidget {
|
||||||
_addCard(
|
_addCard(
|
||||||
AnimatedSwitcher(
|
AnimatedSwitcher(
|
||||||
duration: Duration(milliseconds: 300),
|
duration: Duration(milliseconds: 300),
|
||||||
child: actualPage,
|
child: actualInitializingPage,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
|
@ -79,7 +80,10 @@ class InitializingPage extends StatelessWidget {
|
||||||
MediaQuery.of(context).padding.bottom -
|
MediaQuery.of(context).padding.bottom -
|
||||||
566,
|
566,
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: BrandButton.text(
|
child: BrandButton.text(
|
||||||
title: cubit.state is AppConfigFinished
|
title: cubit.state is AppConfigFinished
|
||||||
|
@ -92,6 +96,22 @@ class InitializingPage extends StatelessWidget {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
(cubit.state is AppConfigFinished)
|
||||||
|
? Container()
|
||||||
|
: Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: BrandButton.text(
|
||||||
|
title: 'basis.connect_to_existing'.tr(),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pushAndRemoveUntil(
|
||||||
|
materialRoute(RecoveryDomain()),
|
||||||
|
(predicate) => false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
54
lib/ui/pages/setup/recovering/recovery_domain.dart
Normal file
54
lib/ui/pages/setup/recovering/recovery_domain.dart
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
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/ui/components/brand_button/brand_button.dart';
|
||||||
|
import 'package:selfprivacy/ui/pages/rootRoute.dart';
|
||||||
|
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||||
|
|
||||||
|
class RecoveryDomain extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var cubit = context.watch<AppConfigCubit>();
|
||||||
|
return BlocListener<AppConfigCubit, AppConfigState>(
|
||||||
|
listener: (context, state) {
|
||||||
|
if (cubit.state is AppConfigFinished) {
|
||||||
|
Navigator.of(context).pushReplacement(materialRoute(RootPage()));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: SafeArea(
|
||||||
|
child: Scaffold(
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
minHeight: MediaQuery.of(context).size.height -
|
||||||
|
MediaQuery.of(context).padding.top -
|
||||||
|
MediaQuery.of(context).padding.bottom -
|
||||||
|
566,
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: BrandButton.text(
|
||||||
|
title: cubit.state is AppConfigFinished
|
||||||
|
? 'basis.close'.tr()
|
||||||
|
: 'basis.later'.tr(),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pushAndRemoveUntil(
|
||||||
|
materialRoute(RootPage()),
|
||||||
|
(predicate) => false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue