158 lines
4.5 KiB
TypeScript
158 lines
4.5 KiB
TypeScript
/**
|
|
* Utility functions for validating IP addresses and CIDR notation
|
|
*/
|
|
import { Address4, Address6 } from 'ip-address';
|
|
import isCidr from 'is-cidr';
|
|
|
|
/**
|
|
* Validates an IPv4 address
|
|
* @param ip The IP address to validate
|
|
* @returns True if the IP is valid, false otherwise
|
|
*/
|
|
export const isValidIPv4 = (ip: string): boolean => {
|
|
try {
|
|
return new Address4(ip).isValid();
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Validates an IPv6 address
|
|
* @param ip The IP address to validate
|
|
* @returns True if the IP is valid, false otherwise
|
|
*/
|
|
export const isValidIPv6 = (ip: string): boolean => {
|
|
try {
|
|
return new Address6(ip).isValid();
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Validates an IP address (IPv4 or IPv6)
|
|
* @param ip The IP address to validate
|
|
* @returns True if the IP is valid, false otherwise
|
|
*/
|
|
export const isValidIP = (ip: string): boolean => {
|
|
return isValidIPv4(ip) || isValidIPv6(ip);
|
|
};
|
|
|
|
/**
|
|
* Validates a CIDR notation
|
|
* @param cidr The CIDR notation to validate
|
|
* @returns True if the CIDR is valid, false otherwise
|
|
*/
|
|
export const isValidCIDR = (cidr: string): boolean => {
|
|
return isCidr(cidr) !== 0;
|
|
};
|
|
|
|
/**
|
|
* Validates a port or port range
|
|
* @param port The port or port range to validate
|
|
* @returns True if the port is valid, false otherwise
|
|
*/
|
|
export const isValidPort = (port: string): boolean => {
|
|
// If port is wildcard, it's valid
|
|
if (port === '*') return true;
|
|
|
|
// Check for a single port
|
|
if (/^\d+$/.test(port)) {
|
|
const portNum = parseInt(port, 10);
|
|
return portNum >= 1 && portNum <= 65535;
|
|
}
|
|
|
|
// Check for a port range (e.g., 1000-2000)
|
|
if (/^\d+-\d+$/.test(port)) {
|
|
const [startStr, endStr] = port.split('-');
|
|
const start = parseInt(startStr, 10);
|
|
const end = parseInt(endStr, 10);
|
|
|
|
return (
|
|
start >= 1 &&
|
|
start <= 65535 &&
|
|
end >= 1 &&
|
|
end <= 65535 &&
|
|
start <= end
|
|
);
|
|
}
|
|
|
|
// Check for multiple ports (e.g., 80,443)
|
|
if (/^\d+(,\d+)*$/.test(port)) {
|
|
const ports = port.split(',');
|
|
return ports.every(p => {
|
|
const portNum = parseInt(p, 10);
|
|
return portNum >= 1 && portNum <= 65535;
|
|
});
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Validates an email address
|
|
* @param email The email address to validate
|
|
* @returns True if the email is valid, false otherwise
|
|
*/
|
|
export const isValidEmail = (email: string): boolean => {
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
return emailRegex.test(email);
|
|
};
|
|
|
|
/**
|
|
* Validates a hostname
|
|
* @param hostname The hostname to validate
|
|
* @returns True if the hostname is valid, false otherwise
|
|
*/
|
|
export const isValidHostname = (hostname: string): boolean => {
|
|
// Simplified hostname validation
|
|
const hostnameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
return hostnameRegex.test(hostname);
|
|
};
|
|
|
|
/**
|
|
* Validates a source value based on its type
|
|
* @param type The source type
|
|
* @param value The source value
|
|
* @returns True if the value is valid for the given type, false otherwise
|
|
*/
|
|
export const isValidSourceValue = (type: string, value: string): boolean => {
|
|
if (type === 'any' && value === '*') return true;
|
|
if (type === 'user') return isValidEmail(value);
|
|
if (type === 'group') return value.startsWith('group:') && value.length > 6;
|
|
if (type === 'ip') return isValidIP(value);
|
|
if (type === 'subnet') return isValidCIDR(value);
|
|
if (type === 'host') return isValidHostname(value);
|
|
if (type === 'tag') return value.startsWith('tag:') && value.length > 4;
|
|
if (type === 'autogroup') return value.startsWith('autogroup:') && value.length > 10;
|
|
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Validates a destination value based on its type
|
|
* @param type The destination type
|
|
* @param value The destination value
|
|
* @param port The port value
|
|
* @returns True if the value and port are valid for the given type, false otherwise
|
|
*/
|
|
export const isValidDestinationValue = (
|
|
type: string,
|
|
value: string,
|
|
port: string
|
|
): boolean => {
|
|
if (!isValidPort(port)) return false;
|
|
|
|
if (type === 'any' && value === '*') return true;
|
|
if (type === 'user') return isValidEmail(value);
|
|
if (type === 'group') return value.startsWith('group:') && value.length > 6;
|
|
if (type === 'ip') return isValidIP(value);
|
|
if (type === 'subnet') return isValidCIDR(value);
|
|
if (type === 'host') return isValidHostname(value);
|
|
if (type === 'tag') return value.startsWith('tag:') && value.length > 4;
|
|
if (type === 'autogroup') return value.startsWith('autogroup:') && value.length > 10;
|
|
|
|
return false;
|
|
};
|