| Server IP : 159.203.156.69 / Your IP : 216.73.217.172 Web Server : nginx/1.24.0 System : Linux main-ubuntu 6.8.0-71-generic #71-Ubuntu SMP PREEMPT_DYNAMIC Tue Jul 22 16:52:38 UTC 2025 x86_64 User : root ( 0) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/tanviranik.com/node_modules/vinext/dist/shims/ |
Upload File : |
{"version":3,"file":"image-config.js","names":[],"sources":["../../src/shims/image-config.ts"],"sourcesContent":["import ipaddr from \"ipaddr.js\";\n\n/**\n * Image remote pattern validation.\n *\n * Validates remote image URLs against the `images.remotePatterns` and\n * `images.domains` config from next.config.js. This prevents SSRF and\n * open-redirect attacks by blocking URLs that don't match any configured\n * pattern.\n *\n * Pattern matching follows Next.js semantics:\n * - `*` matches a single segment (subdomain in hostname, path segment in pathname)\n * - `**` matches any number of segments\n * - protocol, port, and search are matched exactly when specified\n */\n\nexport type RemotePattern = {\n protocol?: string;\n hostname: string;\n port?: string;\n pathname?: string;\n search?: string;\n};\n\n/**\n * Convert a glob pattern (with `*` and `**`) to a RegExp.\n *\n * For hostnames, segments are separated by `.`:\n * - `*` matches a single segment (no dots): [^.]+\n * - `**` matches any number of segments: .+\n *\n * For pathnames, segments are separated by `/`:\n * - `*` matches a single segment (no slashes): [^/]+\n * - `**` matches any number of segments (including empty): .*\n *\n * Literal characters are escaped for regex safety.\n */\nfunction globToRegex(pattern: string, separator: \".\" | \"/\"): RegExp {\n // Split by ** first, then handle * within each part\n let regexStr = \"^\";\n const doubleStar = separator === \".\" ? \".+\" : \".*\";\n const singleStar = separator === \".\" ? \"[^.]+\" : \"[^/]+\";\n\n const parts = pattern.split(\"**\");\n for (let i = 0; i < parts.length; i++) {\n if (i > 0) {\n regexStr += doubleStar;\n }\n // Within each part, split by * and escape the literals\n const subParts = parts[i].split(\"*\");\n for (let j = 0; j < subParts.length; j++) {\n if (j > 0) {\n regexStr += singleStar;\n }\n // Escape regex special chars in the literal portion\n regexStr += subParts[j].replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n }\n }\n regexStr += \"$\";\n return new RegExp(regexStr);\n}\n\n/**\n * Check whether a URL matches a single remote pattern.\n * Follows the same semantics as Next.js's matchRemotePattern().\n */\nexport function matchRemotePattern(pattern: RemotePattern, url: URL): boolean {\n // Protocol check (strip trailing colon for comparison)\n if (pattern.protocol !== undefined) {\n if (pattern.protocol.replace(/:$/, \"\") !== url.protocol.replace(/:$/, \"\")) {\n return false;\n }\n }\n\n // Port check\n if (pattern.port !== undefined) {\n if (pattern.port !== url.port) {\n return false;\n }\n }\n\n // Hostname check (required field)\n if (!globToRegex(pattern.hostname, \".\").test(url.hostname)) {\n return false;\n }\n\n // Search/query string check\n if (pattern.search !== undefined) {\n if (pattern.search !== url.search) {\n return false;\n }\n }\n\n // Pathname check — defaults to ** (match everything) if not specified\n const pathnamePattern = pattern.pathname ?? \"**\";\n if (!globToRegex(pathnamePattern, \"/\").test(url.pathname)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Check whether a URL matches any configured remote pattern or legacy domain.\n */\nexport function hasRemoteMatch(\n domains: string[],\n remotePatterns: RemotePattern[],\n url: URL,\n): boolean {\n return (\n domains.some((domain) => url.hostname === domain) ||\n remotePatterns.some((p) => matchRemotePattern(p, url))\n );\n}\n\n// ─── Private IP detection ───────────────────────────────────────────────\n\n/**\n * Determine whether a string is a private (non-routable) IP address.\n * Works for IPv4 and IPv6, including bracketed and IPv4-mapped forms.\n *\n * Uses ipaddr.js with range() !== 'unicast' — the same approach Next.js\n * takes (via packages/next/src/server/is-private-ip.ts). This covers all\n * IETF non-unicast ranges (CGNAT, benchmarking, multicast, reserved,\n * teredo, documentation, discard, NAT64, etc.) without hand-rolling CIDR\n * prefix checks that are easy to get wrong.\n *\n * https://github.com/vercel/next.js/blob/canary/packages/next/src/server/is-private-ip.ts\n */\nexport function isPrivateIp(ip: string): boolean {\n // Strip IPv6 brackets so ipaddr.js can parse the raw address.\n if (ip.startsWith(\"[\") && ip.endsWith(\"]\")) {\n ip = ip.slice(1, -1);\n }\n\n try {\n const parsed = ipaddr.parse(ip);\n // IPv4-mapped addresses are classified as \"ipv4Mapped\" by ipaddr.js,\n // not \"unicast\". We must look at the embedded IPv4 address to decide\n // whether it's private (e.g., ::ffff:127.0.0.1) or public.\n if (parsed instanceof ipaddr.IPv6 && parsed.isIPv4MappedAddress()) {\n return parsed.toIPv4Address().range() !== \"unicast\";\n }\n return parsed.range() !== \"unicast\";\n } catch {\n // Not a valid IP address (e.g., a domain name) — not private.\n return false;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAqCA,SAAS,YAAY,SAAiB,WAA8B;CAElE,IAAI,WAAW;CACf,MAAM,aAAa,cAAc,MAAM,OAAO;CAC9C,MAAM,aAAa,cAAc,MAAM,UAAU;CAEjD,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,IAAI,IAAI,GACN,YAAY;EAGd,MAAM,WAAW,MAAM,GAAG,MAAM,IAAI;EACpC,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;GACxC,IAAI,IAAI,GACN,YAAY;GAGd,YAAY,SAAS,GAAG,QAAQ,sBAAsB,OAAO;;;CAGjE,YAAY;CACZ,OAAO,IAAI,OAAO,SAAS;;;;;;AAO7B,SAAgB,mBAAmB,SAAwB,KAAmB;CAE5E,IAAI,QAAQ,aAAa,KAAA;MACnB,QAAQ,SAAS,QAAQ,MAAM,GAAG,KAAK,IAAI,SAAS,QAAQ,MAAM,GAAG,EACvE,OAAO;;CAKX,IAAI,QAAQ,SAAS,KAAA;MACf,QAAQ,SAAS,IAAI,MACvB,OAAO;;CAKX,IAAI,CAAC,YAAY,QAAQ,UAAU,IAAI,CAAC,KAAK,IAAI,SAAS,EACxD,OAAO;CAIT,IAAI,QAAQ,WAAW,KAAA;MACjB,QAAQ,WAAW,IAAI,QACzB,OAAO;;CAMX,IAAI,CAAC,YADmB,QAAQ,YAAY,MACV,IAAI,CAAC,KAAK,IAAI,SAAS,EACvD,OAAO;CAGT,OAAO;;;;;AAMT,SAAgB,eACd,SACA,gBACA,KACS;CACT,OACE,QAAQ,MAAM,WAAW,IAAI,aAAa,OAAO,IACjD,eAAe,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC;;;;;;;;;;;;;;AAkB1D,SAAgB,YAAY,IAAqB;CAE/C,IAAI,GAAG,WAAW,IAAI,IAAI,GAAG,SAAS,IAAI,EACxC,KAAK,GAAG,MAAM,GAAG,GAAG;CAGtB,IAAI;EACF,MAAM,SAAS,OAAO,MAAM,GAAG;EAI/B,IAAI,kBAAkB,OAAO,QAAQ,OAAO,qBAAqB,EAC/D,OAAO,OAAO,eAAe,CAAC,OAAO,KAAK;EAE5C,OAAO,OAAO,OAAO,KAAK;SACpB;EAEN,OAAO"}