first commit
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user