mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-09 17:39:42 +00:00
chore: Merge graphql into master
Reviewed-on: https://git.selfprivacy.org/kherel/selfprivacy.org.app/pulls/141 Reviewed-by: Inex Code <inex.code@selfprivacy.org>
This commit is contained in:
commit
7daa87f6c4
|
@ -8,8 +8,12 @@ import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_settings.g
|
||||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/services.graphql.dart';
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/services.graphql.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/users.graphql.dart';
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/users.graphql.dart';
|
||||||
import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart';
|
import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/user.dart';
|
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/api_token.dart';
|
import 'package:selfprivacy/logic/models/json/api_token.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/json/backup.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/json/device_token.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/json/recovery_token_status.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
|
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/server_job.dart';
|
import 'package:selfprivacy/logic/models/json/server_job.dart';
|
||||||
import 'package:selfprivacy/logic/models/service.dart';
|
import 'package:selfprivacy/logic/models/service.dart';
|
||||||
|
@ -43,12 +47,27 @@ class GenericJobMutationReturn extends GenericMutationResult {
|
||||||
final ServerJob? job;
|
final ServerJob? job;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
'Extend GenericMutationResult for mutations, return data for queries',
|
||||||
|
)
|
||||||
|
class ApiResponse<D> {
|
||||||
|
ApiResponse({
|
||||||
|
required this.success,
|
||||||
|
required this.data,
|
||||||
|
this.message,
|
||||||
|
});
|
||||||
|
final bool success;
|
||||||
|
final String? message;
|
||||||
|
final D data;
|
||||||
|
}
|
||||||
|
|
||||||
class ServerApi extends ApiMap
|
class ServerApi extends ApiMap
|
||||||
with VolumeApi, JobsApi, ServerActionsApi, ServicesApi, UsersApi {
|
with VolumeApi, JobsApi, ServerActionsApi, ServicesApi, UsersApi {
|
||||||
ServerApi({
|
ServerApi({
|
||||||
this.hasLogger = false,
|
this.hasLogger = false,
|
||||||
this.isWithToken = true,
|
this.isWithToken = true,
|
||||||
this.customToken = '',
|
this.customToken = '',
|
||||||
|
this.overrideDomain,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -58,7 +77,9 @@ class ServerApi extends ApiMap
|
||||||
@override
|
@override
|
||||||
String customToken;
|
String customToken;
|
||||||
@override
|
@override
|
||||||
String? get rootAddress => getIt<ApiConfigModel>().serverDomain?.domainName;
|
String? get rootAddress =>
|
||||||
|
overrideDomain ?? getIt<ApiConfigModel>().serverDomain?.domainName;
|
||||||
|
String? overrideDomain;
|
||||||
|
|
||||||
Future<String?> getApiVersion() async {
|
Future<String?> getApiVersion() async {
|
||||||
QueryResult response;
|
QueryResult response;
|
||||||
|
@ -94,25 +115,6 @@ class ServerApi extends ApiMap
|
||||||
return usesBinds;
|
return usesBinds;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<ApiToken>> getApiTokens() async {
|
|
||||||
QueryResult response;
|
|
||||||
List<ApiToken> tokens = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
final GraphQLClient client = await getClient();
|
|
||||||
response = await client.query$GetApiTokens();
|
|
||||||
if (response.hasException) {
|
|
||||||
print(response.exception.toString());
|
|
||||||
}
|
|
||||||
tokens = response.data!['api']['devices']
|
|
||||||
.map<ApiToken>((final e) => ApiToken.fromJson(e))
|
|
||||||
.toList();
|
|
||||||
} catch (e) {
|
|
||||||
print(e);
|
|
||||||
}
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> switchService(final String uid, final bool needTurnOn) async {
|
Future<void> switchService(final String uid, final bool needTurnOn) async {
|
||||||
try {
|
try {
|
||||||
final GraphQLClient client = await getClient();
|
final GraphQLClient client = await getClient();
|
||||||
|
@ -193,4 +195,334 @@ class ServerApi extends ApiMap
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<ApiResponse<RecoveryKeyStatus?>> getRecoveryTokenStatus() async {
|
||||||
|
RecoveryKeyStatus? key;
|
||||||
|
QueryResult<Query$RecoveryKey> response;
|
||||||
|
String? error;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
response = await client.query$RecoveryKey();
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
error = response.exception.toString();
|
||||||
|
}
|
||||||
|
key = RecoveryKeyStatus.fromGraphQL(response.parsedData!.api.recoveryKey);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiResponse<RecoveryKeyStatus?>(
|
||||||
|
success: error == null,
|
||||||
|
data: key,
|
||||||
|
message: error,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ApiResponse<String>> generateRecoveryToken(
|
||||||
|
final DateTime? expirationDate,
|
||||||
|
final int? numberOfUses,
|
||||||
|
) async {
|
||||||
|
ApiResponse<String> key;
|
||||||
|
QueryResult<Mutation$GetNewRecoveryApiKey> response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
|
||||||
|
final input = Input$RecoveryKeyLimitsInput(
|
||||||
|
expirationDate: expirationDate,
|
||||||
|
uses: numberOfUses,
|
||||||
|
);
|
||||||
|
final variables = Variables$Mutation$GetNewRecoveryApiKey(
|
||||||
|
limits: input,
|
||||||
|
);
|
||||||
|
final mutation = Options$Mutation$GetNewRecoveryApiKey(
|
||||||
|
variables: variables,
|
||||||
|
);
|
||||||
|
response = await client.mutate$GetNewRecoveryApiKey(
|
||||||
|
mutation,
|
||||||
|
);
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
key = ApiResponse<String>(
|
||||||
|
success: false,
|
||||||
|
data: '',
|
||||||
|
message: response.exception.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
key = ApiResponse<String>(
|
||||||
|
success: true,
|
||||||
|
data: response.parsedData!.getNewRecoveryApiKey.key!,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
key = ApiResponse<String>(
|
||||||
|
success: false,
|
||||||
|
data: '',
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
'Server now aware of all required DNS records. More general approach has to be implemented',
|
||||||
|
)
|
||||||
|
Future<String?> getDkim() async {
|
||||||
|
String? dkim;
|
||||||
|
QueryResult<Query$DomainInfo> response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
response = await client.query$DomainInfo();
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
}
|
||||||
|
dkim = response.parsedData!.system.domainInfo.requiredDnsRecords
|
||||||
|
.firstWhere(
|
||||||
|
(
|
||||||
|
final Query$DomainInfo$system$domainInfo$requiredDnsRecords
|
||||||
|
dnsRecord,
|
||||||
|
) =>
|
||||||
|
dnsRecord.name == 'selector._domainkey' &&
|
||||||
|
dnsRecord.recordType == 'TXT',
|
||||||
|
)
|
||||||
|
.content;
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dkim;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ApiResponse<List<ApiToken>>> getApiTokens() async {
|
||||||
|
ApiResponse<List<ApiToken>> tokens;
|
||||||
|
QueryResult<Query$GetApiTokens> response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
response = await client.query$GetApiTokens();
|
||||||
|
if (response.hasException) {
|
||||||
|
final message = response.exception.toString();
|
||||||
|
print(message);
|
||||||
|
tokens = ApiResponse<List<ApiToken>>(
|
||||||
|
success: false,
|
||||||
|
data: [],
|
||||||
|
message: message,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final List<ApiToken> parsed = response.parsedData!.api.devices
|
||||||
|
.map(
|
||||||
|
(
|
||||||
|
final Query$GetApiTokens$api$devices device,
|
||||||
|
) =>
|
||||||
|
ApiToken.fromGraphQL(device),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
tokens = ApiResponse<List<ApiToken>>(
|
||||||
|
success: true,
|
||||||
|
data: parsed,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
tokens = ApiResponse<List<ApiToken>>(
|
||||||
|
success: false,
|
||||||
|
data: [],
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ApiResponse<void>> deleteApiToken(final String name) async {
|
||||||
|
ApiResponse<void> returnable;
|
||||||
|
QueryResult<Mutation$DeleteDeviceApiToken> response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
|
||||||
|
final variables = Variables$Mutation$DeleteDeviceApiToken(
|
||||||
|
device: name,
|
||||||
|
);
|
||||||
|
final mutation = Options$Mutation$DeleteDeviceApiToken(
|
||||||
|
variables: variables,
|
||||||
|
);
|
||||||
|
response = await client.mutate$DeleteDeviceApiToken(
|
||||||
|
mutation,
|
||||||
|
);
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
returnable = ApiResponse<void>(
|
||||||
|
success: false,
|
||||||
|
data: null,
|
||||||
|
message: response.exception.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
returnable = ApiResponse<void>(
|
||||||
|
success: true,
|
||||||
|
data: null,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
returnable = ApiResponse<void>(
|
||||||
|
success: false,
|
||||||
|
data: null,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ApiResponse<String>> createDeviceToken() async {
|
||||||
|
ApiResponse<String> token;
|
||||||
|
QueryResult<Mutation$GetNewDeviceApiKey> response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
|
||||||
|
final mutation = Options$Mutation$GetNewDeviceApiKey();
|
||||||
|
response = await client.mutate$GetNewDeviceApiKey(
|
||||||
|
mutation,
|
||||||
|
);
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
token = ApiResponse<String>(
|
||||||
|
success: false,
|
||||||
|
data: '',
|
||||||
|
message: response.exception.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
token = ApiResponse<String>(
|
||||||
|
success: true,
|
||||||
|
data: response.parsedData!.getNewDeviceApiKey.key!,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
token = ApiResponse<String>(
|
||||||
|
success: false,
|
||||||
|
data: '',
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> isHttpServerWorking() async => (await getApiVersion()) != null;
|
||||||
|
|
||||||
|
Future<ApiResponse<String>> authorizeDevice(
|
||||||
|
final DeviceToken deviceToken,
|
||||||
|
) async {
|
||||||
|
ApiResponse<String> token;
|
||||||
|
QueryResult<Mutation$AuthorizeWithNewDeviceApiKey> response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
|
||||||
|
final input = Input$UseNewDeviceKeyInput(
|
||||||
|
deviceName: deviceToken.device,
|
||||||
|
key: deviceToken.token,
|
||||||
|
);
|
||||||
|
|
||||||
|
final variables = Variables$Mutation$AuthorizeWithNewDeviceApiKey(
|
||||||
|
input: input,
|
||||||
|
);
|
||||||
|
final mutation = Options$Mutation$AuthorizeWithNewDeviceApiKey(
|
||||||
|
variables: variables,
|
||||||
|
);
|
||||||
|
response = await client.mutate$AuthorizeWithNewDeviceApiKey(
|
||||||
|
mutation,
|
||||||
|
);
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
token = ApiResponse<String>(
|
||||||
|
success: false,
|
||||||
|
data: '',
|
||||||
|
message: response.exception.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
token = ApiResponse<String>(
|
||||||
|
success: true,
|
||||||
|
data: response.parsedData!.authorizeWithNewDeviceApiKey.token!,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
token = ApiResponse<String>(
|
||||||
|
success: false,
|
||||||
|
data: '',
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ApiResponse<String>> useRecoveryToken(
|
||||||
|
final DeviceToken deviceToken,
|
||||||
|
) async {
|
||||||
|
ApiResponse<String> token;
|
||||||
|
QueryResult<Mutation$UseRecoveryApiKey> response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final GraphQLClient client = await getClient();
|
||||||
|
|
||||||
|
final input = Input$UseRecoveryKeyInput(
|
||||||
|
deviceName: deviceToken.device,
|
||||||
|
key: deviceToken.token,
|
||||||
|
);
|
||||||
|
|
||||||
|
final variables = Variables$Mutation$UseRecoveryApiKey(
|
||||||
|
input: input,
|
||||||
|
);
|
||||||
|
final mutation = Options$Mutation$UseRecoveryApiKey(
|
||||||
|
variables: variables,
|
||||||
|
);
|
||||||
|
response = await client.mutate$UseRecoveryApiKey(
|
||||||
|
mutation,
|
||||||
|
);
|
||||||
|
if (response.hasException) {
|
||||||
|
print(response.exception.toString());
|
||||||
|
token = ApiResponse<String>(
|
||||||
|
success: false,
|
||||||
|
data: '',
|
||||||
|
message: response.exception.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
token = ApiResponse<String>(
|
||||||
|
success: true,
|
||||||
|
data: response.parsedData!.useRecoveryApiKey.token!,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
token = ApiResponse<String>(
|
||||||
|
success: false,
|
||||||
|
data: '',
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO: backups're not implemented on server side
|
||||||
|
|
||||||
|
Future<BackupStatus> getBackupStatus() async => BackupStatus(
|
||||||
|
progress: 0.0,
|
||||||
|
status: BackupStatusEnum.error,
|
||||||
|
errorMessage: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
Future<List<Backup>> getBackups() async => [];
|
||||||
|
|
||||||
|
Future<void> uploadBackblazeConfig(final BackblazeBucket bucket) async {}
|
||||||
|
|
||||||
|
Future<void> forceBackupListReload() async {}
|
||||||
|
|
||||||
|
Future<void> startBackup() async {}
|
||||||
|
|
||||||
|
Future<void> restoreBackup(final String backupId) async {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,869 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/hive/user.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/json/api_token.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/json/backup.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/json/device_token.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/json/recovery_token_status.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/service.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/timezone_settings.dart';
|
|
||||||
|
|
||||||
class ApiResponse<D> {
|
|
||||||
ApiResponse({
|
|
||||||
required this.statusCode,
|
|
||||||
required this.data,
|
|
||||||
this.errorMessage,
|
|
||||||
});
|
|
||||||
final int statusCode;
|
|
||||||
final String? errorMessage;
|
|
||||||
final D data;
|
|
||||||
|
|
||||||
bool get isSuccess => statusCode >= 200 && statusCode < 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ServerApi extends ApiMap {
|
|
||||||
ServerApi({
|
|
||||||
this.hasLogger = false,
|
|
||||||
this.isWithToken = true,
|
|
||||||
this.overrideDomain,
|
|
||||||
this.customToken,
|
|
||||||
});
|
|
||||||
@override
|
|
||||||
bool hasLogger;
|
|
||||||
@override
|
|
||||||
bool isWithToken;
|
|
||||||
String? overrideDomain;
|
|
||||||
String? customToken;
|
|
||||||
|
|
||||||
@override
|
|
||||||
BaseOptions get options {
|
|
||||||
BaseOptions options = BaseOptions(
|
|
||||||
connectTimeout: 10000,
|
|
||||||
receiveTimeout: 10000,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isWithToken) {
|
|
||||||
final ServerDomain? serverDomain = getIt<ApiConfigModel>().serverDomain;
|
|
||||||
final String domainName = serverDomain!.domainName;
|
|
||||||
final String? apiToken = getIt<ApiConfigModel>().serverDetails?.apiToken;
|
|
||||||
|
|
||||||
options = BaseOptions(
|
|
||||||
baseUrl: 'https://api.$domainName',
|
|
||||||
connectTimeout: 10000,
|
|
||||||
receiveTimeout: 10000,
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Bearer $apiToken',
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overrideDomain != null) {
|
|
||||||
options = BaseOptions(
|
|
||||||
baseUrl: 'https://api.$overrideDomain',
|
|
||||||
connectTimeout: 10000,
|
|
||||||
receiveTimeout: 10000,
|
|
||||||
headers: customToken != null
|
|
||||||
? {'Authorization': 'Bearer $customToken'}
|
|
||||||
: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String?> getApiVersion() async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
String? apiVersion;
|
|
||||||
|
|
||||||
try {
|
|
||||||
response = await client.get('/api/version');
|
|
||||||
apiVersion = response.data['version'];
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
return apiVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> isHttpServerWorking() async {
|
|
||||||
bool res = false;
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/services/status');
|
|
||||||
res = response.statusCode == HttpStatus.ok;
|
|
||||||
} catch (e) {
|
|
||||||
print(e);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<User>> createUser(final User user) async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.post(
|
|
||||||
'/users',
|
|
||||||
data: {
|
|
||||||
'username': user.login,
|
|
||||||
'password': user.password,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse(
|
|
||||||
errorMessage: e.error.toString(),
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: User(
|
|
||||||
login: user.login,
|
|
||||||
type: UserType.normal,
|
|
||||||
password: user.password,
|
|
||||||
isFoundOnServer: false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isFoundOnServer = false;
|
|
||||||
int code = 0;
|
|
||||||
|
|
||||||
final bool isUserCreated = (response.statusCode != null) &&
|
|
||||||
(response.statusCode == HttpStatus.created);
|
|
||||||
|
|
||||||
if (isUserCreated) {
|
|
||||||
isFoundOnServer = true;
|
|
||||||
code = response.statusCode!;
|
|
||||||
} else {
|
|
||||||
isFoundOnServer = false;
|
|
||||||
code = HttpStatus.notAcceptable;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ApiResponse(
|
|
||||||
statusCode: code,
|
|
||||||
data: User(
|
|
||||||
login: user.login,
|
|
||||||
type: UserType.normal,
|
|
||||||
password: user.password,
|
|
||||||
isFoundOnServer: isFoundOnServer,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<List<String>>> getUsersList({
|
|
||||||
final withMainUser = false,
|
|
||||||
}) async {
|
|
||||||
final List<String> res = [];
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get(
|
|
||||||
'/users',
|
|
||||||
queryParameters: withMainUser ? {'withMainUser': 'true'} : null,
|
|
||||||
);
|
|
||||||
for (final user in response.data) {
|
|
||||||
res.add(user.toString());
|
|
||||||
}
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: [],
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
print(e);
|
|
||||||
return ApiResponse(
|
|
||||||
errorMessage: e.toString(),
|
|
||||||
statusCode: HttpStatus.internalServerError,
|
|
||||||
data: [],
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse(
|
|
||||||
statusCode: code,
|
|
||||||
data: res,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<void>> addUserSshKey(
|
|
||||||
final User user,
|
|
||||||
final String sshKey,
|
|
||||||
) async {
|
|
||||||
late Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.post(
|
|
||||||
'/services/ssh/keys/${user.login}',
|
|
||||||
data: {
|
|
||||||
'public_key': sshKey,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse<void>(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: null,
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse<void>(
|
|
||||||
statusCode: code,
|
|
||||||
data: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<void>> addRootSshKey(final String ssh) async {
|
|
||||||
late Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.put(
|
|
||||||
'/services/ssh/key/send',
|
|
||||||
data: {'public_key': ssh},
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse<void>(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: null,
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse<void>(
|
|
||||||
statusCode: code,
|
|
||||||
data: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<List<String>>> getUserSshKeys(final User user) async {
|
|
||||||
List<String> res;
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/services/ssh/keys/${user.login}');
|
|
||||||
res = (response.data as List<dynamic>)
|
|
||||||
.map((final e) => e as String)
|
|
||||||
.toList();
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse<List<String>>(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: [],
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
return ApiResponse<List<String>>(
|
|
||||||
errorMessage: e.toString(),
|
|
||||||
statusCode: HttpStatus.internalServerError,
|
|
||||||
data: [],
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse<List<String>>(
|
|
||||||
statusCode: code,
|
|
||||||
data: res,
|
|
||||||
errorMessage: response.data is List
|
|
||||||
? null
|
|
||||||
: response.data?.containsKey('error') ?? false
|
|
||||||
? response.data['error']
|
|
||||||
: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<void>> deleteUserSshKey(
|
|
||||||
final User user,
|
|
||||||
final String sshKey,
|
|
||||||
) async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.delete(
|
|
||||||
'/services/ssh/keys/${user.login}',
|
|
||||||
data: {'public_key': sshKey},
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse<void>(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: null,
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse<void>(
|
|
||||||
statusCode: code,
|
|
||||||
data: null,
|
|
||||||
errorMessage: response.data?.containsKey('error') ?? false
|
|
||||||
? response.data['error']
|
|
||||||
: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> deleteUser(final User user) async {
|
|
||||||
bool res = false;
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.delete('/users/${user.login}');
|
|
||||||
res = response.statusCode == HttpStatus.ok ||
|
|
||||||
response.statusCode == HttpStatus.notFound;
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
res = false;
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get rootAddress =>
|
|
||||||
throw UnimplementedError('not used in with implementation');
|
|
||||||
|
|
||||||
Future<bool> apply() async {
|
|
||||||
bool res = false;
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/system/configuration/apply');
|
|
||||||
res = response.statusCode == HttpStatus.ok;
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
res = false;
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> switchService(
|
|
||||||
final Service service,
|
|
||||||
final bool needToTurnOn,
|
|
||||||
) async {
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
client.post(
|
|
||||||
'/services/${service.id}/${needToTurnOn ? 'enable' : 'disable'}',
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map<String, bool>> servicesPowerCheck() async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/services/status');
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return {};
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
'bitwarden': response.data['bitwarden'] == 0,
|
|
||||||
'gitea': response.data['gitea'] == 0,
|
|
||||||
'nextcloud': response.data['nextcloud'] == 0,
|
|
||||||
'ocserv': response.data['ocserv'] == 0,
|
|
||||||
'pleroma': response.data['pleroma'] == 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> uploadBackblazeConfig(final BackblazeBucket bucket) async {
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
client.put(
|
|
||||||
'/services/restic/backblaze/config',
|
|
||||||
data: {
|
|
||||||
'accountId': bucket.applicationKeyId,
|
|
||||||
'accountKey': bucket.applicationKey,
|
|
||||||
'bucket': bucket.bucketName,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> startBackup() async {
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
client.put('/services/restic/backup/create');
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<Backup>> getBackups() async {
|
|
||||||
Response response;
|
|
||||||
List<Backup> backups = [];
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/services/restic/backup/list');
|
|
||||||
backups =
|
|
||||||
response.data.map<Backup>((final e) => Backup.fromJson(e)).toList();
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} catch (e) {
|
|
||||||
print(e);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
return backups;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<BackupStatus> getBackupStatus() async {
|
|
||||||
Response response;
|
|
||||||
BackupStatus status = BackupStatus(
|
|
||||||
status: BackupStatusEnum.error,
|
|
||||||
errorMessage: 'Network error',
|
|
||||||
progress: 0,
|
|
||||||
);
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/services/restic/backup/status');
|
|
||||||
status = BackupStatus.fromJson(response.data);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> forceBackupListReload() async {
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
client.get('/services/restic/backup/reload');
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> restoreBackup(final String backupId) async {
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
client.put(
|
|
||||||
'/services/restic/backup/restore',
|
|
||||||
data: {'backupId': backupId},
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> pullConfigurationUpdate() async {
|
|
||||||
Response response;
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/system/configuration/pull');
|
|
||||||
result = (response.statusCode != null)
|
|
||||||
? (response.statusCode == HttpStatus.ok)
|
|
||||||
: false;
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> reboot() async {
|
|
||||||
Response response;
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/system/reboot');
|
|
||||||
result = (response.statusCode != null)
|
|
||||||
? (response.statusCode == HttpStatus.ok)
|
|
||||||
: false;
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> upgrade() async {
|
|
||||||
Response response;
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/system/configuration/upgrade');
|
|
||||||
result = (response.statusCode != null)
|
|
||||||
? (response.statusCode == HttpStatus.ok)
|
|
||||||
: false;
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<TimeZoneSettings> getServerTimezone() async {
|
|
||||||
TimeZoneSettings settings = TimeZoneSettings();
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
final Response response = await client.get(
|
|
||||||
'/system/configuration/timezone',
|
|
||||||
);
|
|
||||||
settings = TimeZoneSettings.fromString(response.data);
|
|
||||||
} catch (e) {
|
|
||||||
print(e);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
return settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> updateServerTimezone(final TimeZoneSettings settings) async {
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
await client.put(
|
|
||||||
'/system/configuration/timezone',
|
|
||||||
data: settings.toString(),
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String?> getDkim() async {
|
|
||||||
Response response;
|
|
||||||
String? dkim;
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/services/mailserver/dkim');
|
|
||||||
final Codec<String, String> base64toString = utf8.fuse(base64);
|
|
||||||
dkim = base64toString
|
|
||||||
.decode(response.data)
|
|
||||||
.split('(')[1]
|
|
||||||
.split(')')[0]
|
|
||||||
.replaceAll('"', '');
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dkim;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<RecoveryKeyStatus?>> getRecoveryTokenStatus() async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/auth/recovery_token');
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: const RecoveryKeyStatus(exists: false, valid: false),
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse(
|
|
||||||
statusCode: code,
|
|
||||||
data: response.data != null
|
|
||||||
? RecoveryKeyStatus.fromJson(response.data)
|
|
||||||
: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<String>> generateRecoveryToken(
|
|
||||||
final DateTime? expiration,
|
|
||||||
final int? uses,
|
|
||||||
) async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
final Map data = {};
|
|
||||||
if (expiration != null) {
|
|
||||||
data['expiration'] = '${expiration.toIso8601String()}Z';
|
|
||||||
print(data['expiration']);
|
|
||||||
}
|
|
||||||
if (uses != null) {
|
|
||||||
data['uses'] = uses;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
response = await client.post(
|
|
||||||
'/auth/recovery_token',
|
|
||||||
data: data,
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: '',
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
close(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse(
|
|
||||||
statusCode: code,
|
|
||||||
data: response.data != null ? response.data['token'] : '',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<String>> useRecoveryToken(final DeviceToken token) async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.post(
|
|
||||||
'/auth/recovery_token/use',
|
|
||||||
data: {
|
|
||||||
'token': token.token,
|
|
||||||
'device': token.device,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: '',
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse(
|
|
||||||
statusCode: code,
|
|
||||||
data: response.data != null ? response.data['token'] : '',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<String>> authorizeDevice(final DeviceToken token) async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.post(
|
|
||||||
'/auth/new_device/authorize',
|
|
||||||
data: {
|
|
||||||
'token': token.token,
|
|
||||||
'device': token.device,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: '',
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse(statusCode: code, data: response.data['token'] ?? '');
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<String>> createDeviceToken() async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.post('/auth/new_device');
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: '',
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse(
|
|
||||||
statusCode: code,
|
|
||||||
data: response.data != null ? response.data['token'] : '',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<String>> deleteDeviceToken() async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.delete('/auth/new_device');
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: '',
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse(statusCode: code, data: response.data ?? '');
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<List<ApiToken>>> getApiTokens() async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.get('/auth/tokens');
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: [],
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse(
|
|
||||||
statusCode: code,
|
|
||||||
data: (response.data != null)
|
|
||||||
? response.data
|
|
||||||
.map<ApiToken>((final e) => ApiToken.fromJson(e))
|
|
||||||
.toList()
|
|
||||||
: [],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<String>> refreshCurrentApiToken() async {
|
|
||||||
Response response;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.post('/auth/tokens');
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: '',
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
|
|
||||||
return ApiResponse(
|
|
||||||
statusCode: code,
|
|
||||||
data: response.data != null ? response.data['token'] : '',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ApiResponse<void>> deleteApiToken(final String device) async {
|
|
||||||
Response response;
|
|
||||||
final Dio client = await getClient();
|
|
||||||
try {
|
|
||||||
response = await client.delete(
|
|
||||||
'/auth/tokens',
|
|
||||||
data: {
|
|
||||||
'token_name': device,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} on DioError catch (e) {
|
|
||||||
print(e.message);
|
|
||||||
return ApiResponse(
|
|
||||||
errorMessage: e.message,
|
|
||||||
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
||||||
data: null,
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
||||||
return ApiResponse(statusCode: code, data: null);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@ import 'dart:async';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/backblaze.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/backblaze.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/backup.dart';
|
import 'package:selfprivacy/logic/models/json/backup.dart';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
|
||||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/api_token.dart';
|
import 'package:selfprivacy/logic/models/json/api_token.dart';
|
||||||
|
@ -36,7 +36,7 @@ class ApiDevicesCubit
|
||||||
|
|
||||||
Future<List<ApiToken>?> _getApiTokens() async {
|
Future<List<ApiToken>?> _getApiTokens() async {
|
||||||
final ApiResponse<List<ApiToken>> response = await api.getApiTokens();
|
final ApiResponse<List<ApiToken>> response = await api.getApiTokens();
|
||||||
if (response.isSuccess) {
|
if (response.success) {
|
||||||
return response.data;
|
return response.data;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -45,7 +45,7 @@ class ApiDevicesCubit
|
||||||
|
|
||||||
Future<void> deleteDevice(final ApiToken device) async {
|
Future<void> deleteDevice(final ApiToken device) async {
|
||||||
final ApiResponse<void> response = await api.deleteApiToken(device.name);
|
final ApiResponse<void> response = await api.deleteApiToken(device.name);
|
||||||
if (response.isSuccess) {
|
if (response.success) {
|
||||||
emit(
|
emit(
|
||||||
ApiDevicesState(
|
ApiDevicesState(
|
||||||
state.devices.where((final d) => d.name != device.name).toList(),
|
state.devices.where((final d) => d.name != device.name).toList(),
|
||||||
|
@ -54,17 +54,17 @@ class ApiDevicesCubit
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
getIt<NavigationService>()
|
getIt<NavigationService>()
|
||||||
.showSnackBar(response.errorMessage ?? 'Error deleting device');
|
.showSnackBar(response.message ?? 'Error deleting device');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getNewDeviceKey() async {
|
Future<String?> getNewDeviceKey() async {
|
||||||
final ApiResponse<String> response = await api.createDeviceToken();
|
final ApiResponse<String> response = await api.createDeviceToken();
|
||||||
if (response.isSuccess) {
|
if (response.success) {
|
||||||
return response.data;
|
return response.data;
|
||||||
} else {
|
} else {
|
||||||
getIt<NavigationService>().showSnackBar(
|
getIt<NavigationService>().showSnackBar(
|
||||||
response.errorMessage ?? 'Error getting new device key',
|
response.message ?? 'Error getting new device key',
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_depe
|
||||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
||||||
|
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
|
||||||
|
|
||||||
part 'dns_records_state.dart';
|
part 'dns_records_state.dart';
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
|
||||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/recovery_token_status.dart';
|
import 'package:selfprivacy/logic/models/json/recovery_token_status.dart';
|
||||||
|
@ -34,7 +34,7 @@ class RecoveryKeyCubit
|
||||||
Future<RecoveryKeyStatus?> _getRecoveryKeyStatus() async {
|
Future<RecoveryKeyStatus?> _getRecoveryKeyStatus() async {
|
||||||
final ApiResponse<RecoveryKeyStatus?> response =
|
final ApiResponse<RecoveryKeyStatus?> response =
|
||||||
await api.getRecoveryTokenStatus();
|
await api.getRecoveryTokenStatus();
|
||||||
if (response.isSuccess) {
|
if (response.success) {
|
||||||
return response.data;
|
return response.data;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -59,11 +59,11 @@ class RecoveryKeyCubit
|
||||||
}) async {
|
}) async {
|
||||||
final ApiResponse<String> response =
|
final ApiResponse<String> response =
|
||||||
await api.generateRecoveryToken(expirationDate, numberOfUses);
|
await api.generateRecoveryToken(expirationDate, numberOfUses);
|
||||||
if (response.isSuccess) {
|
if (response.success) {
|
||||||
refresh();
|
refresh();
|
||||||
return response.data;
|
return response.data;
|
||||||
} else {
|
} else {
|
||||||
throw GenerationError(response.errorMessage ?? 'Unknown error');
|
throw GenerationError(response.message ?? 'Unknown error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import 'package:selfprivacy/config/hive_config.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
|
@ -498,7 +498,7 @@ class ServerInstallationRepository {
|
||||||
DeviceToken(device: await getDeviceName(), token: newDeviceKey),
|
DeviceToken(device: await getDeviceName(), token: newDeviceKey),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (apiResponse.isSuccess) {
|
if (apiResponse.success) {
|
||||||
return ServerHostingDetails(
|
return ServerHostingDetails(
|
||||||
apiToken: apiResponse.data,
|
apiToken: apiResponse.data,
|
||||||
volume: ServerVolume(
|
volume: ServerVolume(
|
||||||
|
@ -517,7 +517,7 @@ class ServerInstallationRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
throw ServerAuthorizationException(
|
throw ServerAuthorizationException(
|
||||||
apiResponse.errorMessage ?? apiResponse.data,
|
apiResponse.message ?? apiResponse.data,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +535,7 @@ class ServerInstallationRepository {
|
||||||
DeviceToken(device: await getDeviceName(), token: recoveryKey),
|
DeviceToken(device: await getDeviceName(), token: recoveryKey),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (apiResponse.isSuccess) {
|
if (apiResponse.success) {
|
||||||
return ServerHostingDetails(
|
return ServerHostingDetails(
|
||||||
apiToken: apiResponse.data,
|
apiToken: apiResponse.data,
|
||||||
volume: ServerVolume(
|
volume: ServerVolume(
|
||||||
|
@ -554,7 +554,7 @@ class ServerInstallationRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
throw ServerAuthorizationException(
|
throw ServerAuthorizationException(
|
||||||
apiResponse.errorMessage ?? apiResponse.data,
|
apiResponse.message ?? apiResponse.data,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,9 +570,7 @@ class ServerInstallationRepository {
|
||||||
);
|
);
|
||||||
final String serverIp = await getServerIpFromDomain(serverDomain);
|
final String serverIp = await getServerIpFromDomain(serverDomain);
|
||||||
if (recoveryCapabilities == ServerRecoveryCapabilities.legacy) {
|
if (recoveryCapabilities == ServerRecoveryCapabilities.legacy) {
|
||||||
final Map<String, bool> apiResponse =
|
if (await serverApi.isHttpServerWorking()) {
|
||||||
await serverApi.servicesPowerCheck();
|
|
||||||
if (apiResponse.isNotEmpty) {
|
|
||||||
return ServerHostingDetails(
|
return ServerHostingDetails(
|
||||||
apiToken: apiToken,
|
apiToken: apiToken,
|
||||||
volume: ServerVolume(
|
volume: ServerVolume(
|
||||||
|
@ -600,7 +598,7 @@ class ServerInstallationRepository {
|
||||||
DeviceToken(device: await getDeviceName(), token: deviceAuthKey.data),
|
DeviceToken(device: await getDeviceName(), token: deviceAuthKey.data),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (apiResponse.isSuccess) {
|
if (apiResponse.success) {
|
||||||
return ServerHostingDetails(
|
return ServerHostingDetails(
|
||||||
apiToken: apiResponse.data,
|
apiToken: apiResponse.data,
|
||||||
volume: ServerVolume(
|
volume: ServerVolume(
|
||||||
|
@ -619,7 +617,7 @@ class ServerInstallationRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
throw ServerAuthorizationException(
|
throw ServerAuthorizationException(
|
||||||
apiResponse.errorMessage ?? apiResponse.data,
|
apiResponse.message ?? apiResponse.data,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,9 +632,8 @@ class ServerInstallationRepository {
|
||||||
);
|
);
|
||||||
|
|
||||||
final String? serverApiVersion = await serverApi.getApiVersion();
|
final String? serverApiVersion = await serverApi.getApiVersion();
|
||||||
final ApiResponse<List<String>> users =
|
final users = await serverApi.getAllUsers();
|
||||||
await serverApi.getUsersList(withMainUser: true);
|
if (serverApiVersion == null || users.isEmpty) {
|
||||||
if (serverApiVersion == null || !users.isSuccess) {
|
|
||||||
return fallbackUser;
|
return fallbackUser;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -644,10 +641,8 @@ class ServerInstallationRepository {
|
||||||
if (!VersionConstraint.parse('>=1.2.5').allows(parsedVersion)) {
|
if (!VersionConstraint.parse('>=1.2.5').allows(parsedVersion)) {
|
||||||
return fallbackUser;
|
return fallbackUser;
|
||||||
}
|
}
|
||||||
return User(
|
return users.firstWhere(
|
||||||
isFoundOnServer: true,
|
(final User user) => user.type == UserType.primary,
|
||||||
login: users.data[0],
|
|
||||||
type: UserType.primary,
|
|
||||||
);
|
);
|
||||||
} on FormatException {
|
} on FormatException {
|
||||||
return fallbackUser;
|
return fallbackUser;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_api.graphql.dart';
|
||||||
|
|
||||||
part 'api_token.g.dart';
|
part 'api_token.g.dart';
|
||||||
|
|
||||||
|
@ -12,6 +13,14 @@ class ApiToken {
|
||||||
required this.isCaller,
|
required this.isCaller,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ApiToken.fromGraphQL(
|
||||||
|
final Query$GetApiTokens$api$devices device,
|
||||||
|
) : this(
|
||||||
|
name: device.name,
|
||||||
|
date: device.creationDate,
|
||||||
|
isCaller: device.isCaller,
|
||||||
|
);
|
||||||
|
|
||||||
final String name;
|
final String name;
|
||||||
final DateTime date;
|
final DateTime date;
|
||||||
@JsonKey(name: 'is_caller')
|
@JsonKey(name: 'is_caller')
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_api.graphql.dart';
|
||||||
|
|
||||||
part 'recovery_token_status.g.dart';
|
part 'recovery_token_status.g.dart';
|
||||||
|
|
||||||
|
@ -15,6 +16,16 @@ class RecoveryKeyStatus extends Equatable {
|
||||||
this.usesLeft,
|
this.usesLeft,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RecoveryKeyStatus.fromGraphQL(
|
||||||
|
final Query$RecoveryKey$api$recoveryKey recoveryKey,
|
||||||
|
) : this(
|
||||||
|
exists: recoveryKey.exists,
|
||||||
|
date: recoveryKey.creationDate,
|
||||||
|
expiration: recoveryKey.expirationDate,
|
||||||
|
usesLeft: recoveryKey.usesLeft,
|
||||||
|
valid: recoveryKey.valid,
|
||||||
|
);
|
||||||
|
|
||||||
final bool exists;
|
final bool exists;
|
||||||
final DateTime? date;
|
final DateTime? date;
|
||||||
final DateTime? expiration;
|
final DateTime? expiration;
|
||||||
|
|
Loading…
Reference in a new issue