first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
# load
## Purpose
Loads server-signed manifests from the two supported sources: a sentinel chunk inside the file's own chunk space (`manifestSource: "manifest-as-chunk"`) and a separate manifest server keyed by file id (`manifestSource: "server-only"`). Every code path runs the same `parseAndVerifyManifest` so signature verification can never be skipped.
## Features
- `loadManifestAsChunk(fileId, getChunk, serverPubKey)` — reads chunkId `-1` from the chunk source.
- `loadManifestFromServer(fileId, url, fetchFn, serverPubKey)` — issues a `fetch(url + "/manifest/<idHex>")` GET; injectable `fetchFn` for testing.
- `parseAndVerifyManifest(raw, serverPubKey)` — JSON-decodes (with `base64:` Uint8Array unwrapping), validates against `ManifestSchema`, and runs Ed25519 verification with the canonical encoder.
- `MANIFEST_NOT_FOUND` and `MANIFEST_INVALID` are the only errors that can come out of this module — every internal failure is mapped onto one of those two codes.
## Usage: Basic Example
```ts
import { loadManifestAsChunk } from "@suaveplan/drive-plugin-chunks";
const manifest = await loadManifestAsChunk(
fileId,
(id, idx) => chunks.getChunk(id, idx),
serverPubKey
);
```
## Usage: Advanced Example
```ts
import {
loadManifestFromServer,
parseAndVerifyManifest,
} from "@suaveplan/drive-plugin-chunks";
const manifest = await loadManifestFromServer(
fileId,
"https://manifests.example.com",
fetch,
serverPubKey
);
// Verifying a manifest received over a side-channel
const verified = parseAndVerifyManifest(receivedBytes, serverPubKey);
```
## API Reference
- `loadManifestAsChunk(fileId, getChunk, serverPubKey): Promise<Manifest>`.
- `loadManifestFromServer(fileId, url, fetchFn, serverPubKey): Promise<Manifest>`.
- `parseAndVerifyManifest(raw: Uint8Array, serverPubKey: Uint8Array): Manifest`.
- All three throw `ChunksError(CHUNKS.MANIFEST_NOT_FOUND)` (missing input) or `ChunksError(CHUNKS.MANIFEST_INVALID)` (schema or signature failure).
## Implementation Notes
`parseAndVerifyManifest` first tries to parse as UTF-8 JSON because manifests are persisted as JSON inside `plugin.ingest`; the catch falls back to treating the raw bytes as the parsed value, which lets future binary manifest formats slot in without changing the call site. Signature verification rebuilds `withoutSig` with a 64-byte zero placeholder and asks the canonical encoder to lay out the bytes; this matches the layout used at sign time so the verification is over identical bytes.