dify/packages/dev-proxy/src/cookies.spec.ts
Stephen Zhou a84c2d36a3
style: format with vp fmt (#38803)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-12 15:57:46 +00:00

111 lines
3.6 KiB
TypeScript

/**
* @vitest-environment node
*/
import { describe, expect, it } from 'vitest'
import {
getCookieHeaderValue,
rewriteCookieHeaderForUpstream,
rewriteSetCookieHeadersForLocal,
toScopedLocalCookieName,
} from './cookies'
describe('dev proxy cookies', () => {
// Scenario: cookie names should only receive secure host prefixes when configured.
it('should rewrite configured cookie names for HTTPS upstream requests', () => {
// Act
const cookieHeader = rewriteCookieHeaderForUpstream(
'access_token=abc; theme=dark; passport-app=def',
{
hostPrefixCookies: ['access_token', /^passport-/],
useHostPrefix: true,
},
)
// Assert
expect(cookieHeader).toBe('__Host-access_token=abc; theme=dark; __Host-passport-app=def')
})
// Scenario: HTTP upstreams should keep local cookie names even when rewrite config exists.
it('should keep local cookie names for HTTP upstream requests', () => {
// Act
const cookieHeader = rewriteCookieHeaderForUpstream('access_token=abc; refresh_token=def', {
hostPrefixCookies: ['access_token', 'refresh_token'],
useHostPrefix: false,
})
// Assert
expect(cookieHeader).toBe('access_token=abc; refresh_token=def')
})
// Scenario: upstream set-cookie headers should be converted into localhost-safe cookies.
it('should rewrite upstream set-cookie headers for local development', () => {
// Act
const cookies = rewriteSetCookieHeadersForLocal([
'__Host-access_token=abc; Path=/console/api; Domain=cloud.example.com; Secure; SameSite=None; Partitioned',
])
// Assert
expect(cookies).toEqual(['access_token=abc; Path=/; SameSite=Lax'])
})
// Scenario: target-scoped cookies should isolate authentication state between upstream targets.
it('should only forward auth cookies from the active local scope', () => {
// Arrange
const activeAccessTokenName = toScopedLocalCookieName('access_token', 'active')
const otherAccessTokenName = toScopedLocalCookieName('access_token', 'other')
// Act
const cookieHeader = rewriteCookieHeaderForUpstream(
[
`${activeAccessTokenName}=active-token`,
'access_token=legacy-token',
`${otherAccessTokenName}=other-token`,
'theme=dark',
].join('; '),
{
hostPrefixCookies: ['access_token'],
localScopeKey: 'active',
useHostPrefix: true,
},
)
// Assert
expect(cookieHeader).toBe('__Host-access_token=active-token; theme=dark')
})
// Scenario: upstream auth set-cookie headers should be stored under scoped local names.
it('should rewrite upstream set-cookie headers into target-scoped local cookies', () => {
// Arrange
const scopedAccessTokenName = toScopedLocalCookieName('access_token', 'cloud')
// Act
const cookies = rewriteSetCookieHeadersForLocal(
[
'__Host-access_token=abc; Path=/console/api; Domain=cloud.example.com; Secure; SameSite=None; Partitioned',
],
{
hostPrefixCookies: ['access_token'],
localScopeKey: 'cloud',
},
)
// Assert
expect(cookies).toEqual([`${scopedAccessTokenName}=abc; Path=/; SameSite=Lax`])
})
// Scenario: request header helpers should read scoped CSRF cookies without exposing scope logic to callers.
it('should read scoped cookie values from cookie headers', () => {
// Arrange
const scopedCsrfCookieName = toScopedLocalCookieName('csrf_token', 'cloud')
// Act
const csrfToken = getCookieHeaderValue(
`${scopedCsrfCookieName}=csrf; csrf_token=legacy`,
scopedCsrfCookieName,
)
// Assert
expect(csrfToken).toBe('csrf')
})
})