Refactor file access to use fs-safe primitives (#78255)

* refactor: use fs-safe primitives across file access

* fix: preserve invalid managed npm manifests

* fix: keep fs seams for startup metadata
This commit is contained in:
Peter Steinberger
2026-05-06 05:03:11 +01:00
committed by GitHub
parent 0d73f174a9
commit b85b1c68d1
56 changed files with 409 additions and 568 deletions

View File

@@ -2,7 +2,10 @@ import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";
import { writeJsonFileAtomically as writeJsonFileAtomicallyImpl } from "openclaw/plugin-sdk/json-store";
import {
loadJsonFile,
writeJsonFileAtomically as writeJsonFileAtomicallyImpl,
} from "openclaw/plugin-sdk/json-store";
import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
import { resolveConfiguredMatrixAccountIds } from "./account-selection.js";
import { isMatrixLegacyCryptoInspectorAvailable } from "./legacy-crypto-inspector-availability.js";
@@ -208,20 +211,13 @@ function resolveLegacyMatrixFlatStorePlan(params: {
function loadLegacyBotSdkMetadata(cryptoRootDir: string): MatrixLegacyBotSdkMetadata {
const metadataPath = path.join(cryptoRootDir, "bot-sdk.json");
const fallback: MatrixLegacyBotSdkMetadata = { deviceId: null };
try {
if (!fs.existsSync(metadataPath)) {
return fallback;
}
const parsed = JSON.parse(fs.readFileSync(metadataPath, "utf8")) as {
deviceId?: unknown;
};
return {
deviceId:
typeof parsed.deviceId === "string" && parsed.deviceId.trim() ? parsed.deviceId : null,
};
} catch {
return fallback;
}
const parsed = loadJsonFile<{ deviceId?: unknown }>(metadataPath);
return {
deviceId:
typeof parsed?.deviceId === "string" && parsed.deviceId.trim()
? parsed.deviceId
: fallback.deviceId,
};
}
function resolveMatrixLegacyCryptoPlans(params: {
@@ -288,25 +284,11 @@ function resolveMatrixLegacyCryptoPlans(params: {
}
function loadStoredRecoveryKey(filePath: string): MatrixStoredRecoveryKey | null {
try {
if (!fs.existsSync(filePath)) {
return null;
}
return JSON.parse(fs.readFileSync(filePath, "utf8")) as MatrixStoredRecoveryKey;
} catch {
return null;
}
return loadJsonFile<MatrixStoredRecoveryKey>(filePath) ?? null;
}
function loadLegacyCryptoMigrationState(filePath: string): MatrixLegacyCryptoMigrationState | null {
try {
if (!fs.existsSync(filePath)) {
return null;
}
return JSON.parse(fs.readFileSync(filePath, "utf8")) as MatrixLegacyCryptoMigrationState;
} catch {
return null;
}
return loadJsonFile<MatrixLegacyCryptoMigrationState>(filePath) ?? null;
}
async function persistLegacyMigrationState(params: {

View File

@@ -3,6 +3,7 @@ import os from "node:os";
import path from "node:path";
import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";
import { loadJsonFile, saveJsonFile } from "openclaw/plugin-sdk/json-store";
import {
requiresExplicitMatrixDefaultAccount,
resolveMatrixDefaultOrOnlyAccountId,
@@ -105,10 +106,10 @@ function resolveStorageRootMtimeMs(rootDir: string): number {
function readStoredRootMetadata(rootDir: string): StoredRootMetadata {
const metadata: StoredRootMetadata = {};
try {
const parsed = JSON.parse(
fs.readFileSync(path.join(rootDir, STORAGE_META_FILENAME), "utf8"),
) as Partial<StoredRootMetadata>;
const parsed = loadJsonFile<Partial<StoredRootMetadata>>(
path.join(rootDir, STORAGE_META_FILENAME),
);
if (parsed) {
if (typeof parsed.homeserver === "string" && parsed.homeserver.trim()) {
metadata.homeserver = parsed.homeserver.trim();
}
@@ -130,19 +131,17 @@ function readStoredRootMetadata(rootDir: string): StoredRootMetadata {
if (typeof parsed.createdAt === "string" && parsed.createdAt.trim()) {
metadata.createdAt = parsed.createdAt.trim();
}
} catch {
// ignore missing or malformed storage metadata
}
try {
const parsed = JSON.parse(
fs.readFileSync(path.join(rootDir, STARTUP_VERIFICATION_FILENAME), "utf8"),
) as { deviceId?: unknown };
if (!metadata.deviceId && typeof parsed.deviceId === "string" && parsed.deviceId.trim()) {
metadata.deviceId = parsed.deviceId.trim();
}
} catch {
// ignore missing or malformed verification state
const verification = loadJsonFile<{ deviceId?: unknown }>(
path.join(rootDir, STARTUP_VERIFICATION_FILENAME),
);
if (
!metadata.deviceId &&
typeof verification?.deviceId === "string" &&
verification.deviceId.trim()
) {
metadata.deviceId = verification.deviceId.trim();
}
return metadata;
@@ -473,8 +472,7 @@ function writeStoredRootMetadata(
},
): boolean {
try {
fs.mkdirSync(path.dirname(metaPath), { recursive: true });
fs.writeFileSync(metaPath, JSON.stringify(payload, null, 2), "utf-8");
saveJsonFile(metaPath, payload);
return true;
} catch {
return false;

View File

@@ -1,6 +1,5 @@
import fs from "node:fs";
import path from "node:path";
import { decodeRecoveryKey } from "matrix-js-sdk/lib/crypto-api/recovery-key.js";
import { loadJsonFile, saveJsonFile } from "openclaw/plugin-sdk/json-store";
import { formatMatrixErrorMessage, formatMatrixErrorReason } from "../errors.js";
import { LogService } from "./logger.js";
import type {
@@ -399,13 +398,9 @@ export class MatrixRecoveryKeyStore {
return null;
}
try {
if (!fs.existsSync(this.recoveryKeyPath)) {
return null;
}
const raw = fs.readFileSync(this.recoveryKeyPath, "utf8");
const parsed = JSON.parse(raw) as Partial<MatrixStoredRecoveryKey>;
const parsed = loadJsonFile<Partial<MatrixStoredRecoveryKey>>(this.recoveryKeyPath);
if (
parsed.version !== 1 ||
parsed?.version !== 1 ||
typeof parsed.createdAt !== "string" ||
typeof parsed.privateKeyBase64 !== "string" || // pragma: allowlist secret
!parsed.privateKeyBase64.trim()
@@ -450,9 +445,7 @@ export class MatrixRecoveryKeyStore {
}
: undefined,
};
fs.mkdirSync(path.dirname(this.recoveryKeyPath), { recursive: true });
fs.writeFileSync(this.recoveryKeyPath, JSON.stringify(payload, null, 2), "utf8");
fs.chmodSync(this.recoveryKeyPath, 0o600);
saveJsonFile(this.recoveryKeyPath, payload);
} catch (err) {
LogService.warn("MatrixClientLite", "Failed to persist recovery key:", err);
}