123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- import z from "zod";
- export function isValidCIDR(cidr: string): boolean {
- return z.string().cidr().safeParse(cidr).success;
- }
- export function isValidIP(ip: string): boolean {
- return z.string().ip().safeParse(ip).success;
- }
- export function isValidUrlGlobPattern(pattern: string): boolean {
- // Remove leading slash if present
- pattern = pattern.startsWith("/") ? pattern.slice(1) : pattern;
- // Empty string is not valid
- if (!pattern) {
- return false;
- }
- // Split path into segments
- const segments = pattern.split("/");
- // Check each segment
- for (let i = 0; i < segments.length; i++) {
- const segment = segments[i];
- // Empty segments are not allowed (double slashes), except at the end
- if (!segment && i !== segments.length - 1) {
- return false;
- }
- // If segment contains *, it must be exactly *
- if (segment.includes("*") && segment !== "*") {
- return false;
- }
- // Check each character in the segment
- for (let j = 0; j < segment.length; j++) {
- const char = segment[j];
- // Check for percent-encoded sequences
- if (char === "%" && j + 2 < segment.length) {
- const hex1 = segment[j + 1];
- const hex2 = segment[j + 2];
- if (
- !/^[0-9A-Fa-f]$/.test(hex1) ||
- !/^[0-9A-Fa-f]$/.test(hex2)
- ) {
- return false;
- }
- j += 2; // Skip the next two characters
- continue;
- }
- // Allow:
- // - unreserved (A-Z a-z 0-9 - . _ ~)
- // - sub-delims (! $ & ' ( ) * + , ; =)
- // - @ : for compatibility with some systems
- if (!/^[A-Za-z0-9\-._~!$&'()*+,;=@:]$/.test(char)) {
- return false;
- }
- }
- }
- return true;
- }
- export function isUrlValid(url: string | undefined) {
- if (!url) return true; // the link is optional in the schema so if it's empty it's valid
- var pattern = new RegExp(
- "^(https?:\\/\\/)?" + // protocol
- "((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name
- "((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address
- "(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // port and path
- "(\\?[;&a-z\\d%_.~+=-]*)?" + // query string
- "(\\#[-a-z\\d_]*)?$",
- "i"
- );
- return !!pattern.test(url);
- }
- export function isTargetValid(value: string | undefined) {
- if (!value) return true;
- const DOMAIN_REGEX =
- /^[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_])?)*$/;
- const IPV4_REGEX =
- /^(?:(?: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]?)$/;
- const IPV6_REGEX = /^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$/i;
- if (IPV4_REGEX.test(value) || IPV6_REGEX.test(value)) {
- return true;
- }
- return DOMAIN_REGEX.test(value);
- }
|