From b71328a0e448043c360fd89fe5a93450badf46e2 Mon Sep 17 00:00:00 2001 From: dab246 Date: Fri, 10 Nov 2023 10:46:15 +0700 Subject: [PATCH] TF-2271 Add DNService for dns lookup to catch SRV Record to get jmap url (cherry picked from commit 49110aa8db8b4e0707127ae39d5b2db2ecd6e339) --- .../login/data/network/dns_service.dart | 65 +++++++++++++++++++ .../domain/exceptions/login_exception.dart | 4 ++ pubspec.lock | 17 +++++ pubspec.yaml | 5 ++ 4 files changed, 91 insertions(+) create mode 100644 lib/features/login/data/network/dns_service.dart create mode 100644 lib/features/login/domain/exceptions/login_exception.dart diff --git a/lib/features/login/data/network/dns_service.dart b/lib/features/login/data/network/dns_service.dart new file mode 100644 index 000000000..7b33ebbd5 --- /dev/null +++ b/lib/features/login/data/network/dns_service.dart @@ -0,0 +1,65 @@ + +import 'package:core/utils/app_logger.dart'; +import 'package:dns_client/dns_client.dart'; +import 'package:tmail_ui_user/features/login/domain/exceptions/login_exception.dart'; + +class DNSService { + static const String _jmapServiceName = '_jmap._tcp'; + + Future _dnsLookupToUrlFromSRVType({required String hostName}) async { + try { + final url = await _dnsLookupToUrlByGoogle(hostName: hostName); + if (url.isEmpty) { + return await _dnsLookupToUrlByCloudflare(hostName: hostName); + } + return url; + } catch (e) { + return await _dnsLookupToUrlByCloudflare(hostName: hostName); + } + } + + Future _dnsLookupToUrlByGoogle({required String hostName}) async { + final dns = DnsOverHttps.google(); + final listData = await dns.lookupDataByRRType(hostName, RRType.SRVType); + if (listData.isEmpty) { + throw NotFoundDataResourceRecordException(); + } + return _parsingUrlFromDataResourceRecord(listData.first); + } + + Future _dnsLookupToUrlByCloudflare({required String hostName}) async { + final dns = DnsOverHttps.cloudflare(); + final listData = await dns.lookupDataByRRType(hostName, RRType.SRVType); + if (listData.isEmpty) { + throw NotFoundDataResourceRecordException(); + } + return _parsingUrlFromDataResourceRecord(listData.first); + } + + String _parsingUrlFromDataResourceRecord(String data) { + if (data.isEmpty) { + throw NotFoundDataResourceRecordException(); + } + final listFieldData = data.split(' '); + if (listFieldData.isEmpty) { + throw NotFoundUrlException(); + } + final url = _removeDotAtEndOfString(listFieldData.last); + log('DNSService::_parsingUrlFromDataResourceRecord:url: $url'); + return url; + } + + Future getJmapUrl(String emailAddress) async { + final domainName = emailAddress.split('@')[1]; + final jmapHostName = '$_jmapServiceName.$domainName'; + log('DNSHandler::getJmapUrl:jmapHostName: $jmapHostName'); + return await _dnsLookupToUrlFromSRVType(hostName: jmapHostName); + } + + String _removeDotAtEndOfString(String value) { + if (value.lastIndexOf('.') == value.length - 1) { + return value.substring(0, value.length - 1); + } + return value; + } +} diff --git a/lib/features/login/domain/exceptions/login_exception.dart b/lib/features/login/domain/exceptions/login_exception.dart new file mode 100644 index 000000000..665f20c1a --- /dev/null +++ b/lib/features/login/domain/exceptions/login_exception.dart @@ -0,0 +1,4 @@ + +class NotFoundDataResourceRecordException implements Exception {} + +class NotFoundUrlException implements Exception {} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 2f6325165..75979938b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -360,6 +360,15 @@ packages: url: "https://pub.dev" source: hosted version: "5.0.0" + dns_client: + dependency: "direct main" + description: + path: "." + ref: twake-supported + resolved-ref: "0ba4d48f287d408c70612dfc8bacc5ba11cd421b" + url: "https://github.com/dab246/dns_client.git" + source: git + version: "0.2.1" dotted_border: dependency: "direct main" description: @@ -861,6 +870,14 @@ packages: relative: true source: path version: "1.0.0+1" + freezed_annotation: + dependency: transitive + description: + name: freezed_annotation + sha256: "1be037f901137bf2b9a0c309e9bf2694d6ec77687645211218191ade4f41a4b8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" frontend_server_client: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 346277816..49be1beb6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -86,6 +86,11 @@ dependencies: url: https://github.com/dab246/super_tag_editor.git ref: master + dns_client: + git: + url: https://github.com/dab246/dns_client.git + ref: twake-supported + ### Dependencies from pub.dev ### cupertino_icons: 1.0.5