Files
orca/tests/e2e/cross-version-wire/cross-version-web-session-pairing.unit.test.ts
Neil 18bab90efa refactor(main): group client RPC pairing and host runtime owners (#38584)
* refactor(main): group client RPC pairing and host runtime owners

* test: target concrete mobile notification owner in headless fixture

* test: retarget dynamic quit mocks to runtime metadata owner
2026-11-05 09:16:47 -08:00

60 lines
2.8 KiB
TypeScript

import { mkdtempSync, readFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import nacl from 'tweetnacl'
import { beforeAll, describe, expect, it } from 'vitest'
import { DeviceRegistry } from '../../../src/main/runtime/rpc/server/pairing/device-registry'
import type { DeviceEntry } from '../../../src/main/runtime/rpc/server/pairing/device-entry'
import { DEVICE_REGISTRY_FILENAME } from '../../../src/main/runtime/rpc/server/pairing/mobile-pairing-files'
import { importReleaseCheckoutModule, materializeReleaseCheckout } from './release-checkout'
// Across downgrade, preserve ephemeral key rows and token auth; only hosts advertising the capability may receive session-only registration.
// The last release without session-only keys; a newer baseline would itself drop the row.
const PRE_EPHEMERAL_REF = 'v1.4.224'
const SUITE_TIMEOUT_MS = 180_000
type RegistryLike = {
validateToken(token: string): { deviceId: string } | null
updateLastSeen(deviceId: string): void
}
let ReleasedRegistry: new (userDataPath: string) => RegistryLike
beforeAll(async () => {
const checkout = await materializeReleaseCheckout(PRE_EPHEMERAL_REF)
const registryModule = await importReleaseCheckoutModule(
checkout,
'src/main/runtime/rpc/server/pairing/device-registry.ts'
)
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the pinned release's DeviceRegistry class; a changed shape fails the assertions below.
ReleasedRegistry = registryModule.DeviceRegistry as typeof ReleasedRegistry
}, SUITE_TIMEOUT_MS)
describe('cross-version: session-only browser rows', () => {
it('a released registry keeps the session row and token rows; this host drops it on restart', () => {
const userDataPath = mkdtempSync(join(tmpdir(), 'orca-xv-web-session-'))
const current = new DeviceRegistry(userDataPath)
const legacy = current.addDevice('Browser', 'runtime')
current.updateLastSeen(legacy.deviceId)
const keyB64 = Buffer.from(nacl.sign.keyPair().publicKey).toString('base64')
const session = current.forkDeviceKey(legacy.deviceId, keyB64, 'Tab', { ephemeral: true })
const released = new ReleasedRegistry(userDataPath)
expect(released.validateToken(legacy.token)?.deviceId).toBe(legacy.deviceId)
released.updateLastSeen(legacy.deviceId)
const rows: DeviceEntry[] = JSON.parse(
readFileSync(join(userDataPath, DEVICE_REGISTRY_FILENAME), 'utf8')
)
expect(rows.find((row) => row.deviceId === session.deviceId)).toMatchObject({
ephemeral: true,
devicePublicKeyB64: keyB64
})
expect(rows.find((row) => row.deviceId === session.deviceId)?.token).toBeUndefined()
const restarted = new DeviceRegistry(userDataPath)
expect(restarted.getDevice(session.deviceId)).toBeNull()
expect(restarted.validateToken(legacy.token)?.deviceId).toBe(legacy.deviceId)
})
})