This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { lstatSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
|
||||
import { basename, join, relative, resolve, sep } from 'node:path';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
|
||||
export const OWNERSHIP_FILE = '.maestro-e2e-owned';
|
||||
|
||||
export function createOwnedRunDir(cacheRoot, prefix) {
|
||||
mkdirSync(cacheRoot, { recursive: true });
|
||||
const directory = mkdtempSync(join(realpathSync(cacheRoot), prefix));
|
||||
const token = randomUUID();
|
||||
writeFileSync(join(directory, OWNERSHIP_FILE), token, { mode: 0o600 });
|
||||
return { directory, token };
|
||||
}
|
||||
|
||||
export function cleanupOwnedRunDir({ cacheRoot, directory, prefix, token }) {
|
||||
if (!directory || !token || !prefix) return false;
|
||||
let rootReal;
|
||||
let directoryReal;
|
||||
try {
|
||||
rootReal = realpathSync(cacheRoot);
|
||||
if (lstatSync(directory).isSymbolicLink()) return false;
|
||||
directoryReal = realpathSync(directory);
|
||||
} catch (error) {
|
||||
if (error?.code === 'ENOENT') return false;
|
||||
throw error;
|
||||
}
|
||||
const rel = relative(rootReal, directoryReal);
|
||||
if (!rel || rel === '..' || rel.startsWith(`..${sep}`) || resolve(rootReal, rel) !== directoryReal) return false;
|
||||
if (!basename(directoryReal).startsWith(prefix)) return false;
|
||||
let actualToken;
|
||||
try { actualToken = readFileSync(join(directoryReal, OWNERSHIP_FILE), 'utf8'); } catch { return false; }
|
||||
if (actualToken !== token) return false;
|
||||
rmSync(directoryReal, { recursive: true, force: true });
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user