mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 11:30:43 +00:00
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:
committed by
GitHub
parent
0d73f174a9
commit
b85b1c68d1
@@ -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: {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user