fix: isolate watcher task runtimes
This commit is contained in:
@@ -3,6 +3,7 @@ import path from 'path';
|
||||
import { DATA_DIR, GROUPS_DIR } from './config.js';
|
||||
|
||||
const GROUP_FOLDER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
|
||||
const RUNTIME_SEGMENT_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
||||
const RESERVED_FOLDERS = new Set(['global']);
|
||||
|
||||
export function isValidGroupFolder(folder: string): boolean {
|
||||
@@ -21,6 +22,18 @@ export function assertValidGroupFolder(folder: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
function assertValidRuntimeSegment(segment: string, label: string): void {
|
||||
if (!segment || segment !== segment.trim()) {
|
||||
throw new Error(`Invalid ${label} "${segment}"`);
|
||||
}
|
||||
if (!RUNTIME_SEGMENT_PATTERN.test(segment)) {
|
||||
throw new Error(`Invalid ${label} "${segment}"`);
|
||||
}
|
||||
if (segment.includes('/') || segment.includes('\\') || segment.includes('..')) {
|
||||
throw new Error(`Invalid ${label} "${segment}"`);
|
||||
}
|
||||
}
|
||||
|
||||
function ensureWithinBase(baseDir: string, resolvedPath: string): void {
|
||||
const rel = path.relative(baseDir, resolvedPath);
|
||||
if (rel.startsWith('..') || path.isAbsolute(rel)) {
|
||||
@@ -42,3 +55,32 @@ export function resolveGroupIpcPath(folder: string): string {
|
||||
ensureWithinBase(ipcBaseDir, ipcPath);
|
||||
return ipcPath;
|
||||
}
|
||||
|
||||
export function resolveGroupSessionsPath(folder: string): string {
|
||||
assertValidGroupFolder(folder);
|
||||
const sessionsBaseDir = path.resolve(DATA_DIR, 'sessions');
|
||||
const sessionsPath = path.resolve(sessionsBaseDir, folder);
|
||||
ensureWithinBase(sessionsBaseDir, sessionsPath);
|
||||
return sessionsPath;
|
||||
}
|
||||
|
||||
export function resolveTaskRuntimeIpcPath(
|
||||
folder: string,
|
||||
taskId: string,
|
||||
): string {
|
||||
assertValidGroupFolder(folder);
|
||||
assertValidRuntimeSegment(taskId, 'task ID');
|
||||
const ipcBaseDir = path.resolve(DATA_DIR, 'ipc');
|
||||
const ipcPath = path.resolve(ipcBaseDir, folder, 'tasks', taskId);
|
||||
ensureWithinBase(ipcBaseDir, ipcPath);
|
||||
return ipcPath;
|
||||
}
|
||||
|
||||
export function resolveTaskSessionsPath(folder: string, taskId: string): string {
|
||||
assertValidGroupFolder(folder);
|
||||
assertValidRuntimeSegment(taskId, 'task ID');
|
||||
const sessionsBaseDir = path.resolve(DATA_DIR, 'sessions');
|
||||
const sessionsPath = path.resolve(sessionsBaseDir, folder, 'tasks', taskId);
|
||||
ensureWithinBase(sessionsBaseDir, sessionsPath);
|
||||
return sessionsPath;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user