mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 12:26:38 -06:00
fix(signal): clear stale account identity
This commit is contained in:
@@ -145,6 +145,47 @@ describe("signalSetupAdapter", () => {
|
||||
},
|
||||
);
|
||||
|
||||
it("clears the UUID when setup replaces the normalized Signal account", () => {
|
||||
const next = signalSetupAdapter.applyAccountConfig?.({
|
||||
cfg: {
|
||||
channels: {
|
||||
signal: {
|
||||
accounts: {
|
||||
work: {
|
||||
account: "+15555550123",
|
||||
accountUuid: "123e4567-e89b-12d3-a456-426614174000",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
accountId: "work",
|
||||
input: { signalNumber: "+15555550124" },
|
||||
});
|
||||
|
||||
expect(next?.channels?.signal?.accounts?.work?.account).toBe("+15555550124");
|
||||
expect(next?.channels?.signal?.accounts?.work?.accountUuid).toBeUndefined();
|
||||
});
|
||||
|
||||
it("preserves the UUID when setup keeps the same normalized Signal account", () => {
|
||||
const accountUuid = "123e4567-e89b-12d3-a456-426614174000";
|
||||
const next = signalSetupAdapter.applyAccountConfig?.({
|
||||
cfg: {
|
||||
channels: {
|
||||
signal: {
|
||||
account: "+15555550123",
|
||||
accountUuid,
|
||||
},
|
||||
},
|
||||
},
|
||||
accountId: "default",
|
||||
input: { signalNumber: "signal: +1 (555) 555-0123" },
|
||||
});
|
||||
|
||||
expect(next?.channels?.signal?.account).toBe("+15555550123");
|
||||
expect(next?.channels?.signal?.accountUuid).toBe(accountUuid);
|
||||
});
|
||||
|
||||
it("restores a generically promoted default account before writing a named account", () => {
|
||||
const next = signalSetupAdapter.applyAccountConfig?.({
|
||||
cfg: {
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
createPatchedAccountSetupAdapter,
|
||||
createSetupInputPresenceValidator,
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
patchChannelConfigForAccount,
|
||||
promptParsedAllowFromForAccount,
|
||||
setAccountAllowFromForChannel,
|
||||
setSetupChannelEnabled,
|
||||
@@ -169,6 +170,10 @@ export function normalizeSignalAccountInput(value: string | null | undefined): s
|
||||
return `+${digits}`;
|
||||
}
|
||||
|
||||
export function isSameSignalAccount(left: string | null | undefined, right: string): boolean {
|
||||
return normalizeSignalAccountInput(left) === normalizeSignalAccountInput(right);
|
||||
}
|
||||
|
||||
function isUuidLike(value: string): boolean {
|
||||
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
||||
}
|
||||
@@ -504,7 +509,18 @@ export const signalSetupAdapter: ChannelSetupAdapter<SignalSetupInput> = {
|
||||
// transport. Rejoin that pair here so Signal keeps one canonical default-account shape.
|
||||
const cfg = restorePromotedSignalDefaultAccount(params.cfg);
|
||||
const previousTransport = resolveConfiguredSignalTransport(cfg, accountId);
|
||||
const next = signalSetupAdapterBase.applyAccountConfig?.({ ...params, cfg, accountId }) ?? cfg;
|
||||
let next = signalSetupAdapterBase.applyAccountConfig?.({ ...params, cfg, accountId }) ?? cfg;
|
||||
if (
|
||||
suppliedAccount &&
|
||||
!isSameSignalAccount(resolveSignalAccount({ cfg, accountId }).config.account, suppliedAccount)
|
||||
) {
|
||||
next = patchChannelConfigForAccount({
|
||||
cfg: next,
|
||||
channel,
|
||||
accountId,
|
||||
patch: { accountUuid: undefined },
|
||||
});
|
||||
}
|
||||
const configuredTransport = resolveConfiguredSignalTransport(next, accountId);
|
||||
if (configuredTransport && configuredTransport.kind !== "managed-native") {
|
||||
const transport =
|
||||
|
||||
@@ -308,6 +308,39 @@ describe("Signal existing-server setup", () => {
|
||||
expect(finalized?.cfg?.channels?.signal?.account).toBe("+15555550123");
|
||||
});
|
||||
|
||||
it("preserves the UUID when recovery keeps the same normalized account", async () => {
|
||||
mocks.probeSignalTransport.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
error: "selected account is unavailable",
|
||||
});
|
||||
const accountUuid = "123e4567-e89b-12d3-a456-426614174000";
|
||||
const queued = createQueuedWizardPrompter({
|
||||
selectValues: ["account"],
|
||||
textValues: ["signal: +1 (555) 555-0123"],
|
||||
});
|
||||
|
||||
const finalized = await runSetupWizardFinalize({
|
||||
finalize: signalSetupWizard.finalize,
|
||||
cfg: {
|
||||
channels: {
|
||||
signal: {
|
||||
account: "+15555550123",
|
||||
accountUuid,
|
||||
},
|
||||
},
|
||||
},
|
||||
credentialValues: {
|
||||
signalTransportKind: "external-native",
|
||||
signalServerUrl: "http://signal-helper:8080",
|
||||
},
|
||||
prompter: queued.prompter,
|
||||
runtime: createRuntimeEnv({ throwOnExit: false }),
|
||||
});
|
||||
|
||||
expect(finalized?.cfg?.channels?.signal?.account).toBe("+15555550123");
|
||||
expect(finalized?.cfg?.channels?.signal?.accountUuid).toBe(accountUuid);
|
||||
});
|
||||
|
||||
it("rejects an existing-server recovery account owned by a sibling", async () => {
|
||||
mocks.probeSignalTransport.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
} from "./accounts.js";
|
||||
import {
|
||||
assertSignalAccountNotAssignedToSibling,
|
||||
isSameSignalAccount,
|
||||
normalizeSignalAccountInput,
|
||||
signalSetupStateKeys,
|
||||
} from "./setup-core.js";
|
||||
@@ -67,7 +68,15 @@ export async function finalizeSignalExistingServerSetup(params: SignalFinalizePa
|
||||
cfg,
|
||||
channel: "signal",
|
||||
accountId: params.accountId,
|
||||
patch: { account, accountUuid: undefined },
|
||||
patch: {
|
||||
account,
|
||||
...(isSameSignalAccount(
|
||||
resolveSignalAccount({ cfg, accountId: params.accountId }).config.account,
|
||||
account,
|
||||
)
|
||||
? {}
|
||||
: { accountUuid: undefined }),
|
||||
},
|
||||
});
|
||||
shouldPromptAccount = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user