mirror of
https://github.com/langgenius/dify.git
synced 2026-05-26 22:00:53 -04:00
103 lines
3.5 KiB
TypeScript
103 lines
3.5 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')
|
|
})
|
|
})
|