mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 17:37:40 +00:00
* 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
60 lines
2.8 KiB
TypeScript
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)
|
|
})
|
|
})
|