Matrix: tighten migration identity matching

This commit is contained in:
Gustavo Madeira Santana
2026-03-12 03:27:06 +00:00
parent d4847c0163
commit a10d2b277e
2 changed files with 88 additions and 1 deletions

View File

@@ -11,6 +11,48 @@ function writeFile(filePath: string, value: string) {
}
describe("resolveMatrixMigrationAccountTarget", () => {
it("reuses stored user identity for token-only configs when the access token matches", async () => {
await withTempHome(async (home) => {
const stateDir = path.join(home, ".openclaw");
writeFile(
path.join(stateDir, "credentials", "matrix", "credentials-ops.json"),
JSON.stringify(
{
homeserver: "https://matrix.example.org",
userId: "@ops-bot:example.org",
accessToken: "tok-ops",
deviceId: "DEVICE-OPS",
},
null,
2,
),
);
const cfg: OpenClawConfig = {
channels: {
matrix: {
accounts: {
ops: {
homeserver: "https://matrix.example.org",
accessToken: "tok-ops",
},
},
},
},
};
const target = resolveMatrixMigrationAccountTarget({
cfg,
env: process.env,
accountId: "ops",
});
expect(target).not.toBeNull();
expect(target?.userId).toBe("@ops-bot:example.org");
expect(target?.storedDeviceId).toBe("DEVICE-OPS");
});
});
it("ignores stored device IDs from stale cached Matrix credentials", async () => {
await withTempHome(async (home) => {
const stateDir = path.join(home, ".openclaw");
@@ -54,4 +96,44 @@ describe("resolveMatrixMigrationAccountTarget", () => {
expect(target?.storedDeviceId).toBeNull();
});
});
it("does not trust stale stored creds on the same homeserver when the token changes", async () => {
await withTempHome(async (home) => {
const stateDir = path.join(home, ".openclaw");
writeFile(
path.join(stateDir, "credentials", "matrix", "credentials-ops.json"),
JSON.stringify(
{
homeserver: "https://matrix.example.org",
userId: "@old-bot:example.org",
accessToken: "tok-old",
deviceId: "DEVICE-OLD",
},
null,
2,
),
);
const cfg: OpenClawConfig = {
channels: {
matrix: {
accounts: {
ops: {
homeserver: "https://matrix.example.org",
accessToken: "tok-new",
},
},
},
},
};
const target = resolveMatrixMigrationAccountTarget({
cfg,
env: process.env,
accountId: "ops",
});
expect(target).toBeNull();
});
});
});

View File

@@ -165,13 +165,17 @@ export function credentialsMatchResolvedIdentity(
identity: {
homeserver: string;
userId: string;
accessToken: string;
},
): stored is MatrixStoredCredentials {
if (!stored || !identity.homeserver) {
return false;
}
if (!identity.userId) {
return stored.homeserver === identity.homeserver;
if (!identity.accessToken) {
return false;
}
return stored.homeserver === identity.homeserver && stored.accessToken === identity.accessToken;
}
return stored.homeserver === identity.homeserver && stored.userId === identity.userId;
}
@@ -186,6 +190,7 @@ export function resolveMatrixMigrationAccountTarget(params: {
const matchingStored = credentialsMatchResolvedIdentity(stored, {
homeserver: resolved.homeserver,
userId: resolved.userId,
accessToken: resolved.accessToken,
})
? stored
: null;