Skip to content

Commit ab6e2b1

Browse files
fix: Migrate missing fixes from dev-1.2.7 (#619)
* fix: Migrate missing fixes from dev-1.2.7 NOW-713: Update OpenDNS Family Shield IPs - Changed from 208.67.222.123/208.67.220.123 to 208.67.222.222/208.67.220.220 - Updated service, test data, and test assertions QUALITY-439: Allow /31 subnet masks for WAN Static IP - Added max: 31 parameter to SubnetMaskValidator in: - internet_settings_form_validator.dart - pnp_static_ip_view.dart Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Address Qodo review feedback - Add /31 subnet mask tests for QUALITY-439 - Test validates /31 mask (255.255.255.254) accepted with max: 31 - Test validates /31 mask rejected with default max (30) - Update spec documents with new OpenDNS IPs (NOW-713) - spec.md: Update assumptions section - contracts/instant_safety_service_contract.md: Update DNS constants and examples Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b1a1880 commit ab6e2b1

8 files changed

Lines changed: 32 additions & 14 deletions

File tree

lib/page/advanced_settings/internet_settings/utils/internet_settings_form_validator.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ class InternetSettingsFormValidator {
4343
if (value == null || value.isEmpty) {
4444
return ValidationError.invalidSubnetMask;
4545
}
46-
final subnetMaskValidator = SubnetMaskValidator();
46+
// QUALITY-439: Override default max (30) to allow /31 subnet masks for WAN Static IP
47+
final subnetMaskValidator = SubnetMaskValidator(max: 31);
4748
if (subnetMaskValidator.validate(value)) {
4849
return null;
4950
} else {

lib/page/instant_safety/services/instant_safety_service.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ class InstantSafetyService {
4949

5050
// DNS Configuration Constants
5151
static const _fortinetDns1 = '208.91.114.155';
52-
static const _openDnsDns1 = '208.67.222.123';
53-
static const _openDnsDns2 = '208.67.220.123';
52+
// NOW-713: Updated OpenDNS Family Shield IPs
53+
static const _openDnsDns1 = '208.67.222.222';
54+
static const _openDnsDns2 = '208.67.220.220';
5455

5556
/// Fetches current safe browsing configuration from router.
5657
///

lib/page/instant_setup/troubleshooter/views/isp_settings/pnp_static_ip_view.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class _PnpStaticIpViewState extends ConsumerState<PnpStaticIpView> {
3434
var _hasExtraDNS = false;
3535
bool _isLoading = false;
3636

37-
final subnetMaskValidator = SubnetMaskValidator();
37+
// QUALITY-439: Override default max (30) to allow /31 subnet masks for WAN Static IP
38+
final subnetMaskValidator = SubnetMaskValidator(max: 31);
3839
final ipAddressValidator = IpAddressValidator();
3940
final requiredIpAddressValidator = IpAddressRequiredValidator();
4041
String? _ipError;

specs/009-instant-safety-service/contracts/instant_safety_service_contract.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ Future<void> saveSettings(InstantSafetyType safeBrowsingType) async
125125
1. Validates cached LAN settings exist (throws `InvalidInputError` if not)
126126
2. Constructs DHCP settings with appropriate DNS servers based on type:
127127
- `fortinet`: DNS1=208.91.114.155
128-
- `openDNS`: DNS1=208.67.222.123, DNS2=208.67.220.123
128+
- `openDNS`: DNS1=208.67.222.222, DNS2=208.67.220.220
129129
- `off`: Clear all DNS servers
130130
3. Calls `setLANSettings` JNAP action
131131
4. Allows `JNAPSideEffectError` to propagate (handled by UI layer)
@@ -191,7 +191,7 @@ InstantSafetyType _determineSafeBrowsingType(RouterLANSettings lanSettings)
191191
final dnsServer1 = lanSettings.dhcpSettings.dnsServer1;
192192
if (dnsServer1 == '208.91.114.155') {
193193
return InstantSafetyType.fortinet;
194-
} else if (dnsServer1 == '208.67.222.123') {
194+
} else if (dnsServer1 == '208.67.222.222') {
195195
return InstantSafetyType.openDNS;
196196
} else {
197197
return InstantSafetyType.off;
@@ -225,9 +225,9 @@ Private constants within service:
225225
// Fortinet Safe Browsing DNS
226226
static const _fortinetDns1 = '208.91.114.155';
227227
228-
// OpenDNS Family Shield
229-
static const _openDnsDns1 = '208.67.222.123';
230-
static const _openDnsDns2 = '208.67.220.123';
228+
// OpenDNS Family Shield (NOW-713: Updated IPs)
229+
static const _openDnsDns1 = '208.67.222.222';
230+
static const _openDnsDns2 = '208.67.220.220';
231231
```
232232

233233
---

specs/009-instant-safety-service/spec.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,6 @@ The system determines whether the router hardware/firmware supports Fortinet saf
115115
## Assumptions
116116

117117
- The existing `PreservableNotifierMixin` pattern will continue to be used for dirty state management
118-
- DNS server IP addresses for Fortinet (208.91.114.155) and OpenDNS (208.67.222.123, 208.67.220.123) are fixed and do not require configuration
118+
- DNS server IP addresses for Fortinet (208.91.114.155) and OpenDNS Family Shield (208.67.222.222, 208.67.220.220) are fixed and do not require configuration
119119
- The compatibility map for Fortinet support (currently empty) will remain managed within the service layer
120120
- The InstantSafety feature currently has no unit tests, so new tests will be created from scratch

test/mocks/test_data/instant_safety_test_data.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import 'package:privacy_gui/core/jnap/result/jnap_result.dart';
77
class InstantSafetyTestData {
88
// DNS Configuration Constants (matching service)
99
static const fortinetDns1 = '208.91.114.155';
10-
static const openDnsDns1 = '208.67.222.123';
11-
static const openDnsDns2 = '208.67.220.123';
10+
// NOW-713: Updated OpenDNS Family Shield IPs
11+
static const openDnsDns1 = '208.67.222.222';
12+
static const openDnsDns2 = '208.67.220.220';
1213

1314
/// Create default LAN settings response with no safe browsing configured
1415
static JNAPSuccess createLANSettingsSuccess({

test/page/instant_safety/services/instant_safety_service_test.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,9 @@ void main() {
224224

225225
final data = captured.first as Map<String, dynamic>;
226226
final dhcpSettings = data['dhcpSettings'] as Map<String, dynamic>;
227-
expect(dhcpSettings['dnsServer1'], '208.67.222.123');
228-
expect(dhcpSettings['dnsServer2'], '208.67.220.123');
227+
// NOW-713: Updated OpenDNS Family Shield IPs
228+
expect(dhcpSettings['dnsServer1'], '208.67.222.222');
229+
expect(dhcpSettings['dnsServer2'], '208.67.220.220');
229230
});
230231

231232
test('with off clears DNS servers', () async {

test/validator_rules/input_validators_test.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,19 @@ void main() {
378378
expect(validator.validate(invalidMask2), false);
379379
});
380380

381+
// QUALITY-439: Test /31 subnet mask support for WAN Static IP
382+
test('validate method - /31 subnet mask with max: 31', () {
383+
final validator = SubnetMaskValidator(max: 31);
384+
const mask31 = '255.255.255.254'; // /31 subnet mask
385+
expect(validator.validate(mask31), true);
386+
});
387+
388+
test('validate method - /31 subnet mask rejected with default max', () {
389+
final validator = SubnetMaskValidator(); // default max is 30
390+
const mask31 = '255.255.255.254'; // /31 subnet mask
391+
expect(validator.validate(mask31), false);
392+
});
393+
381394
test('validate method - invalid subnet mask (leading whitespace)', () {
382395
final validator = SubnetMaskValidator();
383396
const invalidMask = ' 255.255.255.128';

0 commit comments

Comments
 (0)