Files
orca/src/shared/mobile-e2ee-v2-framing.test.ts
T
Jinwoo HongandOrca 77b154d5dd Add Orca Relay desktop and mobile transport (#8536)
* feat(mobile): define relay protocol groundwork

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): implement replay-safe E2EE v2 sessions

Co-authored-by: Orca <help@stably.ai>

* test(auth): lock cloud refresh single-flight

Co-authored-by: Orca <help@stably.ai>

* test(mobile): complete E2EE v2 adversarial coverage

Co-authored-by: Orca <help@stably.ai>

* refactor(runtime): unify mobile socket wiring

Co-authored-by: Orca <help@stably.ai>

* feat(runtime): add relay control and data clients

Co-authored-by: Orca <help@stably.ai>

* feat(runtime): coordinate desktop relay sessions

Co-authored-by: Orca <help@stably.ai>

* fix(auth): fence stale cloud session mutations

Co-authored-by: Orca <help@stably.ai>

* feat(runtime): add relay pairing and durable revoke

Co-authored-by: Orca <help@stably.ai>

* feat(runtime): add relay credential pairing RPCs

Co-authored-by: Orca <help@stably.ai>

* feat(settings): show Orca Relay sign-in status

Co-authored-by: Orca <help@stably.ai>

* test(relay): prove desktop lifecycle and E2EE splice

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): persist relay pairing state

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): race direct and relay pairing

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): recover pairing through relay director

Co-authored-by: Orca <help@stably.ai>

* fix(relay): preserve origin controls during drain

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): recover interrupted relay pairing

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): add stable relay RPC sessions

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): supervise direct and relay endpoints

Co-authored-by: Orca <help@stably.ai>

* Cover mobile relay director fallback matrix

Co-authored-by: Orca <help@stably.ai>

* Fix relay settings component test isolation

Co-authored-by: Orca <help@stably.ai>

* Remove unrelated merge formatting drift

Co-authored-by: Orca <help@stably.ai>

* Update runtime connection count integration assertion

Co-authored-by: Orca <help@stably.ai>

* Run mobile typecheck through pnpm

Co-authored-by: Orca <help@stably.ai>

* feat(relay): gate desktop controls on mobile demand

Co-authored-by: Orca <help@stably.ai>

* test(mobile): cover served relay recovery

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): upgrade direct pairings to relay

Co-authored-by: Orca <help@stably.ai>

* fix(relay): harden mobile reconnect and teardown

Co-authored-by: Orca <help@stably.ai>

* fix(auth): clarify account sign-in state

Co-authored-by: Orca <help@stably.ai>

* fix(auth): polish sign-in completion flow

Co-authored-by: Orca <help@stably.ai>

* fix(auth): clarify sign-out confirmation

Co-authored-by: Orca <help@stably.ai>

* fix(auth): simplify sign-in completion page

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): add per-device pairing connection mode

Co-authored-by: Orca <help@stably.ai>

* fix(mobile): stabilize pairing option layout

Co-authored-by: Orca <help@stably.ai>

* fix(mobile): give pairing choices stable space

Co-authored-by: Orca <help@stably.ai>

* fix(mobile): stabilize pairing QR regeneration

Co-authored-by: Orca <help@stably.ai>

* Animate mobile pairing flow height

Co-authored-by: Orca <help@stably.ai>

* Configure auth in packaged builds

Co-authored-by: Orca <help@stably.ai>

* Make Orca Relay pairing an opt-in beta

Co-authored-by: Orca <help@stably.ai>

* Show Relay beta details on hover

Co-authored-by: Orca <help@stably.ai>

* Refine mobile relay pairing choice

Co-authored-by: Orca <help@stably.ai>

* Polish Orca Relay pairing controls

Co-authored-by: Orca <help@stably.ai>

* Keep mobile contract fallback test additive

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-14 11:47:05 -07:00

88 lines
2.5 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { openMobileE2EEV2Frame, sealMobileE2EEV2Frame } from './mobile-e2ee-v2-framing'
const key = new Uint8Array(32).fill(7)
const sessionId = new Uint8Array(32).fill(8)
const payload = new TextEncoder().encode('e2ee-auth')
describe('mobile E2EE v2 framing', () => {
it('round-trips counter-zero auth with the fixed nonce layout', () => {
const frame = sealMobileE2EEV2Frame({
payload,
key,
sessionId,
direction: 'mobile-to-desktop',
payloadKind: 'text',
counter: 0n
})
expect(Buffer.from(frame.subarray(0, 24)).toString('hex')).toBe(
'080808080808080808080808020000000000000000000000'
)
expect(
openMobileE2EEV2Frame({
frame,
key,
sessionId,
direction: 'mobile-to-desktop',
payloadKind: 'text',
expectedCounter: 0n
})
).toEqual(payload)
})
it('rejects replay, gap, reflection, kind confusion, and cross-session frames', () => {
const frame = sealMobileE2EEV2Frame({
payload,
key,
sessionId,
direction: 'mobile-to-desktop',
payloadKind: 'binary',
counter: 4n
})
const attempt = (overrides: Partial<Parameters<typeof openMobileE2EEV2Frame>[0]>) =>
openMobileE2EEV2Frame({
frame,
key,
sessionId,
direction: 'mobile-to-desktop',
payloadKind: 'binary',
expectedCounter: 4n,
...overrides
})
expect(attempt({ expectedCounter: 3n })).toBeNull()
expect(attempt({ expectedCounter: 5n })).toBeNull()
expect(attempt({ direction: 'desktop-to-mobile' })).toBeNull()
expect(attempt({ payloadKind: 'text' })).toBeNull()
expect(attempt({ sessionId: new Uint8Array(32).fill(9) })).toBeNull()
})
it('uses one exact-next counter sequence across text and binary kinds', () => {
const kinds = ['text', 'binary', 'text'] as const
const frames = kinds.map((payloadKind, counter) =>
sealMobileE2EEV2Frame({
payload: new Uint8Array([counter]),
key,
sessionId,
direction: 'desktop-to-mobile',
payloadKind,
counter: BigInt(counter)
})
)
for (let counter = 0; counter < frames.length; counter++) {
expect(
openMobileE2EEV2Frame({
frame: frames[counter]!,
key,
sessionId,
direction: 'desktop-to-mobile',
payloadKind: kinds[counter]!,
expectedCounter: BigInt(counter)
})
).toEqual(new Uint8Array([counter]))
}
})
})