@coffre/core 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vault.d.ts CHANGED
@@ -67,6 +67,12 @@ export declare function describeAccessFault(fault: AccessFault, names?: FaultNam
67
67
  export declare function checkpointMessage(checkpoint: Omit<Checkpoint, 'signature' | 'keyId'>): Uint8Array<ArrayBuffer>;
68
68
  /** Whether `checkpoint` was signed by the key whose raw public half is `publicKey`. */
69
69
  export declare function verifyCheckpoint(checkpoint: Checkpoint, publicKey: string): Promise<boolean>;
70
+ /**
71
+ * `verifyCheckpoint` for many checkpoints signed by one key, the key
72
+ * imported once: a full verification checks every checkpoint, one every
73
+ * five minutes.
74
+ */
75
+ export declare function checkpointVerifier(publicKey: string): Promise<(checkpoint: Checkpoint) => Promise<boolean>>;
70
76
  //#endregion
71
77
  //#region src/vault.d.ts
72
78
  /**
@@ -162,11 +168,13 @@ export interface Vault {
162
168
  */
163
169
  keyChecks(): Promise<KeyChecks>;
164
170
  /**
165
- * Check the whole log: rehash it from the first entry, the vault's
166
- * entries by their MACs, every checkpoint against the prefix it signed,
171
+ * Check the whole log: the vault's entries by their MACs, every
172
+ * checkpoint against the prefix it signed, the key batches accounted for,
167
173
  * and replay it to see that who is a member, and what they hold, follow
168
- * from it. A verdict and nothing else, so anyone may ask; the app asks
169
- * for owners.
174
+ * from it. The links and hashes of the chain are the caller's to
175
+ * recompute through `upTo`, as the app does first; with none, the vault
176
+ * recomputes them all itself. A verdict and nothing else, so anyone may
177
+ * ask; the app asks for owners.
170
178
  */
171
179
  verifyLog(input: VerifyLogInput): Promise<LogVerification>;
172
180
  }
@@ -372,9 +380,11 @@ export type LogHead = {
372
380
  };
373
381
  export type VerifyLogInput = {
374
382
  /**
375
- * The last entry the app verified, its own entries by its key: the vault
376
- * checks the log still holds it, so between them both authors' entries
377
- * are authenticated over the same prefix.
383
+ * The last entry the app verified, every link and hash up to it
384
+ * recomputed and its own entries checked by its key: the vault checks the
385
+ * log still holds it, so between them both authors' entries are
386
+ * authenticated over the same prefix, and the vault leaves the links to
387
+ * the app.
378
388
  */
379
389
  upTo?: LogHead | null;
380
390
  };
package/dist/vault.js CHANGED
@@ -6,8 +6,16 @@ function checkpointMessage(checkpoint) {
6
6
  }
7
7
  /** Whether `checkpoint` was signed by the key whose raw public half is `publicKey`. */
8
8
  async function verifyCheckpoint(checkpoint, publicKey) {
9
+ return (await checkpointVerifier(publicKey))(checkpoint);
10
+ }
11
+ /**
12
+ * `verifyCheckpoint` for many checkpoints signed by one key, the key
13
+ * imported once: a full verification checks every checkpoint, one every
14
+ * five minutes.
15
+ */
16
+ async function checkpointVerifier(publicKey) {
9
17
  const key = await crypto.subtle.importKey("raw", new Uint8Array(Buffer.from(publicKey, "base64")), { name: "Ed25519" }, false, ["verify"]);
10
- return crypto.subtle.verify("Ed25519", key, new Uint8Array(Buffer.from(checkpoint.signature, "base64")), checkpointMessage(checkpoint));
18
+ return (checkpoint) => crypto.subtle.verify("Ed25519", key, new Uint8Array(Buffer.from(checkpoint.signature, "base64")), checkpointMessage(checkpoint));
11
19
  }
12
20
  //#endregion
13
21
  //#region src/access-fault.ts
@@ -42,4 +50,4 @@ const ACCESS_ACTIONS = [
42
50
  "access.revoke"
43
51
  ];
44
52
  //#endregion
45
- export { ACCESS_ACTIONS, checkpointMessage, describeAccessFault, verifyCheckpoint };
53
+ export { ACCESS_ACTIONS, checkpointMessage, checkpointVerifier, describeAccessFault, verifyCheckpoint };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coffre/core",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "What coffre's packages share: roles, envelopes, identity, the audit chain and the vault's contract.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -69,7 +69,7 @@
69
69
  "@types/node": "26.1.1",
70
70
  "tsdown": "0.23.0",
71
71
  "typescript": "5.9.3",
72
- "@coffre/conformance": "0.1.12"
72
+ "@coffre/conformance": "0.1.13"
73
73
  },
74
74
  "scripts": {
75
75
  "build": "tsdown",
package/src/checkpoint.ts CHANGED
@@ -8,6 +8,15 @@ export function checkpointMessage(checkpoint: Omit<Checkpoint, 'signature' | 'ke
8
8
 
9
9
  /** Whether `checkpoint` was signed by the key whose raw public half is `publicKey`. */
10
10
  export async function verifyCheckpoint(checkpoint: Checkpoint, publicKey: string): Promise<boolean> {
11
+ return (await checkpointVerifier(publicKey))(checkpoint);
12
+ }
13
+
14
+ /**
15
+ * `verifyCheckpoint` for many checkpoints signed by one key, the key
16
+ * imported once: a full verification checks every checkpoint, one every
17
+ * five minutes.
18
+ */
19
+ export async function checkpointVerifier(publicKey: string): Promise<(checkpoint: Checkpoint) => Promise<boolean>> {
11
20
  const key = await crypto.subtle.importKey('raw', new Uint8Array(Buffer.from(publicKey, 'base64')), { name: 'Ed25519' }, false, ['verify']);
12
- return crypto.subtle.verify('Ed25519', key, new Uint8Array(Buffer.from(checkpoint.signature, 'base64')), checkpointMessage(checkpoint));
21
+ return (checkpoint) => crypto.subtle.verify('Ed25519', key, new Uint8Array(Buffer.from(checkpoint.signature, 'base64')), checkpointMessage(checkpoint));
13
22
  }
package/src/vault.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { AccessFault } from './access-fault.ts';
2
2
  import type { Role } from './access.ts';
3
3
 
4
- export { checkpointMessage, verifyCheckpoint } from './checkpoint.ts';
4
+ export { checkpointMessage, checkpointVerifier, verifyCheckpoint } from './checkpoint.ts';
5
5
  export { describeAccessFault, type AccessFault, type FaultGrant, type FaultNames } from './access-fault.ts';
6
6
 
7
7
  /**
@@ -77,11 +77,13 @@ export interface Vault {
77
77
  */
78
78
  keyChecks(): Promise<KeyChecks>;
79
79
  /**
80
- * Check the whole log: rehash it from the first entry, the vault's
81
- * entries by their MACs, every checkpoint against the prefix it signed,
80
+ * Check the whole log: the vault's entries by their MACs, every
81
+ * checkpoint against the prefix it signed, the key batches accounted for,
82
82
  * and replay it to see that who is a member, and what they hold, follow
83
- * from it. A verdict and nothing else, so anyone may ask; the app asks
84
- * for owners.
83
+ * from it. The links and hashes of the chain are the caller's to
84
+ * recompute through `upTo`, as the app does first; with none, the vault
85
+ * recomputes them all itself. A verdict and nothing else, so anyone may
86
+ * ask; the app asks for owners.
85
87
  */
86
88
  verifyLog(input: VerifyLogInput): Promise<LogVerification>;
87
89
  }
@@ -276,9 +278,11 @@ export type LogHead = { seq: number; hash: string };
276
278
 
277
279
  export type VerifyLogInput = {
278
280
  /**
279
- * The last entry the app verified, its own entries by its key: the vault
280
- * checks the log still holds it, so between them both authors' entries
281
- * are authenticated over the same prefix.
281
+ * The last entry the app verified, every link and hash up to it
282
+ * recomputed and its own entries checked by its key: the vault checks the
283
+ * log still holds it, so between them both authors' entries are
284
+ * authenticated over the same prefix, and the vault leaves the links to
285
+ * the app.
282
286
  */
283
287
  upTo?: LogHead | null;
284
288
  };