Skip to content

Commit 815024f

Browse files
Merge pull request #304 from community-scripts/fix/275
fix: support IPv6 link-local addresses with zone identifiers
2 parents 09868ba + 03fd7bd commit 815024f

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

src/app/_components/ServerForm.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,26 @@ export function ServerForm({ onSubmit, initialData, isEditing = false, onCancel
6363
return true;
6464
}
6565

66+
// Check for IPv6 with zone identifier (link-local addresses like fe80::...%eth0)
67+
let ipv6Address = trimmed;
68+
const zoneIdMatch = trimmed.match(/^(.+)%([a-zA-Z0-9_\-]+)$/);
69+
if (zoneIdMatch) {
70+
ipv6Address = zoneIdMatch[1];
71+
// Zone identifier should be a valid interface name (alphanumeric, underscore, hyphen)
72+
const zoneId = zoneIdMatch[2];
73+
if (!/^[a-zA-Z0-9_\-]+$/.test(zoneId)) {
74+
return false;
75+
}
76+
}
77+
6678
// IPv6 validation (supports compressed format like ::1 and full format)
6779
// Matches: 2001:0db8:85a3:0000:0000:8a2e:0370:7334, ::1, 2001:db8::1, etc.
6880
// Also supports IPv4-mapped IPv6 addresses like ::ffff:192.168.1.1
6981
// Simplified validation: check for valid hex segments separated by colons
7082
const ipv6Pattern = /^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^::1$|^::$|^(?:[0-9a-fA-F]{1,4}:)*::(?:[0-9a-fA-F]{1,4}:)*[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:)*::[0-9a-fA-F]{1,4}$|^::(?:[0-9a-fA-F]{1,4}:)+[0-9a-fA-F]{1,4}$|^::ffff:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
71-
if (ipv6Pattern.test(trimmed)) {
83+
if (ipv6Pattern.test(ipv6Address)) {
7284
// Additional validation: ensure only one :: compression exists
73-
const compressionCount = (trimmed.match(/::/g) || []).length;
85+
const compressionCount = (ipv6Address.match(/::/g) || []).length;
7486
if (compressionCount <= 1) {
7587
return true;
7688
}
@@ -273,7 +285,7 @@ export function ServerForm({ onSubmit, initialData, isEditing = false, onCancel
273285
className={`w-full px-3 py-2 border rounded-md shadow-sm bg-card text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:border-ring ${
274286
errors.ip ? 'border-destructive' : 'border-border'
275287
}`}
276-
placeholder="e.g., 192.168.1.100, server.example.com, or 2001:db8::1"
288+
placeholder="e.g., 192.168.1.100, server.example.com, 2001:db8::1, or fe80::...%eth0"
277289
/>
278290
{errors.ip && <p className="mt-1 text-sm text-destructive">{errors.ip}</p>}
279291
</div>

0 commit comments

Comments
 (0)