import 'package:graphql/client.dart'; import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/api_maps/graphql_maps/api_map.dart'; import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/disk_volumes.graphql.dart'; import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart'; import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_api.graphql.dart'; import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_settings.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/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/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/dns_records.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_job.dart'; import 'package:selfprivacy/logic/models/service.dart'; import 'package:selfprivacy/logic/models/ssh_settings.dart'; import 'package:selfprivacy/logic/models/system_settings.dart'; part 'jobs_api.dart'; part 'server_actions_api.dart'; part 'services_api.dart'; part 'users_api.dart'; part 'volume_api.dart'; class GenericResult { GenericResult({ required this.success, required this.data, this.message, }); /// Whether was a response successfully received, /// doesn't represent success of the request if `data` is `bool` final bool success; final String? message; final T data; } class GenericMutationResult extends GenericResult { GenericMutationResult({ required super.success, required this.code, required super.data, super.message, }); final int code; } class ServerApi extends ApiMap with VolumeApi, JobsApi, ServerActionsApi, ServicesApi, UsersApi { ServerApi({ this.hasLogger = false, this.isWithToken = true, this.customToken = '', this.overrideDomain, }); @override bool hasLogger; @override bool isWithToken; @override String customToken; @override String? get rootAddress => overrideDomain ?? getIt().serverDomain?.domainName; String? overrideDomain; Future getApiVersion() async { QueryResult response; String? apiVersion; try { final GraphQLClient client = await getClient(); response = await client.query$GetApiVersion(); if (response.hasException) { print(response.exception.toString()); } apiVersion = response.data!['api']['version']; } catch (e) { print(e); } return apiVersion; } Future isUsingBinds() async { QueryResult response; bool usesBinds = false; try { final GraphQLClient client = await getClient(); response = await client.query$SystemIsUsingBinds(); if (response.hasException) { print(response.exception.toString()); } usesBinds = response.data!['system']['info']['usingBinds']; } catch (e) { print(e); } return usesBinds; } Future switchService(final String uid, final bool needTurnOn) async { try { final GraphQLClient client = await getClient(); if (needTurnOn) { final variables = Variables$Mutation$EnableService(serviceId: uid); final mutation = Options$Mutation$EnableService(variables: variables); await client.mutate$EnableService(mutation); } else { final variables = Variables$Mutation$DisableService(serviceId: uid); final mutation = Options$Mutation$DisableService(variables: variables); await client.mutate$DisableService(mutation); } } catch (e) { print(e); } } Future setAutoUpgradeSettings( final AutoUpgradeSettings settings, ) async { try { final GraphQLClient client = await getClient(); final input = Input$AutoUpgradeSettingsInput( allowReboot: settings.allowReboot, enableAutoUpgrade: settings.enable, ); final variables = Variables$Mutation$ChangeAutoUpgradeSettings( settings: input, ); final mutation = Options$Mutation$ChangeAutoUpgradeSettings( variables: variables, ); await client.mutate$ChangeAutoUpgradeSettings(mutation); } catch (e) { print(e); } } Future setTimezone(final String timezone) async { try { final GraphQLClient client = await getClient(); final variables = Variables$Mutation$ChangeTimezone( timezone: timezone, ); final mutation = Options$Mutation$ChangeTimezone( variables: variables, ); await client.mutate$ChangeTimezone(mutation); } catch (e) { print(e); } } Future getSystemSettings() async { QueryResult response; SystemSettings settings = SystemSettings( autoUpgradeSettings: AutoUpgradeSettings( allowReboot: false, enable: false, ), sshSettings: SshSettings( enable: false, passwordAuthentication: false, ), timezone: 'Unknown', ); try { final GraphQLClient client = await getClient(); response = await client.query$SystemSettings(); if (response.hasException) { print(response.exception.toString()); } settings = SystemSettings.fromGraphQL(response.parsedData!.system); } catch (e) { print(e); } return settings; } Future> getRecoveryTokenStatus() async { RecoveryKeyStatus? key; QueryResult 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 GenericResult( success: error == null, data: key, message: error, ); } Future> generateRecoveryToken( final DateTime? expirationDate, final int? numberOfUses, ) async { GenericResult key; QueryResult 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 = GenericResult( success: false, data: '', message: response.exception.toString(), ); } key = GenericResult( success: true, data: response.parsedData!.getNewRecoveryApiKey.key!, ); } catch (e) { print(e); key = GenericResult( success: false, data: '', message: e.toString(), ); } return key; } Future> getDnsRecords() async { List records = []; QueryResult response; try { final GraphQLClient client = await getClient(); response = await client.query$DomainInfo(); if (response.hasException) { print(response.exception.toString()); } records = response.parsedData!.system.domainInfo.requiredDnsRecords .map( (final Fragment$dnsRecordFields fragment) => DnsRecord.fromGraphQL(fragment), ) .toList(); } catch (e) { print(e); } return records; } Future>> getApiTokens() async { GenericResult> tokens; QueryResult response; try { final GraphQLClient client = await getClient(); response = await client.query$GetApiTokens(); if (response.hasException) { final message = response.exception.toString(); print(message); tokens = GenericResult>( success: false, data: [], message: message, ); } final List parsed = response.parsedData!.api.devices .map( ( final Query$GetApiTokens$api$devices device, ) => ApiToken.fromGraphQL(device), ) .toList(); tokens = GenericResult>( success: true, data: parsed, ); } catch (e) { print(e); tokens = GenericResult>( success: false, data: [], message: e.toString(), ); } return tokens; } Future> deleteApiToken(final String name) async { GenericResult returnable; QueryResult 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 = GenericResult( success: false, data: null, message: response.exception.toString(), ); } returnable = GenericResult( success: true, data: null, ); } catch (e) { print(e); returnable = GenericResult( success: false, data: null, message: e.toString(), ); } return returnable; } Future> createDeviceToken() async { GenericResult token; QueryResult 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 = GenericResult( success: false, data: '', message: response.exception.toString(), ); } token = GenericResult( success: true, data: response.parsedData!.getNewDeviceApiKey.key!, ); } catch (e) { print(e); token = GenericResult( success: false, data: '', message: e.toString(), ); } return token; } Future isHttpServerWorking() async => (await getApiVersion()) != null; Future> authorizeDevice( final DeviceToken deviceToken, ) async { GenericResult token; QueryResult 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 = GenericResult( success: false, data: '', message: response.exception.toString(), ); } token = GenericResult( success: true, data: response.parsedData!.authorizeWithNewDeviceApiKey.token!, ); } catch (e) { print(e); token = GenericResult( success: false, data: '', message: e.toString(), ); } return token; } Future> useRecoveryToken( final DeviceToken deviceToken, ) async { GenericResult token; QueryResult 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 = GenericResult( success: false, data: '', message: response.exception.toString(), ); } token = GenericResult( success: true, data: response.parsedData!.useRecoveryApiKey.token!, ); } catch (e) { print(e); token = GenericResult( success: false, data: '', message: e.toString(), ); } return token; } /// TODO: backups're not implemented on server side Future getBackupStatus() async => BackupStatus( progress: 0.0, status: BackupStatusEnum.error, errorMessage: null, ); Future> getBackups() async => []; Future uploadBackblazeConfig(final BackblazeBucket bucket) async {} Future forceBackupListReload() async {} Future startBackup() async {} Future restoreBackup(final String backupId) async {} }