feat(editor): F4.5d the firewall in the device sheet
Measured first: SheetRun drives FILIUS' firewall dialog down to its table editor (Swing's own end of an edit). Java's table writes a cell into the rule before it checks it, so that the firewall holds "abc", a mask of 255.0.255.0 or port 0 while the table shows the old value, and reads a port that is no number as all ports. Here nothing the check refuses reaches the rule. - doc: the three switches, the default action, rules (new as Java's, cells by Java's checks: masks of ones then zeros, the directly connected marker as a source only, an empty port for all ports; protocol, action, moved up or down, removed) - editor: the firewall as a page of the router's and home router's sheet, with Java's explanations; the general tab named so (Java: "network interfaces") Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -18,9 +18,23 @@
|
||||
// " 10.0.0.1"; a phone's keyboard puts a space after a word). A name and an
|
||||
// SSID are taken as typed, spaces included, as Java takes them.
|
||||
|
||||
import { IP_ADDRESS_PATTERN, javaIpCheck } from '@mdg-filius/core';
|
||||
import { DIRECTLY_CONNECTED_SOURCE_MARKER, IP_ADDRESS_PATTERN, javaIpCheck, parseIPv4 } from '@mdg-filius/core';
|
||||
|
||||
export type FieldRule = 'name' | 'ipAddress' | 'ipAddressOrEmpty' | 'subnetMask' | 'ssid' | 'seconds' | 'port' | 'macAddress';
|
||||
export type FieldRule =
|
||||
| 'name'
|
||||
| 'ipAddress'
|
||||
| 'ipAddressOrEmpty'
|
||||
| 'subnetMask'
|
||||
| 'ssid'
|
||||
| 'seconds'
|
||||
| 'port'
|
||||
| 'macAddress'
|
||||
/** A firewall rule's source: empty, an address, or Java's marker for "a directly connected network". */
|
||||
| 'firewallSource'
|
||||
/** A firewall rule's mask: empty, or ones then zeros (EingabenUeberpruefung.isValidSubnetmask). */
|
||||
| 'firewallMask'
|
||||
/** A firewall rule's port: empty for all ports, or musterPort. */
|
||||
| 'portOrEmpty';
|
||||
|
||||
/** What a field's text comes to: the value the device takes, or that it takes none. */
|
||||
export type CheckedField = { readonly value: string } | { readonly invalid: true };
|
||||
@@ -71,6 +85,18 @@ export function checkField(rule: FieldRule, text: string): CheckedField {
|
||||
}
|
||||
case 'port':
|
||||
return PORT_PATTERN.test(text.trim()) ? { value: text.trim() } : INVALID;
|
||||
case 'firewallSource':
|
||||
if (text.trim() === DIRECTLY_CONNECTED_SOURCE_MARKER) return { value: DIRECTLY_CONNECTED_SOURCE_MARKER };
|
||||
return checkField('ipAddressOrEmpty', text);
|
||||
case 'firewallMask': {
|
||||
if (text.trim() === '') return { value: '' };
|
||||
const checked = address(text.trim(), SUBNET_MASK_PATTERN);
|
||||
if ('invalid' in checked) return checked;
|
||||
// Ones, then zeros, at least one one (Java: the 32 bits match "^11*0*$").
|
||||
return /^1+0*$/.test(parseIPv4(checked.value)!.toString(2).padStart(32, '0')) ? checked : INVALID;
|
||||
}
|
||||
case 'portOrEmpty':
|
||||
return text.trim() === '' ? { value: '' } : checkField('port', text);
|
||||
case 'macAddress':
|
||||
// Upper case, as the model keeps MAC addresses (Java keeps them as typed and compares ignoring case).
|
||||
return MAC_ADDRESS_PATTERN.test(text.trim()) ? { value: text.trim().toUpperCase() } : INVALID;
|
||||
|
||||
Reference in New Issue
Block a user