From 14263083a57c3624fdd684f136aab7489019434a Mon Sep 17 00:00:00 2001 From: NaiJi Date: Tue, 17 Jan 2023 18:33:25 +0400 Subject: [PATCH] feat: Implement server recovery for different dns providers --- .../graphql_maps/schema/schema.graphql | 3 +- .../graphql_maps/schema/schema.graphql.dart | 2 + .../graphql_maps/schema/server_api.graphql | 8 + .../schema/server_api.graphql.dart | 412 ++++++++++++++++++ .../schema/server_api.graphql.g.dart | 52 +++ .../schema/server_settings.graphql.g.dart | 1 + .../graphql_maps/server_api/server_api.dart | 20 + .../server_installation_cubit.dart | 16 +- lib/logic/models/hive/server_domain.dart | 14 +- 9 files changed, 523 insertions(+), 5 deletions(-) diff --git a/lib/logic/api_maps/graphql_maps/schema/schema.graphql b/lib/logic/api_maps/graphql_maps/schema/schema.graphql index ed167742..81c703d1 100644 --- a/lib/logic/api_maps/graphql_maps/schema/schema.graphql +++ b/lib/logic/api_maps/graphql_maps/schema/schema.graphql @@ -75,7 +75,8 @@ type DeviceApiTokenMutationReturn implements MutationReturnInterface { } enum DnsProvider { - CLOUDFLARE + CLOUDFLARE, + DIGITALOCEAN } type DnsRecord { diff --git a/lib/logic/api_maps/graphql_maps/schema/schema.graphql.dart b/lib/logic/api_maps/graphql_maps/schema/schema.graphql.dart index 11d49a43..305ca781 100644 --- a/lib/logic/api_maps/graphql_maps/schema/schema.graphql.dart +++ b/lib/logic/api_maps/graphql_maps/schema/schema.graphql.dart @@ -687,6 +687,8 @@ class _CopyWithStubImpl$Input$UserMutationInput enum Enum$DnsProvider { @JsonValue('CLOUDFLARE') CLOUDFLARE, + @JsonValue('DIGITALOCEAN') + DIGITALOCEAN, $unknown } diff --git a/lib/logic/api_maps/graphql_maps/schema/server_api.graphql b/lib/logic/api_maps/graphql_maps/schema/server_api.graphql index d4339094..f1012815 100644 --- a/lib/logic/api_maps/graphql_maps/schema/server_api.graphql +++ b/lib/logic/api_maps/graphql_maps/schema/server_api.graphql @@ -72,6 +72,14 @@ query SystemServerProvider { } } +query SystemDnsProvider { + system { + domainInfo { + provider + } + } +} + query GetApiTokens { api { devices { diff --git a/lib/logic/api_maps/graphql_maps/schema/server_api.graphql.dart b/lib/logic/api_maps/graphql_maps/schema/server_api.graphql.dart index 09671eed..16c4a4a6 100644 --- a/lib/logic/api_maps/graphql_maps/schema/server_api.graphql.dart +++ b/lib/logic/api_maps/graphql_maps/schema/server_api.graphql.dart @@ -3597,6 +3597,418 @@ class _CopyWithStubImpl$Query$SystemServerProvider$system$provider call({Enum$ServerProvider? provider, String? $__typename}) => _res; } +@JsonSerializable(explicitToJson: true) +class Query$SystemDnsProvider { + Query$SystemDnsProvider({required this.system, required this.$__typename}); + + @override + factory Query$SystemDnsProvider.fromJson(Map json) => + _$Query$SystemDnsProviderFromJson(json); + + final Query$SystemDnsProvider$system system; + + @JsonKey(name: '__typename') + final String $__typename; + + Map toJson() => _$Query$SystemDnsProviderToJson(this); + int get hashCode { + final l$system = system; + final l$$__typename = $__typename; + return Object.hashAll([l$system, l$$__typename]); + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + if (!(other is Query$SystemDnsProvider) || runtimeType != other.runtimeType) + return false; + final l$system = system; + final lOther$system = other.system; + if (l$system != lOther$system) return false; + final l$$__typename = $__typename; + final lOther$$__typename = other.$__typename; + if (l$$__typename != lOther$$__typename) return false; + return true; + } +} + +extension UtilityExtension$Query$SystemDnsProvider on Query$SystemDnsProvider { + CopyWith$Query$SystemDnsProvider get copyWith => + CopyWith$Query$SystemDnsProvider(this, (i) => i); +} + +abstract class CopyWith$Query$SystemDnsProvider { + factory CopyWith$Query$SystemDnsProvider(Query$SystemDnsProvider instance, + TRes Function(Query$SystemDnsProvider) then) = + _CopyWithImpl$Query$SystemDnsProvider; + + factory CopyWith$Query$SystemDnsProvider.stub(TRes res) = + _CopyWithStubImpl$Query$SystemDnsProvider; + + TRes call({Query$SystemDnsProvider$system? system, String? $__typename}); + CopyWith$Query$SystemDnsProvider$system get system; +} + +class _CopyWithImpl$Query$SystemDnsProvider + implements CopyWith$Query$SystemDnsProvider { + _CopyWithImpl$Query$SystemDnsProvider(this._instance, this._then); + + final Query$SystemDnsProvider _instance; + + final TRes Function(Query$SystemDnsProvider) _then; + + static const _undefined = {}; + + TRes call({Object? system = _undefined, Object? $__typename = _undefined}) => + _then(Query$SystemDnsProvider( + system: system == _undefined || system == null + ? _instance.system + : (system as Query$SystemDnsProvider$system), + $__typename: $__typename == _undefined || $__typename == null + ? _instance.$__typename + : ($__typename as String))); + CopyWith$Query$SystemDnsProvider$system get system { + final local$system = _instance.system; + return CopyWith$Query$SystemDnsProvider$system( + local$system, (e) => call(system: e)); + } +} + +class _CopyWithStubImpl$Query$SystemDnsProvider + implements CopyWith$Query$SystemDnsProvider { + _CopyWithStubImpl$Query$SystemDnsProvider(this._res); + + TRes _res; + + call({Query$SystemDnsProvider$system? system, String? $__typename}) => _res; + CopyWith$Query$SystemDnsProvider$system get system => + CopyWith$Query$SystemDnsProvider$system.stub(_res); +} + +const documentNodeQuerySystemDnsProvider = DocumentNode(definitions: [ + OperationDefinitionNode( + type: OperationType.query, + name: NameNode(value: 'SystemDnsProvider'), + variableDefinitions: [], + directives: [], + selectionSet: SelectionSetNode(selections: [ + FieldNode( + name: NameNode(value: 'system'), + alias: null, + arguments: [], + directives: [], + selectionSet: SelectionSetNode(selections: [ + FieldNode( + name: NameNode(value: 'domainInfo'), + alias: null, + arguments: [], + directives: [], + selectionSet: SelectionSetNode(selections: [ + FieldNode( + name: NameNode(value: 'provider'), + alias: null, + arguments: [], + directives: [], + selectionSet: null), + FieldNode( + name: NameNode(value: '__typename'), + alias: null, + arguments: [], + directives: [], + selectionSet: null) + ])), + FieldNode( + name: NameNode(value: '__typename'), + alias: null, + arguments: [], + directives: [], + selectionSet: null) + ])), + FieldNode( + name: NameNode(value: '__typename'), + alias: null, + arguments: [], + directives: [], + selectionSet: null) + ])), +]); +Query$SystemDnsProvider _parserFn$Query$SystemDnsProvider( + Map data) => + Query$SystemDnsProvider.fromJson(data); + +class Options$Query$SystemDnsProvider + extends graphql.QueryOptions { + Options$Query$SystemDnsProvider( + {String? operationName, + graphql.FetchPolicy? fetchPolicy, + graphql.ErrorPolicy? errorPolicy, + graphql.CacheRereadPolicy? cacheRereadPolicy, + Object? optimisticResult, + Duration? pollInterval, + graphql.Context? context}) + : super( + operationName: operationName, + fetchPolicy: fetchPolicy, + errorPolicy: errorPolicy, + cacheRereadPolicy: cacheRereadPolicy, + optimisticResult: optimisticResult, + pollInterval: pollInterval, + context: context, + document: documentNodeQuerySystemDnsProvider, + parserFn: _parserFn$Query$SystemDnsProvider); +} + +class WatchOptions$Query$SystemDnsProvider + extends graphql.WatchQueryOptions { + WatchOptions$Query$SystemDnsProvider( + {String? operationName, + graphql.FetchPolicy? fetchPolicy, + graphql.ErrorPolicy? errorPolicy, + graphql.CacheRereadPolicy? cacheRereadPolicy, + Object? optimisticResult, + graphql.Context? context, + Duration? pollInterval, + bool? eagerlyFetchResults, + bool carryForwardDataOnException = true, + bool fetchResults = false}) + : super( + operationName: operationName, + fetchPolicy: fetchPolicy, + errorPolicy: errorPolicy, + cacheRereadPolicy: cacheRereadPolicy, + optimisticResult: optimisticResult, + context: context, + document: documentNodeQuerySystemDnsProvider, + pollInterval: pollInterval, + eagerlyFetchResults: eagerlyFetchResults, + carryForwardDataOnException: carryForwardDataOnException, + fetchResults: fetchResults, + parserFn: _parserFn$Query$SystemDnsProvider); +} + +class FetchMoreOptions$Query$SystemDnsProvider + extends graphql.FetchMoreOptions { + FetchMoreOptions$Query$SystemDnsProvider( + {required graphql.UpdateQuery updateQuery}) + : super( + updateQuery: updateQuery, + document: documentNodeQuerySystemDnsProvider); +} + +extension ClientExtension$Query$SystemDnsProvider on graphql.GraphQLClient { + Future> query$SystemDnsProvider( + [Options$Query$SystemDnsProvider? options]) async => + await this.query(options ?? Options$Query$SystemDnsProvider()); + graphql.ObservableQuery watchQuery$SystemDnsProvider( + [WatchOptions$Query$SystemDnsProvider? options]) => + this.watchQuery(options ?? WatchOptions$Query$SystemDnsProvider()); + void writeQuery$SystemDnsProvider( + {required Query$SystemDnsProvider data, bool broadcast = true}) => + this.writeQuery( + graphql.Request( + operation: graphql.Operation( + document: documentNodeQuerySystemDnsProvider)), + data: data.toJson(), + broadcast: broadcast); + Query$SystemDnsProvider? readQuery$SystemDnsProvider( + {bool optimistic = true}) { + final result = this.readQuery( + graphql.Request( + operation: graphql.Operation( + document: documentNodeQuerySystemDnsProvider)), + optimistic: optimistic); + return result == null ? null : Query$SystemDnsProvider.fromJson(result); + } +} + +@JsonSerializable(explicitToJson: true) +class Query$SystemDnsProvider$system { + Query$SystemDnsProvider$system( + {required this.domainInfo, required this.$__typename}); + + @override + factory Query$SystemDnsProvider$system.fromJson(Map json) => + _$Query$SystemDnsProvider$systemFromJson(json); + + final Query$SystemDnsProvider$system$domainInfo domainInfo; + + @JsonKey(name: '__typename') + final String $__typename; + + Map toJson() => _$Query$SystemDnsProvider$systemToJson(this); + int get hashCode { + final l$domainInfo = domainInfo; + final l$$__typename = $__typename; + return Object.hashAll([l$domainInfo, l$$__typename]); + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + if (!(other is Query$SystemDnsProvider$system) || + runtimeType != other.runtimeType) return false; + final l$domainInfo = domainInfo; + final lOther$domainInfo = other.domainInfo; + if (l$domainInfo != lOther$domainInfo) return false; + final l$$__typename = $__typename; + final lOther$$__typename = other.$__typename; + if (l$$__typename != lOther$$__typename) return false; + return true; + } +} + +extension UtilityExtension$Query$SystemDnsProvider$system + on Query$SystemDnsProvider$system { + CopyWith$Query$SystemDnsProvider$system + get copyWith => CopyWith$Query$SystemDnsProvider$system(this, (i) => i); +} + +abstract class CopyWith$Query$SystemDnsProvider$system { + factory CopyWith$Query$SystemDnsProvider$system( + Query$SystemDnsProvider$system instance, + TRes Function(Query$SystemDnsProvider$system) then) = + _CopyWithImpl$Query$SystemDnsProvider$system; + + factory CopyWith$Query$SystemDnsProvider$system.stub(TRes res) = + _CopyWithStubImpl$Query$SystemDnsProvider$system; + + TRes call( + {Query$SystemDnsProvider$system$domainInfo? domainInfo, + String? $__typename}); + CopyWith$Query$SystemDnsProvider$system$domainInfo get domainInfo; +} + +class _CopyWithImpl$Query$SystemDnsProvider$system + implements CopyWith$Query$SystemDnsProvider$system { + _CopyWithImpl$Query$SystemDnsProvider$system(this._instance, this._then); + + final Query$SystemDnsProvider$system _instance; + + final TRes Function(Query$SystemDnsProvider$system) _then; + + static const _undefined = {}; + + TRes call( + {Object? domainInfo = _undefined, + Object? $__typename = _undefined}) => + _then(Query$SystemDnsProvider$system( + domainInfo: domainInfo == _undefined || domainInfo == null + ? _instance.domainInfo + : (domainInfo as Query$SystemDnsProvider$system$domainInfo), + $__typename: $__typename == _undefined || $__typename == null + ? _instance.$__typename + : ($__typename as String))); + CopyWith$Query$SystemDnsProvider$system$domainInfo get domainInfo { + final local$domainInfo = _instance.domainInfo; + return CopyWith$Query$SystemDnsProvider$system$domainInfo( + local$domainInfo, (e) => call(domainInfo: e)); + } +} + +class _CopyWithStubImpl$Query$SystemDnsProvider$system + implements CopyWith$Query$SystemDnsProvider$system { + _CopyWithStubImpl$Query$SystemDnsProvider$system(this._res); + + TRes _res; + + call( + {Query$SystemDnsProvider$system$domainInfo? domainInfo, + String? $__typename}) => + _res; + CopyWith$Query$SystemDnsProvider$system$domainInfo get domainInfo => + CopyWith$Query$SystemDnsProvider$system$domainInfo.stub(_res); +} + +@JsonSerializable(explicitToJson: true) +class Query$SystemDnsProvider$system$domainInfo { + Query$SystemDnsProvider$system$domainInfo( + {required this.provider, required this.$__typename}); + + @override + factory Query$SystemDnsProvider$system$domainInfo.fromJson( + Map json) => + _$Query$SystemDnsProvider$system$domainInfoFromJson(json); + + @JsonKey(unknownEnumValue: Enum$DnsProvider.$unknown) + final Enum$DnsProvider provider; + + @JsonKey(name: '__typename') + final String $__typename; + + Map toJson() => + _$Query$SystemDnsProvider$system$domainInfoToJson(this); + int get hashCode { + final l$provider = provider; + final l$$__typename = $__typename; + return Object.hashAll([l$provider, l$$__typename]); + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + if (!(other is Query$SystemDnsProvider$system$domainInfo) || + runtimeType != other.runtimeType) return false; + final l$provider = provider; + final lOther$provider = other.provider; + if (l$provider != lOther$provider) return false; + final l$$__typename = $__typename; + final lOther$$__typename = other.$__typename; + if (l$$__typename != lOther$$__typename) return false; + return true; + } +} + +extension UtilityExtension$Query$SystemDnsProvider$system$domainInfo + on Query$SystemDnsProvider$system$domainInfo { + CopyWith$Query$SystemDnsProvider$system$domainInfo< + Query$SystemDnsProvider$system$domainInfo> + get copyWith => + CopyWith$Query$SystemDnsProvider$system$domainInfo(this, (i) => i); +} + +abstract class CopyWith$Query$SystemDnsProvider$system$domainInfo { + factory CopyWith$Query$SystemDnsProvider$system$domainInfo( + Query$SystemDnsProvider$system$domainInfo instance, + TRes Function(Query$SystemDnsProvider$system$domainInfo) then) = + _CopyWithImpl$Query$SystemDnsProvider$system$domainInfo; + + factory CopyWith$Query$SystemDnsProvider$system$domainInfo.stub(TRes res) = + _CopyWithStubImpl$Query$SystemDnsProvider$system$domainInfo; + + TRes call({Enum$DnsProvider? provider, String? $__typename}); +} + +class _CopyWithImpl$Query$SystemDnsProvider$system$domainInfo + implements CopyWith$Query$SystemDnsProvider$system$domainInfo { + _CopyWithImpl$Query$SystemDnsProvider$system$domainInfo( + this._instance, this._then); + + final Query$SystemDnsProvider$system$domainInfo _instance; + + final TRes Function(Query$SystemDnsProvider$system$domainInfo) _then; + + static const _undefined = {}; + + TRes call( + {Object? provider = _undefined, Object? $__typename = _undefined}) => + _then(Query$SystemDnsProvider$system$domainInfo( + provider: provider == _undefined || provider == null + ? _instance.provider + : (provider as Enum$DnsProvider), + $__typename: $__typename == _undefined || $__typename == null + ? _instance.$__typename + : ($__typename as String))); +} + +class _CopyWithStubImpl$Query$SystemDnsProvider$system$domainInfo + implements CopyWith$Query$SystemDnsProvider$system$domainInfo { + _CopyWithStubImpl$Query$SystemDnsProvider$system$domainInfo(this._res); + + TRes _res; + + call({Enum$DnsProvider? provider, String? $__typename}) => _res; +} + @JsonSerializable(explicitToJson: true) class Query$GetApiTokens { Query$GetApiTokens({required this.api, required this.$__typename}); diff --git a/lib/logic/api_maps/graphql_maps/schema/server_api.graphql.g.dart b/lib/logic/api_maps/graphql_maps/schema/server_api.graphql.g.dart index f0ec390c..0d658310 100644 --- a/lib/logic/api_maps/graphql_maps/schema/server_api.graphql.g.dart +++ b/lib/logic/api_maps/graphql_maps/schema/server_api.graphql.g.dart @@ -382,6 +382,58 @@ const _$Enum$ServerProviderEnumMap = { Enum$ServerProvider.$unknown: r'$unknown', }; +Query$SystemDnsProvider _$Query$SystemDnsProviderFromJson( + Map json) => + Query$SystemDnsProvider( + system: Query$SystemDnsProvider$system.fromJson( + json['system'] as Map), + $__typename: json['__typename'] as String, + ); + +Map _$Query$SystemDnsProviderToJson( + Query$SystemDnsProvider instance) => + { + 'system': instance.system.toJson(), + '__typename': instance.$__typename, + }; + +Query$SystemDnsProvider$system _$Query$SystemDnsProvider$systemFromJson( + Map json) => + Query$SystemDnsProvider$system( + domainInfo: Query$SystemDnsProvider$system$domainInfo.fromJson( + json['domainInfo'] as Map), + $__typename: json['__typename'] as String, + ); + +Map _$Query$SystemDnsProvider$systemToJson( + Query$SystemDnsProvider$system instance) => + { + 'domainInfo': instance.domainInfo.toJson(), + '__typename': instance.$__typename, + }; + +Query$SystemDnsProvider$system$domainInfo + _$Query$SystemDnsProvider$system$domainInfoFromJson( + Map json) => + Query$SystemDnsProvider$system$domainInfo( + provider: $enumDecode(_$Enum$DnsProviderEnumMap, json['provider'], + unknownValue: Enum$DnsProvider.$unknown), + $__typename: json['__typename'] as String, + ); + +Map _$Query$SystemDnsProvider$system$domainInfoToJson( + Query$SystemDnsProvider$system$domainInfo instance) => + { + 'provider': _$Enum$DnsProviderEnumMap[instance.provider]!, + '__typename': instance.$__typename, + }; + +const _$Enum$DnsProviderEnumMap = { + Enum$DnsProvider.CLOUDFLARE: 'CLOUDFLARE', + Enum$DnsProvider.DIGITALOCEAN: 'DIGITALOCEAN', + Enum$DnsProvider.$unknown: r'$unknown', +}; + Query$GetApiTokens _$Query$GetApiTokensFromJson(Map json) => Query$GetApiTokens( api: Query$GetApiTokens$api.fromJson(json['api'] as Map), diff --git a/lib/logic/api_maps/graphql_maps/schema/server_settings.graphql.g.dart b/lib/logic/api_maps/graphql_maps/schema/server_settings.graphql.g.dart index c928b177..6f4cb2d4 100644 --- a/lib/logic/api_maps/graphql_maps/schema/server_settings.graphql.g.dart +++ b/lib/logic/api_maps/graphql_maps/schema/server_settings.graphql.g.dart @@ -208,6 +208,7 @@ Map _$Query$DomainInfo$system$domainInfoToJson( const _$Enum$DnsProviderEnumMap = { Enum$DnsProvider.CLOUDFLARE: 'CLOUDFLARE', + Enum$DnsProvider.DIGITALOCEAN: 'DIGITALOCEAN', Enum$DnsProvider.$unknown: r'$unknown', }; diff --git a/lib/logic/api_maps/graphql_maps/server_api/server_api.dart b/lib/logic/api_maps/graphql_maps/server_api/server_api.dart index bb703103..51da63ac 100644 --- a/lib/logic/api_maps/graphql_maps/server_api/server_api.dart +++ b/lib/logic/api_maps/graphql_maps/server_api/server_api.dart @@ -11,6 +11,7 @@ import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/users.graphql.dar import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart'; import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart'; import 'package:selfprivacy/logic/models/hive/server_details.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'; @@ -87,6 +88,25 @@ class ServerApi extends ApiMap return providerType; } + Future getDnsProviderType() async { + QueryResult response; + DnsProvider providerType = DnsProvider.unknown; + + try { + final GraphQLClient client = await getClient(); + response = await client.query$SystemDnsProvider(); + if (response.hasException) { + print(response.exception.toString()); + } + providerType = DnsProvider.fromGraphQL( + response.parsedData!.system.domainInfo.provider, + ); + } catch (e) { + print(e); + } + return providerType; + } + Future isUsingBinds() async { QueryResult response; bool usesBinds = false; diff --git a/lib/logic/cubit/server_installation/server_installation_cubit.dart b/lib/logic/cubit/server_installation/server_installation_cubit.dart index 487e60c7..60a801fd 100644 --- a/lib/logic/cubit/server_installation/server_installation_cubit.dart +++ b/lib/logic/cubit/server_installation/server_installation_cubit.dart @@ -537,17 +537,27 @@ class ServerInstallationCubit extends Cubit { token, dataState.recoveryCapabilities, ); - final ServerProvider provider = await ServerApi( + final ServerProvider serverProvider = await ServerApi( customToken: serverDetails.apiToken, isWithToken: true, ).getServerProviderType(); - if (provider == ServerProvider.unknown) { + final DnsProvider dnsProvider = await ServerApi( + customToken: serverDetails.apiToken, + isWithToken: true, + ).getDnsProviderType(); + if (serverProvider == ServerProvider.unknown) { + getIt() + .showSnackBar('recovering.generic_error'.tr()); + return; + } + if (dnsProvider == DnsProvider.unknown) { getIt() .showSnackBar('recovering.generic_error'.tr()); return; } await repository.saveServerDetails(serverDetails); - setServerProviderType(provider); + setServerProviderType(serverProvider); + setDnsProviderType(dnsProvider); emit( dataState.copyWith( serverDetails: serverDetails, diff --git a/lib/logic/models/hive/server_domain.dart b/lib/logic/models/hive/server_domain.dart index a58ff5a1..0b8a5bc8 100644 --- a/lib/logic/models/hive/server_domain.dart +++ b/lib/logic/models/hive/server_domain.dart @@ -1,4 +1,5 @@ import 'package:hive/hive.dart'; +import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart'; part 'server_domain.g.dart'; @@ -30,5 +31,16 @@ enum DnsProvider { @HiveField(1) cloudflare, @HiveField(2) - digitalOcean, + digitalOcean; + + factory DnsProvider.fromGraphQL(final Enum$DnsProvider provider) { + switch (provider) { + case Enum$DnsProvider.CLOUDFLARE: + return cloudflare; + case Enum$DnsProvider.DIGITALOCEAN: + return digitalOcean; + default: + return unknown; + } + } }