From 60ad2c2e96ac0cfe206c1ea1e7c4627035857de5 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 16 Feb 2026 02:19:45 +0000 Subject: [PATCH] refactor(device-pairing): share token update context --- src/infra/device-pairing.ts | 57 +++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/src/infra/device-pairing.ts b/src/infra/device-pairing.ts index 4aba97ee9ab..a6a9c7fcdfb 100644 --- a/src/infra/device-pairing.ts +++ b/src/infra/device-pairing.ts @@ -428,17 +428,16 @@ export async function ensureDeviceToken(params: { }): Promise { return await withLock(async () => { const state = await loadState(params.baseDir); - const device = getPairedDeviceFromState(state, params.deviceId); - if (!device) { - return null; - } - const role = normalizeRole(params.role); - if (!role) { - return null; - } const requestedScopes = normalizeScopes(params.scopes); - const tokens = cloneDeviceTokens(device); - const existing = tokens[role]; + const context = resolveDeviceTokenUpdateContext({ + state, + deviceId: params.deviceId, + role: params.role, + }); + if (!context) { + return null; + } + const { device, role, tokens, existing } = context; if (existing && !existing.revokedAtMs) { if (scopesAllow(requestedScopes, existing.scopes)) { return existing; @@ -460,6 +459,29 @@ export async function ensureDeviceToken(params: { }); } +function resolveDeviceTokenUpdateContext(params: { + state: DevicePairingStateFile; + deviceId: string; + role: string; +}): { + device: PairedDevice; + role: string; + tokens: Record; + existing: DeviceAuthToken | undefined; +} | null { + const device = getPairedDeviceFromState(params.state, params.deviceId); + if (!device) { + return null; + } + const role = normalizeRole(params.role); + if (!role) { + return null; + } + const tokens = cloneDeviceTokens(device); + const existing = tokens[role]; + return { device, role, tokens, existing }; +} + export async function rotateDeviceToken(params: { deviceId: string; role: string; @@ -468,16 +490,15 @@ export async function rotateDeviceToken(params: { }): Promise { return await withLock(async () => { const state = await loadState(params.baseDir); - const device = getPairedDeviceFromState(state, params.deviceId); - if (!device) { + const context = resolveDeviceTokenUpdateContext({ + state, + deviceId: params.deviceId, + role: params.role, + }); + if (!context) { return null; } - const role = normalizeRole(params.role); - if (!role) { - return null; - } - const tokens = cloneDeviceTokens(device); - const existing = tokens[role]; + const { device, role, tokens, existing } = context; const requestedScopes = normalizeScopes(params.scopes ?? existing?.scopes ?? device.scopes); const now = Date.now(); const next = buildDeviceAuthToken({