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 960df30f..9856242d 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/hive/server_domain.dart'; +import 'package:selfprivacy/logic/models/json/desec_dns_info.dart'; class DesecApi extends RestApiMap { DesecApi({ @@ -92,8 +92,8 @@ class DesecApi extends RestApiMap { ); } - Future> getDomains() async { - List domains = []; + Future>> getDomains() async { + List domains = []; late final Response? response; final Dio client = await getClient(); @@ -102,7 +102,11 @@ class DesecApi extends RestApiMap { '', ); await Future.delayed(const Duration(seconds: 1)); - domains = response.data; + domains = response.data! + .map( + (final e) => DesecDomain.fromJson(e), + ) + .toList(); } catch (e) { print(e); return GenericResult( @@ -124,15 +128,17 @@ class DesecApi extends RestApiMap { } Future> createMultipleDnsRecords({ - required final ServerDomain domain, - required final List records, + required final String domainName, + required final List records, }) async { - final String domainName = domain.domainName; final String url = '/$domainName/rrsets/'; final Dio client = await getClient(); try { - await client.post(url, data: records); + await client.post( + url, + data: records.map((final rec) => rec.toJson()).toList(), + ); await Future.delayed(const Duration(seconds: 1)); } catch (e) { print(e); @@ -149,15 +155,17 @@ class DesecApi extends RestApiMap { } Future> removeSimilarRecords({ - required final ServerDomain domain, - required final List records, + required final String domainName, + required final List records, }) async { - final String domainName = domain.domainName; final String url = '/$domainName/rrsets/'; final Dio client = await getClient(); try { - await client.put(url, data: records); + await client.put( + url, + data: records.map((final rec) => rec.toJson()).toList(), + ); await Future.delayed(const Duration(seconds: 1)); } catch (e) { print(e); @@ -173,12 +181,11 @@ class DesecApi extends RestApiMap { return GenericResult(success: true, data: null); } - Future>> getDnsRecords({ - required final ServerDomain domain, - }) async { + Future>> getDnsRecords( + final String domainName, + ) async { Response? response; - final String domainName = domain.domainName; - List allRecords = []; + List allRecords = []; final String url = '/$domainName/rrsets/'; @@ -186,7 +193,11 @@ class DesecApi extends RestApiMap { try { response = await client.get(url); await Future.delayed(const Duration(seconds: 1)); - allRecords = response.data; + allRecords = response.data! + .map( + (final e) => DesecDnsRecord.fromJson(e), + ) + .toList(); } catch (e) { print(e); return GenericResult( diff --git a/lib/logic/models/json/desec_dns_info.dart b/lib/logic/models/json/desec_dns_info.dart new file mode 100644 index 00000000..e6023da7 --- /dev/null +++ b/lib/logic/models/json/desec_dns_info.dart @@ -0,0 +1,63 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'desec_dns_info.g.dart'; + +/// https://desec.readthedocs.io/en/latest/dns/domains.html#domain-management +@JsonSerializable() +class DesecDomain { + DesecDomain( + this.name, + this.minimumTtl, + ); + + /// Restrictions on what is a valid domain name apply on + /// a per-user basis. + /// + /// The maximum length is 191. + final String name; + + /// Smallest TTL that can be used in an RRset. + /// The value is set automatically by DESEC + @JsonKey(name: 'minimum_ttl') + final int minimumTtl; + + static DesecDomain fromJson(final Map json) => + _$DesecDomainFromJson(json); +} + +/// https://desec.readthedocs.io/en/latest/dns/rrsets.html#retrieving-and-creating-dns-records +@JsonSerializable() +class DesecDnsRecord { + DesecDnsRecord({ + required this.subname, + required this.type, + required this.ttl, + required this.records, + }); + + /// Subdomain string which, together with domain, defines the RRset name. + /// Typical examples are www or _443._tcp. + final String subname; + + /// RRset type (uppercase). A broad range of record types is supported, + /// with most DNSSEC-related types (and the SOA type) managed automagically + /// by the backend. + final String type; + + /// Time-to-live value, which dictates for how long resolvers may + /// cache this RRset, measured in seconds. + /// + /// The smallest acceptable value is given by the domain’s minimum TTL setting. + /// The maximum value is 86400 (one day). + final int ttl; + + /// Array of record content strings. + /// + /// The maximum number of array elements is 4091, + /// and the maximum length of the array is 64,000 (after JSON encoding). + final List records; + + static DesecDnsRecord fromJson(final Map json) => + _$DesecDnsRecordFromJson(json); + Map toJson() => _$DesecDnsRecordToJson(this); +} diff --git a/lib/logic/models/json/desec_dns_info.g.dart b/lib/logic/models/json/desec_dns_info.g.dart new file mode 100644 index 00000000..b82ed777 --- /dev/null +++ b/lib/logic/models/json/desec_dns_info.g.dart @@ -0,0 +1,35 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'desec_dns_info.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DesecDomain _$DesecDomainFromJson(Map json) => DesecDomain( + json['name'] as String, + json['minimum_ttl'] as int, + ); + +Map _$DesecDomainToJson(DesecDomain instance) => + { + 'name': instance.name, + 'minimum_ttl': instance.minimumTtl, + }; + +DesecDnsRecord _$DesecDnsRecordFromJson(Map json) => + DesecDnsRecord( + subname: json['subname'] as String, + type: json['type'] as String, + ttl: json['ttl'] as int, + records: + (json['records'] as List).map((e) => e as String).toList(), + ); + +Map _$DesecDnsRecordToJson(DesecDnsRecord instance) => + { + 'subname': instance.subname, + 'type': instance.type, + 'ttl': instance.ttl, + 'records': instance.records, + }; diff --git a/lib/logic/models/json/dns_records.dart b/lib/logic/models/json/dns_records.dart index 3951ae4e..8b0fdf23 100644 --- a/lib/logic/models/json/dns_records.dart +++ b/lib/logic/models/json/dns_records.dart @@ -9,7 +9,6 @@ class DnsRecord { required this.type, required this.name, required this.content, - this.id, this.ttl = 3600, this.priority = 10, this.proxied = false, @@ -32,8 +31,5 @@ class DnsRecord { final int priority; final bool proxied; - /// TODO: Refactoring refactoring refactoring refactoring >:c - final int? id; - Map toJson() => _$DnsRecordToJson(this); } diff --git a/lib/logic/models/json/dns_records.g.dart b/lib/logic/models/json/dns_records.g.dart index b58db5de..c8c12c34 100644 --- a/lib/logic/models/json/dns_records.g.dart +++ b/lib/logic/models/json/dns_records.g.dart @@ -13,5 +13,4 @@ Map _$DnsRecordToJson(DnsRecord instance) => { 'ttl': instance.ttl, 'priority': instance.priority, 'proxied': instance.proxied, - 'id': instance.id, }; diff --git a/lib/logic/providers/dns_providers/desec.dart b/lib/logic/providers/dns_providers/desec.dart index 41d504e4..e20d82bf 100644 --- a/lib/logic/providers/dns_providers/desec.dart +++ b/lib/logic/providers/dns_providers/desec.dart @@ -1,6 +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_records.dart'; import 'package:selfprivacy/logic/providers/dns_providers/dns_provider.dart'; @@ -59,7 +60,7 @@ class DesecDnsProvider extends DnsProvider { domains = result.data .map( - (final el) => el['name'] as String, + (final el) => el.name, ) .toList(); @@ -79,20 +80,20 @@ class DesecDnsProvider extends DnsProvider { ip4, ); - final List bulkRecords = []; + final List bulkRecords = []; for (final DnsRecord record in listDnsRecords) { bulkRecords.add( - { - 'subname': record.name, - 'type': record.type, - 'ttl': record.ttl, - 'records': [extractContent(record)], - }, + DesecDnsRecord( + subname: record.name ?? '', + type: record.type, + ttl: record.ttl, + records: [extractContent(record) ?? ''], + ), ); } return _adapter.api().createMultipleDnsRecords( - domain: domain, + domainName: domain.domainName, records: bulkRecords, ); } @@ -107,28 +108,28 @@ class DesecDnsProvider extends DnsProvider { ip4, ); - final List bulkRecords = []; + final List bulkRecords = []; for (final DnsRecord record in listDnsRecords) { bulkRecords.add( - { - 'subname': record.name, - 'type': record.type, - 'ttl': record.ttl, - 'records': [], - }, + DesecDnsRecord( + subname: record.name ?? '', + type: record.type, + ttl: record.ttl, + records: [], + ), ); } bulkRecords.add( - { - 'subname': 'selector._domainkey', - 'type': 'TXT', - 'ttl': 18000, - 'records': [], - }, + DesecDnsRecord( + subname: 'selector._domainkey', + type: 'TXT', + ttl: 18000, + records: [], + ), ); return _adapter.api().removeSimilarRecords( - domain: domain, + domainName: domain.domainName, records: bulkRecords, ); } @@ -138,7 +139,7 @@ class DesecDnsProvider extends DnsProvider { required final ServerDomain domain, }) async { final List records = []; - final result = await _adapter.api().getDnsRecords(domain: domain); + final result = await _adapter.api().getDnsRecords(domain.domainName); if (result.data.isEmpty || !result.success) { return GenericResult( success: result.success, @@ -150,15 +151,14 @@ class DesecDnsProvider extends DnsProvider { try { for (final record in result.data) { - final String? content = (record['records'] is List) - ? record['records'][0] - : record['records']; + final String? content = + record.records.isEmpty ? null : record.records[0]; records.add( DnsRecord( - name: record['subname'], - type: record['type'], + name: record.subname, + type: record.type, content: content, - ttl: record['ttl'], + ttl: record.ttl, ), ); } @@ -180,14 +180,14 @@ class DesecDnsProvider extends DnsProvider { final ServerDomain domain, ) async { final result = await _adapter.api().createMultipleDnsRecords( - domain: domain, + domainName: domain.domainName, records: [ - { - 'subname': record.name, - 'type': record.type, - 'ttl': record.ttl, - 'records': [extractContent(record)], - }, + DesecDnsRecord( + subname: record.name ?? '', + type: record.type, + ttl: record.ttl, + records: [extractContent(record) ?? ''], + ), ], ); diff --git a/lib/logic/providers/dns_providers/digital_ocean_dns.dart b/lib/logic/providers/dns_providers/digital_ocean_dns.dart index 87f8a479..3056f94d 100644 --- a/lib/logic/providers/dns_providers/digital_ocean_dns.dart +++ b/lib/logic/providers/dns_providers/digital_ocean_dns.dart @@ -129,7 +129,6 @@ class DigitalOceanDnsProvider extends DnsProvider { for (final rawRecord in result.data) { records.add( DnsRecord( - id: rawRecord['id'], name: rawRecord['name'], type: rawRecord['type'], content: rawRecord['data'],