@spfn/auth 0.2.0-beta.86 → 0.2.0-beta.88
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/README.md +347 -27
- package/dist/{authenticate-DTA7W4v2.d.ts → authenticate-ZssfqJ7d.d.ts} +201 -5
- package/dist/client-proof.d.ts +185 -46
- package/dist/client-proof.js +253 -34
- package/dist/client-proof.js.map +1 -1
- package/dist/config.d.ts +36 -0
- package/dist/config.js +18 -0
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +93 -2
- package/dist/errors.js +57 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +33 -3
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +2 -2
- package/dist/server.d.ts +148 -12
- package/dist/server.js +1410 -192
- package/dist/server.js.map +1 -1
- package/dist/{session-CGxgH3C9.d.ts → session-CFK4BT25.d.ts} +1 -1
- package/dist/{types-1BMx0OX1.d.ts → types-CD95yudz.d.ts} +15 -1
- package/migrations/20251125021229_premium_famine/snapshot.json +2641 -0
- package/migrations/20260225130050_smooth_the_fury/snapshot.json +2686 -0
- package/migrations/20260308141417_deep_iceman/snapshot.json +2686 -0
- package/migrations/20260308151309_perfect_deathbird/snapshot.json +2731 -0
- package/migrations/20260308201135_concerned_rawhide_kid/snapshot.json +2786 -0
- package/migrations/20260629103209_lethal_lifeguard/snapshot.json +2786 -0
- package/migrations/20260709073531_easy_hardball/snapshot.json +3119 -0
- package/migrations/20260714081434_glossy_major_mapleleaf/snapshot.json +3112 -0
- package/migrations/20260804105939_amazing_bushwacker/migration.sql +3 -0
- package/migrations/20260804105939_amazing_bushwacker/snapshot.json +3112 -0
- package/migrations/20260804110033_fat_piledriver/migration.sql +2 -0
- package/migrations/20260804110033_fat_piledriver/snapshot.json +3138 -0
- package/package.json +6 -9
- package/migrations/meta/0000_snapshot.json +0 -1632
- package/migrations/meta/0001_snapshot.json +0 -1660
- package/migrations/meta/0002_snapshot.json +0 -1660
- package/migrations/meta/0003_snapshot.json +0 -1689
- package/migrations/meta/0004_snapshot.json +0 -1721
- package/migrations/meta/0005_snapshot.json +0 -1721
- package/migrations/meta/0006_snapshot.json +0 -1921
- package/migrations/meta/0007_snapshot.json +0 -1916
- package/migrations/meta/_journal.json +0 -62
- /package/migrations/{0000_premium_famine.sql → 20251125021229_premium_famine/migration.sql} +0 -0
- /package/migrations/{0001_smooth_the_fury.sql → 20260225130050_smooth_the_fury/migration.sql} +0 -0
- /package/migrations/{0002_deep_iceman.sql → 20260308141417_deep_iceman/migration.sql} +0 -0
- /package/migrations/{0003_perfect_deathbird.sql → 20260308151309_perfect_deathbird/migration.sql} +0 -0
- /package/migrations/{0004_concerned_rawhide_kid.sql → 20260308201135_concerned_rawhide_kid/migration.sql} +0 -0
- /package/migrations/{0005_lethal_lifeguard.sql → 20260629103209_lethal_lifeguard/migration.sql} +0 -0
- /package/migrations/{0006_easy_hardball.sql → 20260709073531_easy_hardball/migration.sql} +0 -0
- /package/migrations/{0007_glossy_major_mapleleaf.sql → 20260714081434_glossy_major_mapleleaf/migration.sql} +0 -0
package/dist/client-proof.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { KeyObject } from 'node:crypto';
|
|
1
2
|
import { MiddlewareHandler } from 'hono';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* SPFN-CANON-JSON-1 — the canonical JSON form the mobile contract pins.
|
|
5
6
|
*
|
|
6
|
-
* The rules (
|
|
7
|
+
* The rules (contracts/mobile/spfn-mobile-contract.json `canonicalJson`):
|
|
7
8
|
* - object keys sorted ascending by UTF-8 byte sequence
|
|
8
9
|
* - no insignificant whitespace
|
|
9
10
|
* - numbers are signed 64-bit integers only
|
|
@@ -43,12 +44,32 @@ declare function isCanonicalBytes(bytes: Uint8Array, value: CanonicalValue): boo
|
|
|
43
44
|
/** Encode a value as SPFN-CANON-JSON-1 bytes. */
|
|
44
45
|
declare function encodeCanonicalJson(value: CanonicalValue): Uint8Array;
|
|
45
46
|
|
|
47
|
+
/**
|
|
48
|
+
* SPFN-PROOF-INPUT-1 — proof-input assembly and verification for clientProofV1.
|
|
49
|
+
*
|
|
50
|
+
* The proof input is 8 fields joined by `\n` in fixed order: profile, method,
|
|
51
|
+
* path, clientId, keyId, nonce, issuedAtMillis, bodySha256. Any C0 control
|
|
52
|
+
* character in any field is a hard refusal (the separator would otherwise be
|
|
53
|
+
* ambiguous), never something to escape. The proof is an ECDSA P-256 signature
|
|
54
|
+
* with SHA-256 over the canonical input's UTF-8 bytes, wire-encoded as the raw
|
|
55
|
+
* `r ‖ s` 64 bytes in base16-lower (128 hex characters). DER is never accepted
|
|
56
|
+
* on the wire: a platform signer that emits DER (Java `Signature`) converts to
|
|
57
|
+
* raw before sending. Low-S normalization is not required — uniqueness is owned
|
|
58
|
+
* by the nonce and replay window, so signature malleability cannot replay.
|
|
59
|
+
*
|
|
60
|
+
* @module server/client-proof/proof
|
|
61
|
+
*/
|
|
62
|
+
|
|
46
63
|
/** The only auth profile this module implements. */
|
|
47
64
|
declare const CLIENT_PROOF_PROFILE = "clientProofV1";
|
|
48
65
|
/** `bodySha256` when an operation carries no body: 64 zero characters. */
|
|
49
66
|
declare const ABSENT_BODY_SHA256: string;
|
|
50
67
|
/** The contract's `clientProofV1.replayWindowMillis`. */
|
|
51
68
|
declare const DEFAULT_REPLAY_WINDOW_MILLIS = 300000;
|
|
69
|
+
/** Raw `r ‖ s`: two 32-byte big-endian integers, always exactly this long. */
|
|
70
|
+
declare const PROOF_SIGNATURE_BYTES = 64;
|
|
71
|
+
/** The wire form is base16-lower of the raw signature: 128 hex characters. */
|
|
72
|
+
declare const PROOF_SIGNATURE_HEX_LENGTH: number;
|
|
52
73
|
interface ClientProofInput {
|
|
53
74
|
method: string;
|
|
54
75
|
path: string;
|
|
@@ -63,22 +84,42 @@ declare class ProofInputError extends Error {
|
|
|
63
84
|
constructor();
|
|
64
85
|
}
|
|
65
86
|
/**
|
|
66
|
-
* The canonical proof-input string the
|
|
87
|
+
* The canonical proof-input string the signature is taken over.
|
|
67
88
|
*
|
|
68
89
|
* @throws ProofInputError when any field contains a C0 control character.
|
|
69
90
|
*/
|
|
70
91
|
declare function canonicalProofInput(input: ClientProofInput): string;
|
|
71
|
-
/** The base16-lower HMAC-SHA-256 proof for `input` under `key`. */
|
|
72
|
-
declare function computeClientProof(input: ClientProofInput, key: Uint8Array): string;
|
|
73
|
-
/** Lowercase base16 SHA-256 of `bytes`. */
|
|
74
|
-
declare function sha256Hex(bytes: Uint8Array): string;
|
|
75
92
|
/**
|
|
76
|
-
*
|
|
93
|
+
* The contract's public-key representation — SPKI DER, base64 (the same
|
|
94
|
+
* representation `user_public_keys` and the web ES256 path store) — as a key
|
|
95
|
+
* object. Anything that is not a P-256 EC key is refused at parse time, so a
|
|
96
|
+
* key that could never verify a proof is never registered.
|
|
77
97
|
*
|
|
78
|
-
*
|
|
79
|
-
* public), then the bytes are compared with `timingSafeEqual`.
|
|
98
|
+
* @throws when the input is not base64 SPKI DER naming a P-256 key.
|
|
80
99
|
*/
|
|
81
|
-
declare function
|
|
100
|
+
declare function parseClientProofPublicKey(spkiDerBase64: string): KeyObject;
|
|
101
|
+
/**
|
|
102
|
+
* Verifies a presented proof against `input` and a registered public key.
|
|
103
|
+
*
|
|
104
|
+
* The input is assembled first, so a C0 control character throws no matter
|
|
105
|
+
* what was presented — an unassemblable input is a contract violation, never
|
|
106
|
+
* a proof answer. Then the wire-format gate: a value that is not exactly 128
|
|
107
|
+
* lowercase hex characters — a DER signature, a truncated one, uppercase hex —
|
|
108
|
+
* is invalid before any cryptography happens.
|
|
109
|
+
*
|
|
110
|
+
* @throws ProofInputError when an input field contains a C0 control character.
|
|
111
|
+
*/
|
|
112
|
+
declare function verifyClientProof(input: ClientProofInput, presentedProof: string, publicKey: KeyObject): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Signs `input` with a PKCS#8 DER base64 private key, producing the wire form
|
|
115
|
+
* (raw `r ‖ s`, base16-lower).
|
|
116
|
+
*
|
|
117
|
+
* The verifying half's counterpart, here for tests and dev clients — a
|
|
118
|
+
* production signer lives in the mobile SDKs against hardware-held keys.
|
|
119
|
+
*/
|
|
120
|
+
declare function signClientProof(input: ClientProofInput, privateKeyPkcs8DerBase64: string): string;
|
|
121
|
+
/** Lowercase base16 SHA-256 of `bytes`. */
|
|
122
|
+
declare function sha256Hex(bytes: Uint8Array): string;
|
|
82
123
|
|
|
83
124
|
/** The six wire codes. The SDKs classify by code, never HTTP status. */
|
|
84
125
|
type ClientProofErrorCode = 'PROOF_INVALID' | 'PROOF_REPLAYED' | 'PROOF_EXPIRED' | 'SESSION_REVOKED' | 'PROFILE_REJECTED' | 'CONTRACT_UNSUPPORTED';
|
|
@@ -115,31 +156,6 @@ declare class ClientProofRefusal {
|
|
|
115
156
|
static proofInvalid(): ClientProofRefusal;
|
|
116
157
|
}
|
|
117
158
|
|
|
118
|
-
/**
|
|
119
|
-
* Everything a clientProofV1 server remembers between requests: issued
|
|
120
|
-
* sessions, the replay ledger, revoked keys and the key directory.
|
|
121
|
-
*
|
|
122
|
-
* The admission order is the contract's, not this file's invention
|
|
123
|
-
* (`clientProofV1.revocationRule` + the replay fixtures):
|
|
124
|
-
*
|
|
125
|
-
* 1. revoked keyId / invalid session → SESSION_REVOKED — before proof
|
|
126
|
-
* verification, so revocation stays distinguishable from a bad proof;
|
|
127
|
-
* 2. issuedAtMillis outside the replay window (0 <= age <= window) → PROOF_EXPIRED;
|
|
128
|
-
* 3. a repeated (clientId, nonce) pair inside the window → PROOF_REPLAYED;
|
|
129
|
-
* 4. only then HMAC verification → PROOF_INVALID on mismatch.
|
|
130
|
-
*
|
|
131
|
-
* A nonce is recorded as spent only on admission: a request refused for any
|
|
132
|
-
* earlier reason has not spent anything, so a client that fixes the reason and
|
|
133
|
-
* retries with the same nonce is not punished twice for one mistake. This is
|
|
134
|
-
* why core's `NonceStore.checkAndSet` (which records on check) is not reused
|
|
135
|
-
* here — its semantics would spend a nonce on a refused request.
|
|
136
|
-
*
|
|
137
|
-
* `admit` is synchronous, so on Node's single thread the whole sequence is
|
|
138
|
-
* atomic: two requests presenting the same nonce cannot interleave inside it.
|
|
139
|
-
*
|
|
140
|
-
* @module server/client-proof/state
|
|
141
|
-
*/
|
|
142
|
-
|
|
143
159
|
/** Millisecond clock. Injectable so expiry paths are testable without waiting. */
|
|
144
160
|
interface ClientProofClock {
|
|
145
161
|
nowMillis(): number;
|
|
@@ -164,11 +180,13 @@ interface ClientProofStats {
|
|
|
164
180
|
}
|
|
165
181
|
interface ClientProofStateOptions {
|
|
166
182
|
/**
|
|
167
|
-
* keyId →
|
|
168
|
-
*
|
|
169
|
-
*
|
|
183
|
+
* keyId → registered public key, as SPKI DER base64. The private half
|
|
184
|
+
* never reaches the server: a client generates its keypair (hardware-held
|
|
185
|
+
* on mobile) and only the public key is registered — at construction here,
|
|
186
|
+
* or later through `registerPublicKey` (the dev `/control/register-key`
|
|
187
|
+
* route).
|
|
170
188
|
*/
|
|
171
|
-
|
|
189
|
+
publicKeys: Record<string, string>;
|
|
172
190
|
clock?: ClientProofClock;
|
|
173
191
|
/** @default 600000 */
|
|
174
192
|
sessionTtlMillis?: number;
|
|
@@ -179,9 +197,10 @@ declare const DEFAULT_SESSION_TTL_MILLIS = 600000;
|
|
|
179
197
|
declare class ClientProofState {
|
|
180
198
|
readonly replayWindowMillis: number;
|
|
181
199
|
private readonly clock;
|
|
182
|
-
private readonly
|
|
200
|
+
private readonly initialPublicKeys;
|
|
201
|
+
private readonly publicKeys;
|
|
183
202
|
private readonly sessions;
|
|
184
|
-
/**
|
|
203
|
+
/** The replay ledger — the shared memory implementation, used dev-only here. */
|
|
185
204
|
private readonly spentNonces;
|
|
186
205
|
private readonly revokedKeyIds;
|
|
187
206
|
private readonly holds;
|
|
@@ -193,6 +212,12 @@ declare class ClientProofState {
|
|
|
193
212
|
private itemsListCount;
|
|
194
213
|
private refusalCount;
|
|
195
214
|
constructor(options: ClientProofStateOptions);
|
|
215
|
+
/**
|
|
216
|
+
* Registers (or replaces) the public key `keyId` presents proofs under.
|
|
217
|
+
*
|
|
218
|
+
* @throws when the key is not base64 SPKI DER naming a P-256 key.
|
|
219
|
+
*/
|
|
220
|
+
registerPublicKey(keyId: string, publicKeySpkiDerBase64: string): void;
|
|
196
221
|
/**
|
|
197
222
|
* Runs the contract's checks in the contract's order and returns the
|
|
198
223
|
* refusal, or null when the request is admitted (spending its nonce).
|
|
@@ -217,7 +242,7 @@ declare class ClientProofState {
|
|
|
217
242
|
/** Revokes a key and drops the sessions it opened. */
|
|
218
243
|
revokeKey(keyId: string): void;
|
|
219
244
|
setSessionTtlMillis(millis: number): void;
|
|
220
|
-
/** Returns the state to how it started, counters included. */
|
|
245
|
+
/** Returns the state to how it started, counters and registered keys included. */
|
|
221
246
|
reset(): void;
|
|
222
247
|
/** Makes the next `count` requests to `path` wait `millis` before processing. */
|
|
223
248
|
holdPath(path: string, millis: number, count: number): void;
|
|
@@ -295,6 +320,101 @@ declare function admitClientProofRequest(args: {
|
|
|
295
320
|
requiresSession: boolean;
|
|
296
321
|
body: Uint8Array;
|
|
297
322
|
}): Admission;
|
|
323
|
+
/**
|
|
324
|
+
* The contract header fields, or null when any is absent or malformed.
|
|
325
|
+
*
|
|
326
|
+
* Fetch `Headers` folds a repeated field into one comma-joined value, so
|
|
327
|
+
* "sent more than once" is not directly observable here; a folded value fails
|
|
328
|
+
* either the issuedAt grammar or proof verification instead.
|
|
329
|
+
*
|
|
330
|
+
* Exported for the authenticate middleware's profile path, which runs the
|
|
331
|
+
* same shape checks over arbitrary routes.
|
|
332
|
+
*/
|
|
333
|
+
declare function readCredentials(headers: Headers): ClientProofCredentials | null;
|
|
334
|
+
/** Exported for the authenticate middleware's profile path. */
|
|
335
|
+
declare function isRequestContentType(value: string | null): boolean;
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* The ledger key. `JSON.stringify` of the pair, so no crafted clientId/nonce
|
|
339
|
+
* concatenation can collide with another pair — the fields are checked for C0
|
|
340
|
+
* controls only later, at proof verification, so the key must be unambiguous
|
|
341
|
+
* for arbitrary strings.
|
|
342
|
+
*/
|
|
343
|
+
declare function replayLedgerKey(clientId: string, nonce: string): string;
|
|
344
|
+
/**
|
|
345
|
+
* What the middleware's replay ledger must answer. Both methods may reject;
|
|
346
|
+
* the caller refuses the request when they do (fail-closed).
|
|
347
|
+
*/
|
|
348
|
+
interface ClientProofReplayStore {
|
|
349
|
+
/** True when (clientId, nonce) was already spent inside the window. */
|
|
350
|
+
isSpent(clientId: string, nonce: string): Promise<boolean>;
|
|
351
|
+
/**
|
|
352
|
+
* Records the pair as spent. False when it was already spent — the caller
|
|
353
|
+
* lost a race and must answer PROOF_REPLAYED, not accept twice.
|
|
354
|
+
*/
|
|
355
|
+
spend(clientId: string, nonce: string): Promise<boolean>;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* The in-memory ledger — the single implementation of the window semantics.
|
|
359
|
+
*
|
|
360
|
+
* Entries carry the millisecond they were recorded at; `prune` drops an entry
|
|
361
|
+
* only once a proof carrying that timestamp would be refused as expired
|
|
362
|
+
* anyway (the exact negation of the admission window check). All methods are
|
|
363
|
+
* synchronous so `ClientProofState.admit` can stay atomic on Node's single
|
|
364
|
+
* thread.
|
|
365
|
+
*/
|
|
366
|
+
declare class MemoryReplayLedger {
|
|
367
|
+
/** replayLedgerKey(...) → the millis it was spent at. */
|
|
368
|
+
private readonly spent;
|
|
369
|
+
isSpent(clientId: string, nonce: string): boolean;
|
|
370
|
+
/** Records the pair at `atMillis`; false when it was already spent. */
|
|
371
|
+
spend(clientId: string, nonce: string, atMillis: number): boolean;
|
|
372
|
+
/** Drops entries older than the window, judged against `nowMillis`. */
|
|
373
|
+
prune(nowMillis: number, windowMillis: number): void;
|
|
374
|
+
get size(): number;
|
|
375
|
+
clear(): void;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* The default store: a process-local `MemoryReplayLedger` on the wall clock.
|
|
379
|
+
*
|
|
380
|
+
* Correct for a single process. Behind a multi-instance deployment each
|
|
381
|
+
* instance keeps its own ledger, so a replay against a *different* instance
|
|
382
|
+
* is not seen — that deployment opts into `RedisReplayStore`.
|
|
383
|
+
*/
|
|
384
|
+
declare class MemoryReplayStore implements ClientProofReplayStore {
|
|
385
|
+
private readonly windowMillis;
|
|
386
|
+
private readonly ledger;
|
|
387
|
+
constructor(windowMillis?: number);
|
|
388
|
+
isSpent(clientId: string, nonce: string): Promise<boolean>;
|
|
389
|
+
spend(clientId: string, nonce: string): Promise<boolean>;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* The opt-in shared ledger over `getCache()` (ioredis): `SET NX PX <window>`.
|
|
393
|
+
*
|
|
394
|
+
* The key hashes the pair, so arbitrary clientId/nonce strings become short,
|
|
395
|
+
* safe Redis keys with no ambiguity. `PX` makes Redis expire the entry itself
|
|
396
|
+
* exactly when a proof reusing the nonce would pass the window check again.
|
|
397
|
+
*
|
|
398
|
+
* Fail-closed by construction: when the cache is not configured or a command
|
|
399
|
+
* rejects, the error propagates and the caller refuses the request. Nothing
|
|
400
|
+
* here answers "not spent" on a store it could not reach.
|
|
401
|
+
*/
|
|
402
|
+
declare class RedisReplayStore implements ClientProofReplayStore {
|
|
403
|
+
private readonly windowMillis;
|
|
404
|
+
constructor(windowMillis?: number);
|
|
405
|
+
isSpent(clientId: string, nonce: string): Promise<boolean>;
|
|
406
|
+
spend(clientId: string, nonce: string): Promise<boolean>;
|
|
407
|
+
private cache;
|
|
408
|
+
private key;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Installs the replay store the authenticate middleware uses. Pass
|
|
412
|
+
* `new RedisReplayStore()` to opt into the shared ledger; pass null to return
|
|
413
|
+
* to the in-memory default.
|
|
414
|
+
*/
|
|
415
|
+
declare function configureClientProofReplayStore(store: ClientProofReplayStore | null): void;
|
|
416
|
+
/** The configured store, or a lazily created in-memory default. */
|
|
417
|
+
declare function getClientProofReplayStore(): ClientProofReplayStore;
|
|
298
418
|
|
|
299
419
|
/**
|
|
300
420
|
* The mobile dev-contract types and operations, decoded from / encoded to
|
|
@@ -302,7 +422,7 @@ declare function admitClientProofRequest(args: {
|
|
|
302
422
|
* or an unknown field is "not the request type this operation declares".
|
|
303
423
|
*
|
|
304
424
|
* This module is the source of truth for `operations`. The exported contract
|
|
305
|
-
* bundle (`contracts/mobile/spfn-mobile-contract.
|
|
425
|
+
* bundle (`contracts/mobile/spfn-mobile-contract.json`) is generated from it
|
|
306
426
|
* by `contract-bundle.ts`; spfn-mobile consumes that export rather than the
|
|
307
427
|
* other way round.
|
|
308
428
|
*
|
|
@@ -310,16 +430,35 @@ declare function admitClientProofRequest(args: {
|
|
|
310
430
|
*/
|
|
311
431
|
|
|
312
432
|
interface ContractOperation {
|
|
313
|
-
id: 'auth.clientProof.handshake' | 'echo.send' | 'items.list';
|
|
433
|
+
id: 'auth.clientProof.handshake' | 'echo.send' | 'items.list' | 'auth.enroll.register' | 'auth.enroll.login' | 'auth.enroll.oauthNative' | 'auth.keys.rotate' | 'auth.keys.list' | 'auth.keys.revoke' | 'auth.keys.revokeAll';
|
|
314
434
|
method: 'POST';
|
|
315
435
|
path: string;
|
|
316
|
-
|
|
436
|
+
/**
|
|
437
|
+
* How a call is admitted. `clientProofV1` operations run the proof
|
|
438
|
+
* admission order; `none` operations are the unproven class — accepted
|
|
439
|
+
* with neither proof headers nor a session header, because enrollment is
|
|
440
|
+
* called before any key exists to sign with.
|
|
441
|
+
*/
|
|
442
|
+
authProfile: 'clientProofV1' | 'none';
|
|
317
443
|
requiresSession: boolean;
|
|
318
444
|
requestType: string;
|
|
319
445
|
responseType: string;
|
|
320
446
|
summary: string;
|
|
321
447
|
}
|
|
322
448
|
declare const CONTRACT_OPERATIONS: readonly ContractOperation[];
|
|
449
|
+
/**
|
|
450
|
+
* The `/_auth` surface exported into the mobile contract: enrollment, login
|
|
451
|
+
* and key rotation. These are ordinary SPFN REST routes, not canonical-JSON
|
|
452
|
+
* operations — the dev handler never serves them, and their wire rules are
|
|
453
|
+
* the `restOperations` section of the bundle, not `canonicalJson`.
|
|
454
|
+
*
|
|
455
|
+
* The three `authProfile: 'none'` operations are the unproven class: they are
|
|
456
|
+
* accepted with neither proof headers nor a session header, because they are
|
|
457
|
+
* how a client obtains a key in the first place. `auth.keys.rotate` requires
|
|
458
|
+
* an authenticated caller (a clientProofV1 proof on this surface); an
|
|
459
|
+
* unproven call to it is refused like any failed admission.
|
|
460
|
+
*/
|
|
461
|
+
declare const AUTH_SURFACE_OPERATIONS: readonly ContractOperation[];
|
|
323
462
|
/** The body is canonical JSON but not the declared request type. */
|
|
324
463
|
declare class ContractTypeError extends Error {
|
|
325
464
|
constructor();
|
|
@@ -415,4 +554,4 @@ interface ClientProofGuardOptions {
|
|
|
415
554
|
*/
|
|
416
555
|
declare function createClientProofGuard(state: ClientProofState, options?: ClientProofGuardOptions): MiddlewareHandler;
|
|
417
556
|
|
|
418
|
-
export { ABSENT_BODY_SHA256, type Admission, CLIENT_PROOF_CONTENT_TYPE, CLIENT_PROOF_HEADERS, CLIENT_PROOF_PROFILE, CONTRACT_OPERATIONS, CONTROL_PREFIX, CONTROL_TOKEN_HEADER, CanonicalJsonError, type CanonicalJsonErrorCode, type CanonicalObject, type CanonicalValue, type ClientProofClock, type ClientProofContext, type ClientProofCredentials, type ClientProofDevHandler, type ClientProofDevHandlerOptions, type ClientProofErrorCode, type ClientProofGuardOptions, type ClientProofInput, ClientProofRefusal, ClientProofState, type ClientProofStateOptions, type ClientProofStats, type ContractItem, type ContractOperation, ContractTypeError, DEFAULT_REPLAY_WINDOW_MILLIS, DEFAULT_SESSION_TTL_MILLIS, DEV_CATALOGUE, DEV_MAX_LIMIT, type EchoRequest, type HandshakeRequest, type ListItemsRequest, ProofInputError, TestClock, admitClientProofRequest, canonicalProofInput,
|
|
557
|
+
export { ABSENT_BODY_SHA256, AUTH_SURFACE_OPERATIONS, type Admission, CLIENT_PROOF_CONTENT_TYPE, CLIENT_PROOF_HEADERS, CLIENT_PROOF_PROFILE, CONTRACT_OPERATIONS, CONTROL_PREFIX, CONTROL_TOKEN_HEADER, CanonicalJsonError, type CanonicalJsonErrorCode, type CanonicalObject, type CanonicalValue, type ClientProofClock, type ClientProofContext, type ClientProofCredentials, type ClientProofDevHandler, type ClientProofDevHandlerOptions, type ClientProofErrorCode, type ClientProofGuardOptions, type ClientProofInput, ClientProofRefusal, type ClientProofReplayStore, ClientProofState, type ClientProofStateOptions, type ClientProofStats, type ContractItem, type ContractOperation, ContractTypeError, DEFAULT_REPLAY_WINDOW_MILLIS, DEFAULT_SESSION_TTL_MILLIS, DEV_CATALOGUE, DEV_MAX_LIMIT, type EchoRequest, type HandshakeRequest, type ListItemsRequest, MemoryReplayLedger, MemoryReplayStore, PROOF_SIGNATURE_BYTES, PROOF_SIGNATURE_HEX_LENGTH, ProofInputError, RedisReplayStore, TestClock, admitClientProofRequest, canonicalProofInput, configureClientProofReplayStore, createClientProofDevHandler, createClientProofGuard, decodeEchoRequest, decodeHandshakeRequest, decodeListItemsRequest, encodeCanonicalJson, encodeEchoResponse, encodeHandshakeResponse, encodeListItemsResponse, getClientProofReplayStore, isCanonicalBytes, isRequestContentType, newHexId, parseCanonicalJson, parseClientProofPublicKey, readCredentials, replayLedgerKey, sha256Hex, signClientProof, systemClock, verifyClientProof };
|