2021-03-25 23:30:34 +00:00
|
|
|
import 'dart:async';
|
2022-02-01 01:56:05 +00:00
|
|
|
import 'dart:convert';
|
2022-02-08 06:59:35 +00:00
|
|
|
import 'dart:io';
|
2021-01-21 21:01:42 +00:00
|
|
|
|
2021-01-21 07:35:38 +00:00
|
|
|
import 'package:dio/dio.dart';
|
2021-03-25 23:30:34 +00:00
|
|
|
import 'package:selfprivacy/config/get_it_config.dart';
|
2021-08-29 13:54:28 +00:00
|
|
|
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
2022-05-18 10:39:11 +00:00
|
|
|
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
|
|
|
import 'package:selfprivacy/logic/models/hive/user.dart';
|
2022-05-14 02:54:40 +00:00
|
|
|
import 'package:selfprivacy/logic/models/json/api_token.dart';
|
|
|
|
import 'package:selfprivacy/logic/models/json/auto_upgrade_settings.dart';
|
|
|
|
import 'package:selfprivacy/logic/models/json/backup.dart';
|
|
|
|
import 'package:selfprivacy/logic/models/json/device_token.dart';
|
2022-05-18 10:39:11 +00:00
|
|
|
import 'package:selfprivacy/logic/models/json/recovery_token_status.dart';
|
2022-02-08 21:01:08 +00:00
|
|
|
import 'package:selfprivacy/logic/models/timezone_settings.dart';
|
2021-01-21 07:35:38 +00:00
|
|
|
|
|
|
|
import 'api_map.dart';
|
|
|
|
|
2022-03-03 17:38:30 +00:00
|
|
|
class ApiResponse<D> {
|
|
|
|
final int statusCode;
|
|
|
|
final String? errorMessage;
|
|
|
|
final D data;
|
|
|
|
|
2022-05-02 11:56:46 +00:00
|
|
|
bool get isSuccess => statusCode >= 200 && statusCode < 300;
|
2022-03-03 17:38:30 +00:00
|
|
|
|
|
|
|
ApiResponse({
|
|
|
|
required this.statusCode,
|
|
|
|
this.errorMessage,
|
|
|
|
required this.data,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-03-25 23:30:34 +00:00
|
|
|
class ServerApi extends ApiMap {
|
2022-05-20 22:56:50 +00:00
|
|
|
@override
|
2022-02-16 07:28:29 +00:00
|
|
|
bool hasLogger;
|
2022-05-20 22:56:50 +00:00
|
|
|
@override
|
2021-03-25 23:30:34 +00:00
|
|
|
bool isWithToken;
|
2022-05-13 13:57:56 +00:00
|
|
|
String? overrideDomain;
|
2022-05-18 10:39:11 +00:00
|
|
|
String? customToken;
|
2021-03-25 23:30:34 +00:00
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
ServerApi(
|
2022-05-18 10:39:11 +00:00
|
|
|
{this.hasLogger = false,
|
|
|
|
this.isWithToken = true,
|
|
|
|
this.overrideDomain,
|
|
|
|
this.customToken});
|
2021-03-25 23:30:34 +00:00
|
|
|
|
2022-05-24 18:55:39 +00:00
|
|
|
@override
|
2021-03-25 23:30:34 +00:00
|
|
|
BaseOptions get options {
|
|
|
|
var options = BaseOptions();
|
|
|
|
|
|
|
|
if (isWithToken) {
|
2022-05-13 13:57:56 +00:00
|
|
|
var cloudFlareDomain = getIt<ApiConfigModel>().serverDomain;
|
2021-03-25 23:30:34 +00:00
|
|
|
var domainName = cloudFlareDomain!.domainName;
|
2022-05-13 13:57:56 +00:00
|
|
|
var apiToken = getIt<ApiConfigModel>().serverDetails?.apiToken;
|
2021-03-25 23:30:34 +00:00
|
|
|
|
2021-11-18 19:10:40 +00:00
|
|
|
options = BaseOptions(baseUrl: 'https://api.$domainName', headers: {
|
2021-12-06 18:31:19 +00:00
|
|
|
'Authorization': 'Bearer $apiToken',
|
2021-11-18 19:10:40 +00:00
|
|
|
});
|
2021-03-25 23:30:34 +00:00
|
|
|
}
|
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
if (overrideDomain != null) {
|
2022-05-18 10:39:11 +00:00
|
|
|
options = BaseOptions(
|
|
|
|
baseUrl: 'https://api.$overrideDomain',
|
|
|
|
headers: customToken != null
|
|
|
|
? {'Authorization': 'Bearer $customToken'}
|
|
|
|
: null,
|
|
|
|
);
|
2022-05-13 13:57:56 +00:00
|
|
|
}
|
|
|
|
|
2021-03-25 23:30:34 +00:00
|
|
|
return options;
|
2021-01-21 21:01:42 +00:00
|
|
|
}
|
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
Future<String?> getApiVersion() async {
|
|
|
|
Response response;
|
|
|
|
|
|
|
|
var client = await getClient();
|
2022-05-24 18:55:39 +00:00
|
|
|
String? apiVersion;
|
2022-05-13 13:57:56 +00:00
|
|
|
|
|
|
|
try {
|
|
|
|
response = await client.get('/api/version');
|
|
|
|
apiVersion = response.data['version'];
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
} finally {
|
|
|
|
close(client);
|
|
|
|
}
|
2022-05-24 18:55:39 +00:00
|
|
|
return apiVersion;
|
2022-05-13 13:57:56 +00:00
|
|
|
}
|
|
|
|
|
2021-01-21 21:01:42 +00:00
|
|
|
Future<bool> isHttpServerWorking() async {
|
2022-05-13 13:57:56 +00:00
|
|
|
bool res = false;
|
2021-01-21 21:01:42 +00:00
|
|
|
Response response;
|
2021-03-25 23:30:34 +00:00
|
|
|
|
|
|
|
var client = await getClient();
|
2021-01-21 21:01:42 +00:00
|
|
|
try {
|
2022-05-13 13:57:56 +00:00
|
|
|
response = await client.get('/services/status');
|
2021-01-21 21:01:42 +00:00
|
|
|
res = response.statusCode == HttpStatus.ok;
|
2022-05-13 13:57:56 +00:00
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
} finally {
|
|
|
|
close(client);
|
2021-01-21 07:35:38 +00:00
|
|
|
}
|
2022-05-24 18:55:39 +00:00
|
|
|
return res;
|
2021-01-21 07:35:38 +00:00
|
|
|
}
|
2021-01-21 21:01:42 +00:00
|
|
|
|
2022-03-03 17:38:30 +00:00
|
|
|
Future<ApiResponse<User>> createUser(User user) async {
|
2022-05-13 13:57:56 +00:00
|
|
|
Response response;
|
2022-05-02 11:56:46 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
var client = await getClient();
|
2022-05-02 11:56:46 +00:00
|
|
|
try {
|
|
|
|
response = await client.post(
|
|
|
|
'/users',
|
|
|
|
data: {
|
|
|
|
'username': user.login,
|
|
|
|
'password': user.password,
|
|
|
|
},
|
|
|
|
);
|
2022-05-13 13:57:56 +00:00
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
2022-03-03 17:38:30 +00:00
|
|
|
return ApiResponse(
|
2022-05-13 13:57:56 +00:00
|
|
|
errorMessage: e.error.toString(),
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
2022-03-03 17:38:30 +00:00
|
|
|
data: User(
|
|
|
|
login: user.login,
|
|
|
|
password: user.password,
|
2022-05-13 13:57:56 +00:00
|
|
|
isFoundOnServer: false,
|
2021-06-20 21:08:52 +00:00
|
|
|
),
|
|
|
|
);
|
2022-05-13 13:57:56 +00:00
|
|
|
} finally {
|
|
|
|
close(client);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isFoundOnServer = false;
|
2022-05-14 02:54:40 +00:00
|
|
|
int code = 0;
|
2022-05-13 13:57:56 +00:00
|
|
|
|
|
|
|
final bool isUserCreated = (response.statusCode != null) &&
|
|
|
|
(response.statusCode == HttpStatus.created);
|
|
|
|
|
|
|
|
if (isUserCreated) {
|
|
|
|
isFoundOnServer = true;
|
2022-05-14 02:54:40 +00:00
|
|
|
code = response.statusCode!;
|
2022-05-02 11:56:46 +00:00
|
|
|
} else {
|
2022-05-13 13:57:56 +00:00
|
|
|
isFoundOnServer = false;
|
2022-05-14 02:54:40 +00:00
|
|
|
code = HttpStatus.notAcceptable;
|
2022-03-03 17:38:30 +00:00
|
|
|
}
|
2022-05-13 13:57:56 +00:00
|
|
|
|
|
|
|
return ApiResponse(
|
2022-05-14 02:54:40 +00:00
|
|
|
statusCode: code,
|
2022-05-13 13:57:56 +00:00
|
|
|
data: User(
|
|
|
|
login: user.login,
|
|
|
|
password: user.password,
|
|
|
|
isFoundOnServer: isFoundOnServer,
|
|
|
|
),
|
|
|
|
);
|
2022-03-03 17:38:30 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 08:06:58 +00:00
|
|
|
Future<ApiResponse<List<String>>> getUsersList({withMainUser = false}) async {
|
2022-03-23 14:07:52 +00:00
|
|
|
List<String> res = [];
|
2022-03-03 17:38:30 +00:00
|
|
|
Response response;
|
|
|
|
|
|
|
|
var client = await getClient();
|
|
|
|
try {
|
2022-05-24 08:06:58 +00:00
|
|
|
response = await client.get('/users',
|
|
|
|
queryParameters: withMainUser ? {'withMainUser': 'true'} : null);
|
2022-03-23 14:07:52 +00:00
|
|
|
for (var user in response.data) {
|
|
|
|
res.add(user.toString());
|
|
|
|
}
|
2022-05-13 13:57:56 +00:00
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
2022-05-14 02:54:40 +00:00
|
|
|
return ApiResponse(
|
|
|
|
errorMessage: e.message,
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
|
|
data: [],
|
|
|
|
);
|
2022-03-03 17:38:30 +00:00
|
|
|
} catch (e) {
|
2022-03-23 14:07:52 +00:00
|
|
|
print(e);
|
2022-05-14 02:54:40 +00:00
|
|
|
return ApiResponse(
|
|
|
|
errorMessage: e.toString(),
|
|
|
|
statusCode: HttpStatus.internalServerError,
|
|
|
|
data: [],
|
|
|
|
);
|
2022-05-13 13:57:56 +00:00
|
|
|
} finally {
|
|
|
|
close(client);
|
2022-03-03 17:38:30 +00:00
|
|
|
}
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
|
|
|
2022-05-13 13:57:56 +00:00
|
|
|
return ApiResponse(
|
|
|
|
statusCode: code,
|
2022-03-03 17:38:30 +00:00
|
|
|
data: res,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<ApiResponse<void>> addUserSshKey(User user, String sshKey) async {
|
2022-05-14 02:54:40 +00:00
|
|
|
late Response response;
|
2022-03-03 17:38:30 +00:00
|
|
|
|
|
|
|
var client = await getClient();
|
2022-05-13 13:57:56 +00:00
|
|
|
try {
|
|
|
|
response = await client.post(
|
|
|
|
'/services/ssh/keys/${user.login}',
|
|
|
|
data: {
|
|
|
|
'public_key': sshKey,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
2022-05-14 02:54:40 +00:00
|
|
|
return ApiResponse<void>(
|
|
|
|
errorMessage: e.message,
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
|
|
data: null,
|
|
|
|
);
|
2022-05-13 13:57:56 +00:00
|
|
|
} finally {
|
|
|
|
close(client);
|
|
|
|
}
|
2022-03-03 17:38:30 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
|
|
|
2022-03-03 17:38:30 +00:00
|
|
|
return ApiResponse<void>(
|
2022-05-14 02:54:40 +00:00
|
|
|
statusCode: code,
|
2022-03-03 17:38:30 +00:00
|
|
|
data: null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<ApiResponse<void>> addRootSshKey(String ssh) async {
|
2022-05-14 02:54:40 +00:00
|
|
|
late Response response;
|
2022-03-03 17:38:30 +00:00
|
|
|
|
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
try {
|
|
|
|
response = await client.put(
|
|
|
|
'/services/ssh/key/send',
|
2022-05-24 18:55:39 +00:00
|
|
|
data: {'public_key': ssh},
|
2022-05-14 02:54:40 +00:00
|
|
|
);
|
|
|
|
} 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;
|
2022-03-03 17:38:30 +00:00
|
|
|
|
|
|
|
return ApiResponse<void>(
|
2022-05-14 02:54:40 +00:00
|
|
|
statusCode: code,
|
2022-03-03 17:38:30 +00:00
|
|
|
data: null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<ApiResponse<List<String>>> getUserSshKeys(User user) async {
|
|
|
|
List<String> res;
|
|
|
|
Response response;
|
|
|
|
|
|
|
|
var client = await getClient();
|
|
|
|
try {
|
2022-05-14 02:54:40 +00:00
|
|
|
response = await client.get('/services/ssh/keys/${user.login}');
|
2022-03-03 17:38:30 +00:00
|
|
|
res = (response.data as List<dynamic>).map((e) => e as String).toList();
|
2022-05-14 02:54:40 +00:00
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
return ApiResponse<List<String>>(
|
|
|
|
errorMessage: e.message,
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
|
|
data: [],
|
|
|
|
);
|
2021-06-08 18:52:44 +00:00
|
|
|
} catch (e) {
|
2022-05-14 02:54:40 +00:00
|
|
|
return ApiResponse<List<String>>(
|
|
|
|
errorMessage: e.toString(),
|
|
|
|
statusCode: HttpStatus.internalServerError,
|
|
|
|
data: [],
|
|
|
|
);
|
|
|
|
} finally {
|
|
|
|
close(client);
|
2021-06-08 18:52:44 +00:00
|
|
|
}
|
2021-06-20 21:08:52 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
|
|
|
2022-03-03 17:38:30 +00:00
|
|
|
return ApiResponse<List<String>>(
|
2022-05-14 02:54:40 +00:00
|
|
|
statusCode: code,
|
2022-03-03 17:38:30 +00:00
|
|
|
data: res,
|
|
|
|
errorMessage: response.data is List
|
|
|
|
? null
|
|
|
|
: response.data?.containsKey('error') ?? false
|
|
|
|
? response.data['error']
|
|
|
|
: null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<ApiResponse<void>> deleteUserSshKey(User user, String sshKey) async {
|
|
|
|
Response response;
|
|
|
|
|
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
try {
|
|
|
|
response = await client.delete(
|
|
|
|
'/services/ssh/keys/${user.login}',
|
2022-05-24 18:55:39 +00:00
|
|
|
data: {'public_key': sshKey},
|
2022-05-14 02:54:40 +00:00
|
|
|
);
|
|
|
|
} 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;
|
2022-03-03 17:38:30 +00:00
|
|
|
|
|
|
|
return ApiResponse<void>(
|
2022-05-14 02:54:40 +00:00
|
|
|
statusCode: code,
|
2022-03-03 17:38:30 +00:00
|
|
|
data: null,
|
|
|
|
errorMessage: response.data?.containsKey('error') ?? false
|
|
|
|
? response.data['error']
|
|
|
|
: null,
|
|
|
|
);
|
2021-06-08 18:52:44 +00:00
|
|
|
}
|
|
|
|
|
2021-12-20 15:25:31 +00:00
|
|
|
Future<bool> deleteUser(User user) async {
|
2022-05-14 02:54:40 +00:00
|
|
|
bool res = false;
|
2021-12-20 15:25:31 +00:00
|
|
|
Response response;
|
|
|
|
|
|
|
|
var client = await getClient();
|
|
|
|
try {
|
2022-05-14 02:54:40 +00:00
|
|
|
response = await client.delete('/users/${user.login}');
|
2022-03-03 17:38:30 +00:00
|
|
|
res = response.statusCode == HttpStatus.ok ||
|
|
|
|
response.statusCode == HttpStatus.notFound;
|
2022-05-14 02:54:40 +00:00
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
2021-12-20 15:25:31 +00:00
|
|
|
res = false;
|
2022-05-14 02:54:40 +00:00
|
|
|
} finally {
|
|
|
|
close(client);
|
2021-12-20 15:25:31 +00:00
|
|
|
}
|
2022-05-24 18:55:39 +00:00
|
|
|
return res;
|
2021-12-20 15:25:31 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 18:55:39 +00:00
|
|
|
@override
|
2021-03-25 23:30:34 +00:00
|
|
|
String get rootAddress =>
|
|
|
|
throw UnimplementedError('not used in with implementation');
|
2021-07-29 05:24:42 +00:00
|
|
|
|
|
|
|
Future<bool> apply() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
bool res = false;
|
2021-07-29 05:24:42 +00:00
|
|
|
Response response;
|
|
|
|
|
|
|
|
var client = await getClient();
|
|
|
|
try {
|
2022-05-14 02:54:40 +00:00
|
|
|
response = await client.get('/system/configuration/apply');
|
2021-07-29 05:24:42 +00:00
|
|
|
res = response.statusCode == HttpStatus.ok;
|
2022-05-14 02:54:40 +00:00
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
2021-07-29 05:24:42 +00:00
|
|
|
res = false;
|
2022-05-14 02:54:40 +00:00
|
|
|
} finally {
|
|
|
|
close(client);
|
2021-07-29 05:24:42 +00:00
|
|
|
}
|
2022-05-24 18:55:39 +00:00
|
|
|
return res;
|
2021-07-29 05:24:42 +00:00
|
|
|
}
|
2021-08-29 13:54:28 +00:00
|
|
|
|
2021-08-29 15:02:51 +00:00
|
|
|
Future<void> switchService(ServiceTypes type, bool needToTurnOn) async {
|
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
try {
|
|
|
|
client.post(
|
|
|
|
'/services/${type.url}/${needToTurnOn ? 'enable' : 'disable'}',
|
|
|
|
);
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
} finally {
|
|
|
|
close(client);
|
|
|
|
}
|
2021-09-02 19:32:07 +00:00
|
|
|
}
|
2021-09-29 13:08:19 +00:00
|
|
|
|
|
|
|
Future<Map<ServiceTypes, bool>> servicesPowerCheck() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
|
|
|
|
2021-09-29 13:08:19 +00:00
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
try {
|
|
|
|
response = await client.get('/services/status');
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
return {};
|
|
|
|
} finally {
|
|
|
|
close(client);
|
|
|
|
}
|
2021-09-29 13:08:19 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
ServiceTypes.passwordManager: response.data['bitwarden'] == 0,
|
|
|
|
ServiceTypes.git: response.data['gitea'] == 0,
|
|
|
|
ServiceTypes.cloud: response.data['nextcloud'] == 0,
|
|
|
|
ServiceTypes.vpn: response.data['ocserv'] == 0,
|
|
|
|
ServiceTypes.socialNetwork: response.data['pleroma'] == 0,
|
|
|
|
};
|
|
|
|
}
|
2021-12-06 18:31:19 +00:00
|
|
|
|
|
|
|
Future<void> uploadBackblazeConfig(BackblazeBucket bucket) async {
|
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
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);
|
|
|
|
}
|
2021-12-06 18:31:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> startBackup() async {
|
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
try {
|
|
|
|
client.put('/services/restic/backup/create');
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
} finally {
|
|
|
|
close(client);
|
|
|
|
}
|
2021-12-06 18:31:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<List<Backup>> getBackups() async {
|
|
|
|
Response response;
|
2022-05-14 02:54:40 +00:00
|
|
|
List<Backup> backups = [];
|
2021-12-06 18:31:19 +00:00
|
|
|
|
|
|
|
var client = await getClient();
|
|
|
|
try {
|
2022-05-14 02:54:40 +00:00
|
|
|
response = await client.get('/services/restic/backup/list');
|
|
|
|
backups = response.data.map<Backup>((e) => Backup.fromJson(e)).toList();
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
2021-12-06 18:31:19 +00:00
|
|
|
} catch (e) {
|
|
|
|
print(e);
|
2022-05-14 02:54:40 +00:00
|
|
|
} finally {
|
|
|
|
close(client);
|
2021-12-06 18:31:19 +00:00
|
|
|
}
|
2022-05-24 18:55:39 +00:00
|
|
|
return backups;
|
2021-12-06 18:31:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<BackupStatus> getBackupStatus() async {
|
|
|
|
Response response;
|
2022-05-14 02:54:40 +00:00
|
|
|
BackupStatus status = BackupStatus(
|
2021-12-06 18:31:19 +00:00
|
|
|
status: BackupStatusEnum.error,
|
|
|
|
errorMessage: 'Network error',
|
|
|
|
progress: 0,
|
|
|
|
);
|
2022-05-14 02:54:40 +00:00
|
|
|
|
|
|
|
var 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);
|
|
|
|
}
|
2022-05-24 18:55:39 +00:00
|
|
|
return status;
|
2021-12-06 18:31:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> forceBackupListReload() async {
|
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
try {
|
|
|
|
client.get('/services/restic/backup/reload');
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
} finally {
|
|
|
|
close(client);
|
|
|
|
}
|
2021-12-06 18:31:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> restoreBackup(String backupId) async {
|
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
try {
|
|
|
|
client.put(
|
|
|
|
'/services/restic/backup/restore',
|
|
|
|
data: {'backupId': backupId},
|
|
|
|
);
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
} finally {
|
|
|
|
close(client);
|
|
|
|
}
|
2021-12-06 18:31:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<bool> pullConfigurationUpdate() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
|
|
|
bool result = false;
|
|
|
|
|
2021-12-06 18:31:19 +00:00
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
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);
|
|
|
|
}
|
2022-05-24 18:55:39 +00:00
|
|
|
return result;
|
2021-12-06 18:31:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<bool> reboot() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
|
|
|
bool result = false;
|
|
|
|
|
2021-12-06 18:31:19 +00:00
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
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);
|
|
|
|
}
|
2022-05-24 18:55:39 +00:00
|
|
|
return result;
|
2021-12-06 18:31:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<bool> upgrade() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
|
|
|
bool result = false;
|
|
|
|
|
2021-12-06 18:31:19 +00:00
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
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);
|
|
|
|
}
|
2022-05-24 18:55:39 +00:00
|
|
|
return result;
|
2021-12-06 18:31:19 +00:00
|
|
|
}
|
2022-02-01 01:56:05 +00:00
|
|
|
|
2022-02-08 21:01:08 +00:00
|
|
|
Future<AutoUpgradeSettings> getAutoUpgradeSettings() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
2022-05-24 18:55:39 +00:00
|
|
|
AutoUpgradeSettings settings = const AutoUpgradeSettings(
|
2022-05-14 02:54:40 +00:00
|
|
|
enable: false,
|
|
|
|
allowReboot: false,
|
2022-05-10 20:42:33 +00:00
|
|
|
);
|
2022-05-14 02:54:40 +00:00
|
|
|
|
|
|
|
var client = await getClient();
|
|
|
|
try {
|
|
|
|
response = await client.get('/system/configuration/autoUpgrade');
|
|
|
|
if (response.data != null) {
|
|
|
|
settings = AutoUpgradeSettings.fromJson(response.data);
|
|
|
|
}
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
} finally {
|
|
|
|
close(client);
|
|
|
|
}
|
2022-05-24 18:55:39 +00:00
|
|
|
return settings;
|
2022-02-08 21:01:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> updateAutoUpgradeSettings(AutoUpgradeSettings settings) async {
|
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
try {
|
|
|
|
await client.put(
|
|
|
|
'/system/configuration/autoUpgrade',
|
|
|
|
data: settings.toJson(),
|
|
|
|
);
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
} finally {
|
|
|
|
close(client);
|
|
|
|
}
|
2022-02-08 21:01:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<TimeZoneSettings> getServerTimezone() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
// I am not sure how to initialize TimeZoneSettings with default value...
|
2022-02-08 21:01:08 +00:00
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response = await client.get('/system/configuration/timezone');
|
2022-03-03 17:38:30 +00:00
|
|
|
close(client);
|
2022-02-08 21:01:08 +00:00
|
|
|
|
|
|
|
return TimeZoneSettings.fromString(response.data);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> updateServerTimezone(TimeZoneSettings settings) async {
|
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
try {
|
|
|
|
await client.put(
|
|
|
|
'/system/configuration/timezone',
|
|
|
|
data: settings.toString(),
|
|
|
|
);
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
} finally {
|
|
|
|
close(client);
|
|
|
|
}
|
2022-02-07 07:53:13 +00:00
|
|
|
}
|
2022-02-17 23:37:15 +00:00
|
|
|
|
2022-05-10 20:42:33 +00:00
|
|
|
Future<String?> getDkim() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
|
|
|
|
2022-02-01 01:56:05 +00:00
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
try {
|
|
|
|
response = await client.get('/services/mailserver/dkim');
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
return null;
|
|
|
|
} finally {
|
|
|
|
close(client);
|
|
|
|
}
|
2022-02-01 01:56:05 +00:00
|
|
|
|
2022-05-10 20:42:33 +00:00
|
|
|
if (response.statusCode == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (response.statusCode == HttpStatus.notFound || response.data == null) {
|
2022-02-01 01:56:05 +00:00
|
|
|
throw Exception('No DKIM key found');
|
|
|
|
}
|
|
|
|
|
2022-05-10 20:42:33 +00:00
|
|
|
if (response.statusCode != HttpStatus.ok) {
|
2022-05-24 18:55:39 +00:00
|
|
|
return '';
|
2022-05-10 20:42:33 +00:00
|
|
|
}
|
|
|
|
|
2022-02-01 01:56:05 +00:00
|
|
|
final base64toString = utf8.fuse(base64);
|
|
|
|
|
2022-02-08 06:59:35 +00:00
|
|
|
return base64toString
|
|
|
|
.decode(response.data)
|
|
|
|
.split('(')[1]
|
|
|
|
.split(')')[0]
|
|
|
|
.replaceAll('"', '');
|
2022-02-01 01:56:05 +00:00
|
|
|
}
|
2022-05-09 23:16:36 +00:00
|
|
|
|
2022-05-24 17:45:13 +00:00
|
|
|
Future<ApiResponse<RecoveryKeyStatus?>> getRecoveryTokenStatus() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
2022-05-09 23:16:36 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
var client = await getClient();
|
|
|
|
try {
|
|
|
|
response = await client.get('/auth/recovery_token');
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
2022-05-09 23:16:36 +00:00
|
|
|
return ApiResponse(
|
2022-05-14 02:54:40 +00:00
|
|
|
errorMessage: e.message,
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
2022-05-24 18:55:39 +00:00
|
|
|
data: const RecoveryKeyStatus(exists: false, valid: false));
|
2022-05-14 02:54:40 +00:00
|
|
|
} finally {
|
|
|
|
close(client);
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
|
|
|
2022-05-09 23:16:36 +00:00
|
|
|
return ApiResponse(
|
2022-05-14 02:54:40 +00:00
|
|
|
statusCode: code,
|
|
|
|
data: response.data != null
|
2022-05-24 17:45:13 +00:00
|
|
|
? RecoveryKeyStatus.fromJson(response.data)
|
2022-05-14 02:54:40 +00:00
|
|
|
: null);
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<ApiResponse<String>> generateRecoveryToken(
|
2022-05-24 16:09:47 +00:00
|
|
|
DateTime? expiration,
|
|
|
|
int? uses,
|
|
|
|
) async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
2022-05-09 23:16:36 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
var client = await getClient();
|
2022-05-24 16:09:47 +00:00
|
|
|
var data = {};
|
|
|
|
if (expiration != null) {
|
|
|
|
data['expiration'] = expiration.toIso8601String();
|
|
|
|
}
|
|
|
|
if (uses != null) {
|
|
|
|
data['uses'] = uses;
|
|
|
|
}
|
2022-05-14 02:54:40 +00:00
|
|
|
try {
|
|
|
|
response = await client.post(
|
|
|
|
'/auth/recovery_token',
|
2022-05-24 16:09:47 +00:00
|
|
|
data: data,
|
2022-05-14 02:54:40 +00:00
|
|
|
);
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
2022-05-09 23:16:36 +00:00
|
|
|
return ApiResponse(
|
2022-05-14 02:54:40 +00:00
|
|
|
errorMessage: e.message,
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
2022-05-24 18:55:39 +00:00
|
|
|
data: '');
|
2022-05-14 02:54:40 +00:00
|
|
|
} finally {
|
|
|
|
close(client);
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
|
|
|
|
|
|
return ApiResponse(
|
|
|
|
statusCode: code,
|
2022-05-24 18:55:39 +00:00
|
|
|
data: response.data != null ? response.data['token'] : '');
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<ApiResponse<String>> useRecoveryToken(DeviceToken token) async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
2022-05-09 23:16:36 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
var 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);
|
2022-05-09 23:16:36 +00:00
|
|
|
return ApiResponse(
|
2022-05-14 02:54:40 +00:00
|
|
|
errorMessage: e.message,
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
2022-05-24 18:55:39 +00:00
|
|
|
data: '');
|
2022-05-14 02:54:40 +00:00
|
|
|
} finally {
|
|
|
|
client.close();
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
|
|
|
|
|
|
return ApiResponse(
|
|
|
|
statusCode: code,
|
2022-05-24 18:55:39 +00:00
|
|
|
data: response.data != null ? response.data['token'] : '');
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<ApiResponse<String>> authorizeDevice(DeviceToken token) async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
2022-05-09 23:16:36 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
var 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);
|
2022-05-09 23:16:36 +00:00
|
|
|
return ApiResponse(
|
2022-05-14 02:54:40 +00:00
|
|
|
errorMessage: e.message,
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
2022-05-24 18:55:39 +00:00
|
|
|
data: '');
|
2022-05-14 02:54:40 +00:00
|
|
|
} finally {
|
|
|
|
client.close();
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
|
|
|
2022-05-24 18:55:39 +00:00
|
|
|
return ApiResponse(statusCode: code, data: response.data['token'] ?? '');
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<ApiResponse<String>> createDeviceToken() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
2022-05-09 23:16:36 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
var client = await getClient();
|
|
|
|
try {
|
|
|
|
response = await client.post('/auth/new_device');
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
2022-05-09 23:16:36 +00:00
|
|
|
return ApiResponse(
|
2022-05-14 02:54:40 +00:00
|
|
|
errorMessage: e.message,
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
2022-05-24 18:55:39 +00:00
|
|
|
data: '');
|
2022-05-14 02:54:40 +00:00
|
|
|
} finally {
|
|
|
|
client.close();
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
|
|
|
|
|
|
return ApiResponse(
|
|
|
|
statusCode: code,
|
2022-05-24 18:55:39 +00:00
|
|
|
data: response.data != null ? response.data['token'] : '');
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<ApiResponse<String>> deleteDeviceToken() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
2022-05-09 23:16:36 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
var client = await getClient();
|
|
|
|
try {
|
|
|
|
response = await client.delete('/auth/new_device');
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
2022-05-09 23:16:36 +00:00
|
|
|
return ApiResponse(
|
2022-05-14 02:54:40 +00:00
|
|
|
errorMessage: e.message,
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
2022-05-24 18:55:39 +00:00
|
|
|
data: '');
|
2022-05-14 02:54:40 +00:00
|
|
|
} finally {
|
|
|
|
client.close();
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
|
|
|
2022-05-24 18:55:39 +00:00
|
|
|
return ApiResponse(statusCode: code, data: response.data ?? '');
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<ApiResponse<List<ApiToken>>> getApiTokens() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
2022-05-09 23:16:36 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
var client = await getClient();
|
|
|
|
try {
|
|
|
|
response = await client.get('/auth/tokens');
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
2022-05-09 23:16:36 +00:00
|
|
|
return ApiResponse(
|
2022-05-14 02:54:40 +00:00
|
|
|
errorMessage: e.message,
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
|
|
data: []);
|
|
|
|
} finally {
|
|
|
|
client.close();
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
|
|
|
|
|
|
return ApiResponse(
|
|
|
|
statusCode: code,
|
|
|
|
data: (response.data != null)
|
|
|
|
? response.data.map<ApiToken>((e) => ApiToken.fromJson(e)).toList()
|
|
|
|
: []);
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<ApiResponse<String>> refreshCurrentApiToken() async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
2022-05-09 23:16:36 +00:00
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
var client = await getClient();
|
|
|
|
try {
|
|
|
|
response = await client.post('/auth/tokens');
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
2022-05-09 23:16:36 +00:00
|
|
|
return ApiResponse(
|
2022-05-14 02:54:40 +00:00
|
|
|
errorMessage: e.message,
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
2022-05-24 18:55:39 +00:00
|
|
|
data: '');
|
2022-05-14 02:54:40 +00:00
|
|
|
} finally {
|
|
|
|
client.close();
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
|
|
|
|
|
|
return ApiResponse(
|
|
|
|
statusCode: code,
|
2022-05-24 18:55:39 +00:00
|
|
|
data: response.data != null ? response.data['token'] : '');
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<ApiResponse<void>> deleteApiToken(String device) async {
|
2022-05-14 02:54:40 +00:00
|
|
|
Response response;
|
2022-05-09 23:16:36 +00:00
|
|
|
var client = await getClient();
|
2022-05-14 02:54:40 +00:00
|
|
|
try {
|
|
|
|
response = await client.delete(
|
|
|
|
'/auth/tokens',
|
|
|
|
data: {
|
|
|
|
'device': device,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
} on DioError catch (e) {
|
|
|
|
print(e.message);
|
|
|
|
return ApiResponse(
|
|
|
|
errorMessage: e.message,
|
|
|
|
statusCode: e.response?.statusCode ?? HttpStatus.internalServerError,
|
|
|
|
data: null);
|
|
|
|
} finally {
|
|
|
|
client.close();
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
|
|
|
|
2022-05-14 02:54:40 +00:00
|
|
|
final int code = response.statusCode ?? HttpStatus.internalServerError;
|
|
|
|
return ApiResponse(statusCode: code, data: null);
|
2022-05-09 23:16:36 +00:00
|
|
|
}
|
2021-08-29 15:02:51 +00:00
|
|
|
}
|
2021-08-29 13:54:28 +00:00
|
|
|
|
|
|
|
extension UrlServerExt on ServiceTypes {
|
|
|
|
String get url {
|
|
|
|
switch (this) {
|
|
|
|
// case ServiceTypes.mail:
|
2022-02-16 07:28:29 +00:00
|
|
|
// return ''; // cannot be switch off
|
2021-08-29 13:54:28 +00:00
|
|
|
// case ServiceTypes.messenger:
|
|
|
|
// return ''; // external service
|
|
|
|
// case ServiceTypes.video:
|
2022-02-16 07:28:29 +00:00
|
|
|
// return ''; // jitsi meet not working
|
2021-08-29 13:54:28 +00:00
|
|
|
case ServiceTypes.passwordManager:
|
|
|
|
return 'bitwarden';
|
|
|
|
case ServiceTypes.cloud:
|
|
|
|
return 'nextcloud';
|
|
|
|
case ServiceTypes.socialNetwork:
|
|
|
|
return 'pleroma';
|
|
|
|
case ServiceTypes.git:
|
|
|
|
return 'gitea';
|
|
|
|
case ServiceTypes.vpn:
|
|
|
|
return 'ocserv';
|
|
|
|
default:
|
|
|
|
throw Exception('wrong state');
|
|
|
|
}
|
|
|
|
}
|
2021-08-29 15:02:51 +00:00
|
|
|
}
|