import fs from "node:fs/promises" ;
import path from "node:path" ;
import { assertNoWindowsNetworkPath } from "../infra/local-file-access.js" ;
import { getDefaultMediaLocalRoots } from "./local-roots.js" ;
import { resolveInboundMediaReference } from "./media-reference.js" ;
export type LocalMediaAccessErrorCode =
| "path-not-allowed"
| "invalid-root"
| "invalid-file-url"
| "network-path-not-allowed"
| "unsafe-bypass"
| "not-found"
| "invalid-path"
| "not-file" ;
export class LocalMediaAccessError extends Error {
code: LocalMediaAccessErrorCode;
constructor(code: LocalMediaAccessErrorCode, message: string, options?: ErrorOptions) {
super (message, options);
this .code = code;
this .name = "LocalMediaAccessError" ;
}
}
export function getDefaultLocalRoots(): readonly string[] {
return getDefaultMediaLocalRoots();
}
export async function assertLocalMediaAllowed(
mediaPath: string,
localRoots: readonly string[] | "any" | undefined,
): Promise<void > {
if (localRoots === "any" ) {
return ;
}
const inboundReference = await resolveInboundMediaReference(mediaPath).catch (() => null );
if (inboundReference) {
return ;
}
try {
assertNoWindowsNetworkPath(mediaPath, "Local media path" );
} catch (err) {
throw new LocalMediaAccessError("network-path-not-allowed" , (err as Error).message, {
cause: err,
});
}
const roots = localRoots ?? getDefaultLocalRoots();
let resolved: string;
try {
resolved = await fs.realpath(mediaPath);
} catch {
resolved = path.resolve(mediaPath);
}
if (localRoots === undefined) {
const workspaceRoot = roots.find((root) => path.basename(root) === "workspace" );
if (workspaceRoot) {
const stateDir = path.dirname(workspaceRoot);
const rel = path.relative(stateDir, resolved);
if (rel && !rel.startsWith(".." ) && !path.isAbsolute(rel)) {
const firstSegment = rel.split(path.sep)[0 ] ?? "" ;
if (firstSegment.startsWith("workspace-" )) {
throw new LocalMediaAccessError(
"path-not-allowed" ,
`Local media path is not under an allowed directory: ${mediaPath}`,
);
}
}
}
}
for (const root of roots) {
let resolvedRoot: string;
try {
resolvedRoot = await fs.realpath(root);
} catch {
resolvedRoot = path.resolve(root);
}
if (resolvedRoot === path.parse(resolvedRoot).root) {
throw new LocalMediaAccessError(
"invalid-root" ,
`Invalid localRoots entry (refuses filesystem root): ${root}. Pass a narrower directory.`,
);
}
if (resolved === resolvedRoot || resolved.startsWith(resolvedRoot + path.sep)) {
return ;
}
}
throw new LocalMediaAccessError(
"path-not-allowed" ,
`Local media path is not under an allowed directory: ${mediaPath}`,
);
}
Messung V0.5 in Prozent C=100 H=99 G=99
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland