mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-11 10:29:39 +00:00
refactor: Move DNS records validation to cubit layer
This commit is contained in:
parent
ada5f1a66c
commit
1c07476764
|
@ -5529,11 +5529,10 @@ extension ClientExtension$Mutation$RemoveRepository on graphql.GraphQLClient {
|
|||
mutate$RemoveRepository(
|
||||
[Options$Mutation$RemoveRepository? options]) async =>
|
||||
await this.mutate(options ?? Options$Mutation$RemoveRepository());
|
||||
graphql.ObservableQuery<Mutation$RemoveRepository>
|
||||
watchMutation$RemoveRepository(
|
||||
[WatchOptions$Mutation$RemoveRepository? options]) =>
|
||||
this.watchMutation(
|
||||
options ?? WatchOptions$Mutation$RemoveRepository());
|
||||
graphql.ObservableQuery<
|
||||
Mutation$RemoveRepository> watchMutation$RemoveRepository(
|
||||
[WatchOptions$Mutation$RemoveRepository? options]) =>
|
||||
this.watchMutation(options ?? WatchOptions$Mutation$RemoveRepository());
|
||||
}
|
||||
|
||||
class Mutation$RemoveRepository$backup {
|
||||
|
|
|
@ -150,6 +150,7 @@ type DnsRecord {
|
|||
recordType: String!
|
||||
name: String!
|
||||
content: String!
|
||||
displayName: String!
|
||||
ttl: Int!
|
||||
priority: Int
|
||||
}
|
||||
|
|
|
@ -4440,11 +4440,10 @@ extension ClientExtension$Mutation$RunSystemRebuild on graphql.GraphQLClient {
|
|||
mutate$RunSystemRebuild(
|
||||
[Options$Mutation$RunSystemRebuild? options]) async =>
|
||||
await this.mutate(options ?? Options$Mutation$RunSystemRebuild());
|
||||
graphql.ObservableQuery<Mutation$RunSystemRebuild>
|
||||
watchMutation$RunSystemRebuild(
|
||||
[WatchOptions$Mutation$RunSystemRebuild? options]) =>
|
||||
this.watchMutation(
|
||||
options ?? WatchOptions$Mutation$RunSystemRebuild());
|
||||
graphql.ObservableQuery<
|
||||
Mutation$RunSystemRebuild> watchMutation$RunSystemRebuild(
|
||||
[WatchOptions$Mutation$RunSystemRebuild? options]) =>
|
||||
this.watchMutation(options ?? WatchOptions$Mutation$RunSystemRebuild());
|
||||
}
|
||||
|
||||
class Mutation$RunSystemRebuild$runSystemRebuild
|
||||
|
@ -4883,11 +4882,10 @@ extension ClientExtension$Mutation$RunSystemRollback on graphql.GraphQLClient {
|
|||
mutate$RunSystemRollback(
|
||||
[Options$Mutation$RunSystemRollback? options]) async =>
|
||||
await this.mutate(options ?? Options$Mutation$RunSystemRollback());
|
||||
graphql.ObservableQuery<Mutation$RunSystemRollback>
|
||||
watchMutation$RunSystemRollback(
|
||||
[WatchOptions$Mutation$RunSystemRollback? options]) =>
|
||||
this.watchMutation(
|
||||
options ?? WatchOptions$Mutation$RunSystemRollback());
|
||||
graphql.ObservableQuery<
|
||||
Mutation$RunSystemRollback> watchMutation$RunSystemRollback(
|
||||
[WatchOptions$Mutation$RunSystemRollback? options]) =>
|
||||
this.watchMutation(options ?? WatchOptions$Mutation$RunSystemRollback());
|
||||
}
|
||||
|
||||
class Mutation$RunSystemRollback$runSystemRollback
|
||||
|
@ -5324,11 +5322,10 @@ extension ClientExtension$Mutation$RunSystemUpgrade on graphql.GraphQLClient {
|
|||
mutate$RunSystemUpgrade(
|
||||
[Options$Mutation$RunSystemUpgrade? options]) async =>
|
||||
await this.mutate(options ?? Options$Mutation$RunSystemUpgrade());
|
||||
graphql.ObservableQuery<Mutation$RunSystemUpgrade>
|
||||
watchMutation$RunSystemUpgrade(
|
||||
[WatchOptions$Mutation$RunSystemUpgrade? options]) =>
|
||||
this.watchMutation(
|
||||
options ?? WatchOptions$Mutation$RunSystemUpgrade());
|
||||
graphql.ObservableQuery<
|
||||
Mutation$RunSystemUpgrade> watchMutation$RunSystemUpgrade(
|
||||
[WatchOptions$Mutation$RunSystemUpgrade? options]) =>
|
||||
this.watchMutation(options ?? WatchOptions$Mutation$RunSystemUpgrade());
|
||||
}
|
||||
|
||||
class Mutation$RunSystemUpgrade$runSystemUpgrade
|
||||
|
@ -11384,11 +11381,10 @@ extension ClientExtension$Mutation$GetNewDeviceApiKey on graphql.GraphQLClient {
|
|||
mutate$GetNewDeviceApiKey(
|
||||
[Options$Mutation$GetNewDeviceApiKey? options]) async =>
|
||||
await this.mutate(options ?? Options$Mutation$GetNewDeviceApiKey());
|
||||
graphql.ObservableQuery<Mutation$GetNewDeviceApiKey>
|
||||
watchMutation$GetNewDeviceApiKey(
|
||||
[WatchOptions$Mutation$GetNewDeviceApiKey? options]) =>
|
||||
this.watchMutation(
|
||||
options ?? WatchOptions$Mutation$GetNewDeviceApiKey());
|
||||
graphql.ObservableQuery<
|
||||
Mutation$GetNewDeviceApiKey> watchMutation$GetNewDeviceApiKey(
|
||||
[WatchOptions$Mutation$GetNewDeviceApiKey? options]) =>
|
||||
this.watchMutation(options ?? WatchOptions$Mutation$GetNewDeviceApiKey());
|
||||
}
|
||||
|
||||
class Mutation$GetNewDeviceApiKey$getNewDeviceApiKey
|
||||
|
|
|
@ -25,6 +25,7 @@ query SystemIsUsingBinds {
|
|||
fragment fragmentDnsRecords on DnsRecord {
|
||||
recordType
|
||||
name
|
||||
displayName
|
||||
content
|
||||
ttl
|
||||
priority
|
||||
|
|
|
@ -8,6 +8,7 @@ class Fragment$fragmentDnsRecords {
|
|||
Fragment$fragmentDnsRecords({
|
||||
required this.recordType,
|
||||
required this.name,
|
||||
required this.displayName,
|
||||
required this.content,
|
||||
required this.ttl,
|
||||
this.priority,
|
||||
|
@ -17,6 +18,7 @@ class Fragment$fragmentDnsRecords {
|
|||
factory Fragment$fragmentDnsRecords.fromJson(Map<String, dynamic> json) {
|
||||
final l$recordType = json['recordType'];
|
||||
final l$name = json['name'];
|
||||
final l$displayName = json['displayName'];
|
||||
final l$content = json['content'];
|
||||
final l$ttl = json['ttl'];
|
||||
final l$priority = json['priority'];
|
||||
|
@ -24,6 +26,7 @@ class Fragment$fragmentDnsRecords {
|
|||
return Fragment$fragmentDnsRecords(
|
||||
recordType: (l$recordType as String),
|
||||
name: (l$name as String),
|
||||
displayName: (l$displayName as String),
|
||||
content: (l$content as String),
|
||||
ttl: (l$ttl as int),
|
||||
priority: (l$priority as int?),
|
||||
|
@ -35,6 +38,8 @@ class Fragment$fragmentDnsRecords {
|
|||
|
||||
final String name;
|
||||
|
||||
final String displayName;
|
||||
|
||||
final String content;
|
||||
|
||||
final int ttl;
|
||||
|
@ -49,6 +54,8 @@ class Fragment$fragmentDnsRecords {
|
|||
_resultData['recordType'] = l$recordType;
|
||||
final l$name = name;
|
||||
_resultData['name'] = l$name;
|
||||
final l$displayName = displayName;
|
||||
_resultData['displayName'] = l$displayName;
|
||||
final l$content = content;
|
||||
_resultData['content'] = l$content;
|
||||
final l$ttl = ttl;
|
||||
|
@ -64,6 +71,7 @@ class Fragment$fragmentDnsRecords {
|
|||
int get hashCode {
|
||||
final l$recordType = recordType;
|
||||
final l$name = name;
|
||||
final l$displayName = displayName;
|
||||
final l$content = content;
|
||||
final l$ttl = ttl;
|
||||
final l$priority = priority;
|
||||
|
@ -71,6 +79,7 @@ class Fragment$fragmentDnsRecords {
|
|||
return Object.hashAll([
|
||||
l$recordType,
|
||||
l$name,
|
||||
l$displayName,
|
||||
l$content,
|
||||
l$ttl,
|
||||
l$priority,
|
||||
|
@ -97,6 +106,11 @@ class Fragment$fragmentDnsRecords {
|
|||
if (l$name != lOther$name) {
|
||||
return false;
|
||||
}
|
||||
final l$displayName = displayName;
|
||||
final lOther$displayName = other.displayName;
|
||||
if (l$displayName != lOther$displayName) {
|
||||
return false;
|
||||
}
|
||||
final l$content = content;
|
||||
final lOther$content = other.content;
|
||||
if (l$content != lOther$content) {
|
||||
|
@ -142,6 +156,7 @@ abstract class CopyWith$Fragment$fragmentDnsRecords<TRes> {
|
|||
TRes call({
|
||||
String? recordType,
|
||||
String? name,
|
||||
String? displayName,
|
||||
String? content,
|
||||
int? ttl,
|
||||
int? priority,
|
||||
|
@ -165,6 +180,7 @@ class _CopyWithImpl$Fragment$fragmentDnsRecords<TRes>
|
|||
TRes call({
|
||||
Object? recordType = _undefined,
|
||||
Object? name = _undefined,
|
||||
Object? displayName = _undefined,
|
||||
Object? content = _undefined,
|
||||
Object? ttl = _undefined,
|
||||
Object? priority = _undefined,
|
||||
|
@ -177,6 +193,9 @@ class _CopyWithImpl$Fragment$fragmentDnsRecords<TRes>
|
|||
name: name == _undefined || name == null
|
||||
? _instance.name
|
||||
: (name as String),
|
||||
displayName: displayName == _undefined || displayName == null
|
||||
? _instance.displayName
|
||||
: (displayName as String),
|
||||
content: content == _undefined || content == null
|
||||
? _instance.content
|
||||
: (content as String),
|
||||
|
@ -198,6 +217,7 @@ class _CopyWithStubImpl$Fragment$fragmentDnsRecords<TRes>
|
|||
call({
|
||||
String? recordType,
|
||||
String? name,
|
||||
String? displayName,
|
||||
String? content,
|
||||
int? ttl,
|
||||
int? priority,
|
||||
|
@ -229,6 +249,13 @@ const fragmentDefinitionfragmentDnsRecords = FragmentDefinitionNode(
|
|||
directives: [],
|
||||
selectionSet: null,
|
||||
),
|
||||
FieldNode(
|
||||
name: NameNode(value: 'displayName'),
|
||||
alias: null,
|
||||
arguments: [],
|
||||
directives: [],
|
||||
selectionSet: null,
|
||||
),
|
||||
FieldNode(
|
||||
name: NameNode(value: 'content'),
|
||||
alias: null,
|
||||
|
|
|
@ -33,16 +33,16 @@ class DnsRecordsCubit
|
|||
final ServerDomain? domain = serverInstallationCubit.state.serverDomain;
|
||||
final String? ipAddress =
|
||||
serverInstallationCubit.state.serverDetails?.ip4;
|
||||
if (domain == null && ipAddress == null) {
|
||||
|
||||
if (domain == null || ipAddress == null) {
|
||||
emit(const DnsRecordsState());
|
||||
return;
|
||||
}
|
||||
|
||||
final List<DnsRecord> allDnsRecords = await api.getDnsRecords();
|
||||
allDnsRecords.removeWhere((final record) => record.type == 'AAAA');
|
||||
final foundRecords =
|
||||
await ProvidersController.currentDnsProvider!.validateDnsRecords(
|
||||
domain!,
|
||||
ipAddress!,
|
||||
final foundRecords = await validateDnsRecords(
|
||||
domain,
|
||||
extractDkimRecord(allDnsRecords)?.content ?? '',
|
||||
allDnsRecords,
|
||||
);
|
||||
|
@ -63,6 +63,93 @@ class DnsRecordsCubit
|
|||
}
|
||||
}
|
||||
|
||||
/// Tries to check whether all known DNS records on the domain by ip4
|
||||
/// match expectations of SelfPrivacy in order to launch.
|
||||
///
|
||||
/// Will return list of [DesiredDnsRecord] objects, which represent
|
||||
/// only those records which have successfully passed validation.
|
||||
Future<GenericResult<List<DesiredDnsRecord>>> validateDnsRecords(
|
||||
final ServerDomain domain,
|
||||
final String dkimPublicKey,
|
||||
final List<DnsRecord> pendingDnsRecords,
|
||||
) async {
|
||||
final result = await ProvidersController.currentDnsProvider!
|
||||
.getDnsRecords(domain: domain);
|
||||
if (result.data.isEmpty || !result.success) {
|
||||
return GenericResult(
|
||||
success: result.success,
|
||||
data: [],
|
||||
code: result.code,
|
||||
message: result.message,
|
||||
);
|
||||
}
|
||||
|
||||
final List<DnsRecord> providerDnsRecords = result.data;
|
||||
final List<DesiredDnsRecord> foundRecords = [];
|
||||
try {
|
||||
for (final DnsRecord pendingDnsRecord in pendingDnsRecords) {
|
||||
if (pendingDnsRecord.name == 'selector._domainkey') {
|
||||
final foundRecord = providerDnsRecords.firstWhere(
|
||||
(final r) =>
|
||||
(r.name == pendingDnsRecord.name) &&
|
||||
r.type == pendingDnsRecord.type,
|
||||
orElse: () => DnsRecord(
|
||||
displayName: pendingDnsRecord.displayName,
|
||||
name: pendingDnsRecord.name,
|
||||
type: pendingDnsRecord.type,
|
||||
content: pendingDnsRecord.content,
|
||||
ttl: pendingDnsRecord.ttl,
|
||||
),
|
||||
);
|
||||
final String foundContent =
|
||||
foundRecord.content!.replaceAll(RegExp(r'\s+'), '').trim();
|
||||
final String desiredContent =
|
||||
pendingDnsRecord.content!.replaceAll(RegExp(r'\s+'), '').trim();
|
||||
final isSatisfied = (desiredContent == foundContent);
|
||||
foundRecords.add(
|
||||
DesiredDnsRecord(
|
||||
name: pendingDnsRecord.name!,
|
||||
displayName: pendingDnsRecord.displayName,
|
||||
content: pendingDnsRecord.content!,
|
||||
isSatisfied: isSatisfied,
|
||||
type: pendingDnsRecord.type,
|
||||
category: DnsRecordsCategory.email,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
final foundMatch = providerDnsRecords.any(
|
||||
(final r) =>
|
||||
r.name == pendingDnsRecord.name &&
|
||||
r.type == pendingDnsRecord.type &&
|
||||
r.content == pendingDnsRecord.content,
|
||||
);
|
||||
foundRecords.add(
|
||||
DesiredDnsRecord(
|
||||
name: pendingDnsRecord.name!,
|
||||
displayName: pendingDnsRecord.displayName,
|
||||
content: pendingDnsRecord.content!,
|
||||
isSatisfied: foundMatch,
|
||||
category: pendingDnsRecord.type == 'A'
|
||||
? DnsRecordsCategory.services
|
||||
: DnsRecordsCategory.email,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
}
|
||||
return GenericResult(
|
||||
data: foundRecords,
|
||||
success: true,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void onChange(final Change<DnsRecordsState> change) {
|
||||
// print(change);
|
||||
|
|
|
@ -34,13 +34,17 @@ DnsRecord _toDnsRecord(
|
|||
String name = desecRecord.subname;
|
||||
int? priority;
|
||||
if (type == 'MX') {
|
||||
name = name.isEmpty ? '@' : name;
|
||||
name = name.isEmpty ? domainName : name;
|
||||
final contentBulk = content.split(' ');
|
||||
content = contentBulk[1];
|
||||
if (content.contains(domainName)) {
|
||||
content =
|
||||
content.substring(0, content.length - 1); // cut away trailing dot
|
||||
}
|
||||
priority = int.parse(contentBulk[0]);
|
||||
}
|
||||
if (type == 'TXT' && content.isNotEmpty && content.startsWith('"')) {
|
||||
content = content.substring(1, content.length); // cut away quotes
|
||||
content = content.substring(1, content.length - 1); // cut away quotes
|
||||
}
|
||||
if (name.isEmpty) {
|
||||
name = domainName;
|
||||
|
|
|
@ -27,9 +27,7 @@ DnsRecord _toDnsRecord(
|
|||
String convert(final String entry) => (entry == '@') ? rootDomain : entry;
|
||||
String name = digitalOceanRecord.name;
|
||||
final String content = convert(digitalOceanRecord.data);
|
||||
if (type != 'MX') {
|
||||
name = convert(name);
|
||||
}
|
||||
name = (name == '@') ? rootDomain : name;
|
||||
return DnsRecord(
|
||||
name: name,
|
||||
content: content,
|
||||
|
|
|
@ -9,6 +9,7 @@ class DnsRecord {
|
|||
required this.type,
|
||||
required this.name,
|
||||
required this.content,
|
||||
this.displayName,
|
||||
this.ttl = 3600,
|
||||
this.priority = 10,
|
||||
this.proxied = false,
|
||||
|
@ -19,12 +20,14 @@ class DnsRecord {
|
|||
) : this(
|
||||
type: record.recordType,
|
||||
name: record.name,
|
||||
displayName: record.displayName,
|
||||
content: record.content,
|
||||
ttl: record.ttl,
|
||||
priority: record.priority ?? 10,
|
||||
);
|
||||
|
||||
final String type;
|
||||
final String? displayName;
|
||||
final String? name;
|
||||
final String? content;
|
||||
final int ttl;
|
||||
|
|
|
@ -8,6 +8,7 @@ part of 'dns_records.dart';
|
|||
|
||||
Map<String, dynamic> _$DnsRecordToJson(DnsRecord instance) => <String, dynamic>{
|
||||
'type': instance.type,
|
||||
'displayName': instance.displayName,
|
||||
'name': instance.name,
|
||||
'content': instance.content,
|
||||
'ttl': instance.ttl,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/cloudflare/cloudflare_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/dns_providers/cloudflare_dns_info.dart';
|
||||
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
||||
|
@ -180,103 +179,6 @@ class CloudflareDnsProvider extends DnsProvider {
|
|||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GenericResult<List<DesiredDnsRecord>>> validateDnsRecords(
|
||||
final ServerDomain domain,
|
||||
final String ip4,
|
||||
final String dkimPublicKey,
|
||||
final List<DnsRecord> pendingDnsRecords,
|
||||
) async {
|
||||
final syncZoneIdResult = await syncZoneId(domain.domainName);
|
||||
if (!syncZoneIdResult.success) {
|
||||
return GenericResult(
|
||||
success: syncZoneIdResult.success,
|
||||
data: [],
|
||||
code: syncZoneIdResult.code,
|
||||
message: syncZoneIdResult.message,
|
||||
);
|
||||
}
|
||||
final result =
|
||||
await _adapter.api().getDnsRecords(zoneId: _adapter.cachedZoneId);
|
||||
if (result.data.isEmpty || !result.success) {
|
||||
return GenericResult(
|
||||
success: result.success,
|
||||
data: [],
|
||||
code: result.code,
|
||||
message: result.message,
|
||||
);
|
||||
}
|
||||
final records = result.data;
|
||||
final List<DesiredDnsRecord> foundRecords = [];
|
||||
try {
|
||||
for (final DnsRecord pendingDnsRecord in pendingDnsRecords) {
|
||||
final record = CloudflareDnsRecord.fromDnsRecord(
|
||||
pendingDnsRecord,
|
||||
domain.domainName,
|
||||
);
|
||||
if (record.name == 'selector._domainkey') {
|
||||
final CloudflareDnsRecord foundRecord = records.firstWhere(
|
||||
(final r) => (r.name == record.name) && r.type == record.type,
|
||||
orElse: () => CloudflareDnsRecord(
|
||||
zoneName: domain.domainName,
|
||||
name: record.name,
|
||||
type: record.type,
|
||||
content: '',
|
||||
ttl: 800,
|
||||
),
|
||||
);
|
||||
// remove all spaces and tabulators from
|
||||
// the foundRecord.content and the record.content
|
||||
// to compare them
|
||||
final String? foundContent =
|
||||
foundRecord.content?.replaceAll(RegExp(r'\s+'), '');
|
||||
final String content =
|
||||
record.content?.replaceAll(RegExp(r'\s+'), '') ?? '';
|
||||
foundRecords.add(
|
||||
DesiredDnsRecord(
|
||||
name: record.name ?? '',
|
||||
description: record.name?.split('.')[0] ?? '',
|
||||
content: record.content ?? '',
|
||||
isSatisfied: foundContent == content,
|
||||
type: record.type,
|
||||
category: DnsRecordsCategory.email,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
final foundMatch = records.any(
|
||||
(final r) =>
|
||||
(r.name == record.name) &&
|
||||
r.type == record.type &&
|
||||
r.content == record.content,
|
||||
);
|
||||
foundRecords.add(
|
||||
DesiredDnsRecord(
|
||||
name: record.name ?? '',
|
||||
description: record.name?.split('.')[0] ?? '',
|
||||
content: record.content ?? '',
|
||||
isSatisfied: foundMatch,
|
||||
type: record.type,
|
||||
category: record.type == 'A'
|
||||
? DnsRecordsCategory.services
|
||||
: DnsRecordsCategory.email,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
}
|
||||
return GenericResult(
|
||||
data: foundRecords,
|
||||
success: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> syncZoneId(final String domain) async {
|
||||
if (domain == _adapter.cachedDomain && _adapter.cachedZoneId.isNotEmpty) {
|
||||
return GenericResult(
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
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/dns_providers/desec_dns_info.dart';
|
||||
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
||||
|
@ -181,91 +180,4 @@ class DesecDnsProvider extends DnsProvider {
|
|||
data: null,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GenericResult<List<DesiredDnsRecord>>> validateDnsRecords(
|
||||
final ServerDomain domain,
|
||||
final String ip4,
|
||||
final String dkimPublicKey,
|
||||
final List<DnsRecord> pendingDnsRecords,
|
||||
) async {
|
||||
final result = await _adapter.api().getDnsRecords(domain.domainName);
|
||||
if (result.data.isEmpty || !result.success) {
|
||||
return GenericResult(
|
||||
success: result.success,
|
||||
data: [],
|
||||
code: result.code,
|
||||
message: result.message,
|
||||
);
|
||||
}
|
||||
|
||||
final records = result.data;
|
||||
final List<DesiredDnsRecord> foundRecords = [];
|
||||
try {
|
||||
for (final DnsRecord pendingDnsRecord in pendingDnsRecords) {
|
||||
final record = DesecDnsRecord.fromDnsRecord(
|
||||
pendingDnsRecord,
|
||||
domain.domainName,
|
||||
);
|
||||
if (record.subname == 'selector._domainkey') {
|
||||
final DesecDnsRecord foundRecord = records.firstWhere(
|
||||
(final r) =>
|
||||
('${r.subname}.${domain.domainName}' == record.subname) &&
|
||||
r.type == record.type,
|
||||
orElse: () => DesecDnsRecord(
|
||||
subname: record.subname,
|
||||
type: record.type,
|
||||
records: [],
|
||||
ttl: record.ttl,
|
||||
),
|
||||
);
|
||||
final desecRecords = foundRecord.records;
|
||||
final content = desecRecords.isEmpty ? '' : desecRecords[0];
|
||||
final String foundContent = content.replaceAll(RegExp(r'\s+'), '');
|
||||
final String desiredContent =
|
||||
record.records[0].replaceAll(RegExp(r'\s+'), '');
|
||||
foundRecords.add(
|
||||
DesiredDnsRecord(
|
||||
name: '${record.subname}.${domain.domainName}',
|
||||
description:
|
||||
record.subname.isEmpty ? record.subname : domain.domainName,
|
||||
content: record.records[0],
|
||||
isSatisfied: foundContent == desiredContent,
|
||||
type: record.type,
|
||||
category: DnsRecordsCategory.email,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
final foundMatch = records.any(
|
||||
(final r) =>
|
||||
r.subname == record.subname &&
|
||||
r.type == record.type &&
|
||||
r.records[0] == record.records[0],
|
||||
);
|
||||
foundRecords.add(
|
||||
DesiredDnsRecord(
|
||||
name: '${record.subname}.${domain.domainName}',
|
||||
description: record.subname,
|
||||
content: record.records[0],
|
||||
isSatisfied: foundMatch,
|
||||
category: record.type == 'A'
|
||||
? DnsRecordsCategory.services
|
||||
: DnsRecordsCategory.email,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
}
|
||||
return GenericResult(
|
||||
data: foundRecords,
|
||||
success: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/desired_dns_record.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/digital_ocean_dns/digital_ocean_dns_api.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/json/dns_providers/digital_ocean_dns_info.dart';
|
||||
|
@ -157,90 +156,4 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
|||
),
|
||||
],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<GenericResult<List<DesiredDnsRecord>>> validateDnsRecords(
|
||||
final ServerDomain domain,
|
||||
final String ip4,
|
||||
final String dkimPublicKey,
|
||||
final List<DnsRecord> pendingDnsRecords,
|
||||
) async {
|
||||
final result = await _adapter.api().getDnsRecords(domain.domainName);
|
||||
if (result.data.isEmpty || !result.success) {
|
||||
return GenericResult(
|
||||
success: result.success,
|
||||
data: [],
|
||||
code: result.code,
|
||||
message: result.message,
|
||||
);
|
||||
}
|
||||
final records = result.data;
|
||||
final List<DesiredDnsRecord> foundRecords = [];
|
||||
try {
|
||||
for (final DnsRecord pendingDnsRecord in pendingDnsRecords) {
|
||||
final record = DigitalOceanDnsRecord.fromDnsRecord(
|
||||
pendingDnsRecord,
|
||||
domain.domainName,
|
||||
);
|
||||
if (record.name == 'selector._domainkey') {
|
||||
final DigitalOceanDnsRecord foundRecord = records.firstWhere(
|
||||
(final r) => (r.name == record.name) && r.type == record.type,
|
||||
orElse: () => DigitalOceanDnsRecord(
|
||||
id: null,
|
||||
name: record.name,
|
||||
type: record.type,
|
||||
data: '',
|
||||
ttl: 800,
|
||||
),
|
||||
);
|
||||
// remove all spaces and tabulators from
|
||||
// the foundRecord.content and the record.content
|
||||
// to compare them
|
||||
final String foundContent =
|
||||
foundRecord.data.replaceAll(RegExp(r'\s+'), '');
|
||||
final String content = record.data.replaceAll(RegExp(r'\s+'), '');
|
||||
foundRecords.add(
|
||||
DesiredDnsRecord(
|
||||
name: record.name,
|
||||
description: record.name == '@' ? domain.domainName : record.name,
|
||||
content: record.data,
|
||||
isSatisfied: foundContent == content,
|
||||
type: record.type,
|
||||
category: DnsRecordsCategory.email,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
final foundMatch = records.any(
|
||||
(final r) =>
|
||||
r.name == record.name &&
|
||||
r.type == record.type &&
|
||||
r.data == record.data,
|
||||
);
|
||||
foundRecords.add(
|
||||
DesiredDnsRecord(
|
||||
name: record.name,
|
||||
description: record.name == '@' ? domain.domainName : record.name,
|
||||
content: record.data,
|
||||
isSatisfied: foundMatch,
|
||||
type: record.type,
|
||||
category: record.type == 'A'
|
||||
? DnsRecordsCategory.services
|
||||
: DnsRecordsCategory.email,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
}
|
||||
return GenericResult(
|
||||
data: foundRecords,
|
||||
success: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:selfprivacy/logic/api_maps/generic_result.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/dns_records.dart';
|
||||
export 'package:selfprivacy/logic/api_maps/generic_result.dart';
|
||||
|
@ -57,17 +56,4 @@ abstract class DnsProvider {
|
|||
final DnsRecord record,
|
||||
final ServerDomain domain,
|
||||
);
|
||||
|
||||
/// Tries to check whether all known DNS records on the domain by ip4
|
||||
/// match expectations of SelfPrivacy in order to launch.
|
||||
///
|
||||
/// Will return list of [DesiredDnsRecord] objects, which represent
|
||||
/// only those records which have successfully passed validation.
|
||||
/// TODO: Unify across DNS providers
|
||||
Future<GenericResult<List<DesiredDnsRecord>>> validateDnsRecords(
|
||||
final ServerDomain domain,
|
||||
final String ip4,
|
||||
final String dkimPublicKey,
|
||||
final List<DnsRecord> pendingDnsRecords,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -151,10 +151,8 @@ class _DnsDetailsPageState extends State<DnsDetailsPage> {
|
|||
? neutralColor
|
||||
: errorColor,
|
||||
),
|
||||
title: Text(dnsRecord.description),
|
||||
subtitle: Text(
|
||||
dnsRecord.displayName ?? dnsRecord.name,
|
||||
),
|
||||
title: Text(dnsRecord.displayName ?? dnsRecord.name),
|
||||
subtitle: Text(dnsRecord.content),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -193,9 +191,8 @@ class _DnsDetailsPageState extends State<DnsDetailsPage> {
|
|||
? neutralColor
|
||||
: errorColor,
|
||||
),
|
||||
title: Text(
|
||||
dnsRecord.description,
|
||||
),
|
||||
title: Text(dnsRecord.displayName ?? dnsRecord.name),
|
||||
subtitle: Text(dnsRecord.name),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue