@7h3/protocol 0.5.4 → 0.6.0
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/bin/7h3.js +155 -5
- package/cborCodec.d.ts +13 -0
- package/gateway.d.ts +19 -1
- package/index.js +651 -507
- package/package.json +1 -1
- package/protocol.d.ts +10 -0
- package/rateLimiter.d.ts +4 -0
- package/webhookBinding.d.ts +24 -0
- package/wsBinding.d.ts +8 -0
package/package.json
CHANGED
package/protocol.d.ts
CHANGED
|
@@ -57,6 +57,16 @@ export declare function verifyEnvelopeEd25519(envelope: ProtocolEnvelope, public
|
|
|
57
57
|
export declare function verifyEnvelopeSignature(envelope: ProtocolEnvelope, material: SignatureVerificationMaterial): Promise<boolean>;
|
|
58
58
|
export declare function verifyCanonicalPayloadSignature(payload: string, signature: ProtocolSignature | undefined, material: SignatureVerificationMaterial): Promise<boolean>;
|
|
59
59
|
export declare const MAX_TTL_MS = 86400000;
|
|
60
|
+
/**
|
|
61
|
+
* How far into the future a timestamp may sit before it is rejected.
|
|
62
|
+
*
|
|
63
|
+
* Matches the transport binding's default so every entry point agrees. Without
|
|
64
|
+
* this ceiling, MAX_TTL_MS bounds nothing: a sender can post-date `timestampMs`
|
|
65
|
+
* by a year and still pass a 24h `ttlMs`, producing an envelope that validates
|
|
66
|
+
* for a year and stays replayable long after any replay store has forgotten its
|
|
67
|
+
* nonce.
|
|
68
|
+
*/
|
|
69
|
+
export declare const MAX_CLOCK_SKEW_MS = 30000;
|
|
60
70
|
export declare function validateEnvelope(envelope: ProtocolEnvelope, nowMs?: number): ProtocolDiagnostic[];
|
|
61
71
|
export declare function createEnvelope(input: {
|
|
62
72
|
sender: string;
|
package/rateLimiter.d.ts
CHANGED
|
@@ -20,6 +20,10 @@ export interface RateLimitStore {
|
|
|
20
20
|
}
|
|
21
21
|
declare class SlidingWindowRateLimiter {
|
|
22
22
|
private windows;
|
|
23
|
+
private readonly maxKeys;
|
|
24
|
+
constructor(opts?: {
|
|
25
|
+
maxKeys?: number;
|
|
26
|
+
});
|
|
23
27
|
check(key: string, policy: RateLimitPolicy, nowMs?: number): RateLimitResult;
|
|
24
28
|
consume(key: string, policy: RateLimitPolicy, nowMs?: number): RateLimitResult;
|
|
25
29
|
reset(key: string): void;
|
package/webhookBinding.d.ts
CHANGED
|
@@ -2,6 +2,26 @@ import { generateEd25519KeypairBase64Url } from './protocol';
|
|
|
2
2
|
export declare const WEBHOOK_SIG_HEADER = "x-7h3-sig";
|
|
3
3
|
export declare const WEBHOOK_TS_HEADER = "x-7h3-ts";
|
|
4
4
|
export declare const WEBHOOK_DEFAULT_TTL_MS = 300000;
|
|
5
|
+
/**
|
|
6
|
+
* A verified webhook signature is otherwise valid to replay any number of
|
|
7
|
+
* times until it ages out of maxAgeMs — the signature+timestamp cover
|
|
8
|
+
* authenticity and freshness, but nothing dedupes delivery. A replayCache
|
|
9
|
+
* closes that gap. The Ed25519/HMAC signature is deterministic per
|
|
10
|
+
* (timestampMs, body, key), so it doubles as a stable dedup key — no wire
|
|
11
|
+
* format change needed.
|
|
12
|
+
*/
|
|
13
|
+
export interface WebhookReplayCache {
|
|
14
|
+
/** Returns true if this key was successfully reserved (first use), false if already seen. */
|
|
15
|
+
consume(key: string, expiresAtMs: number, nowMs: number): boolean | Promise<boolean>;
|
|
16
|
+
}
|
|
17
|
+
/** Bounded in-memory WebhookReplayCache — single process only, does not survive a restart. */
|
|
18
|
+
export declare class InMemoryWebhookReplayCache implements WebhookReplayCache {
|
|
19
|
+
private readonly seen;
|
|
20
|
+
private readonly maxEntries;
|
|
21
|
+
constructor(maxEntries?: number);
|
|
22
|
+
private prune;
|
|
23
|
+
consume(key: string, expiresAtMs: number, nowMs: number): boolean;
|
|
24
|
+
}
|
|
5
25
|
export interface WebhookSignOptions {
|
|
6
26
|
privateKey: string;
|
|
7
27
|
ttlMs?: number;
|
|
@@ -13,10 +33,14 @@ export interface WebhookSignHmacOptions {
|
|
|
13
33
|
export interface WebhookVerifyOptions {
|
|
14
34
|
publicKey: string;
|
|
15
35
|
maxAgeMs?: number;
|
|
36
|
+
/** Optional — rejects a signature that's already been consumed within its TTL window. */
|
|
37
|
+
replayCache?: WebhookReplayCache;
|
|
16
38
|
}
|
|
17
39
|
export interface WebhookVerifyHmacOptions {
|
|
18
40
|
secret: string;
|
|
19
41
|
maxAgeMs?: number;
|
|
42
|
+
/** Optional — rejects a signature that's already been consumed within its TTL window. */
|
|
43
|
+
replayCache?: WebhookReplayCache;
|
|
20
44
|
}
|
|
21
45
|
export interface WebhookHeaders {
|
|
22
46
|
[WEBHOOK_SIG_HEADER]: string;
|
package/wsBinding.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { generateEd25519KeypairBase64Url, type ProtocolEnvelope } from './protocol';
|
|
2
2
|
import type { KeyRegistry } from './keyRegistry';
|
|
3
|
+
import type { ReplayCache } from './protocolReplay';
|
|
3
4
|
import { SignedStreamWriter, type StreamSignerOpts, type StreamVerifierOpts, type StreamVerifyResult, type StreamChunk } from './stream';
|
|
4
5
|
export { type KeyRegistry, generateEd25519KeypairBase64Url };
|
|
5
6
|
export type { StreamSignerOpts, StreamVerifierOpts, StreamVerifyResult, StreamChunk };
|
|
@@ -21,6 +22,13 @@ export interface WsBindingOptions {
|
|
|
21
22
|
keyRegistry: KeyRegistry;
|
|
22
23
|
ttlMs?: number;
|
|
23
24
|
onVerifyFail?: (err: Error, rawData: string) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Optional — signature+TTL alone don't stop a captured frame from being
|
|
27
|
+
* replayed verbatim any number of times within its TTL window. Pass an
|
|
28
|
+
* InMemoryReplayCache (or a distributed one) to dedupe incoming frames by
|
|
29
|
+
* sender/messageId/nonce, same as the HTTP gateway does.
|
|
30
|
+
*/
|
|
31
|
+
replayCache?: ReplayCache;
|
|
24
32
|
}
|
|
25
33
|
export interface ProtectedWebSocket {
|
|
26
34
|
send(payload: unknown): Promise<void>;
|