@sempdev/semp 0.5.1 → 0.5.5
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/brief/address.d.ts +1 -1
- package/dist/brief/address.js +1 -1
- package/dist/brief/brief.d.ts +1 -1
- package/dist/brief/brief.js +1 -1
- package/dist/canonical/marshal.d.ts +2 -2
- package/dist/canonical/marshal.js +2 -2
- package/dist/closure/driver.d.ts +2 -2
- package/dist/closure/driver.js +1 -1
- package/dist/crypto/aead.d.ts +2 -2
- package/dist/crypto/aead.js +2 -2
- package/dist/crypto/kdf.d.ts +1 -1
- package/dist/crypto/kdf.js +1 -1
- package/dist/crypto/mac.d.ts +1 -1
- package/dist/crypto/mac.js +1 -1
- package/dist/delivery/ack.d.ts +5 -5
- package/dist/delivery/ack.js +6 -6
- package/dist/delivery/blocklist.d.ts +1 -1
- package/dist/delivery/blocklist.js +2 -2
- package/dist/delivery/device_sync.d.ts +26 -0
- package/dist/delivery/device_sync.d.ts.map +1 -0
- package/dist/delivery/device_sync.js +18 -0
- package/dist/delivery/device_sync.js.map +1 -0
- package/dist/delivery/disposition.d.ts +1 -1
- package/dist/delivery/fetch.d.ts +1 -1
- package/dist/delivery/fetch.js +1 -1
- package/dist/delivery/inbox.d.ts +2 -2
- package/dist/delivery/inbox.js +2 -2
- package/dist/delivery/index.d.ts +4 -0
- package/dist/delivery/index.d.ts.map +1 -1
- package/dist/delivery/index.js +4 -0
- package/dist/delivery/index.js.map +1 -1
- package/dist/delivery/persistent_silent.d.ts +70 -0
- package/dist/delivery/persistent_silent.d.ts.map +1 -0
- package/dist/delivery/persistent_silent.js +117 -0
- package/dist/delivery/persistent_silent.js.map +1 -0
- package/dist/delivery/pipeline.d.ts +4 -4
- package/dist/delivery/pipeline.js +2 -2
- package/dist/delivery/policy_state.d.ts +2 -2
- package/dist/delivery/policy_state.js +4 -4
- package/dist/delivery/receipt.d.ts +3 -3
- package/dist/delivery/receipt.js +3 -3
- package/dist/delivery/receipt_store.d.ts +1 -1
- package/dist/delivery/receipt_store.js +1 -1
- package/dist/delivery/retry.d.ts +2 -2
- package/dist/delivery/retry.js +2 -2
- package/dist/delivery/scheduler.d.ts +1 -1
- package/dist/delivery/scheduler.js +1 -1
- package/dist/delivery/stage_partition.d.ts +1 -1
- package/dist/delivery/stage_partition.js +1 -1
- package/dist/delivery/staged_runner.d.ts +1 -1
- package/dist/delivery/staged_runner.js +2 -2
- package/dist/delivery/status_message.d.ts +75 -0
- package/dist/delivery/status_message.d.ts.map +1 -0
- package/dist/delivery/status_message.js +109 -0
- package/dist/delivery/status_message.js.map +1 -0
- package/dist/delivery/upgrade_signal.d.ts +48 -0
- package/dist/delivery/upgrade_signal.d.ts.map +1 -0
- package/dist/delivery/upgrade_signal.js +48 -0
- package/dist/delivery/upgrade_signal.js.map +1 -0
- package/dist/discovery/configuration.d.ts +20 -1
- package/dist/discovery/configuration.d.ts.map +1 -1
- package/dist/discovery/configuration.js.map +1 -1
- package/dist/discovery/dns.d.ts +27 -1
- package/dist/discovery/dns.d.ts.map +1 -1
- package/dist/discovery/dns.js +37 -0
- package/dist/discovery/dns.js.map +1 -1
- package/dist/discovery/index.d.ts +2 -2
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +1 -1
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/partition.d.ts +1 -1
- package/dist/discovery/partition.js +1 -1
- package/dist/discovery/resolver.d.ts +5 -5
- package/dist/discovery/resolver.js +5 -5
- package/dist/discovery/txt.d.ts +1 -1
- package/dist/discovery/txt.js +1 -1
- package/dist/enclosure/forwarding.d.ts +1 -1
- package/dist/enclosure/forwarding.js +1 -1
- package/dist/envelope/buckets.d.ts +2 -2
- package/dist/envelope/buckets.js +2 -2
- package/dist/envelope/compose.d.ts +17 -2
- package/dist/envelope/compose.d.ts.map +1 -1
- package/dist/envelope/compose.js +29 -11
- package/dist/envelope/compose.js.map +1 -1
- package/dist/envelope/encode.d.ts +2 -2
- package/dist/envelope/encode.js +3 -3
- package/dist/envelope/index.d.ts +1 -1
- package/dist/envelope/index.d.ts.map +1 -1
- package/dist/envelope/index.js +1 -1
- package/dist/envelope/index.js.map +1 -1
- package/dist/envelope/open_any.d.ts.map +1 -1
- package/dist/envelope/open_any.js +5 -5
- package/dist/envelope/open_any.js.map +1 -1
- package/dist/envelope/open_verified.d.ts +1 -1
- package/dist/envelope/open_verified.js +1 -1
- package/dist/envelope/padding.d.ts +2 -2
- package/dist/envelope/padding.js +3 -3
- package/dist/envelope/verify.d.ts +1 -1
- package/dist/envelope/verify.js +1 -1
- package/dist/extensions/index.d.ts +1 -0
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +1 -0
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/limits.d.ts +2 -2
- package/dist/extensions/limits.js +2 -2
- package/dist/extensions/validation_failure.d.ts +48 -0
- package/dist/extensions/validation_failure.d.ts.map +1 -0
- package/dist/extensions/validation_failure.js +25 -0
- package/dist/extensions/validation_failure.js.map +1 -0
- package/dist/handshake/abort.d.ts +1 -1
- package/dist/handshake/abort.js +1 -1
- package/dist/handshake/client_state.d.ts +5 -5
- package/dist/handshake/client_state.js +5 -5
- package/dist/handshake/confirm.d.ts +2 -2
- package/dist/handshake/confirm.js +2 -2
- package/dist/handshake/driver.d.ts +2 -2
- package/dist/handshake/driver.js +1 -1
- package/dist/handshake/federation.d.ts +6 -6
- package/dist/handshake/federation.js +5 -5
- package/dist/handshake/first_contact.d.ts +1 -1
- package/dist/handshake/first_contact.js +1 -1
- package/dist/handshake/identity.d.ts +1 -1
- package/dist/handshake/identity.js +1 -1
- package/dist/handshake/pow.js +1 -1
- package/dist/handshake/server_state.d.ts +3 -3
- package/dist/handshake/server_state.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/keys/compromise.d.ts +2 -2
- package/dist/keys/compromise.js +1 -1
- package/dist/keys/device_certificate.d.ts +3 -3
- package/dist/keys/device_certificate.js +4 -4
- package/dist/keys/key_revocation.d.ts +2 -2
- package/dist/keys/key_revocation.js +1 -1
- package/dist/keys/request.d.ts +17 -3
- package/dist/keys/request.d.ts.map +1 -1
- package/dist/keys/request.js.map +1 -1
- package/dist/keys/sign.d.ts +1 -1
- package/dist/keys/sign.js +1 -1
- package/dist/keys/signed.d.ts +3 -3
- package/dist/keys/signed.js +3 -3
- package/dist/keys/store.js +1 -1
- package/dist/largeattachment/crypto.d.ts +1 -1
- package/dist/largeattachment/crypto.js +2 -2
- package/dist/largeattachment/upload.d.ts +3 -3
- package/dist/largeattachment/upload.js +1 -1
- package/dist/migration/index.d.ts +1 -1
- package/dist/migration/index.d.ts.map +1 -1
- package/dist/migration/index.js +1 -1
- package/dist/migration/index.js.map +1 -1
- package/dist/migration/lockout.d.ts +2 -2
- package/dist/migration/lockout.js +2 -2
- package/dist/migration/migration.d.ts +6 -4
- package/dist/migration/migration.d.ts.map +1 -1
- package/dist/migration/migration.js +3 -3
- package/dist/migration/migration.js.map +1 -1
- package/dist/migration/notice.d.ts +31 -19
- package/dist/migration/notice.d.ts.map +1 -1
- package/dist/migration/notice.js +37 -71
- package/dist/migration/notice.js.map +1 -1
- package/dist/migration/orchestrate.d.ts +10 -10
- package/dist/migration/orchestrate.d.ts.map +1 -1
- package/dist/migration/orchestrate.js +23 -23
- package/dist/migration/orchestrate.js.map +1 -1
- package/dist/migration/sign.js +9 -9
- package/dist/migration/sign.js.map +1 -1
- package/dist/migration/types.d.ts +35 -29
- package/dist/migration/types.d.ts.map +1 -1
- package/dist/migration/types.js +5 -7
- package/dist/migration/types.js.map +1 -1
- package/dist/recovery/bundle_store.js +1 -1
- package/dist/recovery/sign.js +3 -3
- package/dist/recovery/types.d.ts +3 -3
- package/dist/reputation/abuse_report.d.ts +3 -3
- package/dist/reputation/abuse_report.js +2 -2
- package/dist/reputation/eligibility.d.ts +44 -0
- package/dist/reputation/eligibility.d.ts.map +1 -0
- package/dist/reputation/eligibility.js +58 -0
- package/dist/reputation/eligibility.js.map +1 -0
- package/dist/reputation/evidence.d.ts +47 -0
- package/dist/reputation/evidence.d.ts.map +1 -0
- package/dist/reputation/evidence.js +117 -0
- package/dist/reputation/evidence.js.map +1 -0
- package/dist/reputation/gossip_fetch.d.ts +2 -2
- package/dist/reputation/gossip_fetch.js +1 -1
- package/dist/reputation/index.d.ts +4 -1
- package/dist/reputation/index.d.ts.map +1 -1
- package/dist/reputation/index.js +4 -1
- package/dist/reputation/index.js.map +1 -1
- package/dist/reputation/pow.d.ts +1 -1
- package/dist/reputation/pow.js +1 -1
- package/dist/reputation/references.d.ts +51 -0
- package/dist/reputation/references.d.ts.map +1 -0
- package/dist/reputation/references.js +95 -0
- package/dist/reputation/references.js.map +1 -0
- package/dist/reputation/sign.d.ts +1 -1
- package/dist/reputation/sign.js +2 -2
- package/dist/reputation/types.d.ts +46 -2
- package/dist/reputation/types.d.ts.map +1 -1
- package/dist/reputation/types.js +14 -0
- package/dist/reputation/types.js.map +1 -1
- package/dist/reputation/whois.d.ts +1 -1
- package/dist/reputation/whois.js +1 -1
- package/dist/seal/wrap.d.ts +2 -2
- package/dist/seal/wrap.js +4 -4
- package/dist/session/dispatcher.d.ts +3 -3
- package/dist/session/dispatcher.js +1 -1
- package/dist/session/rekey_seal.d.ts +3 -3
- package/dist/session/rekey_seal.js +3 -3
- package/dist/session/session.d.ts +3 -3
- package/dist/session/session.js +3 -3
- package/dist/transparency/log.d.ts +1 -1
- package/dist/transparency/log.js +2 -2
- package/dist/transparency/types.d.ts +2 -2
- package/dist/transparency/types.js +1 -1
- package/dist/transport/h2.d.ts +33 -12
- package/dist/transport/h2.d.ts.map +1 -1
- package/dist/transport/h2.js +40 -13
- package/dist/transport/h2.js.map +1 -1
- package/dist/transport/index.d.ts +1 -1
- package/dist/transport/index.d.ts.map +1 -1
- package/dist/transport/index.js +1 -1
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/memory.js +1 -1
- package/dist/transport/ws.d.ts +1 -1
- package/dist/transport/ws.js +1 -1
- package/package.json +1 -1
|
@@ -62,7 +62,7 @@ export type LocalAddressFunc = (address: string) => boolean;
|
|
|
62
62
|
export type InboxStore = Pick<Inbox, "store">;
|
|
63
63
|
/** Hook returning the current session-id retired status. */
|
|
64
64
|
export type SessionRetiredFunc = (sessionId: string) => Promise<boolean>;
|
|
65
|
-
/** Decoded brief shape
|
|
65
|
+
/** Decoded brief shape - minimal fields the pipeline needs. */
|
|
66
66
|
export interface DecodedBrief {
|
|
67
67
|
to: string[];
|
|
68
68
|
cc?: string[];
|
|
@@ -108,7 +108,7 @@ export interface PipelineConfig {
|
|
|
108
108
|
/** Default clock-skew tolerance for step 2; defaults to 15 minutes. */
|
|
109
109
|
clockSkewMs?: number;
|
|
110
110
|
}
|
|
111
|
-
/** Envelope-wide rejection produced by steps 1
|
|
111
|
+
/** Envelope-wide rejection produced by steps 1-7. */
|
|
112
112
|
export interface PipelineRejection {
|
|
113
113
|
reasonCode: string;
|
|
114
114
|
reason: string;
|
|
@@ -125,14 +125,14 @@ export interface PipelineResult {
|
|
|
125
125
|
*/
|
|
126
126
|
results: SubmissionResult[];
|
|
127
127
|
/**
|
|
128
|
-
* Envelope-wide rejection (steps 1
|
|
128
|
+
* Envelope-wide rejection (steps 1-7). Implies {@link results} is
|
|
129
129
|
* empty.
|
|
130
130
|
*/
|
|
131
131
|
rejection?: PipelineRejection;
|
|
132
132
|
}
|
|
133
133
|
/**
|
|
134
134
|
* Receive-side delivery pipeline. Single-process, callable across
|
|
135
|
-
* many envelopes. Concurrency is the caller's responsibility
|
|
135
|
+
* many envelopes. Concurrency is the caller's responsibility - each
|
|
136
136
|
* `process()` call is independent and stateless beyond the
|
|
137
137
|
* configured hooks.
|
|
138
138
|
*/
|
|
@@ -27,7 +27,7 @@ import { unwrap as sealUnwrap } from "../seal/index.js";
|
|
|
27
27
|
import { matchBlockList } from "./blocklist.js";
|
|
28
28
|
/**
|
|
29
29
|
* Receive-side delivery pipeline. Single-process, callable across
|
|
30
|
-
* many envelopes. Concurrency is the caller's responsibility
|
|
30
|
+
* many envelopes. Concurrency is the caller's responsibility - each
|
|
31
31
|
* `process()` call is independent and stateless beyond the
|
|
32
32
|
* configured hooks.
|
|
33
33
|
*/
|
|
@@ -92,7 +92,7 @@ export class Pipeline {
|
|
|
92
92
|
return result;
|
|
93
93
|
}
|
|
94
94
|
// Steps 6 + 7: home-server brief-only open. We don't need
|
|
95
|
-
// K_enclosure here
|
|
95
|
+
// K_enclosure here - only the recipient client does. Walk the
|
|
96
96
|
// configured candidates and try each against
|
|
97
97
|
// env.seal.brief_recipients.
|
|
98
98
|
let brief;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* rejects the whole message; unrelated operations in the same
|
|
9
9
|
* message MUST NOT be applied.
|
|
10
10
|
*
|
|
11
|
-
* Apply does NOT verify the signature on the message
|
|
11
|
+
* Apply does NOT verify the signature on the message - callers MUST
|
|
12
12
|
* run {@link verifyUserPolicyMessage} before invoking
|
|
13
13
|
* {@link PolicyState.apply}.
|
|
14
14
|
*
|
|
@@ -57,7 +57,7 @@ export interface PolicySnapshot {
|
|
|
57
57
|
* Per-user policy state. Concurrency-safe within a single JS event
|
|
58
58
|
* loop (no async mutation between read-modify-write).
|
|
59
59
|
*
|
|
60
|
-
* Does NOT enforce DELIVERY.md §7.5 encrypted-at-rest storage
|
|
60
|
+
* Does NOT enforce DELIVERY.md §7.5 encrypted-at-rest storage -
|
|
61
61
|
* that is the persistence layer's responsibility.
|
|
62
62
|
*/
|
|
63
63
|
export declare class PolicyState {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* rejects the whole message; unrelated operations in the same
|
|
9
9
|
* message MUST NOT be applied.
|
|
10
10
|
*
|
|
11
|
-
* Apply does NOT verify the signature on the message
|
|
11
|
+
* Apply does NOT verify the signature on the message - callers MUST
|
|
12
12
|
* run {@link verifyUserPolicyMessage} before invoking
|
|
13
13
|
* {@link PolicyState.apply}.
|
|
14
14
|
*
|
|
@@ -46,7 +46,7 @@ function messageFor(code, d) {
|
|
|
46
46
|
* Per-user policy state. Concurrency-safe within a single JS event
|
|
47
47
|
* loop (no async mutation between read-modify-write).
|
|
48
48
|
*
|
|
49
|
-
* Does NOT enforce DELIVERY.md §7.5 encrypted-at-rest storage
|
|
49
|
+
* Does NOT enforce DELIVERY.md §7.5 encrypted-at-rest storage -
|
|
50
50
|
* that is the persistence layer's responsibility.
|
|
51
51
|
*/
|
|
52
52
|
export class PolicyState {
|
|
@@ -138,7 +138,7 @@ export class PolicyState {
|
|
|
138
138
|
currentVersion: this.policyVersionValue,
|
|
139
139
|
});
|
|
140
140
|
}
|
|
141
|
-
// Pre-flight every op for unsupported-kind before mutating
|
|
141
|
+
// Pre-flight every op for unsupported-kind before mutating -
|
|
142
142
|
// §7.2 atomicity.
|
|
143
143
|
for (let i = 0; i < m.operations.length; i++) {
|
|
144
144
|
const op = m.operations[i];
|
|
@@ -257,7 +257,7 @@ function entryIdFor(op) {
|
|
|
257
257
|
* not specific op-kind violations.
|
|
258
258
|
*
|
|
259
259
|
* The mapping leans on the validator's stable error-string format
|
|
260
|
-
* (`delivery: user policy operations[N] ...`)
|
|
260
|
+
* (`delivery: user policy operations[N] ...`) - same approach as
|
|
261
261
|
* the semp-go reference.
|
|
262
262
|
*/
|
|
263
263
|
function classifyOpInvalid(msg, m) {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* This module provides:
|
|
12
12
|
*
|
|
13
13
|
* - {@link computeEnvelopeHash}: SHA-256 over canonical envelope bytes
|
|
14
|
-
* (the same canonical form `seal.signature` is computed over
|
|
14
|
+
* (the same canonical form `seal.signature` is computed over -
|
|
15
15
|
* `signature` and `session_mac` blanked, `hop_count` and `padding`
|
|
16
16
|
* omitted).
|
|
17
17
|
* - {@link signDeliveryReceipt}: build + sign a receipt from
|
|
@@ -95,7 +95,7 @@ export interface SignDeliveryReceiptResult {
|
|
|
95
95
|
/**
|
|
96
96
|
* SHA-256 of canonical envelope bytes, base64-encoded, per
|
|
97
97
|
* §1.1.1.3. The caller is responsible for producing the canonical
|
|
98
|
-
* bytes
|
|
98
|
+
* bytes - typically via `envelope.canonicalEnvelopeFor(env)` which
|
|
99
99
|
* applies §4.3 elision (signature, session_mac, hop_count, padding).
|
|
100
100
|
*/
|
|
101
101
|
export declare function computeEnvelopeHash(canonicalEnvelopeBytes: Uint8Array): string;
|
|
@@ -117,7 +117,7 @@ export interface VerifyDeliveryReceiptInput {
|
|
|
117
117
|
* structural validation failure (use {@link validateReceipt} ahead
|
|
118
118
|
* of time to surface those as boolean false instead).
|
|
119
119
|
*
|
|
120
|
-
* Does NOT cross-check `accepted_at` against the verifier's clock
|
|
120
|
+
* Does NOT cross-check `accepted_at` against the verifier's clock -
|
|
121
121
|
* that is a §1.1.1.5 caller-side decision and MUST be applied with
|
|
122
122
|
* the {@link ReceiptClockSkewToleranceSeconds} tolerance.
|
|
123
123
|
*/
|
package/dist/delivery/receipt.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* This module provides:
|
|
12
12
|
*
|
|
13
13
|
* - {@link computeEnvelopeHash}: SHA-256 over canonical envelope bytes
|
|
14
|
-
* (the same canonical form `seal.signature` is computed over
|
|
14
|
+
* (the same canonical form `seal.signature` is computed over -
|
|
15
15
|
* `signature` and `session_mac` blanked, `hop_count` and `padding`
|
|
16
16
|
* omitted).
|
|
17
17
|
* - {@link signDeliveryReceipt}: build + sign a receipt from
|
|
@@ -49,7 +49,7 @@ export const ReceiptClockSkewToleranceSeconds = 120;
|
|
|
49
49
|
/**
|
|
50
50
|
* SHA-256 of canonical envelope bytes, base64-encoded, per
|
|
51
51
|
* §1.1.1.3. The caller is responsible for producing the canonical
|
|
52
|
-
* bytes
|
|
52
|
+
* bytes - typically via `envelope.canonicalEnvelopeFor(env)` which
|
|
53
53
|
* applies §4.3 elision (signature, session_mac, hop_count, padding).
|
|
54
54
|
*/
|
|
55
55
|
export function computeEnvelopeHash(canonicalEnvelopeBytes) {
|
|
@@ -105,7 +105,7 @@ export function signDeliveryReceipt(input) {
|
|
|
105
105
|
* structural validation failure (use {@link validateReceipt} ahead
|
|
106
106
|
* of time to surface those as boolean false instead).
|
|
107
107
|
*
|
|
108
|
-
* Does NOT cross-check `accepted_at` against the verifier's clock
|
|
108
|
+
* Does NOT cross-check `accepted_at` against the verifier's clock -
|
|
109
109
|
* that is a §1.1.1.5 caller-side decision and MUST be applied with
|
|
110
110
|
* the {@link ReceiptClockSkewToleranceSeconds} tolerance.
|
|
111
111
|
*/
|
|
@@ -68,7 +68,7 @@ export declare const DefaultReceiptRetentionMs: number;
|
|
|
68
68
|
* Reference {@link ReceiptStore} backed by a Map. Acknowledge drops
|
|
69
69
|
* the receipt immediately so no plaintext archive accumulates.
|
|
70
70
|
*
|
|
71
|
-
* Single-process only
|
|
71
|
+
* Single-process only - production deployments replace this with a
|
|
72
72
|
* durable backend.
|
|
73
73
|
*/
|
|
74
74
|
export declare class InMemoryReceiptStore implements ReceiptStore {
|
|
@@ -28,7 +28,7 @@ export const DefaultReceiptRetentionMs = 72 * 60 * 60 * 1000;
|
|
|
28
28
|
* Reference {@link ReceiptStore} backed by a Map. Acknowledge drops
|
|
29
29
|
* the receipt immediately so no plaintext archive accumulates.
|
|
30
30
|
*
|
|
31
|
-
* Single-process only
|
|
31
|
+
* Single-process only - production deployments replace this with a
|
|
32
32
|
* durable backend.
|
|
33
33
|
*/
|
|
34
34
|
export class InMemoryReceiptStore {
|
package/dist/delivery/retry.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export declare const MinRetryInitialIntervalMs = 60000;
|
|
|
14
14
|
export declare const MinRetryMultiplier = 2;
|
|
15
15
|
/** Cap on individual inter-attempt intervals per §2.3 (6 hours). */
|
|
16
16
|
export declare const MaxRetryIntervalMs: number;
|
|
17
|
-
/** Minimum jitter half-width per §2.3 (10%
|
|
17
|
+
/** Minimum jitter half-width per §2.3 (10% - RECOMMENDED 25%). */
|
|
18
18
|
export declare const MinRetryJitterFraction = 0.1;
|
|
19
19
|
/**
|
|
20
20
|
* Lower bound on the realized jittered interval per §2.3:
|
|
@@ -69,7 +69,7 @@ export declare function nextAttemptAt(cfg: RetryConfig, previous: Date, attempt:
|
|
|
69
69
|
*/
|
|
70
70
|
export declare function isRecoverableReason(reasonCode: string): boolean;
|
|
71
71
|
/**
|
|
72
|
-
* Effective delivery deadline per §2.4
|
|
72
|
+
* Effective delivery deadline per §2.4 - the earlier of
|
|
73
73
|
* `postmark.expires` and `queuedAt + horizon`. `horizon <= 0`
|
|
74
74
|
* defaults to {@link DefaultMaxRetryHorizonMs}; values larger than
|
|
75
75
|
* {@link MaxRetryHorizonCapMs} clamp down.
|
package/dist/delivery/retry.js
CHANGED
|
@@ -14,7 +14,7 @@ export const MinRetryInitialIntervalMs = 60_000;
|
|
|
14
14
|
export const MinRetryMultiplier = 2.0;
|
|
15
15
|
/** Cap on individual inter-attempt intervals per §2.3 (6 hours). */
|
|
16
16
|
export const MaxRetryIntervalMs = 6 * 60 * 60 * 1000;
|
|
17
|
-
/** Minimum jitter half-width per §2.3 (10%
|
|
17
|
+
/** Minimum jitter half-width per §2.3 (10% - RECOMMENDED 25%). */
|
|
18
18
|
export const MinRetryJitterFraction = 0.10;
|
|
19
19
|
/**
|
|
20
20
|
* Lower bound on the realized jittered interval per §2.3:
|
|
@@ -103,7 +103,7 @@ export function isRecoverableReason(reasonCode) {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
/**
|
|
106
|
-
* Effective delivery deadline per §2.4
|
|
106
|
+
* Effective delivery deadline per §2.4 - the earlier of
|
|
107
107
|
* `postmark.expires` and `queuedAt + horizon`. `horizon <= 0`
|
|
108
108
|
* defaults to {@link DefaultMaxRetryHorizonMs}; values larger than
|
|
109
109
|
* {@link MaxRetryHorizonCapMs} clamp down.
|
|
@@ -141,7 +141,7 @@ export declare class Scheduler {
|
|
|
141
141
|
}
|
|
142
142
|
/**
|
|
143
143
|
* Reference in-memory {@link SchedulerStore}. Tests / single-process
|
|
144
|
-
* demos only
|
|
144
|
+
* demos only - production deployments back the queue with durable
|
|
145
145
|
* storage per DELIVERY.md §2.1.
|
|
146
146
|
*/
|
|
147
147
|
export declare class InMemorySchedulerStore implements SchedulerStore {
|
|
@@ -288,7 +288,7 @@ export class Scheduler {
|
|
|
288
288
|
}
|
|
289
289
|
/**
|
|
290
290
|
* Reference in-memory {@link SchedulerStore}. Tests / single-process
|
|
291
|
-
* demos only
|
|
291
|
+
* demos only - production deployments back the queue with durable
|
|
292
292
|
* storage per DELIVERY.md §2.1.
|
|
293
293
|
*/
|
|
294
294
|
export class InMemorySchedulerStore {
|
|
@@ -66,7 +66,7 @@ export interface PartitionInput {
|
|
|
66
66
|
* excluded from the partition entirely.
|
|
67
67
|
* 2. Compute the implicit full-access stage as
|
|
68
68
|
* `max(delegated_stages_with_mode_not_none) + 1`, taken across
|
|
69
|
-
* ALL delegates with `receive.mode !== "none"`
|
|
69
|
+
* ALL delegates with `receive.mode !== "none"` - not just those
|
|
70
70
|
* that allowed THIS envelope. Matches §10.3.3.1's "the maximum
|
|
71
71
|
* is taken over all delegated devices of the account that have
|
|
72
72
|
* a receive matcher whose mode is not none". When no such
|
|
@@ -26,7 +26,7 @@ import { scopeAllowsSender } from "../keys/device_certificate.js";
|
|
|
26
26
|
* excluded from the partition entirely.
|
|
27
27
|
* 2. Compute the implicit full-access stage as
|
|
28
28
|
* `max(delegated_stages_with_mode_not_none) + 1`, taken across
|
|
29
|
-
* ALL delegates with `receive.mode !== "none"`
|
|
29
|
+
* ALL delegates with `receive.mode !== "none"` - not just those
|
|
30
30
|
* that allowed THIS envelope. Matches §10.3.3.1's "the maximum
|
|
31
31
|
* is taken over all delegated devices of the account that have
|
|
32
32
|
* a receive matcher whose mode is not none". When no such
|
|
@@ -66,7 +66,7 @@ export declare class StagedRunner {
|
|
|
66
66
|
* `submitterDeviceId` is the device_id bound to the session that
|
|
67
67
|
* delivered the disposition; it MUST equal `d.device_id`.
|
|
68
68
|
*
|
|
69
|
-
* Idempotent on repeats from the same device
|
|
69
|
+
* Idempotent on repeats from the same device - keeps the FIRST
|
|
70
70
|
* disposition (conservative aggregation).
|
|
71
71
|
*/
|
|
72
72
|
ingestDisposition(envelopeId: string, submitterDeviceId: string, d: Disposition): void;
|
|
@@ -114,7 +114,7 @@ export class StagedRunner {
|
|
|
114
114
|
* `submitterDeviceId` is the device_id bound to the session that
|
|
115
115
|
* delivered the disposition; it MUST equal `d.device_id`.
|
|
116
116
|
*
|
|
117
|
-
* Idempotent on repeats from the same device
|
|
117
|
+
* Idempotent on repeats from the same device - keeps the FIRST
|
|
118
118
|
* disposition (conservative aggregation).
|
|
119
119
|
*/
|
|
120
120
|
ingestDisposition(envelopeId, submitterDeviceId, d) {
|
|
@@ -256,7 +256,7 @@ export class StagedRunner {
|
|
|
256
256
|
});
|
|
257
257
|
}
|
|
258
258
|
if (rebuilt.length === 0) {
|
|
259
|
-
// No stages remain
|
|
259
|
+
// No stages remain - let the next tick detect completion.
|
|
260
260
|
rec.stages = [];
|
|
261
261
|
return;
|
|
262
262
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEMP_STATUS recipient-status configuration message per
|
|
3
|
+
* draft-gokce-semp-delivery §1.6.5.
|
|
4
|
+
*
|
|
5
|
+
* The client composes a signed StatusMessage carrying the user's
|
|
6
|
+
* state, optional message and until, plus the visibility rule
|
|
7
|
+
* that determines which senders may receive the status in
|
|
8
|
+
* acknowledgments. The client transmits the record to the home
|
|
9
|
+
* server as a signed message under the originating device's key;
|
|
10
|
+
* the home server verifies, checks device_id against the
|
|
11
|
+
* registered device set, and applies the latest update by
|
|
12
|
+
* updated_at.
|
|
13
|
+
*
|
|
14
|
+
* This is distinct from the runtime recipient-status surface in
|
|
15
|
+
* `./status.ts` (the value attached to delivery acknowledgments).
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
/** Wire-level type discriminator. */
|
|
20
|
+
export declare const StatusMessageType = "SEMP_STATUS";
|
|
21
|
+
/** Wire-level version. */
|
|
22
|
+
export declare const StatusMessageVersion = "1.0.0";
|
|
23
|
+
/** Domain-separation prefix for SEMP_STATUS signatures. */
|
|
24
|
+
export declare const StatusMessagePrefix = "SEMP-STATUS:";
|
|
25
|
+
/** Recipient state value pinned by §1.6.3. */
|
|
26
|
+
export type StatusState = "available" | "away" | "do_not_disturb";
|
|
27
|
+
/** Visibility mode for the SEMP_STATUS record per §1.6.5. */
|
|
28
|
+
export type StatusVisibilityMode = "nobody" | "everyone" | "users";
|
|
29
|
+
/** Single entry in StatusVisibility.allow. */
|
|
30
|
+
export type StatusVisibilityEntry = {
|
|
31
|
+
type: "domain";
|
|
32
|
+
domain: string;
|
|
33
|
+
} | {
|
|
34
|
+
type: "user";
|
|
35
|
+
address: string;
|
|
36
|
+
};
|
|
37
|
+
/** Visibility configuration per §1.6.5. */
|
|
38
|
+
export interface StatusVisibility {
|
|
39
|
+
mode: StatusVisibilityMode;
|
|
40
|
+
allow?: StatusVisibilityEntry[];
|
|
41
|
+
}
|
|
42
|
+
/** Signature block on a SEMP_STATUS message. */
|
|
43
|
+
export interface StatusMessageSignature {
|
|
44
|
+
algorithm: string;
|
|
45
|
+
key_id: string;
|
|
46
|
+
value: string;
|
|
47
|
+
}
|
|
48
|
+
/** SEMP_STATUS configuration record per §1.6.5. */
|
|
49
|
+
export interface StatusMessage {
|
|
50
|
+
type: typeof StatusMessageType;
|
|
51
|
+
version: string;
|
|
52
|
+
user_id: string;
|
|
53
|
+
state: StatusState | string;
|
|
54
|
+
message?: string;
|
|
55
|
+
/** ISO 8601 UTC. */
|
|
56
|
+
until?: string;
|
|
57
|
+
visibility: StatusVisibility;
|
|
58
|
+
/** ISO 8601 UTC. */
|
|
59
|
+
updated_at: string;
|
|
60
|
+
device_id: string;
|
|
61
|
+
signature: StatusMessageSignature;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Sign `m.signature` with the originating device's identity
|
|
65
|
+
* private key under the SEMP-STATUS: prefix. Mutates m in place
|
|
66
|
+
* and returns the base64 signature value.
|
|
67
|
+
*/
|
|
68
|
+
export declare function signStatusMessage(m: StatusMessage, devicePriv: Uint8Array, deviceKeyId: string): string;
|
|
69
|
+
/** Verify `m.signature` against the originating device's public key. */
|
|
70
|
+
export declare function verifyStatusMessage(m: StatusMessage, devicePub: Uint8Array): boolean;
|
|
71
|
+
/** Structural validation per §1.6.5. */
|
|
72
|
+
export declare function validateStatusMessage(m: StatusMessage, opts?: {
|
|
73
|
+
skipSignatureCheck?: boolean;
|
|
74
|
+
}): void;
|
|
75
|
+
//# sourceMappingURL=status_message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status_message.d.ts","sourceRoot":"","sources":["../../src/delivery/status_message.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,qCAAqC;AACrC,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAE/C,0BAA0B;AAC1B,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAE5C,2DAA2D;AAC3D,eAAO,MAAM,mBAAmB,iBAAiB,CAAC;AAElD,8CAA8C;AAC9C,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,gBAAgB,CAAC;AAElE,6DAA6D;AAC7D,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAEnE,8CAA8C;AAC9C,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,KAAK,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACjC;AAED,gDAAgD;AAChD,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,mDAAmD;AACnD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,iBAAiB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,gBAAgB,CAAC;IAC7B,oBAAoB;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,sBAAsB,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,aAAa,EAChB,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,MAAM,GAClB,MAAM,CAsBR;AAED,wEAAwE;AACxE,wBAAgB,mBAAmB,CACjC,CAAC,EAAE,aAAa,EAChB,SAAS,EAAE,UAAU,GACpB,OAAO,CAYT;AAED,wCAAwC;AACxC,wBAAgB,qBAAqB,CACnC,CAAC,EAAE,aAAa,EAChB,IAAI,GAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1C,IAAI,CA6CN"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEMP_STATUS recipient-status configuration message per
|
|
3
|
+
* draft-gokce-semp-delivery §1.6.5.
|
|
4
|
+
*
|
|
5
|
+
* The client composes a signed StatusMessage carrying the user's
|
|
6
|
+
* state, optional message and until, plus the visibility rule
|
|
7
|
+
* that determines which senders may receive the status in
|
|
8
|
+
* acknowledgments. The client transmits the record to the home
|
|
9
|
+
* server as a signed message under the originating device's key;
|
|
10
|
+
* the home server verifies, checks device_id against the
|
|
11
|
+
* registered device set, and applies the latest update by
|
|
12
|
+
* updated_at.
|
|
13
|
+
*
|
|
14
|
+
* This is distinct from the runtime recipient-status surface in
|
|
15
|
+
* `./status.ts` (the value attached to delivery acknowledgments).
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
import { signSignedDoc, verifySignedDoc } from "../keys/index.js";
|
|
20
|
+
/** Wire-level type discriminator. */
|
|
21
|
+
export const StatusMessageType = "SEMP_STATUS";
|
|
22
|
+
/** Wire-level version. */
|
|
23
|
+
export const StatusMessageVersion = "1.0.0";
|
|
24
|
+
/** Domain-separation prefix for SEMP_STATUS signatures. */
|
|
25
|
+
export const StatusMessagePrefix = "SEMP-STATUS:";
|
|
26
|
+
/**
|
|
27
|
+
* Sign `m.signature` with the originating device's identity
|
|
28
|
+
* private key under the SEMP-STATUS: prefix. Mutates m in place
|
|
29
|
+
* and returns the base64 signature value.
|
|
30
|
+
*/
|
|
31
|
+
export function signStatusMessage(m, devicePriv, deviceKeyId) {
|
|
32
|
+
if (deviceKeyId === "") {
|
|
33
|
+
throw new Error("delivery: empty device key_id");
|
|
34
|
+
}
|
|
35
|
+
if (m.type === "") {
|
|
36
|
+
m.type = StatusMessageType;
|
|
37
|
+
}
|
|
38
|
+
if (m.version === "") {
|
|
39
|
+
m.version = StatusMessageVersion;
|
|
40
|
+
}
|
|
41
|
+
validateStatusMessage(m, { skipSignatureCheck: true });
|
|
42
|
+
m.signature.algorithm = "ed25519";
|
|
43
|
+
m.signature.key_id = deviceKeyId;
|
|
44
|
+
m.signature.value = "";
|
|
45
|
+
const { signedJSON, signatureB64 } = signSignedDoc({
|
|
46
|
+
preSignJSON: m,
|
|
47
|
+
seed: devicePriv,
|
|
48
|
+
signaturePath: "signature.value",
|
|
49
|
+
prefix: StatusMessagePrefix,
|
|
50
|
+
});
|
|
51
|
+
m.signature.value = signedJSON.signature.value;
|
|
52
|
+
return signatureB64;
|
|
53
|
+
}
|
|
54
|
+
/** Verify `m.signature` against the originating device's public key. */
|
|
55
|
+
export function verifyStatusMessage(m, devicePub) {
|
|
56
|
+
validateStatusMessage(m);
|
|
57
|
+
if (m.signature.value === "") {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const { ok } = verifySignedDoc({
|
|
61
|
+
signedJSON: m,
|
|
62
|
+
publicKey: devicePub,
|
|
63
|
+
signaturePath: "signature.value",
|
|
64
|
+
prefix: StatusMessagePrefix,
|
|
65
|
+
});
|
|
66
|
+
return ok;
|
|
67
|
+
}
|
|
68
|
+
/** Structural validation per §1.6.5. */
|
|
69
|
+
export function validateStatusMessage(m, opts = {}) {
|
|
70
|
+
if (m.type !== StatusMessageType) {
|
|
71
|
+
throw new Error(`delivery: status message type ${JSON.stringify(m.type)}, want ${StatusMessageType}`);
|
|
72
|
+
}
|
|
73
|
+
if (m.version === "") {
|
|
74
|
+
throw new Error("delivery: status message missing version");
|
|
75
|
+
}
|
|
76
|
+
if (m.user_id === "") {
|
|
77
|
+
throw new Error("delivery: status message missing user_id");
|
|
78
|
+
}
|
|
79
|
+
if (m.state === "") {
|
|
80
|
+
throw new Error("delivery: status message missing state");
|
|
81
|
+
}
|
|
82
|
+
if (m.device_id === "") {
|
|
83
|
+
throw new Error("delivery: status message missing device_id");
|
|
84
|
+
}
|
|
85
|
+
if (m.updated_at === "") {
|
|
86
|
+
throw new Error("delivery: status message missing updated_at");
|
|
87
|
+
}
|
|
88
|
+
if (m.visibility.mode === "") {
|
|
89
|
+
throw new Error("delivery: status message visibility.mode is empty");
|
|
90
|
+
}
|
|
91
|
+
if (m.visibility.allow !== undefined) {
|
|
92
|
+
for (let i = 0; i < m.visibility.allow.length; i++) {
|
|
93
|
+
const e = m.visibility.allow[i];
|
|
94
|
+
if (e === undefined) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (e.type === "domain" && e.domain === "") {
|
|
98
|
+
throw new Error(`delivery: status visibility.allow[${i}] type=domain missing domain`);
|
|
99
|
+
}
|
|
100
|
+
if (e.type === "user" && e.address === "") {
|
|
101
|
+
throw new Error(`delivery: status visibility.allow[${i}] type=user missing address`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!opts.skipSignatureCheck && m.signature === undefined) {
|
|
106
|
+
throw new Error("delivery: status message missing signature");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=status_message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status_message.js","sourceRoot":"","sources":["../../src/delivery/status_message.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEMP upgrade-signaling SMTP headers per
|
|
3
|
+
* draft-gokce-semp-client §5.7.
|
|
4
|
+
*
|
|
5
|
+
* A SEMP-capable client SHOULD include these on every outbound
|
|
6
|
+
* SMTP message so a receiving SEMP-capable client can offer a
|
|
7
|
+
* thread upgrade without an additional DNS lookup. A recipient
|
|
8
|
+
* client that acts on the signal MUST verify the advertised
|
|
9
|
+
* identity by completing SEMP discovery against
|
|
10
|
+
* {@link UpgradeHeaderDomain} and fetching the identity key from
|
|
11
|
+
* that domain before treating the upgrade as trusted.
|
|
12
|
+
*
|
|
13
|
+
* The signal is unauthenticated at the SMTP layer; treat the
|
|
14
|
+
* headers as a hint only.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Boolean-style header name set to {@link UpgradeCapabilityPresent}
|
|
20
|
+
* whenever the sender's client can receive via SEMP at a published
|
|
21
|
+
* SEMP address.
|
|
22
|
+
*/
|
|
23
|
+
export declare const UpgradeHeaderCapability = "SEMP-Capability";
|
|
24
|
+
/**
|
|
25
|
+
* Header carrying the fingerprint of the sender's current SEMP
|
|
26
|
+
* identity public key in `<algorithm>:<hex>` form (for example
|
|
27
|
+
* `ed25519:abc123...`).
|
|
28
|
+
*/
|
|
29
|
+
export declare const UpgradeHeaderIdentity = "SEMP-Identity";
|
|
30
|
+
/**
|
|
31
|
+
* Header naming the sender's SEMP domain (the domain part of the
|
|
32
|
+
* sender's SEMP address). MAY differ from the domain of the SMTP
|
|
33
|
+
* `From` header.
|
|
34
|
+
*/
|
|
35
|
+
export declare const UpgradeHeaderDomain = "SEMP-Domain";
|
|
36
|
+
/**
|
|
37
|
+
* Header carrying the full SEMP address of the sender so the
|
|
38
|
+
* recipient does not have to infer it from the SMTP `From`
|
|
39
|
+
* local-part when the SMTP and SEMP local-parts differ.
|
|
40
|
+
*/
|
|
41
|
+
export declare const UpgradeHeaderAddress = "SEMP-Address";
|
|
42
|
+
/**
|
|
43
|
+
* Value the sender writes into the {@link UpgradeHeaderCapability}
|
|
44
|
+
* header. Single fixed value; future spec versions may extend the
|
|
45
|
+
* vocabulary.
|
|
46
|
+
*/
|
|
47
|
+
export declare const UpgradeCapabilityPresent = "1";
|
|
48
|
+
//# sourceMappingURL=upgrade_signal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade_signal.d.ts","sourceRoot":"","sources":["../../src/delivery/upgrade_signal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,kBAAkB,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,iBAAiB,CAAC;AAEnD;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,MAAM,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEMP upgrade-signaling SMTP headers per
|
|
3
|
+
* draft-gokce-semp-client §5.7.
|
|
4
|
+
*
|
|
5
|
+
* A SEMP-capable client SHOULD include these on every outbound
|
|
6
|
+
* SMTP message so a receiving SEMP-capable client can offer a
|
|
7
|
+
* thread upgrade without an additional DNS lookup. A recipient
|
|
8
|
+
* client that acts on the signal MUST verify the advertised
|
|
9
|
+
* identity by completing SEMP discovery against
|
|
10
|
+
* {@link UpgradeHeaderDomain} and fetching the identity key from
|
|
11
|
+
* that domain before treating the upgrade as trusted.
|
|
12
|
+
*
|
|
13
|
+
* The signal is unauthenticated at the SMTP layer; treat the
|
|
14
|
+
* headers as a hint only.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Boolean-style header name set to {@link UpgradeCapabilityPresent}
|
|
20
|
+
* whenever the sender's client can receive via SEMP at a published
|
|
21
|
+
* SEMP address.
|
|
22
|
+
*/
|
|
23
|
+
export const UpgradeHeaderCapability = "SEMP-Capability";
|
|
24
|
+
/**
|
|
25
|
+
* Header carrying the fingerprint of the sender's current SEMP
|
|
26
|
+
* identity public key in `<algorithm>:<hex>` form (for example
|
|
27
|
+
* `ed25519:abc123...`).
|
|
28
|
+
*/
|
|
29
|
+
export const UpgradeHeaderIdentity = "SEMP-Identity";
|
|
30
|
+
/**
|
|
31
|
+
* Header naming the sender's SEMP domain (the domain part of the
|
|
32
|
+
* sender's SEMP address). MAY differ from the domain of the SMTP
|
|
33
|
+
* `From` header.
|
|
34
|
+
*/
|
|
35
|
+
export const UpgradeHeaderDomain = "SEMP-Domain";
|
|
36
|
+
/**
|
|
37
|
+
* Header carrying the full SEMP address of the sender so the
|
|
38
|
+
* recipient does not have to infer it from the SMTP `From`
|
|
39
|
+
* local-part when the SMTP and SEMP local-parts differ.
|
|
40
|
+
*/
|
|
41
|
+
export const UpgradeHeaderAddress = "SEMP-Address";
|
|
42
|
+
/**
|
|
43
|
+
* Value the sender writes into the {@link UpgradeHeaderCapability}
|
|
44
|
+
* header. Single fixed value; future spec versions may extend the
|
|
45
|
+
* vocabulary.
|
|
46
|
+
*/
|
|
47
|
+
export const UpgradeCapabilityPresent = "1";
|
|
48
|
+
//# sourceMappingURL=upgrade_signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade_signal.js","sourceRoot":"","sources":["../../src/delivery/upgrade_signal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAEzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,eAAe,CAAC;AAErD;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAEjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAEnD;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAC"}
|
|
@@ -50,10 +50,28 @@ export interface ConfigEndpoints {
|
|
|
50
50
|
backup?: string;
|
|
51
51
|
migration?: string;
|
|
52
52
|
transparency_log?: string;
|
|
53
|
-
attachment_storage?: string;
|
|
54
53
|
/** Forward-compatible: any unknown endpoint URL keys land here. */
|
|
55
54
|
[key: string]: string | TransportEndpoints | undefined;
|
|
56
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Trust-gossip reciprocity policy mode per DISCOVERY.md §3.1.5 /
|
|
58
|
+
* DELIVERY.md §12.1. A peer that enforces reciprocity MUST
|
|
59
|
+
* disclose its policy in the configuration document so prospective
|
|
60
|
+
* consumers can capability-negotiate before fetching.
|
|
61
|
+
*
|
|
62
|
+
* - "none": no reciprocity requirement.
|
|
63
|
+
* - "lenient": prefers reciprocity but serves non-publishers; MAY
|
|
64
|
+
* weight their observations lower.
|
|
65
|
+
* - "strict": refuses to serve consumers that do not meet
|
|
66
|
+
* `minimum_publish_volume` across `evaluation_window_days`.
|
|
67
|
+
*/
|
|
68
|
+
export type ReciprocityMode = "none" | "lenient" | "strict";
|
|
69
|
+
/** Reciprocity policy disclosure per §3.1.5. */
|
|
70
|
+
export interface ReciprocityPolicy {
|
|
71
|
+
mode: ReciprocityMode;
|
|
72
|
+
minimum_publish_volume?: number;
|
|
73
|
+
evaluation_window_days?: number;
|
|
74
|
+
}
|
|
57
75
|
/** Operational limits per §3.1.3. */
|
|
58
76
|
export interface ConfigLimits {
|
|
59
77
|
max_envelope_size: number;
|
|
@@ -76,6 +94,7 @@ export interface Configuration {
|
|
|
76
94
|
suites: string[];
|
|
77
95
|
limits: ConfigLimits;
|
|
78
96
|
extensions?: ConfigExtension[];
|
|
97
|
+
reciprocity?: ReciprocityPolicy;
|
|
79
98
|
/** Forward-compatible: unknown top-level fields preserved here. */
|
|
80
99
|
[key: string]: unknown;
|
|
81
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/discovery/configuration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,+DAA+D;AAC/D,eAAO,MAAM,aAAa,oCAAoC,CAAC;AAE/D,qCAAqC;AACrC,eAAO,MAAM,iBAAiB,uBAAuB,CAAC;AAEtD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAAY,CAAC;AAE3C,kDAAkD;AAClD,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAExD,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,EAAE,kBAAkB,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,
|
|
1
|
+
{"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/discovery/configuration.ts"],"names":[],"mappings":"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"}
|