Skip to content

Commit 80aa102

Browse files
waleedlatif1claude
andcommitted
refactor(cors): replace embed-path regex with explicit segment check
The regex form `^/api/(chat|form)/(?!manage|validate)[^/]+(/(otp|sso))?$` was opaque on review and would silently exclude any future identifier subroute outside the hard-coded (otp|sso) group from the embed policy. Replace it with an imperative segment check and a named EMBED_RESERVED_SEGMENTS Set, so the policy boundary is visible at the top of the function and adding a reserved subpath is a one-line diff. Add a test asserting that future identifier subroutes also get the embed policy. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 99bb0f9 commit 80aa102

2 files changed

Lines changed: 29 additions & 6 deletions

File tree

apps/sim/proxy.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ describe('resolveApiCorsPolicy', () => {
6767
expect(resolveApiCorsPolicy(makeRequest('/api/chat/abc')).origin).toBe('*')
6868
})
6969

70+
it('applies the embed policy to future identifier subroutes (not just /otp, /sso)', () => {
71+
const policy = resolveApiCorsPolicy(
72+
makeRequest('/api/chat/abc/transcript', 'https://customer.example')
73+
)
74+
expect(policy.origin).toBe('https://customer.example')
75+
expect(policy.credentials).toBe(false)
76+
})
77+
7078
it('uses the default credentialed policy for workspace-internal chat/form routes', () => {
7179
const paths = [
7280
'/api/chat',

apps/sim/proxy.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,27 @@ const WORKFLOW_EXECUTE_HEADERS =
2323
'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, X-API-Key'
2424

2525
/**
26-
* Matches embed endpoints: /api/{chat,form}/{identifier} and subroutes
27-
* (/otp, /sso). The identifier segment explicitly excludes the
28-
* workspace-internal subpaths `manage` and `validate` so those continue
29-
* to use the default credentialed policy.
26+
* Workspace-internal segments under /api/{chat,form}/* that must NOT
27+
* receive the embed policy. They serve the workspace UI with session
28+
* cookies and need the default credentialed policy.
3029
*/
31-
const EMBED_PATH = /^\/api\/(chat|form)\/(?!manage(\/|$)|validate(\/|$))[^/]+(\/(otp|sso))?$/
30+
const EMBED_RESERVED_SEGMENTS = new Set(['manage', 'validate'])
31+
32+
/**
33+
* True for /api/{chat,form}/[identifier] and any deeper subroute
34+
* (e.g. /otp, /sso). The identifier segment is explicitly checked
35+
* against EMBED_RESERVED_SEGMENTS so workspace-internal routes fall
36+
* through to the default credentialed policy.
37+
*/
38+
function isEmbedPath(pathname: string): boolean {
39+
const segments = pathname.split('/')
40+
if (segments.length < 4) return false
41+
if (segments[1] !== 'api') return false
42+
if (segments[2] !== 'chat' && segments[2] !== 'form') return false
43+
const identifier = segments[3]
44+
if (!identifier || EMBED_RESERVED_SEGMENTS.has(identifier)) return false
45+
return true
46+
}
3247

3348
interface CorsRule {
3449
match: (pathname: string) => boolean
@@ -70,7 +85,7 @@ const CORS_RULES: readonly CorsRule[] = [
7085
// tokens, not cookies). Workspace-internal subpaths (`manage`, `validate`,
7186
// and the bare collection routes) are deliberately excluded so they
7287
// continue to receive the default credentialed policy.
73-
match: (p) => EMBED_PATH.test(p),
88+
match: (p) => isEmbedPath(p),
7489
policy: (request) => ({
7590
origin: request.headers.get('origin') || '*',
7691
credentials: false,

0 commit comments

Comments
 (0)