mirror of
https://github.com/stablyai/orca.git
synced 2026-09-23 16:02:24 +00:00
* fix(browser): move cookie scoping off psl's stale suffix list psl@1.15.0 is its latest release and ships a Dec-2024 snapshot of the public suffix list. Measured against the current upstream list, it fails to recognise 600 of 10,030 suffixes; tldts misses 2. That gap is a cookie-isolation bug. psl does not know `api.br` is a suffix, so it falls back to the `br` rule and maps foo.api.br, bar.api.br and example.api.br all onto the single family `api.br`. Unrelated registrants then share a removal scope, and a replace-mode import for one clears the others' cookies. The same holds for seg.ar, co.az, gov.cz and ~597 more. tldts is called with allowPrivateDomains, without which the PSL's PRIVATE section is ignored and every *.github.io / *.s3.amazonaws.com / *.vercel.app tenant collapses into one family — 21 of 49 probed hosts changed family under the default. The new test pins that boundary. One deliberate behaviour change: hosts under `.local` (not in the PSL) were their own family under psl, which returned an all-null parse for them; they now resolve to the two-label boundary (app.orca.local -> orca.local), matching what Chromium treats as the registrable domain. * fix(build): bundle tldts into the main process like psl was psl sat in BUNDLED_MAIN_DEPENDENCIES, so it was inlined into the main bundle rather than externalized and copied into resources/node_modules. Swapping the dependency without moving that entry left a bare tldts import that afterPack's runtime-closure check rejects. * fix(build): point the output contract at tldts and drop the psl shim The contract test still asserted psl was in BUNDLED_MAIN_DEPENDENCIES, so it failed once the entry became tldts. src/types/psl.ts declared a module that no longer resolves; tldts ships its own types. * test(browser): pin the suffix boundaries the tldts swap moved Three semantic changes shipped untested: - `.local` is unlisted, and the libraries disagreed on what that means. psl returned an all-null parse so every `*.orca.local` host was its own family; tldts stops at `orca.local`. The consequence is wider than the family name — importDomainAncestors now yields the shared parent, so a replace-mode import of one host clears non-host-only cookies every sibling shares. - psl's snapshot had `compute.amazonaws.com` as a literal PRIVATE suffix; the current list only carries the wildcard, so the bare host is ICANN now. - The renderer's `psl.isValid` gate had no direct test at all — nothing imported the module from a test. Also drops comments that explained a boundary in terms of psl's internals. One was wrong under tldts: bracketed IPv6 does not reach an error branch, it parses with the brackets stripped and falls through the unlisted path.
119 lines
4.4 KiB
TypeScript
119 lines
4.4 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
import {
|
|
AssignmentRequestSchema as BaselineRequest,
|
|
AssignmentResponseSchema as BaselineResponse
|
|
} from '../../cloud/apps/relay/src/test-fixtures/relay-contract-baseline/director-messages'
|
|
import {
|
|
DrainSchema as BaselineDrain,
|
|
HostHelloSchema as BaselineHello
|
|
} from '../../cloud/apps/relay/src/test-fixtures/relay-contract-baseline/control-messages'
|
|
import { AssignmentRequestSchema } from '../../cloud/packages/relay-contract/src/director-messages'
|
|
import { HostHelloSchema } from '../../cloud/packages/relay-contract/src/control-messages'
|
|
import { requestRelayAssignment } from '../../src/main/runtime/relay/relay-http-client'
|
|
import { RelayAssignRateGate } from '../../src/main/runtime/relay/relay-assign-rate-gate'
|
|
|
|
const assignment = {
|
|
v: 1,
|
|
cellUrl: 'https://asia.example.test',
|
|
assignmentEpoch: 3,
|
|
lease: 'synthetic-assignment'
|
|
}
|
|
const window = {
|
|
generation: 1,
|
|
assignmentEpoch: 3,
|
|
incumbentRegion: 'asia-east2',
|
|
expiresAt: 100_000_000,
|
|
policyVersion: 1
|
|
}
|
|
function request(fetch: typeof globalThis.fetch) {
|
|
return requestRelayAssignment({
|
|
directorUrl: 'https://director.example.test',
|
|
relayHostId: 'abcdefghijklmnop',
|
|
relayToken: 'synthetic-authorization',
|
|
preferredRegion: 'asia-east2',
|
|
reconnect: true,
|
|
regionCorrection: { v: 1, action: 'issue-window' },
|
|
fetch,
|
|
assignRateGate: new RelayAssignRateGate()
|
|
})
|
|
}
|
|
|
|
describe('relay correction mixed-version wire contracts', () => {
|
|
it('new desktop falls back against the actual pinned old director parser', async () => {
|
|
const bodies: unknown[] = []
|
|
const fetch = vi.fn<typeof globalThis.fetch>(async (_url, init) => {
|
|
const body: unknown = JSON.parse(String(init?.body))
|
|
bodies.push(body)
|
|
return BaselineRequest.safeParse(body).success
|
|
? Response.json(BaselineResponse.parse(assignment))
|
|
: new Response(null, { status: 400 })
|
|
})
|
|
expect(await request(fetch)).toEqual(assignment)
|
|
expect(bodies).toHaveLength(2)
|
|
expect(AssignmentRequestSchema.safeParse(bodies[0]).success).toBe(true)
|
|
expect(BaselineRequest.safeParse(bodies[0]).success).toBe(false)
|
|
expect(bodies[1]).toEqual({
|
|
v: 1,
|
|
relayHostId: 'abcdefghijklmnop',
|
|
preferredRegion: 'asia-east2',
|
|
reconnect: true
|
|
})
|
|
})
|
|
|
|
it('the old desktop assignment shape remains accepted by the new director', () => {
|
|
const request = BaselineRequest.parse({ v: 1, relayHostId: 'abcdefghijklmnop' })
|
|
expect(AssignmentRequestSchema.parse(request)).toEqual(request)
|
|
expect(BaselineResponse.parse(assignment)).toEqual(assignment)
|
|
})
|
|
|
|
it('the negotiated capability requires no change to the strict old host hello', () => {
|
|
const hello = {
|
|
v: 1,
|
|
relayHostId: 'abcdefghijklmnop',
|
|
assignmentEpoch: 3,
|
|
hostPublicKeyB64: Buffer.alloc(32).toString('base64'),
|
|
appVersion: 'test'
|
|
}
|
|
expect(BaselineHello.parse(HostHelloSchema.parse(hello))).toEqual(hello)
|
|
expect(BaselineHello.safeParse({ ...hello, idleRegionalRehome: true }).success).toBe(false)
|
|
})
|
|
|
|
it('the idle cutover uses a drain frame understood by the pinned old desktop', () => {
|
|
const drain = { recovery: 'resolve-director', graceMs: 0 }
|
|
expect(BaselineDrain.parse(drain)).toEqual(drain)
|
|
})
|
|
|
|
it.each([
|
|
{ v: 1, window: { ...window, policyVersion: 2 } },
|
|
{ v: 2, window },
|
|
{ v: 1, window: { ...window, expiresAt: -1 } },
|
|
{ v: 1, window: { ...window, unexpectedField: true } }
|
|
])(
|
|
'defers unsupported or malformed optional correction without losing placement: %j',
|
|
async (regionCorrection) => {
|
|
const result = await request(async () => Response.json({ ...assignment, regionCorrection }))
|
|
expect(result).toMatchObject(assignment)
|
|
expect(result.regionCorrection).toBeUndefined()
|
|
}
|
|
)
|
|
|
|
it('still accepts supported correction metadata', async () => {
|
|
const regionCorrection = { v: 1, window }
|
|
expect(await request(async () => Response.json({ ...assignment, regionCorrection }))).toEqual({
|
|
...assignment,
|
|
regionCorrection
|
|
})
|
|
})
|
|
|
|
it.each([
|
|
{ cellUrl: 'http://untrusted.example.test' },
|
|
{ assignmentEpoch: -1 },
|
|
{ lease: '' },
|
|
{ unexpectedField: true }
|
|
])('keeps the core assignment strict: %j', async (invalid) => {
|
|
await expect(request(async () => Response.json({ ...assignment, ...invalid }))).rejects.toThrow(
|
|
'relay_assignment_failed_502'
|
|
)
|
|
})
|
|
})
|