Spaces:
Running
Running
| // micromatch is only available at node runtime, so it cannot be used here since the code path that calls this function | |
| // can be run from edge. This is a simple implementation that safely achieves the required functionality. | |
| // the goal is to match the functionality for remotePatterns as defined here - | |
| // https://nextjs.org/docs/app/api-reference/components/image#remotepatterns | |
| // TODO - retrofit micromatch to work in edge and use that instead | |
| ; | |
| Object.defineProperty(exports, "__esModule", { | |
| value: true | |
| }); | |
| Object.defineProperty(exports, "isCsrfOriginAllowed", { | |
| enumerable: true, | |
| get: function() { | |
| return isCsrfOriginAllowed; | |
| } | |
| }); | |
| function matchWildcardDomain(domain, pattern) { | |
| // DNS names are case-insensitive per RFC 1035 | |
| // Use ASCII-only toLowerCase to avoid unicode issues | |
| const normalizedDomain = domain.replace(/[A-Z]/g, (c)=>c.toLowerCase()); | |
| const normalizedPattern = pattern.replace(/[A-Z]/g, (c)=>c.toLowerCase()); | |
| const domainParts = normalizedDomain.split('.'); | |
| const patternParts = normalizedPattern.split('.'); | |
| if (patternParts.length < 1) { | |
| // pattern is empty and therefore invalid to match against | |
| return false; | |
| } | |
| if (domainParts.length < patternParts.length) { | |
| // domain has too few segments and thus cannot match | |
| return false; | |
| } | |
| // Prevent wildcards from matching entire domains (e.g. '**' or '*.com') | |
| // This ensures wildcards can only match subdomains, not the main domain | |
| if (patternParts.length === 1 && (patternParts[0] === '*' || patternParts[0] === '**')) { | |
| return false; | |
| } | |
| while(patternParts.length){ | |
| const patternPart = patternParts.pop(); | |
| const domainPart = domainParts.pop(); | |
| switch(patternPart){ | |
| case '': | |
| { | |
| // invalid pattern. pattern segments must be non empty | |
| return false; | |
| } | |
| case '*': | |
| { | |
| // wildcard matches anything so we continue if the domain part is non-empty | |
| if (domainPart) { | |
| continue; | |
| } else { | |
| return false; | |
| } | |
| } | |
| case '**': | |
| { | |
| // if this is not the last item in the pattern the pattern is invalid | |
| if (patternParts.length > 0) { | |
| return false; | |
| } | |
| // recursive wildcard matches anything so we terminate here if the domain part is non empty | |
| return domainPart !== undefined; | |
| } | |
| case undefined: | |
| default: | |
| { | |
| if (domainPart !== patternPart) { | |
| return false; | |
| } | |
| } | |
| } | |
| } | |
| // We exhausted the pattern. If we also exhausted the domain we have a match | |
| return domainParts.length === 0; | |
| } | |
| const isCsrfOriginAllowed = (originDomain, allowedOrigins = [])=>{ | |
| // DNS names are case-insensitive per RFC 1035 | |
| // Use ASCII-only toLowerCase to avoid unicode issues | |
| const normalizedOrigin = originDomain.replace(/[A-Z]/g, (c)=>c.toLowerCase()); | |
| return allowedOrigins.some((allowedOrigin)=>{ | |
| if (!allowedOrigin) return false; | |
| const normalizedAllowed = allowedOrigin.replace(/[A-Z]/g, (c)=>c.toLowerCase()); | |
| return normalizedAllowed === normalizedOrigin || matchWildcardDomain(originDomain, allowedOrigin); | |
| }); | |
| }; | |
| //# sourceMappingURL=csrf-protection.js.map |