mirror of
https://github.com/langgenius/dify.git
synced 2026-05-15 04:00:46 -04:00
97 lines
3.1 KiB
TypeScript
97 lines
3.1 KiB
TypeScript
import type { CookieRewriteOptions } from './types'
|
|
|
|
const SECURE_COOKIE_PREFIX_PATTERN = /^__(Host|Secure)-/
|
|
const SAME_SITE_NONE_PATTERN = /^samesite=none$/i
|
|
const COOKIE_PATH_PATTERN = /^path=/i
|
|
const COOKIE_DOMAIN_PATTERN = /^domain=/i
|
|
const COOKIE_SECURE_PATTERN = /^secure$/i
|
|
const COOKIE_PARTITIONED_PATTERN = /^partitioned$/i
|
|
|
|
const stripSecureCookiePrefix = (cookieName: string) => cookieName.replace(SECURE_COOKIE_PREFIX_PATTERN, '')
|
|
|
|
const matchesCookieName = (cookieName: string, matcher: string | RegExp) =>
|
|
typeof matcher === 'string'
|
|
? matcher === cookieName
|
|
: matcher.test(cookieName)
|
|
|
|
const shouldUseHostPrefix = (cookieName: string, options: CookieRewriteOptions) => {
|
|
const normalizedCookieName = stripSecureCookiePrefix(cookieName)
|
|
|
|
return options.hostPrefixCookies?.some(matcher => matchesCookieName(normalizedCookieName, matcher)) || false
|
|
}
|
|
|
|
const toUpstreamCookieName = (cookieName: string, options: CookieRewriteOptions) => {
|
|
if (cookieName.startsWith('__Host-'))
|
|
return cookieName
|
|
|
|
if (cookieName.startsWith('__Secure-'))
|
|
return `__Host-${stripSecureCookiePrefix(cookieName)}`
|
|
|
|
if (!shouldUseHostPrefix(cookieName, options))
|
|
return cookieName
|
|
|
|
return `__Host-${cookieName}`
|
|
}
|
|
|
|
export const toLocalCookieName = (cookieName: string) => stripSecureCookiePrefix(cookieName)
|
|
|
|
export const rewriteCookieHeaderForUpstream = (
|
|
cookieHeader: string | undefined,
|
|
options: CookieRewriteOptions & { useHostPrefix?: boolean },
|
|
) => {
|
|
if (!cookieHeader)
|
|
return cookieHeader
|
|
|
|
const { useHostPrefix = true } = options
|
|
|
|
return cookieHeader
|
|
.split(/;\s*/)
|
|
.filter(Boolean)
|
|
.map((cookie) => {
|
|
const separatorIndex = cookie.indexOf('=')
|
|
if (separatorIndex === -1)
|
|
return cookie
|
|
|
|
const cookieName = cookie.slice(0, separatorIndex).trim()
|
|
const cookieValue = cookie.slice(separatorIndex + 1)
|
|
const upstreamCookieName = useHostPrefix
|
|
? toUpstreamCookieName(cookieName, options)
|
|
: cookieName
|
|
|
|
return `${upstreamCookieName}=${cookieValue}`
|
|
})
|
|
.join('; ')
|
|
}
|
|
|
|
const rewriteSetCookieValueForLocal = (setCookieValue: string) => {
|
|
const [rawCookiePair, ...rawAttributes] = setCookieValue.split(';')
|
|
const separatorIndex = rawCookiePair!.indexOf('=')
|
|
|
|
if (separatorIndex === -1)
|
|
return setCookieValue
|
|
|
|
const cookieName = rawCookiePair!.slice(0, separatorIndex).trim()
|
|
const cookieValue = rawCookiePair!.slice(separatorIndex + 1)
|
|
const rewrittenAttributes = rawAttributes
|
|
.map(attribute => attribute.trim())
|
|
.filter(attribute =>
|
|
!COOKIE_DOMAIN_PATTERN.test(attribute)
|
|
&& !COOKIE_SECURE_PATTERN.test(attribute)
|
|
&& !COOKIE_PARTITIONED_PATTERN.test(attribute),
|
|
)
|
|
.map((attribute) => {
|
|
if (SAME_SITE_NONE_PATTERN.test(attribute))
|
|
return 'SameSite=Lax'
|
|
|
|
if (COOKIE_PATH_PATTERN.test(attribute))
|
|
return 'Path=/'
|
|
|
|
return attribute
|
|
})
|
|
|
|
return [`${toLocalCookieName(cookieName)}=${cookieValue}`, ...rewrittenAttributes].join('; ')
|
|
}
|
|
|
|
export const rewriteSetCookieHeadersForLocal = (setCookieHeaders: readonly string[]) =>
|
|
setCookieHeaders.map(rewriteSetCookieValueForLocal)
|