From 212afb69509675dbbd823828e4f39d50a8e23590 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 12 Mar 2026 22:42:04 +0000 Subject: [PATCH] refactor: clarify pairing setup auth labels --- extensions/device-pair/index.ts | 32 +++++++++++++-------------- src/pairing/setup-code.ts | 38 ++++++++++++++++++++------------- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/extensions/device-pair/index.ts b/extensions/device-pair/index.ts index 67a50e8734b..825d1668ac0 100644 --- a/extensions/device-pair/index.ts +++ b/extensions/device-pair/index.ts @@ -41,10 +41,8 @@ type ResolveUrlResult = { error?: string; }; -type ResolveAuthResult = { - token?: string; - password?: string; - label?: string; +type ResolveAuthLabelResult = { + label?: "token" | "password"; error?: string; }; @@ -187,7 +185,7 @@ async function resolveTailnetHost(): Promise { ); } -function resolveAuth(cfg: OpenClawPluginApi["config"]): ResolveAuthResult { +function resolveAuthLabel(cfg: OpenClawPluginApi["config"]): ResolveAuthLabelResult { const mode = cfg.gateway?.auth?.mode; const token = pickFirstDefined([ @@ -203,13 +201,13 @@ function resolveAuth(cfg: OpenClawPluginApi["config"]): ResolveAuthResult { ]) ?? undefined; if (mode === "token" || mode === "password") { - return resolveRequiredAuth(mode, { token, password }); + return resolveRequiredAuthLabel(mode, { token, password }); } if (token) { - return { token, label: "token" }; + return { label: "token" }; } if (password) { - return { password, label: "password" }; + return { label: "password" }; } return { error: "Gateway auth is not configured (no token or password)." }; } @@ -227,17 +225,17 @@ function pickFirstDefined(candidates: Array): string | null { return null; } -function resolveRequiredAuth( +function resolveRequiredAuthLabel( mode: "token" | "password", values: { token?: string; password?: string }, -): ResolveAuthResult { +): ResolveAuthLabelResult { if (mode === "token") { return values.token - ? { token: values.token, label: "token" } + ? { label: "token" } : { error: "Gateway auth is set to token, but no token is configured." }; } return values.password - ? { password: values.password, label: "password" } + ? { label: "password" } : { error: "Gateway auth is set to password, but no password is configured." }; } @@ -393,9 +391,9 @@ export default function register(api: OpenClawPluginApi) { return { text: `✅ Paired ${label}${platformLabel}.` }; } - const auth = resolveAuth(api.config); - if (auth.error) { - return { text: `Error: ${auth.error}` }; + const authLabelResult = resolveAuthLabel(api.config); + if (authLabelResult.error) { + return { text: `Error: ${authLabelResult.error}` }; } const urlResult = await resolveGatewayUrl(api); @@ -411,7 +409,7 @@ export default function register(api: OpenClawPluginApi) { if (action === "qr") { const setupCode = encodeSetupCode(payload); const qrAscii = await renderQrAscii(setupCode); - const authLabel = auth.label ?? "auth"; + const authLabel = authLabelResult.label ?? "auth"; const channel = ctx.channel; const target = ctx.senderId?.trim() || ctx.from?.trim() || ctx.to?.trim() || ""; @@ -502,7 +500,7 @@ export default function register(api: OpenClawPluginApi) { const channel = ctx.channel; const target = ctx.senderId?.trim() || ctx.from?.trim() || ctx.to?.trim() || ""; - const authLabel = auth.label ?? "auth"; + const authLabel = authLabelResult.label ?? "auth"; if (channel === "telegram" && target) { try { diff --git a/src/pairing/setup-code.ts b/src/pairing/setup-code.ts index de8f3c651cb..e241af8c5ed 100644 --- a/src/pairing/setup-code.ts +++ b/src/pairing/setup-code.ts @@ -57,9 +57,7 @@ type ResolveUrlResult = { error?: string; }; -type ResolveAuthResult = { - token?: string; - password?: string; +type ResolveAuthLabelResult = { label?: "token" | "password"; error?: string; }; @@ -165,7 +163,10 @@ function resolveGatewayPasswordFromEnv(env: NodeJS.ProcessEnv): string | undefin ); } -function resolveAuth(cfg: OpenClawConfig, env: NodeJS.ProcessEnv): ResolveAuthResult { +function resolvePairingSetupAuthLabel( + cfg: OpenClawConfig, + env: NodeJS.ProcessEnv, +): ResolveAuthLabelResult { const mode = cfg.gateway?.auth?.mode; const defaults = cfg.secrets?.defaults; const tokenRef = resolveSecretInputRef({ @@ -188,19 +189,19 @@ function resolveAuth(cfg: OpenClawConfig, env: NodeJS.ProcessEnv): ResolveAuthRe if (!password) { return { error: "Gateway auth is set to password, but no password is configured." }; } - return { password, label: "password" }; + return { label: "password" }; } if (mode === "token") { if (!token) { return { error: "Gateway auth is set to token, but no token is configured." }; } - return { token, label: "token" }; + return { label: "token" }; } if (token) { - return { token, label: "token" }; + return { label: "token" }; } if (password) { - return { password, label: "password" }; + return { label: "password" }; } return { error: "Gateway auth is not configured (no token or password)." }; } @@ -287,6 +288,14 @@ async function resolveGatewayPasswordSecretRef( }; } +async function materializePairingSetupAuthConfig( + cfg: OpenClawConfig, + env: NodeJS.ProcessEnv, +): Promise { + const cfgWithToken = await resolveGatewayTokenSecretRef(cfg, env); + return await resolveGatewayPasswordSecretRef(cfgWithToken, env); +} + async function resolveGatewayUrl( cfg: OpenClawConfig, opts: { @@ -361,11 +370,10 @@ export async function resolvePairingSetupFromConfig( ): Promise { assertExplicitGatewayAuthModeWhenBothConfigured(cfg); const env = options.env ?? process.env; - const cfgWithToken = await resolveGatewayTokenSecretRef(cfg, env); - const cfgForAuth = await resolveGatewayPasswordSecretRef(cfgWithToken, env); - const auth = resolveAuth(cfgForAuth, env); - if (auth.error) { - return { ok: false, error: auth.error }; + const cfgForAuth = await materializePairingSetupAuthConfig(cfg, env); + const authLabel = resolvePairingSetupAuthLabel(cfgForAuth, env); + if (authLabel.error) { + return { ok: false, error: authLabel.error }; } const urlResult = await resolveGatewayUrl(cfgForAuth, { @@ -381,7 +389,7 @@ export async function resolvePairingSetupFromConfig( return { ok: false, error: urlResult.error ?? "Gateway URL unavailable." }; } - if (!auth.label) { + if (!authLabel.label) { return { ok: false, error: "Gateway auth is not configured (no token or password)." }; } @@ -395,7 +403,7 @@ export async function resolvePairingSetupFromConfig( }) ).token, }, - authLabel: auth.label, + authLabel: authLabel.label, urlSource: urlResult.source ?? "unknown", }; }