mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-23 22:55:24 +00:00
refactor: trim bluebubbles runtime seams
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { isBlockedHostnameOrIp } from "openclaw/plugin-sdk/infra-runtime";
|
||||
import { isBlockedHostnameOrIp } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { resolveBlueBubblesAccount } from "./accounts.js";
|
||||
import type { OpenClawConfig } from "./runtime-api.js";
|
||||
import { normalizeResolvedSecretInputString } from "./secret-input.js";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import crypto from "node:crypto";
|
||||
import path from "node:path";
|
||||
import type { SsrFPolicy } from "openclaw/plugin-sdk/infra-runtime";
|
||||
import type { SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { resolveBlueBubblesServerAccount } from "./account-resolve.js";
|
||||
import { assertMultipartActionOk, postMultipartFormData } from "./multipart.js";
|
||||
import { getCachedBlueBubblesPrivateApiStatus } from "./probe.js";
|
||||
|
||||
60
extensions/bluebubbles/src/local-file-access.ts
Normal file
60
extensions/bluebubbles/src/local-file-access.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import path from "node:path";
|
||||
import { fileURLToPath, URL } from "node:url";
|
||||
|
||||
function isLocalFileUrlHost(hostname: string): boolean {
|
||||
return hostname === "" || hostname.toLowerCase() === "localhost";
|
||||
}
|
||||
|
||||
function assertNoWindowsNetworkPath(filePath: string, label = "Path"): void {
|
||||
if (process.platform !== "win32") {
|
||||
return;
|
||||
}
|
||||
const normalized = filePath.replace(/\//g, "\\");
|
||||
if (normalized.startsWith("\\\\?\\UNC\\") || normalized.startsWith("\\\\")) {
|
||||
throw new Error(`${label} cannot use Windows network paths: ${filePath}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function safeFileURLToPath(fileUrl: string): string {
|
||||
let parsed: URL;
|
||||
try {
|
||||
parsed = new URL(fileUrl);
|
||||
} catch {
|
||||
throw new Error(`Invalid file:// URL: ${fileUrl}`);
|
||||
}
|
||||
if (parsed.protocol !== "file:") {
|
||||
throw new Error(`Invalid file:// URL: ${fileUrl}`);
|
||||
}
|
||||
if (!isLocalFileUrlHost(parsed.hostname)) {
|
||||
throw new Error(`file:// URLs with remote hosts are not allowed: ${fileUrl}`);
|
||||
}
|
||||
const filePath = fileURLToPath(parsed);
|
||||
assertNoWindowsNetworkPath(filePath, "Local file URL");
|
||||
return filePath;
|
||||
}
|
||||
|
||||
function trySafeFileURLToPath(fileUrl: string): string | undefined {
|
||||
try {
|
||||
return safeFileURLToPath(fileUrl);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function basenameFromMediaSource(source?: string): string | undefined {
|
||||
if (!source) {
|
||||
return undefined;
|
||||
}
|
||||
if (source.startsWith("file://")) {
|
||||
const filePath = trySafeFileURLToPath(source);
|
||||
return filePath ? path.basename(filePath) || undefined : undefined;
|
||||
}
|
||||
if (/^https?:\/\//i.test(source)) {
|
||||
try {
|
||||
return path.basename(new URL(source).pathname) || undefined;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return path.basename(source) || undefined;
|
||||
}
|
||||
@@ -2,9 +2,9 @@ import { constants as fsConstants } from "node:fs";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { basenameFromMediaSource, safeFileURLToPath } from "openclaw/plugin-sdk/infra-runtime";
|
||||
import { resolveBlueBubblesAccount } from "./accounts.js";
|
||||
import { sendBlueBubblesAttachment } from "./attachments.js";
|
||||
import { basenameFromMediaSource, safeFileURLToPath } from "./local-file-access.js";
|
||||
import { resolveBlueBubblesMessageId } from "./monitor.js";
|
||||
import { resolveChannelMediaMaxBytes, type OpenClawConfig } from "./runtime-api.js";
|
||||
import { getBlueBubblesRuntime } from "./runtime.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { SsrFPolicy } from "openclaw/plugin-sdk/infra-runtime";
|
||||
import type { SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { blueBubblesFetchWithTimeout } from "./types.js";
|
||||
|
||||
export function concatUint8Arrays(parts: Uint8Array[]): Uint8Array {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { fetchWithSsrFGuard, type SsrFPolicy } from "openclaw/plugin-sdk/infra-runtime";
|
||||
import type { DmPolicy, GroupPolicy } from "openclaw/plugin-sdk/setup";
|
||||
import { fetchWithSsrFGuard, type SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
|
||||
export type { SsrFPolicy } from "openclaw/plugin-sdk/infra-runtime";
|
||||
export type { SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
export type { DmPolicy, GroupPolicy } from "openclaw/plugin-sdk/setup";
|
||||
|
||||
export type BlueBubblesGroupConfig = {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
export {
|
||||
closeDispatcher,
|
||||
createPinnedDispatcher,
|
||||
isBlockedHostnameOrIp,
|
||||
resolvePinnedHostnameWithPolicy,
|
||||
type LookupFn,
|
||||
type SsrFPolicy,
|
||||
|
||||
Reference in New Issue
Block a user