Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
import { promises as fs } from "node:fs";
import path from "node:path";
import { Unpacker } from "@suaveplan/packer";
import {
SERVER_KEYS_CODES,
ServerKeysError,
} from "../../error-codes/error-codes.js";
import { checkSignal, loadFile } from "../keys/keys-io.js";
import type { FileCommandOptions, FilesLogger } from "./files.types.js";
import { deserializePacket, hexToBytes, readManifest } from "./packet-io.js";
const SILENT: () => void = () => {};
const SILENT_LOGGER: FilesLogger = { info: SILENT, error: SILENT };
function pickLogger(options: FileCommandOptions | undefined): FilesLogger {
return options?.logger ?? SILENT_LOGGER;
}
/** Result envelope for {@link serveFileCommand}. */
export interface ServeFileResult {
readonly outputPath: string;
readonly bytesWritten: number;
readonly packetsRead: number;
readonly fileId: string;
}
/**
* Reconstruct the original file from the prepared packet directory.
* Verifies each packet's signature + checksum against the manifest's
* `signerPublicKey` before writing to disk. Output path defaults to
* `<packetDir>/<manifest.originalFilename>`.
*/
export async function serveFileCommand(
packetDir: string,
options: FileCommandOptions = {}
): Promise<ServeFileResult> {
if (!packetDir) {
throw new ServerKeysError(
SERVER_KEYS_CODES.INVALID_INPUT,
"packetDir is required"
);
}
checkSignal(options.signal, "serve-file");
const manifest = await readManifest(packetDir);
const verifyKey = hexToBytes(manifest.signerPublicKey);
const reconstructed = new Uint8Array(manifest.originalSize);
let writeOffset = 0;
let packetsRead = 0;
const sorted = [...manifest.packets].sort((a, b) => a.index - b.index);
if (sorted.length !== manifest.totalPackets) {
throw new ServerKeysError(
SERVER_KEYS_CODES.PACKET_INTEGRITY_FAILED,
`Manifest declares ${manifest.totalPackets} packets but only ${sorted.length} entries present`
);
}
for (let i = 0; i < sorted.length; i++) {
const record = sorted[i];
/* istanbul ignore start -- defensive: `sorted` is derived from manifest.packets via Array.sort, which preserves length and never introduces sparse holes. */
if (!record) continue;
/* istanbul ignore stop */
if (record.index !== i) {
throw new ServerKeysError(
SERVER_KEYS_CODES.PACKET_INTEGRITY_FAILED,
`Packet sequence broken at index ${i}: manifest entry has index=${record.index}`
);
}
checkSignal(options.signal, "serve-file");
const buf = await loadFile(path.join(packetDir, record.filename));
const { packed } = deserializePacket(buf);
const unpacker = new Unpacker();
let result: Awaited<ReturnType<typeof unpacker.unpack>>;
try {
result = await unpacker.unpack(packed, {
verifySignature: true,
verifyKey,
verifyChecksum: true,
});
} catch (err) {
let extras: {
cause?: Error;
context: { index: number };
} = { context: { index: record.index } };
/* istanbul ignore start -- defensive: Unpacker.unpack rejects with Error subclasses on every documented failure mode, so the else branch is unreachable. */
if (err instanceof Error) {
extras = { cause: err, context: { index: record.index } };
}
/* istanbul ignore stop */
throw new ServerKeysError(
SERVER_KEYS_CODES.PACKET_INTEGRITY_FAILED,
`Packet ${record.index} (${record.filename}) failed verification`,
extras
);
}
if (result.data.byteLength !== record.originalSize) {
throw new ServerKeysError(
SERVER_KEYS_CODES.PACKET_INTEGRITY_FAILED,
`Packet ${record.index} size mismatch: expected ${record.originalSize} got ${result.data.byteLength}`
);
}
reconstructed.set(result.data, writeOffset);
writeOffset += result.data.byteLength;
packetsRead++;
}
if (writeOffset !== manifest.originalSize) {
throw new ServerKeysError(
SERVER_KEYS_CODES.PACKET_INTEGRITY_FAILED,
`Reassembled size ${writeOffset} does not match manifest.originalSize ${manifest.originalSize}`
);
}
const outputPath =
options.output ?? path.join(packetDir, manifest.originalFilename);
await fs.mkdir(path.dirname(outputPath), { recursive: true });
await fs.writeFile(outputPath, reconstructed);
pickLogger(options).info(
`serve-file: fileId=${manifest.fileId} packets=${packetsRead} bytes=${writeOffset} out=${outputPath}`
);
return {
outputPath,
bytesWritten: writeOffset,
packetsRead,
fileId: manifest.fileId,
};
}