mirror of
https://github.com/stablyai/orca.git
synced 2026-10-20 16:03:20 +00:00
fix(relay): make fenceAndCloseNow stop the liveness safety net (#12482)
The 5-minute liveness tick from #12432 survived fenceAndCloseNow(), so a tick landing between the pre-sign-out fence and the profile wipe could briefly resurrect a broker (benign but soft — the entitlement check bails afterward). The fence now clears the interval; the next auth mutation re-arms it via refreshDemand, and the safety net otherwise behaves identically. Found in release review of the #12432 cherry-pick. Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
committed by
Jinjing
co-authored by
OrcaWin
parent
7600e9a0e3
commit
a8cad67166
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { MobilePairingConnectionContext } from '../runtime-rpc'
|
||||
import { DesktopRelayService, pairingAuthorizationForContext } from './desktop-relay-service'
|
||||
|
||||
@@ -61,6 +61,47 @@ describe('pairingAuthorizationForContext', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('liveness safety net lifecycle', () => {
|
||||
afterEach(() => vi.useRealTimers())
|
||||
|
||||
it('fences hard: the tick stops on fence and re-arms on the next auth mutation', () => {
|
||||
// Why: a tick surviving the pre-sign-out fence could catch the window
|
||||
// before the profile wipe and briefly resurrect a broker.
|
||||
vi.useFakeTimers()
|
||||
const coordinator = {
|
||||
reconcile: vi.fn(),
|
||||
ensureLive: vi.fn(),
|
||||
fenceAndCloseNow: vi.fn(),
|
||||
stop: vi.fn()
|
||||
}
|
||||
const service = Object.create(DesktopRelayService.prototype) as DesktopRelayService
|
||||
Object.assign(service, {
|
||||
coordinator,
|
||||
demandLedger: { nextPendingExpiry: () => null },
|
||||
stopped: false,
|
||||
livenessTimer: null,
|
||||
demandExpiryTimer: null
|
||||
})
|
||||
|
||||
service.start()
|
||||
vi.advanceTimersByTime(5 * 60_000)
|
||||
expect(coordinator.ensureLive).toHaveBeenCalledTimes(1)
|
||||
|
||||
service.fenceAndCloseNow()
|
||||
expect(coordinator.fenceAndCloseNow).toHaveBeenCalledOnce()
|
||||
vi.advanceTimersByTime(30 * 60_000)
|
||||
expect(coordinator.ensureLive).toHaveBeenCalledTimes(1)
|
||||
|
||||
service.authMutated()
|
||||
vi.advanceTimersByTime(5 * 60_000)
|
||||
expect(coordinator.ensureLive).toHaveBeenCalledTimes(2)
|
||||
|
||||
service.stop()
|
||||
vi.advanceTimersByTime(30 * 60_000)
|
||||
expect(coordinator.ensureLive).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('local-only mobile pairing', () => {
|
||||
it('refuses endpoint discovery and provisioning without opening Relay demand', async () => {
|
||||
const registry = {
|
||||
|
||||
@@ -96,9 +96,6 @@ export class DesktopRelayService {
|
||||
|
||||
start(): void {
|
||||
this.refreshDemand()
|
||||
if (!this.livenessTimer) {
|
||||
this.livenessTimer = setInterval(() => this.ensureLive(), RELAY_LIVENESS_INTERVAL_MS)
|
||||
}
|
||||
}
|
||||
|
||||
// Safe to call from any wake signal (power resume, network change).
|
||||
@@ -113,6 +110,13 @@ export class DesktopRelayService {
|
||||
}
|
||||
|
||||
fenceAndCloseNow(): void {
|
||||
// Why: a fence must be hard — a surviving liveness tick could catch the
|
||||
// window between the pre-sign-out fence and the profile wipe and briefly
|
||||
// resurrect a broker. The next auth mutation re-arms via refreshDemand.
|
||||
if (this.livenessTimer) {
|
||||
clearInterval(this.livenessTimer)
|
||||
this.livenessTimer = null
|
||||
}
|
||||
this.coordinator.fenceAndCloseNow()
|
||||
}
|
||||
|
||||
@@ -307,6 +311,9 @@ export class DesktopRelayService {
|
||||
if (this.stopped) {
|
||||
return
|
||||
}
|
||||
if (!this.livenessTimer) {
|
||||
this.livenessTimer = setInterval(() => this.ensureLive(), RELAY_LIVENESS_INTERVAL_MS)
|
||||
}
|
||||
if (this.demandExpiryTimer) {
|
||||
clearTimeout(this.demandExpiryTimer)
|
||||
this.demandExpiryTimer = null
|
||||
|
||||
Reference in New Issue
Block a user