mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-07 22:09:57 +00:00
refactor(extensions): dedupe connector helper usage
This commit is contained in:
@@ -3,12 +3,8 @@ import type { CoreConfig } from "../../types.js";
|
||||
import type { MatrixActionClient, MatrixActionClientOpts } from "./types.js";
|
||||
import { getMatrixRuntime } from "../../runtime.js";
|
||||
import { getActiveMatrixClient } from "../active-client.js";
|
||||
import {
|
||||
createMatrixClient,
|
||||
isBunRuntime,
|
||||
resolveMatrixAuth,
|
||||
resolveSharedMatrixClient,
|
||||
} from "../client.js";
|
||||
import { createPreparedMatrixClient } from "../client-bootstrap.js";
|
||||
import { isBunRuntime, resolveMatrixAuth, resolveSharedMatrixClient } from "../client.js";
|
||||
|
||||
export function ensureNodeRuntime() {
|
||||
if (isBunRuntime()) {
|
||||
@@ -42,24 +38,10 @@ export async function resolveActionClient(
|
||||
cfg: getMatrixRuntime().config.loadConfig() as CoreConfig,
|
||||
accountId,
|
||||
});
|
||||
const client = await createMatrixClient({
|
||||
homeserver: auth.homeserver,
|
||||
userId: auth.userId,
|
||||
accessToken: auth.accessToken,
|
||||
encryption: auth.encryption,
|
||||
localTimeoutMs: opts.timeoutMs,
|
||||
const client = await createPreparedMatrixClient({
|
||||
auth,
|
||||
timeoutMs: opts.timeoutMs,
|
||||
accountId,
|
||||
});
|
||||
if (auth.encryption && client.crypto) {
|
||||
try {
|
||||
const joinedRooms = await client.getJoinedRooms();
|
||||
await (client.crypto as { prepare: (rooms?: string[]) => Promise<void> }).prepare(
|
||||
joinedRooms,
|
||||
);
|
||||
} catch {
|
||||
// Ignore crypto prep failures for one-off actions.
|
||||
}
|
||||
}
|
||||
await client.start();
|
||||
return { client, stopOnDone: true };
|
||||
}
|
||||
|
||||
39
extensions/matrix/src/matrix/client-bootstrap.ts
Normal file
39
extensions/matrix/src/matrix/client-bootstrap.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { createMatrixClient } from "./client.js";
|
||||
|
||||
type MatrixClientBootstrapAuth = {
|
||||
homeserver: string;
|
||||
userId: string;
|
||||
accessToken: string;
|
||||
encryption?: boolean;
|
||||
};
|
||||
|
||||
type MatrixCryptoPrepare = {
|
||||
prepare: (rooms?: string[]) => Promise<void>;
|
||||
};
|
||||
|
||||
type MatrixBootstrapClient = Awaited<ReturnType<typeof createMatrixClient>>;
|
||||
|
||||
export async function createPreparedMatrixClient(opts: {
|
||||
auth: MatrixClientBootstrapAuth;
|
||||
timeoutMs?: number;
|
||||
accountId?: string;
|
||||
}): Promise<MatrixBootstrapClient> {
|
||||
const client = await createMatrixClient({
|
||||
homeserver: opts.auth.homeserver,
|
||||
userId: opts.auth.userId,
|
||||
accessToken: opts.auth.accessToken,
|
||||
encryption: opts.auth.encryption,
|
||||
localTimeoutMs: opts.timeoutMs,
|
||||
accountId: opts.accountId,
|
||||
});
|
||||
if (opts.auth.encryption && client.crypto) {
|
||||
try {
|
||||
const joinedRooms = await client.getJoinedRooms();
|
||||
await (client.crypto as MatrixCryptoPrepare).prepare(joinedRooms);
|
||||
} catch {
|
||||
// Ignore crypto prep failures for one-off requests.
|
||||
}
|
||||
}
|
||||
await client.start();
|
||||
return client;
|
||||
}
|
||||
@@ -22,14 +22,12 @@ describe("downloadMatrixMedia", () => {
|
||||
setMatrixRuntime(runtimeStub);
|
||||
});
|
||||
|
||||
it("decrypts encrypted media when file payloads are present", async () => {
|
||||
function makeEncryptedMediaFixture() {
|
||||
const decryptMedia = vi.fn().mockResolvedValue(Buffer.from("decrypted"));
|
||||
|
||||
const client = {
|
||||
crypto: { decryptMedia },
|
||||
mxcToHttp: vi.fn().mockReturnValue("https://example/mxc"),
|
||||
} as unknown as import("@vector-im/matrix-bot-sdk").MatrixClient;
|
||||
|
||||
const file = {
|
||||
url: "mxc://example/file",
|
||||
key: {
|
||||
@@ -43,6 +41,11 @@ describe("downloadMatrixMedia", () => {
|
||||
hashes: { sha256: "hash" },
|
||||
v: "v2",
|
||||
};
|
||||
return { decryptMedia, client, file };
|
||||
}
|
||||
|
||||
it("decrypts encrypted media when file payloads are present", async () => {
|
||||
const { decryptMedia, client, file } = makeEncryptedMediaFixture();
|
||||
|
||||
const result = await downloadMatrixMedia({
|
||||
client,
|
||||
@@ -64,26 +67,7 @@ describe("downloadMatrixMedia", () => {
|
||||
});
|
||||
|
||||
it("rejects encrypted media that exceeds maxBytes before decrypting", async () => {
|
||||
const decryptMedia = vi.fn().mockResolvedValue(Buffer.from("decrypted"));
|
||||
|
||||
const client = {
|
||||
crypto: { decryptMedia },
|
||||
mxcToHttp: vi.fn().mockReturnValue("https://example/mxc"),
|
||||
} as unknown as import("@vector-im/matrix-bot-sdk").MatrixClient;
|
||||
|
||||
const file = {
|
||||
url: "mxc://example/file",
|
||||
key: {
|
||||
kty: "oct",
|
||||
key_ops: ["encrypt", "decrypt"],
|
||||
alg: "A256CTR",
|
||||
k: "secret",
|
||||
ext: true,
|
||||
},
|
||||
iv: "iv",
|
||||
hashes: { sha256: "hash" },
|
||||
v: "v2",
|
||||
};
|
||||
const { decryptMedia, client, file } = makeEncryptedMediaFixture();
|
||||
|
||||
await expect(
|
||||
downloadMatrixMedia({
|
||||
|
||||
@@ -3,12 +3,8 @@ import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/acco
|
||||
import type { CoreConfig } from "../../types.js";
|
||||
import { getMatrixRuntime } from "../../runtime.js";
|
||||
import { getActiveMatrixClient, getAnyActiveMatrixClient } from "../active-client.js";
|
||||
import {
|
||||
createMatrixClient,
|
||||
isBunRuntime,
|
||||
resolveMatrixAuth,
|
||||
resolveSharedMatrixClient,
|
||||
} from "../client.js";
|
||||
import { createPreparedMatrixClient } from "../client-bootstrap.js";
|
||||
import { isBunRuntime, resolveMatrixAuth, resolveSharedMatrixClient } from "../client.js";
|
||||
|
||||
const getCore = () => getMatrixRuntime();
|
||||
|
||||
@@ -92,25 +88,10 @@ export async function resolveMatrixClient(opts: {
|
||||
return { client, stopOnDone: false };
|
||||
}
|
||||
const auth = await resolveMatrixAuth({ accountId });
|
||||
const client = await createMatrixClient({
|
||||
homeserver: auth.homeserver,
|
||||
userId: auth.userId,
|
||||
accessToken: auth.accessToken,
|
||||
encryption: auth.encryption,
|
||||
localTimeoutMs: opts.timeoutMs,
|
||||
const client = await createPreparedMatrixClient({
|
||||
auth,
|
||||
timeoutMs: opts.timeoutMs,
|
||||
accountId,
|
||||
});
|
||||
if (auth.encryption && client.crypto) {
|
||||
try {
|
||||
const joinedRooms = await client.getJoinedRooms();
|
||||
await (client.crypto as { prepare: (rooms?: string[]) => Promise<void> }).prepare(
|
||||
joinedRooms,
|
||||
);
|
||||
} catch {
|
||||
// Ignore crypto prep failures for one-off sends; normal sync will retry.
|
||||
}
|
||||
}
|
||||
// @vector-im/matrix-bot-sdk uses start() instead of startClient()
|
||||
await client.start();
|
||||
return { client, stopOnDone: true };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user