mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-08 17:11:14 +00:00
chore: Merge endpoint-errors into master
Reviewed-on: https://git.selfprivacy.org/kherel/selfprivacy.org.app/pulls/149 Reviewed-by: Inex Code <inex.code@selfprivacy.org>
This commit is contained in:
commit
51ca8bce27
|
@ -273,6 +273,7 @@
|
|||
"place_where_data": "A place where your data and SelfPrivacy services will reside:",
|
||||
"how": "How to obtain API token",
|
||||
"provider_bad_key_error": "Provider API key is invalid",
|
||||
"could_not_connect": "Counldn't connect to the provider.",
|
||||
"choose_location_type": "Choose your server location and type:",
|
||||
"back_to_locations": "Go back to available locations!",
|
||||
"no_locations_found": "No available locations found. Make sure your account is accessible.",
|
||||
|
|
|
@ -272,6 +272,7 @@
|
|||
"place_where_data": "Здесь будут жить ваши данные и SelfPrivacy-сервисы:",
|
||||
"how": "Как получить API Token",
|
||||
"provider_bad_key_error": "API ключ провайдера неверен",
|
||||
"could_not_connect": "Не удалось соединиться с провайдером.",
|
||||
"choose_location_type": "Выберите локацию и тип вашего сервера:",
|
||||
"back_to_locations": "Назад к доступным локациям!",
|
||||
"no_locations_found": "Не найдено локаций. Убедитесь, что ваш аккаунт доступен.",
|
||||
|
|
15
lib/logic/api_maps/api_generic_result.dart
Normal file
15
lib/logic/api_maps/api_generic_result.dart
Normal file
|
@ -0,0 +1,15 @@
|
|||
class APIGenericResult<T> {
|
||||
APIGenericResult({
|
||||
required this.success,
|
||||
required this.data,
|
||||
this.message,
|
||||
this.code,
|
||||
});
|
||||
|
||||
/// Whether was a response successfully received,
|
||||
/// doesn't represent success of the request if `data<T>` is `bool`
|
||||
final bool success;
|
||||
final String? message;
|
||||
final T data;
|
||||
final int? code;
|
||||
}
|
|
@ -22,13 +22,13 @@ mixin JobsApi on ApiMap {
|
|||
return jobsList;
|
||||
}
|
||||
|
||||
Future<GenericMutationResult<bool>> removeApiJob(final String uid) async {
|
||||
Future<APIGenericResult<bool>> removeApiJob(final String uid) async {
|
||||
try {
|
||||
final GraphQLClient client = await getClient();
|
||||
final variables = Variables$Mutation$RemoveJob(jobId: uid);
|
||||
final mutation = Options$Mutation$RemoveJob(variables: variables);
|
||||
final response = await client.mutate$RemoveJob(mutation);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: response.parsedData?.removeJob.success ?? false,
|
||||
success: true,
|
||||
code: response.parsedData?.removeJob.code ?? 0,
|
||||
|
@ -36,7 +36,7 @@ mixin JobsApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: false,
|
||||
success: false,
|
||||
code: 0,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:graphql/client.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/api_generic_result.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/api_map.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/disk_volumes.graphql.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart';
|
||||
|
@ -22,36 +23,14 @@ import 'package:selfprivacy/logic/models/service.dart';
|
|||
import 'package:selfprivacy/logic/models/ssh_settings.dart';
|
||||
import 'package:selfprivacy/logic/models/system_settings.dart';
|
||||
|
||||
export 'package:selfprivacy/logic/api_maps/api_generic_result.dart';
|
||||
|
||||
part 'jobs_api.dart';
|
||||
part 'server_actions_api.dart';
|
||||
part 'services_api.dart';
|
||||
part 'users_api.dart';
|
||||
part 'volume_api.dart';
|
||||
|
||||
class GenericResult<T> {
|
||||
GenericResult({
|
||||
required this.success,
|
||||
required this.data,
|
||||
this.message,
|
||||
});
|
||||
|
||||
/// Whether was a response successfully received,
|
||||
/// doesn't represent success of the request if `data<T>` is `bool`
|
||||
final bool success;
|
||||
final String? message;
|
||||
final T data;
|
||||
}
|
||||
|
||||
class GenericMutationResult<T> extends GenericResult<T> {
|
||||
GenericMutationResult({
|
||||
required super.success,
|
||||
required this.code,
|
||||
required super.data,
|
||||
super.message,
|
||||
});
|
||||
final int code;
|
||||
}
|
||||
|
||||
class ServerApi extends ApiMap
|
||||
with VolumeApi, JobsApi, ServerActionsApi, ServicesApi, UsersApi {
|
||||
ServerApi({
|
||||
|
@ -206,7 +185,7 @@ class ServerApi extends ApiMap
|
|||
return settings;
|
||||
}
|
||||
|
||||
Future<GenericResult<RecoveryKeyStatus?>> getRecoveryTokenStatus() async {
|
||||
Future<APIGenericResult<RecoveryKeyStatus?>> getRecoveryTokenStatus() async {
|
||||
RecoveryKeyStatus? key;
|
||||
QueryResult<Query$RecoveryKey> response;
|
||||
String? error;
|
||||
|
@ -223,18 +202,18 @@ class ServerApi extends ApiMap
|
|||
print(e);
|
||||
}
|
||||
|
||||
return GenericResult<RecoveryKeyStatus?>(
|
||||
return APIGenericResult<RecoveryKeyStatus?>(
|
||||
success: error == null,
|
||||
data: key,
|
||||
message: error,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<String>> generateRecoveryToken(
|
||||
Future<APIGenericResult<String>> generateRecoveryToken(
|
||||
final DateTime? expirationDate,
|
||||
final int? numberOfUses,
|
||||
) async {
|
||||
GenericResult<String> key;
|
||||
APIGenericResult<String> key;
|
||||
QueryResult<Mutation$GetNewRecoveryApiKey> response;
|
||||
|
||||
try {
|
||||
|
@ -255,19 +234,19 @@ class ServerApi extends ApiMap
|
|||
);
|
||||
if (response.hasException) {
|
||||
print(response.exception.toString());
|
||||
key = GenericResult<String>(
|
||||
key = APIGenericResult<String>(
|
||||
success: false,
|
||||
data: '',
|
||||
message: response.exception.toString(),
|
||||
);
|
||||
}
|
||||
key = GenericResult<String>(
|
||||
key = APIGenericResult<String>(
|
||||
success: true,
|
||||
data: response.parsedData!.getNewRecoveryApiKey.key!,
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
key = GenericResult<String>(
|
||||
key = APIGenericResult<String>(
|
||||
success: false,
|
||||
data: '',
|
||||
message: e.toString(),
|
||||
|
@ -300,8 +279,8 @@ class ServerApi extends ApiMap
|
|||
return records;
|
||||
}
|
||||
|
||||
Future<GenericResult<List<ApiToken>>> getApiTokens() async {
|
||||
GenericResult<List<ApiToken>> tokens;
|
||||
Future<APIGenericResult<List<ApiToken>>> getApiTokens() async {
|
||||
APIGenericResult<List<ApiToken>> tokens;
|
||||
QueryResult<Query$GetApiTokens> response;
|
||||
|
||||
try {
|
||||
|
@ -310,7 +289,7 @@ class ServerApi extends ApiMap
|
|||
if (response.hasException) {
|
||||
final message = response.exception.toString();
|
||||
print(message);
|
||||
tokens = GenericResult<List<ApiToken>>(
|
||||
tokens = APIGenericResult<List<ApiToken>>(
|
||||
success: false,
|
||||
data: [],
|
||||
message: message,
|
||||
|
@ -324,13 +303,13 @@ class ServerApi extends ApiMap
|
|||
ApiToken.fromGraphQL(device),
|
||||
)
|
||||
.toList();
|
||||
tokens = GenericResult<List<ApiToken>>(
|
||||
tokens = APIGenericResult<List<ApiToken>>(
|
||||
success: true,
|
||||
data: parsed,
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
tokens = GenericResult<List<ApiToken>>(
|
||||
tokens = APIGenericResult<List<ApiToken>>(
|
||||
success: false,
|
||||
data: [],
|
||||
message: e.toString(),
|
||||
|
@ -340,8 +319,8 @@ class ServerApi extends ApiMap
|
|||
return tokens;
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> deleteApiToken(final String name) async {
|
||||
GenericResult<void> returnable;
|
||||
Future<APIGenericResult<void>> deleteApiToken(final String name) async {
|
||||
APIGenericResult<void> returnable;
|
||||
QueryResult<Mutation$DeleteDeviceApiToken> response;
|
||||
|
||||
try {
|
||||
|
@ -358,19 +337,19 @@ class ServerApi extends ApiMap
|
|||
);
|
||||
if (response.hasException) {
|
||||
print(response.exception.toString());
|
||||
returnable = GenericResult<void>(
|
||||
returnable = APIGenericResult<void>(
|
||||
success: false,
|
||||
data: null,
|
||||
message: response.exception.toString(),
|
||||
);
|
||||
}
|
||||
returnable = GenericResult<void>(
|
||||
returnable = APIGenericResult<void>(
|
||||
success: true,
|
||||
data: null,
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
returnable = GenericResult<void>(
|
||||
returnable = APIGenericResult<void>(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
|
@ -380,8 +359,8 @@ class ServerApi extends ApiMap
|
|||
return returnable;
|
||||
}
|
||||
|
||||
Future<GenericResult<String>> createDeviceToken() async {
|
||||
GenericResult<String> token;
|
||||
Future<APIGenericResult<String>> createDeviceToken() async {
|
||||
APIGenericResult<String> token;
|
||||
QueryResult<Mutation$GetNewDeviceApiKey> response;
|
||||
|
||||
try {
|
||||
|
@ -393,19 +372,19 @@ class ServerApi extends ApiMap
|
|||
);
|
||||
if (response.hasException) {
|
||||
print(response.exception.toString());
|
||||
token = GenericResult<String>(
|
||||
token = APIGenericResult<String>(
|
||||
success: false,
|
||||
data: '',
|
||||
message: response.exception.toString(),
|
||||
);
|
||||
}
|
||||
token = GenericResult<String>(
|
||||
token = APIGenericResult<String>(
|
||||
success: true,
|
||||
data: response.parsedData!.getNewDeviceApiKey.key!,
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
token = GenericResult<String>(
|
||||
token = APIGenericResult<String>(
|
||||
success: false,
|
||||
data: '',
|
||||
message: e.toString(),
|
||||
|
@ -417,10 +396,10 @@ class ServerApi extends ApiMap
|
|||
|
||||
Future<bool> isHttpServerWorking() async => (await getApiVersion()) != null;
|
||||
|
||||
Future<GenericResult<String>> authorizeDevice(
|
||||
Future<APIGenericResult<String>> authorizeDevice(
|
||||
final DeviceToken deviceToken,
|
||||
) async {
|
||||
GenericResult<String> token;
|
||||
APIGenericResult<String> token;
|
||||
QueryResult<Mutation$AuthorizeWithNewDeviceApiKey> response;
|
||||
|
||||
try {
|
||||
|
@ -442,19 +421,19 @@ class ServerApi extends ApiMap
|
|||
);
|
||||
if (response.hasException) {
|
||||
print(response.exception.toString());
|
||||
token = GenericResult<String>(
|
||||
token = APIGenericResult<String>(
|
||||
success: false,
|
||||
data: '',
|
||||
message: response.exception.toString(),
|
||||
);
|
||||
}
|
||||
token = GenericResult<String>(
|
||||
token = APIGenericResult<String>(
|
||||
success: true,
|
||||
data: response.parsedData!.authorizeWithNewDeviceApiKey.token!,
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
token = GenericResult<String>(
|
||||
token = APIGenericResult<String>(
|
||||
success: false,
|
||||
data: '',
|
||||
message: e.toString(),
|
||||
|
@ -464,10 +443,10 @@ class ServerApi extends ApiMap
|
|||
return token;
|
||||
}
|
||||
|
||||
Future<GenericResult<String>> useRecoveryToken(
|
||||
Future<APIGenericResult<String>> useRecoveryToken(
|
||||
final DeviceToken deviceToken,
|
||||
) async {
|
||||
GenericResult<String> token;
|
||||
APIGenericResult<String> token;
|
||||
QueryResult<Mutation$UseRecoveryApiKey> response;
|
||||
|
||||
try {
|
||||
|
@ -489,19 +468,19 @@ class ServerApi extends ApiMap
|
|||
);
|
||||
if (response.hasException) {
|
||||
print(response.exception.toString());
|
||||
token = GenericResult<String>(
|
||||
token = APIGenericResult<String>(
|
||||
success: false,
|
||||
data: '',
|
||||
message: response.exception.toString(),
|
||||
);
|
||||
}
|
||||
token = GenericResult<String>(
|
||||
token = APIGenericResult<String>(
|
||||
success: true,
|
||||
data: response.parsedData!.useRecoveryApiKey.token!,
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
token = GenericResult<String>(
|
||||
token = APIGenericResult<String>(
|
||||
success: false,
|
||||
data: '',
|
||||
message: e.toString(),
|
||||
|
|
|
@ -20,7 +20,7 @@ mixin ServicesApi on ApiMap {
|
|||
return services;
|
||||
}
|
||||
|
||||
Future<GenericMutationResult<bool>> enableService(
|
||||
Future<APIGenericResult<bool>> enableService(
|
||||
final String serviceId,
|
||||
) async {
|
||||
try {
|
||||
|
@ -28,7 +28,7 @@ mixin ServicesApi on ApiMap {
|
|||
final variables = Variables$Mutation$EnableService(serviceId: serviceId);
|
||||
final mutation = Options$Mutation$EnableService(variables: variables);
|
||||
final response = await client.mutate$EnableService(mutation);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: response.parsedData?.enableService.success ?? false,
|
||||
success: true,
|
||||
code: response.parsedData?.enableService.code ?? 0,
|
||||
|
@ -36,7 +36,7 @@ mixin ServicesApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: false,
|
||||
success: false,
|
||||
code: 0,
|
||||
|
@ -45,7 +45,7 @@ mixin ServicesApi on ApiMap {
|
|||
}
|
||||
}
|
||||
|
||||
Future<GenericMutationResult<void>> disableService(
|
||||
Future<APIGenericResult<void>> disableService(
|
||||
final String serviceId,
|
||||
) async {
|
||||
try {
|
||||
|
@ -53,7 +53,7 @@ mixin ServicesApi on ApiMap {
|
|||
final variables = Variables$Mutation$DisableService(serviceId: serviceId);
|
||||
final mutation = Options$Mutation$DisableService(variables: variables);
|
||||
final response = await client.mutate$DisableService(mutation);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: null,
|
||||
success: response.parsedData?.disableService.success ?? false,
|
||||
code: response.parsedData?.disableService.code ?? 0,
|
||||
|
@ -61,7 +61,7 @@ mixin ServicesApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: null,
|
||||
success: false,
|
||||
code: 0,
|
||||
|
@ -70,7 +70,7 @@ mixin ServicesApi on ApiMap {
|
|||
}
|
||||
}
|
||||
|
||||
Future<GenericMutationResult<bool>> stopService(
|
||||
Future<APIGenericResult<bool>> stopService(
|
||||
final String serviceId,
|
||||
) async {
|
||||
try {
|
||||
|
@ -78,7 +78,7 @@ mixin ServicesApi on ApiMap {
|
|||
final variables = Variables$Mutation$StopService(serviceId: serviceId);
|
||||
final mutation = Options$Mutation$StopService(variables: variables);
|
||||
final response = await client.mutate$StopService(mutation);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: response.parsedData?.stopService.success ?? false,
|
||||
success: true,
|
||||
code: response.parsedData?.stopService.code ?? 0,
|
||||
|
@ -86,7 +86,7 @@ mixin ServicesApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: false,
|
||||
success: false,
|
||||
code: 0,
|
||||
|
@ -95,13 +95,13 @@ mixin ServicesApi on ApiMap {
|
|||
}
|
||||
}
|
||||
|
||||
Future<GenericMutationResult> startService(final String serviceId) async {
|
||||
Future<APIGenericResult> startService(final String serviceId) async {
|
||||
try {
|
||||
final GraphQLClient client = await getClient();
|
||||
final variables = Variables$Mutation$StartService(serviceId: serviceId);
|
||||
final mutation = Options$Mutation$StartService(variables: variables);
|
||||
final response = await client.mutate$StartService(mutation);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: null,
|
||||
success: response.parsedData?.startService.success ?? false,
|
||||
code: response.parsedData?.startService.code ?? 0,
|
||||
|
@ -109,7 +109,7 @@ mixin ServicesApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: null,
|
||||
success: false,
|
||||
code: 0,
|
||||
|
@ -118,7 +118,7 @@ mixin ServicesApi on ApiMap {
|
|||
}
|
||||
}
|
||||
|
||||
Future<GenericMutationResult<bool>> restartService(
|
||||
Future<APIGenericResult<bool>> restartService(
|
||||
final String serviceId,
|
||||
) async {
|
||||
try {
|
||||
|
@ -126,7 +126,7 @@ mixin ServicesApi on ApiMap {
|
|||
final variables = Variables$Mutation$RestartService(serviceId: serviceId);
|
||||
final mutation = Options$Mutation$RestartService(variables: variables);
|
||||
final response = await client.mutate$RestartService(mutation);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: response.parsedData?.restartService.success ?? false,
|
||||
success: true,
|
||||
code: response.parsedData?.restartService.code ?? 0,
|
||||
|
@ -134,7 +134,7 @@ mixin ServicesApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: false,
|
||||
success: false,
|
||||
code: 0,
|
||||
|
@ -143,7 +143,7 @@ mixin ServicesApi on ApiMap {
|
|||
}
|
||||
}
|
||||
|
||||
Future<GenericMutationResult<ServerJob?>> moveService(
|
||||
Future<APIGenericResult<ServerJob?>> moveService(
|
||||
final String serviceId,
|
||||
final String destination,
|
||||
) async {
|
||||
|
@ -158,7 +158,7 @@ mixin ServicesApi on ApiMap {
|
|||
final mutation = Options$Mutation$MoveService(variables: variables);
|
||||
final response = await client.mutate$MoveService(mutation);
|
||||
final jobJson = response.parsedData?.moveService.job?.toJson();
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
success: true,
|
||||
code: response.parsedData?.moveService.code ?? 0,
|
||||
message: response.parsedData?.moveService.message,
|
||||
|
@ -166,7 +166,7 @@ mixin ServicesApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
success: false,
|
||||
code: 0,
|
||||
message: e.toString(),
|
||||
|
|
|
@ -45,7 +45,7 @@ mixin UsersApi on ApiMap {
|
|||
return user;
|
||||
}
|
||||
|
||||
Future<GenericMutationResult<User?>> createUser(
|
||||
Future<APIGenericResult<User?>> createUser(
|
||||
final String username,
|
||||
final String password,
|
||||
) async {
|
||||
|
@ -56,7 +56,7 @@ mixin UsersApi on ApiMap {
|
|||
);
|
||||
final mutation = Options$Mutation$CreateUser(variables: variables);
|
||||
final response = await client.mutate$CreateUser(mutation);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
success: true,
|
||||
code: response.parsedData?.createUser.code ?? 500,
|
||||
message: response.parsedData?.createUser.message,
|
||||
|
@ -66,7 +66,7 @@ mixin UsersApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
success: false,
|
||||
code: 0,
|
||||
message: e.toString(),
|
||||
|
@ -75,7 +75,7 @@ mixin UsersApi on ApiMap {
|
|||
}
|
||||
}
|
||||
|
||||
Future<GenericMutationResult<bool>> deleteUser(
|
||||
Future<APIGenericResult<bool>> deleteUser(
|
||||
final String username,
|
||||
) async {
|
||||
try {
|
||||
|
@ -83,7 +83,7 @@ mixin UsersApi on ApiMap {
|
|||
final variables = Variables$Mutation$DeleteUser(username: username);
|
||||
final mutation = Options$Mutation$DeleteUser(variables: variables);
|
||||
final response = await client.mutate$DeleteUser(mutation);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: response.parsedData?.deleteUser.success ?? false,
|
||||
success: true,
|
||||
code: response.parsedData?.deleteUser.code ?? 500,
|
||||
|
@ -91,7 +91,7 @@ mixin UsersApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: false,
|
||||
success: false,
|
||||
code: 500,
|
||||
|
@ -100,7 +100,7 @@ mixin UsersApi on ApiMap {
|
|||
}
|
||||
}
|
||||
|
||||
Future<GenericMutationResult<User?>> updateUser(
|
||||
Future<APIGenericResult<User?>> updateUser(
|
||||
final String username,
|
||||
final String password,
|
||||
) async {
|
||||
|
@ -111,7 +111,7 @@ mixin UsersApi on ApiMap {
|
|||
);
|
||||
final mutation = Options$Mutation$UpdateUser(variables: variables);
|
||||
final response = await client.mutate$UpdateUser(mutation);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
success: true,
|
||||
code: response.parsedData?.updateUser.code ?? 500,
|
||||
message: response.parsedData?.updateUser.message,
|
||||
|
@ -121,7 +121,7 @@ mixin UsersApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: null,
|
||||
success: false,
|
||||
code: 0,
|
||||
|
@ -130,7 +130,7 @@ mixin UsersApi on ApiMap {
|
|||
}
|
||||
}
|
||||
|
||||
Future<GenericMutationResult<User?>> addSshKey(
|
||||
Future<APIGenericResult<User?>> addSshKey(
|
||||
final String username,
|
||||
final String sshKey,
|
||||
) async {
|
||||
|
@ -144,7 +144,7 @@ mixin UsersApi on ApiMap {
|
|||
);
|
||||
final mutation = Options$Mutation$AddSshKey(variables: variables);
|
||||
final response = await client.mutate$AddSshKey(mutation);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
success: true,
|
||||
code: response.parsedData?.addSshKey.code ?? 500,
|
||||
message: response.parsedData?.addSshKey.message,
|
||||
|
@ -154,7 +154,7 @@ mixin UsersApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: null,
|
||||
success: false,
|
||||
code: 0,
|
||||
|
@ -163,7 +163,7 @@ mixin UsersApi on ApiMap {
|
|||
}
|
||||
}
|
||||
|
||||
Future<GenericMutationResult<User?>> removeSshKey(
|
||||
Future<APIGenericResult<User?>> removeSshKey(
|
||||
final String username,
|
||||
final String sshKey,
|
||||
) async {
|
||||
|
@ -177,7 +177,7 @@ mixin UsersApi on ApiMap {
|
|||
);
|
||||
final mutation = Options$Mutation$RemoveSshKey(variables: variables);
|
||||
final response = await client.mutate$RemoveSshKey(mutation);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
success: response.parsedData?.removeSshKey.success ?? false,
|
||||
code: response.parsedData?.removeSshKey.code ?? 500,
|
||||
message: response.parsedData?.removeSshKey.message,
|
||||
|
@ -187,7 +187,7 @@ mixin UsersApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericMutationResult(
|
||||
return APIGenericResult(
|
||||
data: null,
|
||||
success: false,
|
||||
code: 0,
|
||||
|
|
|
@ -57,10 +57,10 @@ mixin VolumeApi on ApiMap {
|
|||
}
|
||||
}
|
||||
|
||||
Future<GenericMutationResult<String?>> migrateToBinds(
|
||||
Future<APIGenericResult<String?>> migrateToBinds(
|
||||
final Map<String, String> serviceToDisk,
|
||||
) async {
|
||||
GenericMutationResult<String?>? mutation;
|
||||
APIGenericResult<String?>? mutation;
|
||||
|
||||
try {
|
||||
final GraphQLClient client = await getClient();
|
||||
|
@ -78,7 +78,7 @@ mixin VolumeApi on ApiMap {
|
|||
await client.mutate$MigrateToBinds(
|
||||
migrateMutation,
|
||||
);
|
||||
mutation = mutation = GenericMutationResult(
|
||||
mutation = mutation = APIGenericResult(
|
||||
success: true,
|
||||
code: result.parsedData!.migrateToBinds.code,
|
||||
message: result.parsedData!.migrateToBinds.message,
|
||||
|
@ -86,7 +86,7 @@ mixin VolumeApi on ApiMap {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
mutation = GenericMutationResult(
|
||||
mutation = APIGenericResult(
|
||||
success: false,
|
||||
code: 0,
|
||||
message: e.toString(),
|
||||
|
|
|
@ -2,9 +2,12 @@ import 'dart:io';
|
|||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/api_generic_result.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
||||
|
||||
export 'package:selfprivacy/logic/api_maps/api_generic_result.dart';
|
||||
|
||||
class BackblazeApiAuth {
|
||||
BackblazeApiAuth({required this.authorizationToken, required this.apiUrl});
|
||||
|
||||
|
@ -71,28 +74,43 @@ class BackblazeApi extends ApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<bool> isValid(final String encodedApiKey) async {
|
||||
Future<APIGenericResult<bool>> isApiTokenValid(
|
||||
final String encodedApiKey,
|
||||
) async {
|
||||
final Dio client = await getClient();
|
||||
bool isTokenValid = false;
|
||||
try {
|
||||
final Response response = await client.get(
|
||||
'b2_authorize_account',
|
||||
options: Options(headers: {'Authorization': 'Basic $encodedApiKey'}),
|
||||
options: Options(
|
||||
followRedirects: false,
|
||||
validateStatus: (final status) =>
|
||||
status != null && (status >= 200 || status == 401),
|
||||
headers: {'Authorization': 'Basic $encodedApiKey'},
|
||||
),
|
||||
);
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
if (response.data['allowed']['capabilities'].contains('listBuckets')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
isTokenValid = response.data['allowed']['capabilities'].contains('listBuckets');
|
||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||
return false;
|
||||
isTokenValid = false;
|
||||
} else {
|
||||
throw Exception('code: ${response.statusCode}');
|
||||
}
|
||||
} on DioError {
|
||||
return false;
|
||||
} on DioError catch (e) {
|
||||
print(e);
|
||||
return APIGenericResult(
|
||||
data: false,
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return APIGenericResult(
|
||||
data: isTokenValid,
|
||||
success: true,
|
||||
);
|
||||
}
|
||||
|
||||
// Create bucket
|
||||
|
|
|
@ -46,33 +46,50 @@ class CloudflareApi extends DnsProviderApi {
|
|||
String rootAddress = 'https://api.cloudflare.com/client/v4';
|
||||
|
||||
@override
|
||||
Future<bool> isApiTokenValid(final String token) async {
|
||||
Future<APIGenericResult<bool>> isApiTokenValid(final String token) async {
|
||||
bool isValid = false;
|
||||
Response? response;
|
||||
String message = '';
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
response = await client.get(
|
||||
'/user/tokens/verify',
|
||||
options: Options(headers: {'Authorization': 'Bearer $token'}),
|
||||
options: Options(
|
||||
followRedirects: false,
|
||||
validateStatus: (final status) =>
|
||||
status != null && (status >= 200 || status == 401),
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
isValid = false;
|
||||
message = e.toString();
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
if (response != null) {
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
isValid = true;
|
||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||
isValid = false;
|
||||
} else {
|
||||
throw Exception('code: ${response.statusCode}');
|
||||
}
|
||||
if (response == null) {
|
||||
return APIGenericResult(
|
||||
data: isValid,
|
||||
success: false,
|
||||
message: message,
|
||||
);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
isValid = true;
|
||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||
isValid = false;
|
||||
} else {
|
||||
throw Exception('code: ${response.statusCode}');
|
||||
}
|
||||
|
||||
return APIGenericResult(
|
||||
data: isValid,
|
||||
success: true,
|
||||
message: response.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -96,7 +113,7 @@ class CloudflareApi extends DnsProviderApi {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> removeSimilarRecords({
|
||||
Future<APIGenericResult<void>> removeSimilarRecords({
|
||||
required final ServerDomain domain,
|
||||
final String? ip4,
|
||||
}) async {
|
||||
|
@ -122,9 +139,16 @@ class CloudflareApi extends DnsProviderApi {
|
|||
await Future.wait(allDeleteFutures);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return APIGenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return APIGenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -166,7 +190,7 @@ class CloudflareApi extends DnsProviderApi {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> createMultipleDnsRecords({
|
||||
Future<APIGenericResult<void>> createMultipleDnsRecords({
|
||||
required final ServerDomain domain,
|
||||
final String? ip4,
|
||||
}) async {
|
||||
|
@ -189,9 +213,18 @@ class CloudflareApi extends DnsProviderApi {
|
|||
} on DioError catch (e) {
|
||||
print(e.message);
|
||||
rethrow;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return APIGenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return APIGenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
List<DnsRecord> projectDnsRecords(
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import 'package:selfprivacy/logic/api_maps/api_generic_result.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
||||
|
||||
export 'package:selfprivacy/logic/api_maps/api_generic_result.dart';
|
||||
|
||||
class DomainNotFoundException implements Exception {
|
||||
DomainNotFoundException(this.message);
|
||||
final String message;
|
||||
|
@ -11,11 +14,11 @@ abstract class DnsProviderApi extends ApiMap {
|
|||
Future<List<DnsRecord>> getDnsRecords({
|
||||
required final ServerDomain domain,
|
||||
});
|
||||
Future<void> removeSimilarRecords({
|
||||
Future<APIGenericResult<void>> removeSimilarRecords({
|
||||
required final ServerDomain domain,
|
||||
final String? ip4,
|
||||
});
|
||||
Future<void> createMultipleDnsRecords({
|
||||
Future<APIGenericResult<void>> createMultipleDnsRecords({
|
||||
required final ServerDomain domain,
|
||||
final String? ip4,
|
||||
});
|
||||
|
@ -26,6 +29,6 @@ abstract class DnsProviderApi extends ApiMap {
|
|||
Future<String?> getZoneId(final String domain);
|
||||
Future<List<String>> domainList();
|
||||
|
||||
Future<bool> isApiTokenValid(final String token);
|
||||
Future<APIGenericResult<bool>> isApiTokenValid(final String token);
|
||||
RegExp getApiTokenValidation();
|
||||
}
|
||||
|
|
|
@ -59,35 +59,50 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
String get displayProviderName => 'Digital Ocean';
|
||||
|
||||
@override
|
||||
Future<bool> isApiTokenValid(final String token) async {
|
||||
Future<APIGenericResult<bool>> isApiTokenValid(final String token) async {
|
||||
bool isValid = false;
|
||||
Response? response;
|
||||
String message = '';
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
response = await client.get(
|
||||
'/account',
|
||||
options: Options(
|
||||
followRedirects: false,
|
||||
validateStatus: (final status) =>
|
||||
status != null && (status >= 200 || status == 401),
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
isValid = false;
|
||||
message = e.toString();
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
if (response != null) {
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
isValid = true;
|
||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||
isValid = false;
|
||||
} else {
|
||||
throw Exception('code: ${response.statusCode}');
|
||||
}
|
||||
if (response == null) {
|
||||
return APIGenericResult(
|
||||
data: isValid,
|
||||
success: false,
|
||||
message: message,
|
||||
);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
isValid = true;
|
||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||
isValid = false;
|
||||
} else {
|
||||
throw Exception('code: ${response.statusCode}');
|
||||
}
|
||||
|
||||
return APIGenericResult(
|
||||
data: isValid,
|
||||
success: true,
|
||||
message: response.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
/// Hardcoded on their documentation and there is no pricing API at all
|
||||
|
@ -99,10 +114,10 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
);
|
||||
|
||||
@override
|
||||
Future<ServerVolume?> createVolume() async {
|
||||
Future<APIGenericResult<ServerVolume?>> createVolume() async {
|
||||
ServerVolume? volume;
|
||||
|
||||
final Response createVolumeResponse;
|
||||
Response? createVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final List<ServerVolume> volumes = await getVolumes();
|
||||
|
@ -131,11 +146,21 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return APIGenericResult(
|
||||
data: null,
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return volume;
|
||||
return APIGenericResult(
|
||||
data: volume,
|
||||
success: true,
|
||||
code: createVolumeResponse.statusCode,
|
||||
message: createVolumeResponse.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -204,13 +229,13 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<bool> attachVolume(
|
||||
Future<APIGenericResult<bool>> attachVolume(
|
||||
final ServerVolume volume,
|
||||
final int serverId,
|
||||
) async {
|
||||
bool success = false;
|
||||
|
||||
final Response attachVolumeResponse;
|
||||
Response? attachVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
attachVolumeResponse = await client.post(
|
||||
|
@ -226,11 +251,21 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
attachVolumeResponse.data['action']['status'].toString() != 'error';
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return APIGenericResult(
|
||||
data: false,
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return success;
|
||||
return APIGenericResult(
|
||||
data: success,
|
||||
success: true,
|
||||
code: attachVolumeResponse.statusCode,
|
||||
message: attachVolumeResponse.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -308,7 +343,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<ServerHostingDetails?> createServer({
|
||||
Future<APIGenericResult<ServerHostingDetails?>> createServer({
|
||||
required final String dnsApiToken,
|
||||
required final User rootUser,
|
||||
required final String domainName,
|
||||
|
@ -330,6 +365,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
"#cloud-config\nruncmd:\n- curl https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-infect/raw/branch/$infectBranch/nixos-infect | PROVIDER=$infectProviderName STAGING_ACME='$stagingAcme' DOMAIN='$domainName' LUSER='${rootUser.login}' ENCODED_PASSWORD='$base64Password' CF_TOKEN=$dnsApiToken DB_PASSWORD=$dbPassword API_TOKEN=$apiToken HOSTNAME=$formattedHostname bash 2>&1 | tee /tmp/infect.log";
|
||||
print(userdataString);
|
||||
|
||||
Response? serverCreateResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Map<String, Object> data = {
|
||||
|
@ -341,14 +377,15 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
};
|
||||
print('Decoded data: $data');
|
||||
|
||||
final Response serverCreateResponse = await client.post(
|
||||
serverCreateResponse = await client.post(
|
||||
'/droplets',
|
||||
data: data,
|
||||
);
|
||||
|
||||
final int serverId = serverCreateResponse.data['droplet']['id'];
|
||||
final ServerVolume? newVolume = await createVolume();
|
||||
final bool attachedVolume = await attachVolume(newVolume!, serverId);
|
||||
final ServerVolume? newVolume = (await createVolume()).data;
|
||||
final bool attachedVolume =
|
||||
(await attachVolume(newVolume!, serverId)).data;
|
||||
|
||||
String? ipv4;
|
||||
int attempts = 0;
|
||||
|
@ -376,11 +413,21 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return APIGenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return serverDetails;
|
||||
return APIGenericResult(
|
||||
data: serverDetails,
|
||||
success: true,
|
||||
code: serverCreateResponse.statusCode,
|
||||
message: serverCreateResponse.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -694,7 +741,8 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<List<ServerProviderLocation>> getAvailableLocations() async {
|
||||
Future<APIGenericResult<List<ServerProviderLocation>>>
|
||||
getAvailableLocations() async {
|
||||
List<ServerProviderLocation> locations = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
|
@ -715,15 +763,20 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
.toList();
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return APIGenericResult(
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return locations;
|
||||
return APIGenericResult(data: locations, success: true);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ServerType>> getServerTypesByLocation({
|
||||
Future<APIGenericResult<List<ServerType>>> getServerTypesByLocation({
|
||||
required final ServerProviderLocation location,
|
||||
}) async {
|
||||
final List<ServerType> types = [];
|
||||
|
@ -756,19 +809,26 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return APIGenericResult(
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return types;
|
||||
return APIGenericResult(data: types, success: true);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> createReverseDns({
|
||||
Future<APIGenericResult<void>> createReverseDns({
|
||||
required final ServerHostingDetails serverDetails,
|
||||
required final ServerDomain domain,
|
||||
}) async {
|
||||
/// TODO remove from provider interface
|
||||
const bool success = true;
|
||||
return APIGenericResult(success: success, data: null);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -60,35 +60,50 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
String get displayProviderName => 'Hetzner';
|
||||
|
||||
@override
|
||||
Future<bool> isApiTokenValid(final String token) async {
|
||||
Future<APIGenericResult<bool>> isApiTokenValid(final String token) async {
|
||||
bool isValid = false;
|
||||
Response? response;
|
||||
String message = '';
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
response = await client.get(
|
||||
'/servers',
|
||||
options: Options(
|
||||
followRedirects: false,
|
||||
validateStatus: (final status) =>
|
||||
status != null && (status >= 200 || status == 401),
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
isValid = false;
|
||||
message = e.toString();
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
if (response != null) {
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
isValid = true;
|
||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||
isValid = false;
|
||||
} else {
|
||||
throw Exception('code: ${response.statusCode}');
|
||||
}
|
||||
if (response == null) {
|
||||
return APIGenericResult(
|
||||
data: isValid,
|
||||
success: false,
|
||||
message: message,
|
||||
);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
isValid = true;
|
||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||
isValid = false;
|
||||
} else {
|
||||
throw Exception('code: ${response.statusCode}');
|
||||
}
|
||||
|
||||
return APIGenericResult(
|
||||
data: isValid,
|
||||
success: true,
|
||||
message: response.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -125,10 +140,10 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<ServerVolume?> createVolume() async {
|
||||
Future<APIGenericResult<ServerVolume?>> createVolume() async {
|
||||
ServerVolume? volume;
|
||||
|
||||
final Response createVolumeResponse;
|
||||
Response? createVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
createVolumeResponse = await client.post(
|
||||
|
@ -156,11 +171,21 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return APIGenericResult(
|
||||
data: null,
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return volume;
|
||||
return APIGenericResult(
|
||||
data: volume,
|
||||
success: true,
|
||||
code: createVolumeResponse.statusCode,
|
||||
message: createVolumeResponse.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -244,13 +269,13 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<bool> attachVolume(
|
||||
Future<APIGenericResult<bool>> attachVolume(
|
||||
final ServerVolume volume,
|
||||
final int serverId,
|
||||
) async {
|
||||
bool success = false;
|
||||
|
||||
final Response attachVolumeResponse;
|
||||
Response? attachVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
attachVolumeResponse = await client.post(
|
||||
|
@ -268,7 +293,12 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
client.close();
|
||||
}
|
||||
|
||||
return success;
|
||||
return APIGenericResult(
|
||||
data: success,
|
||||
success: true,
|
||||
code: attachVolumeResponse?.statusCode,
|
||||
message: attachVolumeResponse?.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -320,31 +350,33 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<ServerHostingDetails?> createServer({
|
||||
Future<APIGenericResult<ServerHostingDetails?>> createServer({
|
||||
required final String dnsApiToken,
|
||||
required final User rootUser,
|
||||
required final String domainName,
|
||||
required final String serverType,
|
||||
}) async {
|
||||
ServerHostingDetails? details;
|
||||
final APIGenericResult<ServerVolume?> newVolumeResponse =
|
||||
await createVolume();
|
||||
|
||||
final ServerVolume? newVolume = await createVolume();
|
||||
if (newVolume == null) {
|
||||
return details;
|
||||
if (!newVolumeResponse.success || newVolumeResponse.data == null) {
|
||||
return APIGenericResult(
|
||||
data: null,
|
||||
success: false,
|
||||
message: newVolumeResponse.message,
|
||||
code: newVolumeResponse.code,
|
||||
);
|
||||
}
|
||||
|
||||
details = await createServerWithVolume(
|
||||
return createServerWithVolume(
|
||||
dnsApiToken: dnsApiToken,
|
||||
rootUser: rootUser,
|
||||
domainName: domainName,
|
||||
volume: newVolume,
|
||||
volume: newVolumeResponse.data!,
|
||||
serverType: serverType,
|
||||
);
|
||||
|
||||
return details;
|
||||
}
|
||||
|
||||
Future<ServerHostingDetails?> createServerWithVolume({
|
||||
Future<APIGenericResult<ServerHostingDetails?>> createServerWithVolume({
|
||||
required final String dnsApiToken,
|
||||
required final User rootUser,
|
||||
required final String domainName,
|
||||
|
@ -366,6 +398,7 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
final String userdataString =
|
||||
"#cloud-config\nruncmd:\n- curl https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-infect/raw/branch/$infectBranch/nixos-infect | STAGING_ACME='$stagingAcme' PROVIDER=$infectProviderName NIX_CHANNEL=nixos-21.05 DOMAIN='$domainName' LUSER='${rootUser.login}' ENCODED_PASSWORD='$base64Password' CF_TOKEN=$dnsApiToken DB_PASSWORD=$dbPassword API_TOKEN=$apiToken HOSTNAME=$hostname bash 2>&1 | tee /tmp/infect.log";
|
||||
|
||||
Response? serverCreateResponse;
|
||||
ServerHostingDetails? serverDetails;
|
||||
DioError? hetznerError;
|
||||
bool success = false;
|
||||
|
@ -385,7 +418,7 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
};
|
||||
print('Decoded data: $data');
|
||||
|
||||
final Response serverCreateResponse = await client.post(
|
||||
serverCreateResponse = await client.post(
|
||||
'/servers',
|
||||
data: data,
|
||||
);
|
||||
|
@ -413,11 +446,19 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
await deleteVolume(volume);
|
||||
}
|
||||
|
||||
if (hetznerError != null) {
|
||||
throw hetznerError;
|
||||
String? apiResultMessage = serverCreateResponse?.statusMessage;
|
||||
if (hetznerError != null &&
|
||||
hetznerError.response!.data['error']['code'] == 'uniqueness_error') {
|
||||
apiResultMessage = 'uniqueness_error';
|
||||
}
|
||||
|
||||
return serverDetails;
|
||||
return APIGenericResult(
|
||||
data: serverDetails,
|
||||
success: success && hetznerError == null,
|
||||
code: serverCreateResponse?.statusCode ??
|
||||
hetznerError?.response?.statusCode,
|
||||
message: apiResultMessage,
|
||||
);
|
||||
}
|
||||
|
||||
static String getHostnameFromDomain(final String domain) {
|
||||
|
@ -692,7 +733,8 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<List<ServerProviderLocation>> getAvailableLocations() async {
|
||||
Future<APIGenericResult<List<ServerProviderLocation>>>
|
||||
getAvailableLocations() async {
|
||||
List<ServerProviderLocation> locations = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
|
@ -713,15 +755,20 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
.toList();
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return APIGenericResult(
|
||||
success: false,
|
||||
data: [],
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return locations;
|
||||
return APIGenericResult(success: true, data: locations);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ServerType>> getServerTypesByLocation({
|
||||
Future<APIGenericResult<List<ServerType>>> getServerTypesByLocation({
|
||||
required final ServerProviderLocation location,
|
||||
}) async {
|
||||
final List<ServerType> types = [];
|
||||
|
@ -754,15 +801,20 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return APIGenericResult(
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return types;
|
||||
return APIGenericResult(data: types, success: true);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> createReverseDns({
|
||||
Future<APIGenericResult<void>> createReverseDns({
|
||||
required final ServerHostingDetails serverDetails,
|
||||
required final ServerDomain domain,
|
||||
}) async {
|
||||
|
@ -777,8 +829,15 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return APIGenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return APIGenericResult(success: true, data: null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:selfprivacy/logic/api_maps/api_generic_result.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
|
@ -8,6 +9,8 @@ import 'package:selfprivacy/logic/models/server_metadata.dart';
|
|||
import 'package:selfprivacy/logic/models/server_provider_location.dart';
|
||||
import 'package:selfprivacy/logic/models/server_type.dart';
|
||||
|
||||
export 'package:selfprivacy/logic/api_maps/api_generic_result.dart';
|
||||
|
||||
class ProviderApiTokenValidation {
|
||||
ProviderApiTokenValidation({
|
||||
required this.length,
|
||||
|
@ -19,8 +22,9 @@ class ProviderApiTokenValidation {
|
|||
|
||||
abstract class ServerProviderApi extends ApiMap {
|
||||
Future<List<ServerBasicInfo>> getServers();
|
||||
Future<List<ServerProviderLocation>> getAvailableLocations();
|
||||
Future<List<ServerType>> getServerTypesByLocation({
|
||||
Future<APIGenericResult<List<ServerProviderLocation>>>
|
||||
getAvailableLocations();
|
||||
Future<APIGenericResult<List<ServerType>>> getServerTypesByLocation({
|
||||
required final ServerProviderLocation location,
|
||||
});
|
||||
|
||||
|
@ -28,18 +32,18 @@ abstract class ServerProviderApi extends ApiMap {
|
|||
Future<ServerHostingDetails> powerOn();
|
||||
|
||||
Future<void> deleteServer({required final String domainName});
|
||||
Future<ServerHostingDetails?> createServer({
|
||||
Future<APIGenericResult<ServerHostingDetails?>> createServer({
|
||||
required final String dnsApiToken,
|
||||
required final User rootUser,
|
||||
required final String domainName,
|
||||
required final String serverType,
|
||||
});
|
||||
Future<void> createReverseDns({
|
||||
Future<APIGenericResult<void>> createReverseDns({
|
||||
required final ServerHostingDetails serverDetails,
|
||||
required final ServerDomain domain,
|
||||
});
|
||||
|
||||
Future<bool> isApiTokenValid(final String token);
|
||||
Future<APIGenericResult<bool>> isApiTokenValid(final String token);
|
||||
ProviderApiTokenValidation getApiTokenValidation();
|
||||
Future<List<ServerMetadataEntity>> getMetadata(final int serverId);
|
||||
Future<ServerMetrics?> getMetrics(
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
import 'package:selfprivacy/logic/api_maps/api_generic_result.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart';
|
||||
import 'package:selfprivacy/logic/models/disk_size.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
import 'package:selfprivacy/logic/models/price.dart';
|
||||
|
||||
export 'package:selfprivacy/logic/api_maps/api_generic_result.dart';
|
||||
|
||||
mixin VolumeProviderApi on ApiMap {
|
||||
Future<ServerVolume?> createVolume();
|
||||
Future<APIGenericResult<ServerVolume?>> createVolume();
|
||||
Future<List<ServerVolume>> getVolumes({final String? status});
|
||||
Future<bool> attachVolume(final ServerVolume volume, final int serverId);
|
||||
Future<APIGenericResult<bool>> attachVolume(
|
||||
final ServerVolume volume,
|
||||
final int serverId,
|
||||
);
|
||||
Future<bool> detachVolume(final ServerVolume volume);
|
||||
Future<bool> resizeVolume(final ServerVolume volume, final DiskSize size);
|
||||
Future<void> deleteVolume(final ServerVolume volume);
|
||||
|
|
|
@ -35,7 +35,7 @@ class ApiDevicesCubit
|
|||
}
|
||||
|
||||
Future<List<ApiToken>?> _getApiTokens() async {
|
||||
final GenericResult<List<ApiToken>> response = await api.getApiTokens();
|
||||
final APIGenericResult<List<ApiToken>> response = await api.getApiTokens();
|
||||
if (response.success) {
|
||||
return response.data;
|
||||
} else {
|
||||
|
@ -44,7 +44,8 @@ class ApiDevicesCubit
|
|||
}
|
||||
|
||||
Future<void> deleteDevice(final ApiToken device) async {
|
||||
final GenericResult<void> response = await api.deleteApiToken(device.name);
|
||||
final APIGenericResult<void> response =
|
||||
await api.deleteApiToken(device.name);
|
||||
if (response.success) {
|
||||
emit(
|
||||
ApiDevicesState(
|
||||
|
@ -59,7 +60,7 @@ class ApiDevicesCubit
|
|||
}
|
||||
|
||||
Future<String?> getNewDeviceKey() async {
|
||||
final GenericResult<String> response = await api.createDeviceToken();
|
||||
final APIGenericResult<String> response = await api.createDeviceToken();
|
||||
if (response.success) {
|
||||
return response.data;
|
||||
} else {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:async';
|
||||
import 'package:cubit_form/cubit_form.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/backblaze.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
||||
|
@ -7,7 +8,6 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
|
||||
class BackblazeFormCubit extends FormCubit {
|
||||
BackblazeFormCubit(this.serverInstallationCubit) {
|
||||
//var regExp = RegExp(r"\s+|[-!$%^&*()@+|~=`{}\[\]:<>?,.\/]");
|
||||
keyId = FieldCubit(
|
||||
initalValue: '',
|
||||
validations: [
|
||||
|
@ -40,7 +40,7 @@ class BackblazeFormCubit extends FormCubit {
|
|||
|
||||
@override
|
||||
FutureOr<bool> asyncValidation() async {
|
||||
late bool isKeyValid;
|
||||
late APIGenericResult<bool> backblazeResponse;
|
||||
final BackblazeApi apiClient = BackblazeApi(isWithToken: false);
|
||||
|
||||
try {
|
||||
|
@ -48,18 +48,30 @@ class BackblazeFormCubit extends FormCubit {
|
|||
keyId.state.value,
|
||||
applicationKey.state.value,
|
||||
);
|
||||
isKeyValid = await apiClient.isValid(encodedApiKey);
|
||||
backblazeResponse = await apiClient.isApiTokenValid(encodedApiKey);
|
||||
} catch (e) {
|
||||
addError(e);
|
||||
isKeyValid = false;
|
||||
backblazeResponse = APIGenericResult(
|
||||
success: false,
|
||||
data: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
}
|
||||
|
||||
if (!isKeyValid) {
|
||||
keyId.setError('initializing.backblaze_bad_key_error'.tr());
|
||||
applicationKey.setError('initializing.backblaze_bad_key_error'.tr());
|
||||
if (!backblazeResponse.success) {
|
||||
getIt<NavigationService>().showSnackBar(
|
||||
'initializing.could_not_connect'.tr(),
|
||||
);
|
||||
keyId.setError('');
|
||||
applicationKey.setError('');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (!backblazeResponse.data) {
|
||||
keyId.setError('initializing.backblaze_bad_key_error'.tr());
|
||||
applicationKey.setError('initializing.backblaze_bad_key_error'.tr());
|
||||
}
|
||||
|
||||
return backblazeResponse.data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,21 +28,24 @@ class DnsProviderFormCubit extends FormCubit {
|
|||
|
||||
@override
|
||||
FutureOr<bool> asyncValidation() async {
|
||||
late bool isKeyValid;
|
||||
bool? isKeyValid;
|
||||
|
||||
try {
|
||||
isKeyValid = await initializingCubit
|
||||
.isDnsProviderApiTokenValid(apiKey.state.value);
|
||||
} catch (e) {
|
||||
addError(e);
|
||||
isKeyValid = false;
|
||||
}
|
||||
|
||||
if (isKeyValid == null) {
|
||||
apiKey.setError('');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isKeyValid) {
|
||||
apiKey.setError('initializing.cloudflare_bad_key_error'.tr());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return isKeyValid;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,21 +29,24 @@ class ProviderFormCubit extends FormCubit {
|
|||
|
||||
@override
|
||||
FutureOr<bool> asyncValidation() async {
|
||||
late bool isKeyValid;
|
||||
bool? isKeyValid;
|
||||
|
||||
try {
|
||||
isKeyValid = await serverInstallationCubit
|
||||
.isServerProviderApiTokenValid(apiKey.state.value);
|
||||
} catch (e) {
|
||||
addError(e);
|
||||
isKeyValid = false;
|
||||
}
|
||||
|
||||
if (isKeyValid == null) {
|
||||
apiKey.setError('');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isKeyValid) {
|
||||
apiKey.setError('initializing.provider_bad_key_error'.tr());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return isKeyValid;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,10 +113,11 @@ class ApiProviderVolumeCubit
|
|||
}
|
||||
|
||||
Future<void> createVolume() async {
|
||||
final ServerVolume? volume = await ApiController
|
||||
.currentVolumeProviderApiFactory!
|
||||
.getVolumeProvider()
|
||||
.createVolume();
|
||||
final ServerVolume? volume = (await ApiController
|
||||
.currentVolumeProviderApiFactory!
|
||||
.getVolumeProvider()
|
||||
.createVolume())
|
||||
.data;
|
||||
|
||||
final diskVolume = DiskVolume(providerVolume: volume);
|
||||
await attachVolume(diskVolume);
|
||||
|
|
|
@ -32,7 +32,7 @@ class RecoveryKeyCubit
|
|||
}
|
||||
|
||||
Future<RecoveryKeyStatus?> _getRecoveryKeyStatus() async {
|
||||
final GenericResult<RecoveryKeyStatus?> response =
|
||||
final APIGenericResult<RecoveryKeyStatus?> response =
|
||||
await api.getRecoveryTokenStatus();
|
||||
if (response.success) {
|
||||
return response.data;
|
||||
|
@ -57,7 +57,7 @@ class RecoveryKeyCubit
|
|||
final DateTime? expirationDate,
|
||||
final int? numberOfUses,
|
||||
}) async {
|
||||
final GenericResult<String> response =
|
||||
final APIGenericResult<String> response =
|
||||
await api.generateRecoveryToken(expirationDate, numberOfUses);
|
||||
if (response.success) {
|
||||
refresh();
|
||||
|
|
|
@ -76,18 +76,29 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
.getDnsProvider()
|
||||
.getApiTokenValidation();
|
||||
|
||||
Future<bool> isServerProviderApiTokenValid(
|
||||
Future<bool?> isServerProviderApiTokenValid(
|
||||
final String providerToken,
|
||||
) async =>
|
||||
ApiController.currentServerProviderApiFactory!
|
||||
.getServerProvider(
|
||||
settings: const ServerProviderApiSettings(
|
||||
isWithToken: false,
|
||||
),
|
||||
)
|
||||
.isApiTokenValid(providerToken);
|
||||
) async {
|
||||
final APIGenericResult<bool> apiResponse =
|
||||
await ApiController.currentServerProviderApiFactory!
|
||||
.getServerProvider(
|
||||
settings: const ServerProviderApiSettings(
|
||||
isWithToken: false,
|
||||
),
|
||||
)
|
||||
.isApiTokenValid(providerToken);
|
||||
|
||||
Future<bool> isDnsProviderApiTokenValid(
|
||||
if (!apiResponse.success) {
|
||||
getIt<NavigationService>().showSnackBar(
|
||||
'initializing.could_not_connect'.tr(),
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return apiResponse.data;
|
||||
}
|
||||
|
||||
Future<bool?> isDnsProviderApiTokenValid(
|
||||
final String providerToken,
|
||||
) async {
|
||||
if (ApiController.currentDnsProviderApiFactory == null) {
|
||||
|
@ -100,11 +111,21 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
);
|
||||
}
|
||||
|
||||
return ApiController.currentDnsProviderApiFactory!
|
||||
.getDnsProvider(
|
||||
settings: const DnsProviderApiSettings(isWithToken: false),
|
||||
)
|
||||
.isApiTokenValid(providerToken);
|
||||
final APIGenericResult<bool> apiResponse =
|
||||
await ApiController.currentDnsProviderApiFactory!
|
||||
.getDnsProvider(
|
||||
settings: const DnsProviderApiSettings(isWithToken: false),
|
||||
)
|
||||
.isApiTokenValid(providerToken);
|
||||
|
||||
if (!apiResponse.success) {
|
||||
getIt<NavigationService>().showSnackBar(
|
||||
'initializing.could_not_connect'.tr(),
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return apiResponse.data;
|
||||
}
|
||||
|
||||
Future<List<ServerProviderLocation>> fetchAvailableLocations() async {
|
||||
|
@ -112,9 +133,18 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
return [];
|
||||
}
|
||||
|
||||
return ApiController.currentServerProviderApiFactory!
|
||||
final APIGenericResult apiResult = await ApiController
|
||||
.currentServerProviderApiFactory!
|
||||
.getServerProvider()
|
||||
.getAvailableLocations();
|
||||
|
||||
if (!apiResult.success) {
|
||||
getIt<NavigationService>().showSnackBar(
|
||||
'initializing.could_not_connect'.tr(),
|
||||
);
|
||||
}
|
||||
|
||||
return apiResult.data;
|
||||
}
|
||||
|
||||
Future<List<ServerType>> fetchAvailableTypesByLocation(
|
||||
|
@ -124,9 +154,18 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
return [];
|
||||
}
|
||||
|
||||
return ApiController.currentServerProviderApiFactory!
|
||||
final APIGenericResult apiResult = await ApiController
|
||||
.currentServerProviderApiFactory!
|
||||
.getServerProvider()
|
||||
.getServerTypesByLocation(location: location);
|
||||
|
||||
if (!apiResult.success) {
|
||||
getIt<NavigationService>().showSnackBar(
|
||||
'initializing.could_not_connect'.tr(),
|
||||
);
|
||||
}
|
||||
|
||||
return apiResult.data;
|
||||
}
|
||||
|
||||
void setServerProviderKey(final String serverProviderKey) async {
|
||||
|
|
|
@ -75,13 +75,12 @@ class ServerInstallationRepository {
|
|||
);
|
||||
}
|
||||
|
||||
if (serverDomain != null && serverDomain.provider != DnsProvider.unknown) {
|
||||
ApiController.initDnsProviderApiFactory(
|
||||
DnsProviderApiFactorySettings(
|
||||
provider: serverDomain.provider,
|
||||
),
|
||||
);
|
||||
}
|
||||
// No other DNS provider is supported for now, so it's fine.
|
||||
ApiController.initDnsProviderApiFactory(
|
||||
DnsProviderApiFactorySettings(
|
||||
provider: DnsProvider.cloudflare,
|
||||
),
|
||||
);
|
||||
|
||||
if (box.get(BNames.hasFinalChecked, defaultValue: false)) {
|
||||
return ServerInstallationFinished(
|
||||
|
@ -247,22 +246,52 @@ class ServerInstallationRepository {
|
|||
}) async {
|
||||
final ServerProviderApi api =
|
||||
ApiController.currentServerProviderApiFactory!.getServerProvider();
|
||||
|
||||
void showInstallationErrorPopUp() {
|
||||
showPopUpAlert(
|
||||
alertTitle: 'modals.unexpected_error'.tr(),
|
||||
description: 'modals.try_again'.tr(),
|
||||
actionButtonTitle: 'modals.yes'.tr(),
|
||||
actionButtonOnPressed: () async {
|
||||
ServerHostingDetails? serverDetails;
|
||||
try {
|
||||
final APIGenericResult createResult = await api.createServer(
|
||||
dnsApiToken: cloudFlareKey,
|
||||
rootUser: rootUser,
|
||||
domainName: domainName,
|
||||
serverType: getIt<ApiConfigModel>().serverType!,
|
||||
);
|
||||
serverDetails = createResult.data;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
||||
if (serverDetails == null) {
|
||||
print('Server is not initialized!');
|
||||
return;
|
||||
}
|
||||
await saveServerDetails(serverDetails);
|
||||
onSuccess(serverDetails);
|
||||
},
|
||||
cancelButtonOnPressed: onCancel,
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
final ServerHostingDetails? serverDetails = await api.createServer(
|
||||
final APIGenericResult<ServerHostingDetails?> createServerResult =
|
||||
await api.createServer(
|
||||
dnsApiToken: cloudFlareKey,
|
||||
rootUser: rootUser,
|
||||
domainName: domainName,
|
||||
serverType: getIt<ApiConfigModel>().serverType!,
|
||||
);
|
||||
|
||||
if (serverDetails == null) {
|
||||
print('Server is not initialized!');
|
||||
return;
|
||||
if (createServerResult.data == null) {
|
||||
const String e = 'Server is not initialized!';
|
||||
print(e);
|
||||
}
|
||||
saveServerDetails(serverDetails);
|
||||
onSuccess(serverDetails);
|
||||
} on DioError catch (e) {
|
||||
if (e.response!.data['error']['code'] == 'uniqueness_error') {
|
||||
|
||||
if (createServerResult.message == 'uniqueness_error') {
|
||||
showPopUpAlert(
|
||||
alertTitle: 'modals.already_exists'.tr(),
|
||||
description: 'modals.destroy_server'.tr(),
|
||||
|
@ -274,39 +303,13 @@ class ServerInstallationRepository {
|
|||
|
||||
ServerHostingDetails? serverDetails;
|
||||
try {
|
||||
serverDetails = await api.createServer(
|
||||
dnsApiToken: cloudFlareKey,
|
||||
rootUser: rootUser,
|
||||
domainName: domainName,
|
||||
serverType: getIt<ApiConfigModel>().serverType!,
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
||||
if (serverDetails == null) {
|
||||
print('Server is not initialized!');
|
||||
return;
|
||||
}
|
||||
await saveServerDetails(serverDetails);
|
||||
onSuccess(serverDetails);
|
||||
},
|
||||
cancelButtonOnPressed: onCancel,
|
||||
);
|
||||
} else {
|
||||
showPopUpAlert(
|
||||
alertTitle: 'modals.unexpected_error'.tr(),
|
||||
description: 'modals.try_again'.tr(),
|
||||
actionButtonTitle: 'modals.yes'.tr(),
|
||||
actionButtonOnPressed: () async {
|
||||
ServerHostingDetails? serverDetails;
|
||||
try {
|
||||
serverDetails = await api.createServer(
|
||||
final APIGenericResult createResult = await api.createServer(
|
||||
dnsApiToken: cloudFlareKey,
|
||||
rootUser: rootUser,
|
||||
domainName: domainName,
|
||||
serverType: getIt<ApiConfigModel>().serverType!,
|
||||
);
|
||||
serverDetails = createResult.data;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
@ -320,7 +323,14 @@ class ServerInstallationRepository {
|
|||
},
|
||||
cancelButtonOnPressed: onCancel,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
saveServerDetails(createServerResult.data!);
|
||||
onSuccess(createServerResult.data!);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
showInstallationErrorPopUp();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,21 +344,9 @@ class ServerInstallationRepository {
|
|||
final ServerProviderApi serverApi =
|
||||
ApiController.currentServerProviderApiFactory!.getServerProvider();
|
||||
|
||||
await dnsProviderApi.removeSimilarRecords(
|
||||
ip4: serverDetails.ip4,
|
||||
domain: domain,
|
||||
);
|
||||
|
||||
try {
|
||||
await dnsProviderApi.createMultipleDnsRecords(
|
||||
ip4: serverDetails.ip4,
|
||||
domain: domain,
|
||||
);
|
||||
} on DioError catch (e) {
|
||||
void showDomainErrorPopUp(final String error) {
|
||||
showPopUpAlert(
|
||||
alertTitle: e.response!.data['errors'][0]['code'] == 1038
|
||||
? 'modals.you_cant_use_this_api'.tr()
|
||||
: 'domain.error'.tr(),
|
||||
alertTitle: error,
|
||||
description: 'modals.delete_server_volume'.tr(),
|
||||
cancelButtonOnPressed: onCancel,
|
||||
actionButtonTitle: 'basis.delete'.tr(),
|
||||
|
@ -359,14 +357,50 @@ class ServerInstallationRepository {
|
|||
onCancel();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
final APIGenericResult removingResult =
|
||||
await dnsProviderApi.removeSimilarRecords(
|
||||
ip4: serverDetails.ip4,
|
||||
domain: domain,
|
||||
);
|
||||
|
||||
if (!removingResult.success) {
|
||||
showDomainErrorPopUp('domain.error'.tr());
|
||||
return false;
|
||||
}
|
||||
|
||||
await serverApi.createReverseDns(
|
||||
bool createdSuccessfully = false;
|
||||
String errorMessage = 'domain.error'.tr();
|
||||
try {
|
||||
final APIGenericResult createResult =
|
||||
await dnsProviderApi.createMultipleDnsRecords(
|
||||
ip4: serverDetails.ip4,
|
||||
domain: domain,
|
||||
);
|
||||
createdSuccessfully = createResult.success;
|
||||
} on DioError catch (e) {
|
||||
if (e.response!.data['errors'][0]['code'] == 1038) {
|
||||
errorMessage = 'modals.you_cant_use_this_api'.tr();
|
||||
}
|
||||
}
|
||||
|
||||
if (!createdSuccessfully) {
|
||||
showDomainErrorPopUp(errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
final APIGenericResult createReverseResult =
|
||||
await serverApi.createReverseDns(
|
||||
serverDetails: serverDetails,
|
||||
domain: domain,
|
||||
);
|
||||
|
||||
if (!createReverseResult.success) {
|
||||
showDomainErrorPopUp(errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -479,7 +513,7 @@ class ServerInstallationRepository {
|
|||
overrideDomain: serverDomain.domainName,
|
||||
);
|
||||
final String serverIp = await getServerIpFromDomain(serverDomain);
|
||||
final GenericResult<String> result = await serverApi.authorizeDevice(
|
||||
final APIGenericResult<String> result = await serverApi.authorizeDevice(
|
||||
DeviceToken(device: await getDeviceName(), token: newDeviceKey),
|
||||
);
|
||||
|
||||
|
@ -516,7 +550,7 @@ class ServerInstallationRepository {
|
|||
overrideDomain: serverDomain.domainName,
|
||||
);
|
||||
final String serverIp = await getServerIpFromDomain(serverDomain);
|
||||
final GenericResult<String> result = await serverApi.useRecoveryToken(
|
||||
final APIGenericResult<String> result = await serverApi.useRecoveryToken(
|
||||
DeviceToken(device: await getDeviceName(), token: recoveryKey),
|
||||
);
|
||||
|
||||
|
@ -577,9 +611,9 @@ class ServerInstallationRepository {
|
|||
);
|
||||
}
|
||||
}
|
||||
final GenericResult<String> deviceAuthKey =
|
||||
final APIGenericResult<String> deviceAuthKey =
|
||||
await serverApi.createDeviceToken();
|
||||
final GenericResult<String> result = await serverApi.authorizeDevice(
|
||||
final APIGenericResult<String> result = await serverApi.authorizeDevice(
|
||||
DeviceToken(device: await getDeviceName(), token: deviceAuthKey.data),
|
||||
);
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
|||
return;
|
||||
}
|
||||
// If API returned error, do nothing
|
||||
final GenericMutationResult<User?> result =
|
||||
final APIGenericResult<User?> result =
|
||||
await api.createUser(user.login, password);
|
||||
if (result.data == null) {
|
||||
getIt<NavigationService>()
|
||||
|
@ -101,7 +101,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
|||
return;
|
||||
}
|
||||
final List<User> loadedUsers = List<User>.from(state.users);
|
||||
final GenericMutationResult result = await api.deleteUser(user.login);
|
||||
final APIGenericResult result = await api.deleteUser(user.login);
|
||||
if (result.success && result.data) {
|
||||
loadedUsers.removeWhere((final User u) => u.login == user.login);
|
||||
await box.clear();
|
||||
|
@ -128,7 +128,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
|||
.showSnackBar('users.could_not_change_password'.tr());
|
||||
return;
|
||||
}
|
||||
final GenericMutationResult<User?> result =
|
||||
final APIGenericResult<User?> result =
|
||||
await api.updateUser(user.login, newPassword);
|
||||
if (result.data == null) {
|
||||
getIt<NavigationService>().showSnackBar(
|
||||
|
@ -138,7 +138,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
|||
}
|
||||
|
||||
Future<void> addSshKey(final User user, final String publicKey) async {
|
||||
final GenericMutationResult<User?> result =
|
||||
final APIGenericResult<User?> result =
|
||||
await api.addSshKey(user.login, publicKey);
|
||||
if (result.data != null) {
|
||||
final User updatedUser = result.data!;
|
||||
|
@ -157,7 +157,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
|||
}
|
||||
|
||||
Future<void> deleteSshKey(final User user, final String publicKey) async {
|
||||
final GenericMutationResult<User?> result =
|
||||
final APIGenericResult<User?> result =
|
||||
await api.removeSshKey(user.login, publicKey);
|
||||
if (result.data != null) {
|
||||
final User updatedUser = result.data!;
|
||||
|
|
|
@ -77,7 +77,7 @@ class InitializingPage extends StatelessWidget {
|
|||
'Domain',
|
||||
'User',
|
||||
'Server',
|
||||
'Check',
|
||||
'Installation',
|
||||
],
|
||||
activeIndex: cubit.state.porgressBar,
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue