fix(matrix): use fixed crypto bootstrap command (#97181)

* fix(matrix): use fixed crypto bootstrap command

* chore(matrix): drop release metadata bump
This commit is contained in:
Patrick Erichsen
2026-06-29 21:02:00 -07:00
committed by GitHub
parent 72f837a4a4
commit 85ee71223f
2 changed files with 49 additions and 62 deletions
+46 -49
View File
@@ -56,55 +56,54 @@ function resolveTestNativeBindingFilename(): string | null {
describe("ensureMatrixCryptoRuntime", () => {
it("returns immediately when matrix SDK loads", async () => {
const runCommand = vi.fn();
const requireFn = vi.fn(() => ({}));
await ensureMatrixCryptoRuntime({
log: logStub,
requireFn,
runCommand,
resolveFn: () => "/tmp/download-lib.js",
nodeExecutable: "/usr/bin/node",
});
expect(requireFn).toHaveBeenCalledTimes(1);
expect(runCommand).not.toHaveBeenCalled();
});
it("bootstraps missing crypto runtime and retries matrix SDK load", async () => {
let bootstrapped = false;
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-crypto-bootstrap-"));
const scriptPath = path.join(tmpDir, "download-lib.js");
const markerPath = path.join(tmpDir, "bootstrapped");
fs.writeFileSync(
scriptPath,
[
'const fs = require("node:fs");',
`if (fs.realpathSync(process.cwd()) !== ${JSON.stringify(fs.realpathSync(tmpDir))}) process.exit(2);`,
'if (process.env.COREPACK_ENABLE_DOWNLOAD_PROMPT !== "0") process.exit(3);',
`fs.writeFileSync(${JSON.stringify(markerPath)}, "ok");`,
].join("\n"),
);
const requireFn = vi.fn(() => {
if (!bootstrapped) {
if (!fs.existsSync(markerPath)) {
throw new Error(
"Cannot find module '@matrix-org/matrix-sdk-crypto-nodejs-linux-x64-gnu' (required by matrix sdk)",
);
}
return {};
});
const runCommand = vi.fn(async () => {
bootstrapped = true;
return { code: 0, stdout: "", stderr: "" };
});
await ensureMatrixCryptoRuntime({
log: logStub,
requireFn,
runCommand,
resolveFn: () => "/tmp/download-lib.js",
nodeExecutable: "/usr/bin/node",
});
try {
await ensureMatrixCryptoRuntime({
log: logStub,
requireFn,
resolveFn: () => scriptPath,
});
expect(runCommand).toHaveBeenCalledWith({
argv: ["/usr/bin/node", "/tmp/download-lib.js"],
cwd: "/tmp",
timeoutMs: 300_000,
env: { COREPACK_ENABLE_DOWNLOAD_PROMPT: "0" },
});
expect(requireFn).toHaveBeenCalledTimes(2);
expect(fs.readFileSync(markerPath, "utf8")).toBe("ok");
expect(requireFn).toHaveBeenCalledTimes(2);
} finally {
fs.rmSync(tmpDir, { recursive: true, force: true });
}
});
it("rethrows non-crypto module errors without bootstrapping", async () => {
const runCommand = vi.fn();
const requireFn = vi.fn(() => {
throw new Error("Cannot find module 'not-the-matrix-crypto-runtime'");
});
@@ -113,13 +112,10 @@ describe("ensureMatrixCryptoRuntime", () => {
ensureMatrixCryptoRuntime({
log: logStub,
requireFn,
runCommand,
resolveFn: () => "/tmp/download-lib.js",
nodeExecutable: "/usr/bin/node",
}),
).rejects.toThrow("Cannot find module 'not-the-matrix-crypto-runtime'");
expect(runCommand).not.toHaveBeenCalled();
expect(requireFn).toHaveBeenCalledTimes(1);
});
@@ -132,38 +128,39 @@ describe("ensureMatrixCryptoRuntime", () => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-crypto-runtime-"));
const scriptPath = path.join(tmpDir, "download-lib.js");
const nativeBindingPath = path.join(tmpDir, nativeBindingFilename);
fs.writeFileSync(scriptPath, "");
fs.writeFileSync(
scriptPath,
[
'const fs = require("node:fs");',
`fs.writeFileSync(${JSON.stringify(nativeBindingPath)}, Buffer.alloc(1_000_000));`,
].join("\n"),
);
fs.writeFileSync(nativeBindingPath, Buffer.alloc(16));
let bootstrapped = false;
const requireFn = vi.fn(() => {
if (!bootstrapped) {
if (!fs.existsSync(nativeBindingPath) || fs.statSync(nativeBindingPath).size < 1_000_000) {
throw new Error(
"Cannot find module '@matrix-org/matrix-sdk-crypto-nodejs-linux-x64-gnu' (required by matrix sdk)",
);
}
return {};
});
const runCommand = vi.fn(async () => {
bootstrapped = true;
fs.writeFileSync(nativeBindingPath, Buffer.alloc(1_000_000));
return { code: 0, stdout: "", stderr: "" };
});
await ensureMatrixCryptoRuntime({
log: logStub,
requireFn,
runCommand,
resolveFn: () => scriptPath,
nodeExecutable: "/usr/bin/node",
});
try {
await ensureMatrixCryptoRuntime({
log: logStub,
requireFn,
resolveFn: () => scriptPath,
});
expect(runCommand).toHaveBeenCalledTimes(1);
expect(requireFn).toHaveBeenCalledTimes(2);
expect(fs.statSync(nativeBindingPath).size).toBe(1_000_000);
expect(logStub).toHaveBeenCalledWith(
"matrix: removed incomplete native crypto runtime (16 bytes); it will be downloaded again",
);
expect(requireFn).toHaveBeenCalledTimes(2);
expect(fs.statSync(nativeBindingPath).size).toBe(1_000_000);
expect(logStub).toHaveBeenCalledWith(
"matrix: removed incomplete native crypto runtime (16 bytes); it will be downloaded again",
);
} finally {
fs.rmSync(tmpDir, { recursive: true, force: true });
}
});
});
+3 -13
View File
@@ -16,14 +16,7 @@ export const MATRIX_COMMAND_OUTPUT_TAIL_BYTES = 64 * 1024;
type MatrixCryptoRuntimeDeps = {
requireFn?: (id: string) => unknown;
runCommand?: (params: {
argv: string[];
cwd: string;
timeoutMs: number;
env?: NodeJS.ProcessEnv;
}) => Promise<CommandResult>;
resolveFn?: (id: string) => string;
nodeExecutable?: string;
log?: (message: string) => void;
};
@@ -266,8 +259,7 @@ function removeIncompleteMatrixCryptoNativeBinding(params: {
export async function ensureMatrixCryptoRuntime(
params: MatrixCryptoRuntimeDeps = {},
): Promise<void> {
const usesDefaultRuntime =
!params.requireFn && !params.runCommand && !params.resolveFn && !params.nodeExecutable;
const usesDefaultRuntime = !params.requireFn && !params.resolveFn;
if (usesDefaultRuntime && defaultMatrixCryptoRuntimeEnsurePromise) {
await defaultMatrixCryptoRuntimeEnsurePromise;
return;
@@ -300,10 +292,8 @@ async function ensureMatrixCryptoRuntimeOnce(params: MatrixCryptoRuntimeDeps): P
const scriptPath = resolveFn("@matrix-org/matrix-sdk-crypto-nodejs/download-lib.js");
params.log?.("matrix: bootstrapping native crypto runtime");
const runCommand = params.runCommand ?? runFixedCommandWithTimeout;
const nodeExecutable = params.nodeExecutable ?? process.execPath;
const result = await runCommand({
argv: [nodeExecutable, scriptPath],
const result = await runFixedCommandWithTimeout({
argv: [process.execPath, scriptPath],
cwd: path.dirname(scriptPath),
timeoutMs: 300_000,
env: { COREPACK_ENABLE_DOWNLOAD_PROMPT: "0" },