Files
platform/src/extensions/browser-relay/background-utils.js
T
pastilhasandClaude Opus 4.6 8f1963fedb user-scoped channel sessions, whatsapp disconnect cleanup, browser relay token fix
Channel session IDs now include userId (channel-{provider}-{userId}-{contextId})
to prevent cross-user contamination in multi-user setups. WhatsApp disconnect
properly logs out and clears cached auth. Browser relay uses server-derived token
directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 14:14:47 +00:00

52 lines
1.7 KiB
JavaScript

// Based on OpenClaw Browser Extension Relay (MIT License)
// https://github.com/nicepkg/openclaw
export function reconnectDelayMs(
attempt,
opts = { baseMs: 1000, maxMs: 30000, jitterMs: 1000, random: Math.random },
) {
const baseMs = Number.isFinite(opts.baseMs) ? opts.baseMs : 1000;
const maxMs = Number.isFinite(opts.maxMs) ? opts.maxMs : 30000;
const jitterMs = Number.isFinite(opts.jitterMs) ? opts.jitterMs : 1000;
const random = typeof opts.random === "function" ? opts.random : Math.random;
const safeAttempt = Math.max(0, Number.isFinite(attempt) ? attempt : 0);
const backoff = Math.min(baseMs * 2 ** safeAttempt, maxMs);
return backoff + Math.max(0, jitterMs) * random();
}
export async function deriveRelayToken(gatewayToken, port) {
const enc = new TextEncoder();
const key = await crypto.subtle.importKey(
"raw",
enc.encode(gatewayToken),
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"],
);
const sig = await crypto.subtle.sign(
"HMAC",
key,
enc.encode(`officer-browser-relay-v1:${port}`),
);
return [...new Uint8Array(sig)].map((b) => b.toString(16).padStart(2, "0")).join("");
}
export async function buildRelayWsUrl(host, port, gatewayToken) {
const token = String(gatewayToken || "").trim();
if (!token) {
throw new Error(
"Missing relay token in extension settings (chrome.storage.local.relayToken)",
);
}
// Token is already derived server-side — use it directly
return `ws://${host}:${port}/extension?token=${encodeURIComponent(token)}`;
}
export function isRetryableReconnectError(err) {
const message = err instanceof Error ? err.message : String(err || "");
if (message.includes("Missing relay token")) {
return false;
}
return true;
}