diff --git a/src/infra/matrix-account-selection.ts b/src/infra/matrix-account-selection.ts deleted file mode 100644 index 195589597be..00000000000 --- a/src/infra/matrix-account-selection.ts +++ /dev/null @@ -1,96 +0,0 @@ -import type { OpenClawConfig } from "../config/config.js"; -import { - DEFAULT_ACCOUNT_ID, - normalizeAccountId, - normalizeOptionalAccountId, -} from "../routing/session-key.js"; - -function isRecord(value: unknown): value is Record { - return Boolean(value) && typeof value === "object" && !Array.isArray(value); -} - -export function resolveMatrixChannelConfig(cfg: OpenClawConfig): Record | null { - return isRecord(cfg.channels?.matrix) ? cfg.channels.matrix : null; -} - -export function findMatrixAccountEntry( - cfg: OpenClawConfig, - accountId: string, -): Record | null { - const channel = resolveMatrixChannelConfig(cfg); - if (!channel) { - return null; - } - - const accounts = isRecord(channel.accounts) ? channel.accounts : null; - if (!accounts) { - return null; - } - - const normalizedAccountId = normalizeAccountId(accountId); - for (const [rawAccountId, value] of Object.entries(accounts)) { - if (normalizeAccountId(rawAccountId) === normalizedAccountId && isRecord(value)) { - return value; - } - } - - return null; -} - -export function resolveConfiguredMatrixAccountIds(cfg: OpenClawConfig): string[] { - const channel = resolveMatrixChannelConfig(cfg); - if (!channel) { - return []; - } - - const accounts = isRecord(channel.accounts) ? channel.accounts : null; - if (!accounts) { - return [DEFAULT_ACCOUNT_ID]; - } - - const ids = Object.entries(accounts) - .filter(([, value]) => isRecord(value)) - .map(([accountId]) => normalizeAccountId(accountId)); - - return Array.from(new Set(ids.length > 0 ? ids : [DEFAULT_ACCOUNT_ID])).toSorted((a, b) => - a.localeCompare(b), - ); -} - -export function resolveMatrixDefaultOrOnlyAccountId(cfg: OpenClawConfig): string { - const channel = resolveMatrixChannelConfig(cfg); - if (!channel) { - return DEFAULT_ACCOUNT_ID; - } - - const configuredDefault = normalizeOptionalAccountId( - typeof channel.defaultAccount === "string" ? channel.defaultAccount : undefined, - ); - const configuredAccountIds = resolveConfiguredMatrixAccountIds(cfg); - if (configuredDefault && configuredAccountIds.includes(configuredDefault)) { - return configuredDefault; - } - if (configuredAccountIds.includes(DEFAULT_ACCOUNT_ID)) { - return DEFAULT_ACCOUNT_ID; - } - - if (configuredAccountIds.length === 1) { - return configuredAccountIds[0] ?? DEFAULT_ACCOUNT_ID; - } - return DEFAULT_ACCOUNT_ID; -} - -export function requiresExplicitMatrixDefaultAccount(cfg: OpenClawConfig): boolean { - const channel = resolveMatrixChannelConfig(cfg); - if (!channel) { - return false; - } - const configuredAccountIds = resolveConfiguredMatrixAccountIds(cfg); - if (configuredAccountIds.length <= 1) { - return false; - } - const configuredDefault = normalizeOptionalAccountId( - typeof channel.defaultAccount === "string" ? channel.defaultAccount : undefined, - ); - return !(configuredDefault && configuredAccountIds.includes(configuredDefault)); -} diff --git a/src/infra/matrix-env-vars.ts b/src/infra/matrix-env-vars.ts deleted file mode 100644 index b5c437d4859..00000000000 --- a/src/infra/matrix-env-vars.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { normalizeAccountId } from "../routing/session-key.js"; - -export function resolveMatrixEnvAccountToken(accountId: string): string { - return Array.from(normalizeAccountId(accountId)) - .map((char) => - /[a-z0-9]/.test(char) - ? char.toUpperCase() - : `_X${char.codePointAt(0)?.toString(16).toUpperCase() ?? "00"}_`, - ) - .join(""); -} - -export function getMatrixScopedEnvVarNames(accountId: string): { - homeserver: string; - userId: string; - accessToken: string; - password: string; - deviceId: string; - deviceName: string; -} { - const token = resolveMatrixEnvAccountToken(accountId); - return { - homeserver: `MATRIX_${token}_HOMESERVER`, - userId: `MATRIX_${token}_USER_ID`, - accessToken: `MATRIX_${token}_ACCESS_TOKEN`, - password: `MATRIX_${token}_PASSWORD`, - deviceId: `MATRIX_${token}_DEVICE_ID`, - deviceName: `MATRIX_${token}_DEVICE_NAME`, - }; -} diff --git a/src/infra/matrix-storage-paths.ts b/src/infra/matrix-storage-paths.ts deleted file mode 100644 index 08ab39c16a5..00000000000 --- a/src/infra/matrix-storage-paths.ts +++ /dev/null @@ -1,93 +0,0 @@ -import crypto from "node:crypto"; -import path from "node:path"; -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js"; - -export function sanitizeMatrixPathSegment(value: string): string { - const cleaned = value - .trim() - .toLowerCase() - .replace(/[^a-z0-9._-]+/g, "_") - .replace(/^_+|_+$/g, ""); - return cleaned || "unknown"; -} - -export function resolveMatrixHomeserverKey(homeserver: string): string { - try { - const url = new URL(homeserver); - if (url.host) { - return sanitizeMatrixPathSegment(url.host); - } - } catch { - // fall through - } - return sanitizeMatrixPathSegment(homeserver); -} - -export function hashMatrixAccessToken(accessToken: string): string { - return crypto.createHash("sha256").update(accessToken).digest("hex").slice(0, 16); -} - -export function resolveMatrixCredentialsFilename(accountId?: string | null): string { - const normalized = normalizeAccountId(accountId); - return normalized === DEFAULT_ACCOUNT_ID ? "credentials.json" : `credentials-${normalized}.json`; -} - -export function resolveMatrixCredentialsDir(stateDir: string): string { - return path.join(stateDir, "credentials", "matrix"); -} - -export function resolveMatrixCredentialsPath(params: { - stateDir: string; - accountId?: string | null; -}): string { - return path.join( - resolveMatrixCredentialsDir(params.stateDir), - resolveMatrixCredentialsFilename(params.accountId), - ); -} - -export function resolveMatrixLegacyFlatStoreRoot(stateDir: string): string { - return path.join(stateDir, "matrix"); -} - -export function resolveMatrixLegacyFlatStoragePaths(stateDir: string): { - rootDir: string; - storagePath: string; - cryptoPath: string; -} { - const rootDir = resolveMatrixLegacyFlatStoreRoot(stateDir); - return { - rootDir, - storagePath: path.join(rootDir, "bot-storage.json"), - cryptoPath: path.join(rootDir, "crypto"), - }; -} - -export function resolveMatrixAccountStorageRoot(params: { - stateDir: string; - homeserver: string; - userId: string; - accessToken: string; - accountId?: string | null; -}): { - rootDir: string; - accountKey: string; - tokenHash: string; -} { - const accountKey = sanitizeMatrixPathSegment(params.accountId ?? DEFAULT_ACCOUNT_ID); - const userKey = sanitizeMatrixPathSegment(params.userId); - const serverKey = resolveMatrixHomeserverKey(params.homeserver); - const tokenHash = hashMatrixAccessToken(params.accessToken); - return { - rootDir: path.join( - params.stateDir, - "matrix", - "accounts", - accountKey, - `${serverKey}__${userKey}`, - tokenHash, - ), - accountKey, - tokenHash, - }; -}