diff --git a/lib/core/utils/ip_utils.dart b/lib/core/utils/ip_utils.dart new file mode 100644 index 00000000..d7c9e1f5 --- /dev/null +++ b/lib/core/utils/ip_utils.dart @@ -0,0 +1,18 @@ +const String fallbackObscuredAddress = "*.*.*.*"; + +String obscureIp(String ip) { + try { + if (ip.contains(".")) { + final splits = ip.split("."); + return "${splits.first}.*.*.${splits.last}"; + } else if (ip.contains(":")) { + final splits = ip.split(":"); + return [ + splits.first, + ...splits.sublist(1).map((part) => "*" * part.length), + ].join(":"); + } + // ignore: empty_catches + } catch (e) {} + return fallbackObscuredAddress; +} diff --git a/lib/features/proxy/active/ip_widget.dart b/lib/features/proxy/active/ip_widget.dart index a1e88ee1..07f6fb17 100644 --- a/lib/features/proxy/active/ip_widget.dart +++ b/lib/features/proxy/active/ip_widget.dart @@ -1,7 +1,7 @@ import 'package:circle_flags/circle_flags.dart'; -import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:hiddify/core/localization/translations.dart'; +import 'package:hiddify/core/utils/ip_utils.dart'; import 'package:hiddify/utils/riverpod_utils.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -49,7 +49,7 @@ class IPText extends HookConsumerWidget { ? EdgeInsets.zero : const EdgeInsetsDirectional.only(end: 48), child: Text( - "*.*.*.*", + obscureIp(ip), semanticsLabel: t.general.hidden, style: constrained ? textTheme.labelMedium : textTheme.labelLarge, @@ -76,31 +76,14 @@ class IPCountryFlag extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final t = ref.watch(translationsProvider); - final isVisible = ref.watch(_showIp); return Semantics( label: t.proxies.ipInfoSemantics.country, - child: InkWell( - onTap: () { - ref.read(_showIp.notifier).state = !isVisible; - }, - borderRadius: BorderRadius.circular(12), - child: Container( - width: size, - height: size, - padding: const EdgeInsets.all(2), - child: Center( - child: AnimatedCrossFade( - firstChild: CircleFlag(countryCode), - secondChild: - Icon(FluentIcons.eye_off_24_regular, size: size * .8), - crossFadeState: isVisible - ? CrossFadeState.showFirst - : CrossFadeState.showSecond, - duration: const Duration(milliseconds: 200), - ), - ), - ), + child: Container( + width: size, + height: size, + padding: const EdgeInsets.all(2), + child: Center(child: CircleFlag(countryCode)), ), ); } diff --git a/test/core/utils/ip_utils_test.dart b/test/core/utils/ip_utils_test.dart new file mode 100644 index 00000000..d0211d5f --- /dev/null +++ b/test/core/utils/ip_utils_test.dart @@ -0,0 +1,36 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:hiddify/core/utils/ip_utils.dart'; + +void main() { + group( + "obscureIp", + () { + test( + "Should pass given valid IPV4", + () { + const ipv4 = "1.1.1.1"; + final obscured = obscureIp(ipv4); + expect(obscured, "1.*.*.1"); + }, + ); + + test( + "Should pass given valid full IPV6", + () { + const ipv6 = "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210"; + final obscured = obscureIp(ipv6); + expect(obscured, "FEDC:****:****:****:****:****:****:****"); + }, + ); + + test( + "Should pass given valid IPV6", + () { + const ipv6 = "::1"; + final obscured = obscureIp(ipv6); + expect(obscured, "::*"); + }, + ); + }, + ); +}