diff --git a/lib/logic/api_maps/rest_maps/dns_providers/desec/desec_api.dart b/lib/logic/api_maps/rest_maps/dns_providers/desec/desec_api.dart index 9856242d..2bc15c22 100644 --- a/lib/logic/api_maps/rest_maps/dns_providers/desec/desec_api.dart +++ b/lib/logic/api_maps/rest_maps/dns_providers/desec/desec_api.dart @@ -4,7 +4,7 @@ import 'package:dio/dio.dart'; import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/api_maps/generic_result.dart'; import 'package:selfprivacy/logic/api_maps/rest_maps/rest_api_map.dart'; -import 'package:selfprivacy/logic/models/json/desec_dns_info.dart'; +import 'package:selfprivacy/logic/models/json/dns_providers/desec_dns_info.dart'; class DesecApi extends RestApiMap { DesecApi({ diff --git a/lib/logic/models/json/dns_providers/desec_dns_adapter.dart b/lib/logic/models/json/dns_providers/desec_dns_adapter.dart new file mode 100644 index 00000000..7d2828c0 --- /dev/null +++ b/lib/logic/models/json/dns_providers/desec_dns_adapter.dart @@ -0,0 +1,53 @@ +part of 'desec_dns_info.dart'; + +DesecDnsRecord _fromDnsRecord(final DnsRecord dnsRecord) { + final String type = dnsRecord.type; + String content = dnsRecord.content ?? ''; + String name = dnsRecord.name ?? ''; + if (type == 'MX') { + name = (name == '@') ? '' : name; + content = '${dnsRecord.priority} $content'; + } + if (type == 'TXT' && content.isNotEmpty && !content.startsWith('"')) { + content = '"$content"'; + } + + return DesecDnsRecord( + subname: name, + type: type, + ttl: dnsRecord.ttl, + records: [content], + ); +} + +DnsRecord _toDnsRecord(final DesecDnsRecord desecRecord) { + final String type = desecRecord.type; + String content = desecRecord.records.isEmpty ? '' : desecRecord.records[0]; + String name = desecRecord.subname; + int? priority; + if (type == 'MX') { + name = name.isEmpty ? '@' : name; + final contentBulk = content.split(' '); + content = contentBulk[1]; + priority = int.parse(contentBulk[0]); + } + if (type == 'TXT' && content.isNotEmpty && content.startsWith('"')) { + content = content.substring(1, content.length); // cut away quotes + } + + return DnsRecord( + name: name, + type: type, + ttl: desecRecord.ttl, + content: content, + priority: priority ?? 10, + ); +} + +DesecDomain _fromServerDomain(final ServerDomain serverDomain) => + DesecDomain(name: serverDomain.domainName); + +ServerDomain _toServerDomain(final DesecDomain desecDomain) => ServerDomain( + domainName: desecDomain.name, + provider: DnsProviderType.desec, + ); diff --git a/lib/logic/models/json/desec_dns_info.dart b/lib/logic/models/json/dns_providers/desec_dns_info.dart similarity index 77% rename from lib/logic/models/json/desec_dns_info.dart rename to lib/logic/models/json/dns_providers/desec_dns_info.dart index 4709f86c..b9a599e7 100644 --- a/lib/logic/models/json/desec_dns_info.dart +++ b/lib/logic/models/json/dns_providers/desec_dns_info.dart @@ -1,15 +1,19 @@ import 'package:json_annotation/json_annotation.dart'; +import 'package:selfprivacy/logic/models/hive/server_domain.dart'; import 'package:selfprivacy/logic/models/json/dns_records.dart'; - +part 'desec_dns_adapter.dart'; part 'desec_dns_info.g.dart'; /// https://desec.readthedocs.io/en/latest/dns/domains.html#domain-management @JsonSerializable() class DesecDomain { - DesecDomain( - this.name, + DesecDomain({ + required this.name, this.minimumTtl, - ); + }); + + factory DesecDomain.fromServerDomain(final ServerDomain serverDomain) => + _fromServerDomain(serverDomain); /// Restrictions on what is a valid domain name apply on /// a per-user basis. @@ -20,34 +24,16 @@ class DesecDomain { /// Smallest TTL that can be used in an RRset. /// The value is set automatically by DESEC @JsonKey(name: 'minimum_ttl') - final int minimumTtl; + final int? minimumTtl; static DesecDomain fromJson(final Map json) => _$DesecDomainFromJson(json); + ServerDomain toServerDomain() => _toServerDomain(this); } /// https://desec.readthedocs.io/en/latest/dns/rrsets.html#retrieving-and-creating-dns-records @JsonSerializable() class DesecDnsRecord { - factory DesecDnsRecord.fromDnsRecord(final DnsRecord record) { - final String type = record.type; - String content = record.content ?? ''; - String name = record.name ?? ''; - if (type == 'MX') { - name = ''; - content = '10 $content'; - } - if (type == 'TXT' && content.isNotEmpty && !content.startsWith('"')) { - content = '"$content"'; - } - - return DesecDnsRecord( - subname: name, - type: type, - ttl: record.ttl, - records: [content], - ); - } DesecDnsRecord({ required this.subname, required this.type, @@ -55,6 +41,9 @@ class DesecDnsRecord { required this.records, }); + factory DesecDnsRecord.fromDnsRecord(final DnsRecord dnsRecord) => + _fromDnsRecord(dnsRecord); + /// Subdomain string which, together with domain, defines the RRset name. /// Typical examples are www or _443._tcp. final String subname; @@ -80,4 +69,5 @@ class DesecDnsRecord { static DesecDnsRecord fromJson(final Map json) => _$DesecDnsRecordFromJson(json); Map toJson() => _$DesecDnsRecordToJson(this); + DnsRecord toDnsRecord() => _toDnsRecord(this); } diff --git a/lib/logic/models/json/desec_dns_info.g.dart b/lib/logic/models/json/dns_providers/desec_dns_info.g.dart similarity index 100% rename from lib/logic/models/json/desec_dns_info.g.dart rename to lib/logic/models/json/dns_providers/desec_dns_info.g.dart diff --git a/lib/logic/providers/dns_providers/desec.dart b/lib/logic/providers/dns_providers/desec.dart index 35364b26..71e18df7 100644 --- a/lib/logic/providers/dns_providers/desec.dart +++ b/lib/logic/providers/dns_providers/desec.dart @@ -1,7 +1,7 @@ import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/desec/desec_api.dart'; import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/desired_dns_record.dart'; import 'package:selfprivacy/logic/models/hive/server_domain.dart'; -import 'package:selfprivacy/logic/models/json/desec_dns_info.dart'; +import 'package:selfprivacy/logic/models/json/dns_providers/desec_dns_info.dart'; import 'package:selfprivacy/logic/models/json/dns_records.dart'; import 'package:selfprivacy/logic/providers/dns_providers/dns_provider.dart'; import 'package:selfprivacy/utils/network_utils.dart'; @@ -47,8 +47,8 @@ class DesecDnsProvider extends DnsProvider { } @override - Future>> domainList() async { - List domains = []; + Future>> domainList() async { + List domains = []; final result = await _adapter.api().getDomains(); if (result.data.isEmpty || !result.success) { return GenericResult( @@ -60,8 +60,8 @@ class DesecDnsProvider extends DnsProvider { } domains = result.data - .map( - (final el) => el.name, + .map( + (final el) => el.toServerDomain(), ) .toList(); @@ -146,16 +146,7 @@ class DesecDnsProvider extends DnsProvider { try { for (final record in result.data) { - final String? content = - record.records.isEmpty ? null : record.records[0]; - records.add( - DnsRecord( - name: record.subname, - type: record.type, - content: content, - ttl: record.ttl, - ), - ); + records.add(record.toDnsRecord()); } } catch (e) { print(e); @@ -234,8 +225,7 @@ class DesecDnsProvider extends DnsProvider { } else { final foundMatch = records.any( (final r) => - ('${r.subname}.${domain.domainName}' == record.subname || - record.subname == '') && + r.subname == record.subname && r.type == record.type && r.records[0] == record.records[0], ); diff --git a/lib/logic/providers/dns_providers/dns_provider.dart b/lib/logic/providers/dns_providers/dns_provider.dart index cd5c39f3..b2110b95 100644 --- a/lib/logic/providers/dns_providers/dns_provider.dart +++ b/lib/logic/providers/dns_providers/dns_provider.dart @@ -18,7 +18,7 @@ abstract class DnsProvider { Future> tryInitApiByToken(final String token); /// Returns list of all available domain entries assigned to the account. - Future>> domainList(); + Future>> domainList(); /// Tries to create all main domain records needed /// for SelfPrivacy to launch on requested domain by ip4.