Added the guarded, one-shot monero:pilot-address command

This commit is contained in:
2026-10-22 19:10:08 -04:00
parent 83d3d104c1
commit 36963fed30
7 changed files with 135 additions and 2 deletions
+33
View File
@@ -0,0 +1,33 @@
import { constants } from 'node:fs';
import { open } from 'node:fs/promises';
import { isAbsolute } from 'node:path';
const MAX_REQUEST_BYTES = 64 * 1024;
/** Read a signed wallet request only from a bounded owner-only regular file. */
export async function loadPilotMoneroDepositRequestFile(path: string): Promise<unknown> {
if (process.platform === 'win32') throw new Error('Pilot address command requires POSIX protected-file permission checks');
if (!isAbsolute(path)) throw new Error('Pilot address request file path must be absolute');
let file;
try { file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW); }
catch { throw new Error('Pilot address request file is inaccessible or is a symbolic link'); }
try {
const info = await file.stat();
if (!info.isFile() || info.size < 1 || info.size > MAX_REQUEST_BYTES || (info.mode & 0o077) !== 0) {
throw new Error('Pilot address request file must be bounded and owner-only');
}
const chunks: Buffer[] = [];
let total = 0;
for (;;) {
const chunk = Buffer.allocUnsafe(Math.min(4096, MAX_REQUEST_BYTES + 1 - total));
const { bytesRead } = await file.read(chunk);
if (bytesRead === 0) break;
total += bytesRead;
if (total > MAX_REQUEST_BYTES) throw new Error('Pilot address request file exceeds size limit');
chunks.push(chunk.subarray(0, bytesRead));
}
const text = new TextDecoder('utf-8', { fatal: true }).decode(Buffer.concat(chunks));
try { return JSON.parse(text) as unknown; }
catch { throw new Error('Pilot address request file does not contain valid JSON'); }
} finally { await file.close(); }
}