@sempdev/semp 0.4.3
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/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/brief/address.d.ts +77 -0
- package/dist/brief/address.d.ts.map +1 -0
- package/dist/brief/address.js +217 -0
- package/dist/brief/address.js.map +1 -0
- package/dist/brief/brief.d.ts +75 -0
- package/dist/brief/brief.d.ts.map +1 -0
- package/dist/brief/brief.js +56 -0
- package/dist/brief/brief.js.map +1 -0
- package/dist/brief/index.d.ts +11 -0
- package/dist/brief/index.d.ts.map +1 -0
- package/dist/brief/index.js +11 -0
- package/dist/brief/index.js.map +1 -0
- package/dist/canonical/index.d.ts +8 -0
- package/dist/canonical/index.d.ts.map +1 -0
- package/dist/canonical/index.js +8 -0
- package/dist/canonical/index.js.map +1 -0
- package/dist/canonical/marshal.d.ts +35 -0
- package/dist/canonical/marshal.d.ts.map +1 -0
- package/dist/canonical/marshal.js +107 -0
- package/dist/canonical/marshal.js.map +1 -0
- package/dist/clockskew/index.d.ts +52 -0
- package/dist/clockskew/index.d.ts.map +1 -0
- package/dist/clockskew/index.js +62 -0
- package/dist/clockskew/index.js.map +1 -0
- package/dist/closure/closure.d.ts +106 -0
- package/dist/closure/closure.d.ts.map +1 -0
- package/dist/closure/closure.js +152 -0
- package/dist/closure/closure.js.map +1 -0
- package/dist/closure/driver.d.ts +103 -0
- package/dist/closure/driver.d.ts.map +1 -0
- package/dist/closure/driver.js +126 -0
- package/dist/closure/driver.js.map +1 -0
- package/dist/closure/index.d.ts +13 -0
- package/dist/closure/index.d.ts.map +1 -0
- package/dist/closure/index.js +13 -0
- package/dist/closure/index.js.map +1 -0
- package/dist/closure/store.d.ts +80 -0
- package/dist/closure/store.d.ts.map +1 -0
- package/dist/closure/store.js +89 -0
- package/dist/closure/store.js.map +1 -0
- package/dist/crypto/aead.d.ts +29 -0
- package/dist/crypto/aead.d.ts.map +1 -0
- package/dist/crypto/aead.js +48 -0
- package/dist/crypto/aead.js.map +1 -0
- package/dist/crypto/argon2.d.ts +20 -0
- package/dist/crypto/argon2.d.ts.map +1 -0
- package/dist/crypto/argon2.js +28 -0
- package/dist/crypto/argon2.js.map +1 -0
- package/dist/crypto/index.d.ts +14 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +14 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/kdf.d.ts +96 -0
- package/dist/crypto/kdf.d.ts.map +1 -0
- package/dist/crypto/kdf.js +122 -0
- package/dist/crypto/kdf.js.map +1 -0
- package/dist/crypto/kem.d.ts +85 -0
- package/dist/crypto/kem.d.ts.map +1 -0
- package/dist/crypto/kem.js +130 -0
- package/dist/crypto/kem.js.map +1 -0
- package/dist/crypto/mac.d.ts +19 -0
- package/dist/crypto/mac.d.ts.map +1 -0
- package/dist/crypto/mac.js +32 -0
- package/dist/crypto/mac.js.map +1 -0
- package/dist/delivery/ack.d.ts +125 -0
- package/dist/delivery/ack.d.ts.map +1 -0
- package/dist/delivery/ack.js +141 -0
- package/dist/delivery/ack.js.map +1 -0
- package/dist/delivery/blocklist.d.ts +87 -0
- package/dist/delivery/blocklist.d.ts.map +1 -0
- package/dist/delivery/blocklist.js +107 -0
- package/dist/delivery/blocklist.js.map +1 -0
- package/dist/delivery/cancel.d.ts +60 -0
- package/dist/delivery/cancel.d.ts.map +1 -0
- package/dist/delivery/cancel.js +43 -0
- package/dist/delivery/cancel.js.map +1 -0
- package/dist/delivery/disposition.d.ts +106 -0
- package/dist/delivery/disposition.d.ts.map +1 -0
- package/dist/delivery/disposition.js +105 -0
- package/dist/delivery/disposition.js.map +1 -0
- package/dist/delivery/fetch.d.ts +59 -0
- package/dist/delivery/fetch.d.ts.map +1 -0
- package/dist/delivery/fetch.js +47 -0
- package/dist/delivery/fetch.js.map +1 -0
- package/dist/delivery/forwarder.d.ts +106 -0
- package/dist/delivery/forwarder.d.ts.map +1 -0
- package/dist/delivery/forwarder.js +251 -0
- package/dist/delivery/forwarder.js.map +1 -0
- package/dist/delivery/inbox.d.ts +42 -0
- package/dist/delivery/inbox.d.ts.map +1 -0
- package/dist/delivery/inbox.js +68 -0
- package/dist/delivery/inbox.js.map +1 -0
- package/dist/delivery/index.d.ts +31 -0
- package/dist/delivery/index.d.ts.map +1 -0
- package/dist/delivery/index.js +31 -0
- package/dist/delivery/index.js.map +1 -0
- package/dist/delivery/internalroute.d.ts +50 -0
- package/dist/delivery/internalroute.d.ts.map +1 -0
- package/dist/delivery/internalroute.js +23 -0
- package/dist/delivery/internalroute.js.map +1 -0
- package/dist/delivery/pipeline.d.ts +153 -0
- package/dist/delivery/pipeline.d.ts.map +1 -0
- package/dist/delivery/pipeline.js +356 -0
- package/dist/delivery/pipeline.js.map +1 -0
- package/dist/delivery/policy_state.d.ts +105 -0
- package/dist/delivery/policy_state.d.ts.map +1 -0
- package/dist/delivery/policy_state.js +293 -0
- package/dist/delivery/policy_state.js.map +1 -0
- package/dist/delivery/queue.d.ts +47 -0
- package/dist/delivery/queue.d.ts.map +1 -0
- package/dist/delivery/queue.js +33 -0
- package/dist/delivery/queue.js.map +1 -0
- package/dist/delivery/receipt.d.ts +137 -0
- package/dist/delivery/receipt.d.ts.map +1 -0
- package/dist/delivery/receipt.js +181 -0
- package/dist/delivery/receipt.js.map +1 -0
- package/dist/delivery/receipt_store.d.ts +81 -0
- package/dist/delivery/receipt_store.d.ts.map +1 -0
- package/dist/delivery/receipt_store.js +74 -0
- package/dist/delivery/receipt_store.js.map +1 -0
- package/dist/delivery/retry.d.ts +78 -0
- package/dist/delivery/retry.d.ts.map +1 -0
- package/dist/delivery/retry.js +132 -0
- package/dist/delivery/retry.js.map +1 -0
- package/dist/delivery/scheduler.d.ts +156 -0
- package/dist/delivery/scheduler.d.ts.map +1 -0
- package/dist/delivery/scheduler.js +349 -0
- package/dist/delivery/scheduler.js.map +1 -0
- package/dist/delivery/stage_partition.d.ts +87 -0
- package/dist/delivery/stage_partition.d.ts.map +1 -0
- package/dist/delivery/stage_partition.js +122 -0
- package/dist/delivery/stage_partition.js.map +1 -0
- package/dist/delivery/staged_runner.d.ts +100 -0
- package/dist/delivery/staged_runner.d.ts.map +1 -0
- package/dist/delivery/staged_runner.js +277 -0
- package/dist/delivery/staged_runner.js.map +1 -0
- package/dist/delivery/submission.d.ts +72 -0
- package/dist/delivery/submission.d.ts.map +1 -0
- package/dist/delivery/submission.js +58 -0
- package/dist/delivery/submission.js.map +1 -0
- package/dist/delivery/sync.d.ts +68 -0
- package/dist/delivery/sync.d.ts.map +1 -0
- package/dist/delivery/sync.js +99 -0
- package/dist/delivery/sync.js.map +1 -0
- package/dist/delivery/user_policy.d.ts +74 -0
- package/dist/delivery/user_policy.d.ts.map +1 -0
- package/dist/delivery/user_policy.js +140 -0
- package/dist/delivery/user_policy.js.map +1 -0
- package/dist/discovery/cache.d.ts +37 -0
- package/dist/discovery/cache.d.ts.map +1 -0
- package/dist/discovery/cache.js +45 -0
- package/dist/discovery/cache.js.map +1 -0
- package/dist/discovery/configuration.d.ts +97 -0
- package/dist/discovery/configuration.d.ts.map +1 -0
- package/dist/discovery/configuration.js +146 -0
- package/dist/discovery/configuration.js.map +1 -0
- package/dist/discovery/dns.d.ts +56 -0
- package/dist/discovery/dns.d.ts.map +1 -0
- package/dist/discovery/dns.js +120 -0
- package/dist/discovery/dns.js.map +1 -0
- package/dist/discovery/domain_keys.d.ts +62 -0
- package/dist/discovery/domain_keys.d.ts.map +1 -0
- package/dist/discovery/domain_keys.js +89 -0
- package/dist/discovery/domain_keys.js.map +1 -0
- package/dist/discovery/index.d.ts +19 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +19 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/lookup.d.ts +72 -0
- package/dist/discovery/lookup.d.ts.map +1 -0
- package/dist/discovery/lookup.js +121 -0
- package/dist/discovery/lookup.js.map +1 -0
- package/dist/discovery/onion.d.ts +34 -0
- package/dist/discovery/onion.d.ts.map +1 -0
- package/dist/discovery/onion.js +61 -0
- package/dist/discovery/onion.js.map +1 -0
- package/dist/discovery/partition.d.ts +96 -0
- package/dist/discovery/partition.d.ts.map +1 -0
- package/dist/discovery/partition.js +247 -0
- package/dist/discovery/partition.js.map +1 -0
- package/dist/discovery/resolver.d.ts +113 -0
- package/dist/discovery/resolver.d.ts.map +1 -0
- package/dist/discovery/resolver.js +176 -0
- package/dist/discovery/resolver.js.map +1 -0
- package/dist/discovery/txt.d.ts +39 -0
- package/dist/discovery/txt.d.ts.map +1 -0
- package/dist/discovery/txt.js +71 -0
- package/dist/discovery/txt.js.map +1 -0
- package/dist/enclosure/forwarding.d.ts +128 -0
- package/dist/enclosure/forwarding.d.ts.map +1 -0
- package/dist/enclosure/forwarding.js +119 -0
- package/dist/enclosure/forwarding.js.map +1 -0
- package/dist/enclosure/index.d.ts +11 -0
- package/dist/enclosure/index.d.ts.map +1 -0
- package/dist/enclosure/index.js +11 -0
- package/dist/enclosure/index.js.map +1 -0
- package/dist/envelope/buckets.d.ts +38 -0
- package/dist/envelope/buckets.d.ts.map +1 -0
- package/dist/envelope/buckets.js +73 -0
- package/dist/envelope/buckets.js.map +1 -0
- package/dist/envelope/canonical.d.ts +28 -0
- package/dist/envelope/canonical.d.ts.map +1 -0
- package/dist/envelope/canonical.js +54 -0
- package/dist/envelope/canonical.js.map +1 -0
- package/dist/envelope/compose.d.ts +171 -0
- package/dist/envelope/compose.d.ts.map +1 -0
- package/dist/envelope/compose.js +237 -0
- package/dist/envelope/compose.js.map +1 -0
- package/dist/envelope/encode.d.ts +41 -0
- package/dist/envelope/encode.d.ts.map +1 -0
- package/dist/envelope/encode.js +69 -0
- package/dist/envelope/encode.js.map +1 -0
- package/dist/envelope/index.d.ts +20 -0
- package/dist/envelope/index.d.ts.map +1 -0
- package/dist/envelope/index.js +20 -0
- package/dist/envelope/index.js.map +1 -0
- package/dist/envelope/open_any.d.ts +48 -0
- package/dist/envelope/open_any.d.ts.map +1 -0
- package/dist/envelope/open_any.js +81 -0
- package/dist/envelope/open_any.js.map +1 -0
- package/dist/envelope/open_verified.d.ts +59 -0
- package/dist/envelope/open_verified.d.ts.map +1 -0
- package/dist/envelope/open_verified.js +67 -0
- package/dist/envelope/open_verified.js.map +1 -0
- package/dist/envelope/padding.d.ts +55 -0
- package/dist/envelope/padding.d.ts.map +1 -0
- package/dist/envelope/padding.js +162 -0
- package/dist/envelope/padding.js.map +1 -0
- package/dist/envelope/rejection.d.ts +22 -0
- package/dist/envelope/rejection.d.ts.map +1 -0
- package/dist/envelope/rejection.js +30 -0
- package/dist/envelope/rejection.js.map +1 -0
- package/dist/envelope/sendtime.d.ts +49 -0
- package/dist/envelope/sendtime.d.ts.map +1 -0
- package/dist/envelope/sendtime.js +87 -0
- package/dist/envelope/sendtime.js.map +1 -0
- package/dist/envelope/verify.d.ts +29 -0
- package/dist/envelope/verify.d.ts.map +1 -0
- package/dist/envelope/verify.js +90 -0
- package/dist/envelope/verify.js.map +1 -0
- package/dist/extensions/index.d.ts +7 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +7 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/limits.d.ts +101 -0
- package/dist/extensions/limits.d.ts.map +1 -0
- package/dist/extensions/limits.js +175 -0
- package/dist/extensions/limits.js.map +1 -0
- package/dist/handshake/abort.d.ts +49 -0
- package/dist/handshake/abort.d.ts.map +1 -0
- package/dist/handshake/abort.js +82 -0
- package/dist/handshake/abort.js.map +1 -0
- package/dist/handshake/capabilities.d.ts +46 -0
- package/dist/handshake/capabilities.d.ts.map +1 -0
- package/dist/handshake/capabilities.js +114 -0
- package/dist/handshake/capabilities.js.map +1 -0
- package/dist/handshake/client_state.d.ts +186 -0
- package/dist/handshake/client_state.d.ts.map +1 -0
- package/dist/handshake/client_state.js +520 -0
- package/dist/handshake/client_state.js.map +1 -0
- package/dist/handshake/confirm.d.ts +21 -0
- package/dist/handshake/confirm.d.ts.map +1 -0
- package/dist/handshake/confirm.js +27 -0
- package/dist/handshake/confirm.js.map +1 -0
- package/dist/handshake/driver.d.ts +126 -0
- package/dist/handshake/driver.d.ts.map +1 -0
- package/dist/handshake/driver.js +251 -0
- package/dist/handshake/driver.js.map +1 -0
- package/dist/handshake/federation.d.ts +365 -0
- package/dist/handshake/federation.d.ts.map +1 -0
- package/dist/handshake/federation.js +664 -0
- package/dist/handshake/federation.js.map +1 -0
- package/dist/handshake/first_contact.d.ts +57 -0
- package/dist/handshake/first_contact.d.ts.map +1 -0
- package/dist/handshake/first_contact.js +124 -0
- package/dist/handshake/first_contact.js.map +1 -0
- package/dist/handshake/identity.d.ts +101 -0
- package/dist/handshake/identity.d.ts.map +1 -0
- package/dist/handshake/identity.js +117 -0
- package/dist/handshake/identity.js.map +1 -0
- package/dist/handshake/index.d.ts +21 -0
- package/dist/handshake/index.d.ts.map +1 -0
- package/dist/handshake/index.js +21 -0
- package/dist/handshake/index.js.map +1 -0
- package/dist/handshake/messages.d.ts +176 -0
- package/dist/handshake/messages.d.ts.map +1 -0
- package/dist/handshake/messages.js +125 -0
- package/dist/handshake/messages.js.map +1 -0
- package/dist/handshake/pow.d.ts +53 -0
- package/dist/handshake/pow.d.ts.map +1 -0
- package/dist/handshake/pow.js +142 -0
- package/dist/handshake/pow.js.map +1 -0
- package/dist/handshake/resume_driver.d.ts +56 -0
- package/dist/handshake/resume_driver.d.ts.map +1 -0
- package/dist/handshake/resume_driver.js +75 -0
- package/dist/handshake/resume_driver.js.map +1 -0
- package/dist/handshake/server.d.ts +112 -0
- package/dist/handshake/server.d.ts.map +1 -0
- package/dist/handshake/server.js +247 -0
- package/dist/handshake/server.js.map +1 -0
- package/dist/handshake/server_state.d.ts +102 -0
- package/dist/handshake/server_state.d.ts.map +1 -0
- package/dist/handshake/server_state.js +278 -0
- package/dist/handshake/server_state.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/keys/compromise.d.ts +118 -0
- package/dist/keys/compromise.d.ts.map +1 -0
- package/dist/keys/compromise.js +218 -0
- package/dist/keys/compromise.js.map +1 -0
- package/dist/keys/device_certificate.d.ts +166 -0
- package/dist/keys/device_certificate.d.ts.map +1 -0
- package/dist/keys/device_certificate.js +328 -0
- package/dist/keys/device_certificate.js.map +1 -0
- package/dist/keys/device_records.d.ts +175 -0
- package/dist/keys/device_records.d.ts.map +1 -0
- package/dist/keys/device_records.js +418 -0
- package/dist/keys/device_records.js.map +1 -0
- package/dist/keys/directory_cache.d.ts +64 -0
- package/dist/keys/directory_cache.d.ts.map +1 -0
- package/dist/keys/directory_cache.js +98 -0
- package/dist/keys/directory_cache.js.map +1 -0
- package/dist/keys/directory_state.d.ts +79 -0
- package/dist/keys/directory_state.d.ts.map +1 -0
- package/dist/keys/directory_state.js +155 -0
- package/dist/keys/directory_state.js.map +1 -0
- package/dist/keys/index.d.ts +18 -0
- package/dist/keys/index.d.ts.map +1 -0
- package/dist/keys/index.js +18 -0
- package/dist/keys/index.js.map +1 -0
- package/dist/keys/key_revocation.d.ts +61 -0
- package/dist/keys/key_revocation.d.ts.map +1 -0
- package/dist/keys/key_revocation.js +88 -0
- package/dist/keys/key_revocation.js.map +1 -0
- package/dist/keys/request.d.ts +124 -0
- package/dist/keys/request.d.ts.map +1 -0
- package/dist/keys/request.js +130 -0
- package/dist/keys/request.js.map +1 -0
- package/dist/keys/sign.d.ts +49 -0
- package/dist/keys/sign.d.ts.map +1 -0
- package/dist/keys/sign.js +80 -0
- package/dist/keys/sign.js.map +1 -0
- package/dist/keys/signed.d.ts +80 -0
- package/dist/keys/signed.d.ts.map +1 -0
- package/dist/keys/signed.js +138 -0
- package/dist/keys/signed.js.map +1 -0
- package/dist/keys/store.d.ts +138 -0
- package/dist/keys/store.d.ts.map +1 -0
- package/dist/keys/store.js +107 -0
- package/dist/keys/store.js.map +1 -0
- package/dist/largeattachment/crypto.d.ts +47 -0
- package/dist/largeattachment/crypto.d.ts.map +1 -0
- package/dist/largeattachment/crypto.js +235 -0
- package/dist/largeattachment/crypto.js.map +1 -0
- package/dist/largeattachment/enclosure.d.ts +48 -0
- package/dist/largeattachment/enclosure.d.ts.map +1 -0
- package/dist/largeattachment/enclosure.js +102 -0
- package/dist/largeattachment/enclosure.js.map +1 -0
- package/dist/largeattachment/index.d.ts +15 -0
- package/dist/largeattachment/index.d.ts.map +1 -0
- package/dist/largeattachment/index.js +15 -0
- package/dist/largeattachment/index.js.map +1 -0
- package/dist/largeattachment/store.d.ts +36 -0
- package/dist/largeattachment/store.d.ts.map +1 -0
- package/dist/largeattachment/store.js +37 -0
- package/dist/largeattachment/store.js.map +1 -0
- package/dist/largeattachment/types.d.ts +56 -0
- package/dist/largeattachment/types.d.ts.map +1 -0
- package/dist/largeattachment/types.js +31 -0
- package/dist/largeattachment/types.js.map +1 -0
- package/dist/largeattachment/upload.d.ts +62 -0
- package/dist/largeattachment/upload.d.ts.map +1 -0
- package/dist/largeattachment/upload.js +166 -0
- package/dist/largeattachment/upload.js.map +1 -0
- package/dist/migration/index.d.ts +17 -0
- package/dist/migration/index.d.ts.map +1 -0
- package/dist/migration/index.js +17 -0
- package/dist/migration/index.js.map +1 -0
- package/dist/migration/lockout.d.ts +48 -0
- package/dist/migration/lockout.d.ts.map +1 -0
- package/dist/migration/lockout.js +57 -0
- package/dist/migration/lockout.js.map +1 -0
- package/dist/migration/migration.d.ts +48 -0
- package/dist/migration/migration.d.ts.map +1 -0
- package/dist/migration/migration.js +58 -0
- package/dist/migration/migration.js.map +1 -0
- package/dist/migration/notice.d.ts +33 -0
- package/dist/migration/notice.d.ts.map +1 -0
- package/dist/migration/notice.js +85 -0
- package/dist/migration/notice.js.map +1 -0
- package/dist/migration/orchestrate.d.ts +109 -0
- package/dist/migration/orchestrate.d.ts.map +1 -0
- package/dist/migration/orchestrate.js +212 -0
- package/dist/migration/orchestrate.js.map +1 -0
- package/dist/migration/publication_store.d.ts +34 -0
- package/dist/migration/publication_store.d.ts.map +1 -0
- package/dist/migration/publication_store.js +44 -0
- package/dist/migration/publication_store.js.map +1 -0
- package/dist/migration/sign.d.ts +65 -0
- package/dist/migration/sign.d.ts.map +1 -0
- package/dist/migration/sign.js +331 -0
- package/dist/migration/sign.js.map +1 -0
- package/dist/migration/types.d.ts +92 -0
- package/dist/migration/types.d.ts.map +1 -0
- package/dist/migration/types.js +26 -0
- package/dist/migration/types.js.map +1 -0
- package/dist/reasoncodes.d.ts +42 -0
- package/dist/reasoncodes.d.ts.map +1 -0
- package/dist/reasoncodes.js +80 -0
- package/dist/reasoncodes.js.map +1 -0
- package/dist/recovery/bundle.d.ts +34 -0
- package/dist/recovery/bundle.d.ts.map +1 -0
- package/dist/recovery/bundle.js +144 -0
- package/dist/recovery/bundle.js.map +1 -0
- package/dist/recovery/bundle_crypto.d.ts +60 -0
- package/dist/recovery/bundle_crypto.d.ts.map +1 -0
- package/dist/recovery/bundle_crypto.js +179 -0
- package/dist/recovery/bundle_crypto.js.map +1 -0
- package/dist/recovery/bundle_store.d.ts +57 -0
- package/dist/recovery/bundle_store.d.ts.map +1 -0
- package/dist/recovery/bundle_store.js +104 -0
- package/dist/recovery/bundle_store.js.map +1 -0
- package/dist/recovery/index.d.ts +19 -0
- package/dist/recovery/index.d.ts.map +1 -0
- package/dist/recovery/index.js +19 -0
- package/dist/recovery/index.js.map +1 -0
- package/dist/recovery/manifest_crosscheck.d.ts +59 -0
- package/dist/recovery/manifest_crosscheck.d.ts.map +1 -0
- package/dist/recovery/manifest_crosscheck.js +59 -0
- package/dist/recovery/manifest_crosscheck.js.map +1 -0
- package/dist/recovery/shamir.d.ts +51 -0
- package/dist/recovery/shamir.d.ts.map +1 -0
- package/dist/recovery/shamir.js +181 -0
- package/dist/recovery/shamir.js.map +1 -0
- package/dist/recovery/sign.d.ts +61 -0
- package/dist/recovery/sign.d.ts.map +1 -0
- package/dist/recovery/sign.js +359 -0
- package/dist/recovery/sign.js.map +1 -0
- package/dist/recovery/types.d.ts +180 -0
- package/dist/recovery/types.d.ts.map +1 -0
- package/dist/recovery/types.js +31 -0
- package/dist/recovery/types.js.map +1 -0
- package/dist/reputation/abuse_report.d.ts +62 -0
- package/dist/reputation/abuse_report.d.ts.map +1 -0
- package/dist/reputation/abuse_report.js +111 -0
- package/dist/reputation/abuse_report.js.map +1 -0
- package/dist/reputation/bucketize.d.ts +31 -0
- package/dist/reputation/bucketize.d.ts.map +1 -0
- package/dist/reputation/bucketize.js +77 -0
- package/dist/reputation/bucketize.js.map +1 -0
- package/dist/reputation/gossip.d.ts +24 -0
- package/dist/reputation/gossip.d.ts.map +1 -0
- package/dist/reputation/gossip.js +64 -0
- package/dist/reputation/gossip.js.map +1 -0
- package/dist/reputation/gossip_fetch.d.ts +64 -0
- package/dist/reputation/gossip_fetch.d.ts.map +1 -0
- package/dist/reputation/gossip_fetch.js +114 -0
- package/dist/reputation/gossip_fetch.js.map +1 -0
- package/dist/reputation/index.d.ts +20 -0
- package/dist/reputation/index.d.ts.map +1 -0
- package/dist/reputation/index.js +20 -0
- package/dist/reputation/index.js.map +1 -0
- package/dist/reputation/observation_store.d.ts +67 -0
- package/dist/reputation/observation_store.d.ts.map +1 -0
- package/dist/reputation/observation_store.js +171 -0
- package/dist/reputation/observation_store.js.map +1 -0
- package/dist/reputation/pow.d.ts +91 -0
- package/dist/reputation/pow.d.ts.map +1 -0
- package/dist/reputation/pow.js +209 -0
- package/dist/reputation/pow.js.map +1 -0
- package/dist/reputation/sign.d.ts +40 -0
- package/dist/reputation/sign.d.ts.map +1 -0
- package/dist/reputation/sign.js +202 -0
- package/dist/reputation/sign.js.map +1 -0
- package/dist/reputation/types.d.ts +133 -0
- package/dist/reputation/types.d.ts.map +1 -0
- package/dist/reputation/types.js +33 -0
- package/dist/reputation/types.js.map +1 -0
- package/dist/reputation/whois.d.ts +25 -0
- package/dist/reputation/whois.d.ts.map +1 -0
- package/dist/reputation/whois.js +20 -0
- package/dist/reputation/whois.js.map +1 -0
- package/dist/seal/index.d.ts +8 -0
- package/dist/seal/index.d.ts.map +1 -0
- package/dist/seal/index.js +8 -0
- package/dist/seal/index.js.map +1 -0
- package/dist/seal/wrap.d.ts +74 -0
- package/dist/seal/wrap.d.ts.map +1 -0
- package/dist/seal/wrap.js +213 -0
- package/dist/seal/wrap.js.map +1 -0
- package/dist/session/dispatcher.d.ts +65 -0
- package/dist/session/dispatcher.d.ts.map +1 -0
- package/dist/session/dispatcher.js +96 -0
- package/dist/session/dispatcher.js.map +1 -0
- package/dist/session/index.d.ts +15 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +15 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/rekey.d.ts +108 -0
- package/dist/session/rekey.d.ts.map +1 -0
- package/dist/session/rekey.js +207 -0
- package/dist/session/rekey.js.map +1 -0
- package/dist/session/rekey_seal.d.ts +66 -0
- package/dist/session/rekey_seal.d.ts.map +1 -0
- package/dist/session/rekey_seal.js +153 -0
- package/dist/session/rekey_seal.js.map +1 -0
- package/dist/session/resume.d.ts +125 -0
- package/dist/session/resume.d.ts.map +1 -0
- package/dist/session/resume.js +263 -0
- package/dist/session/resume.js.map +1 -0
- package/dist/session/session.d.ts +136 -0
- package/dist/session/session.d.ts.map +1 -0
- package/dist/session/session.js +188 -0
- package/dist/session/session.js.map +1 -0
- package/dist/transparency/index.d.ts +13 -0
- package/dist/transparency/index.d.ts.map +1 -0
- package/dist/transparency/index.js +13 -0
- package/dist/transparency/index.js.map +1 -0
- package/dist/transparency/log.d.ts +61 -0
- package/dist/transparency/log.d.ts.map +1 -0
- package/dist/transparency/log.js +133 -0
- package/dist/transparency/log.js.map +1 -0
- package/dist/transparency/merkle.d.ts +59 -0
- package/dist/transparency/merkle.d.ts.map +1 -0
- package/dist/transparency/merkle.js +314 -0
- package/dist/transparency/merkle.js.map +1 -0
- package/dist/transparency/sign.d.ts +48 -0
- package/dist/transparency/sign.d.ts.map +1 -0
- package/dist/transparency/sign.js +140 -0
- package/dist/transparency/sign.js.map +1 -0
- package/dist/transparency/types.d.ts +97 -0
- package/dist/transparency/types.d.ts.map +1 -0
- package/dist/transparency/types.js +25 -0
- package/dist/transparency/types.js.map +1 -0
- package/dist/transport/h2.d.ts +163 -0
- package/dist/transport/h2.d.ts.map +1 -0
- package/dist/transport/h2.js +397 -0
- package/dist/transport/h2.js.map +1 -0
- package/dist/transport/index.d.ts +15 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +15 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/memory.d.ts +21 -0
- package/dist/transport/memory.d.ts.map +1 -0
- package/dist/transport/memory.js +112 -0
- package/dist/transport/memory.js.map +1 -0
- package/dist/transport/transport.d.ts +54 -0
- package/dist/transport/transport.d.ts.map +1 -0
- package/dist/transport/transport.js +20 -0
- package/dist/transport/transport.js.map +1 -0
- package/dist/transport/ws.d.ts +40 -0
- package/dist/transport/ws.d.ts.map +1 -0
- package/dist/transport/ws.js +204 -0
- package/dist/transport/ws.js.map +1 -0
- package/package.json +147 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abuse_report.d.ts","sourceRoot":"","sources":["../../src/reputation/abuse_report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,uBAAuB,EAC5B,KAAK,QAAQ,EAGd,MAAM,YAAY,CAAC;AAOpB,wCAAwC;AACxC,MAAM,WAAW,gBAAgB;IAC/B,2BAA2B;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,aAAa,GAAG,MAAM,CAAC;IACjC,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CA+BnE;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;AAEzE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,QAAQ,EACZ,aAAa,EAAE,aAAa,GAAG,IAAI,GAClC,OAAO,CAAC,IAAI,CAAC,CAoDf;AAOD,YAAY,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEMP_ABUSE_REPORT compose helpers per REPUTATION.md §3.2 / §3.5 /
|
|
3
|
+
* §3.7.
|
|
4
|
+
*
|
|
5
|
+
* Abuse reports flow user → home-server over an authenticated
|
|
6
|
+
* session — the handshake identifies the reporting user so the
|
|
7
|
+
* report itself does NOT carry its own signature. The report's
|
|
8
|
+
* evidence MAY include decrypted envelope fragments, in which case
|
|
9
|
+
* an embedded {@link DisclosureAuthorization} signed by the
|
|
10
|
+
* affected user is required per §3.5 + §3.7.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import { AbuseReportType, Version, } from "./types.js";
|
|
15
|
+
import { authAllowsBrief, authAllowsEnclosure, verifyDisclosureAuthorization, } from "./sign.js";
|
|
16
|
+
/**
|
|
17
|
+
* Construct a SEMP_ABUSE_REPORT with `type` / `version` /
|
|
18
|
+
* `timestamp` / `extensions` pre-populated.
|
|
19
|
+
*
|
|
20
|
+
* Throws when required fields are missing.
|
|
21
|
+
*/
|
|
22
|
+
export function newAbuseReport(input) {
|
|
23
|
+
if (input.id === "") {
|
|
24
|
+
throw new Error("reputation: abuse report missing id");
|
|
25
|
+
}
|
|
26
|
+
if (input.reporter === "") {
|
|
27
|
+
throw new Error("reputation: abuse report missing reporter");
|
|
28
|
+
}
|
|
29
|
+
if (input.reported_domain === "") {
|
|
30
|
+
throw new Error("reputation: abuse report missing reported_domain");
|
|
31
|
+
}
|
|
32
|
+
if (input.category === "") {
|
|
33
|
+
throw new Error("reputation: abuse report missing category");
|
|
34
|
+
}
|
|
35
|
+
const r = {
|
|
36
|
+
type: AbuseReportType,
|
|
37
|
+
version: Version,
|
|
38
|
+
id: input.id,
|
|
39
|
+
reporter: input.reporter,
|
|
40
|
+
reported_domain: input.reported_domain,
|
|
41
|
+
category: input.category,
|
|
42
|
+
timestamp: isoSecond((input.nowFn ?? (() => new Date()))()),
|
|
43
|
+
evidence: input.evidence,
|
|
44
|
+
extensions: input.extensions ?? {},
|
|
45
|
+
};
|
|
46
|
+
if (input.reported_address !== undefined && input.reported_address !== "") {
|
|
47
|
+
r.reported_address = input.reported_address;
|
|
48
|
+
}
|
|
49
|
+
if (input.description !== undefined && input.description !== "") {
|
|
50
|
+
r.description = input.description;
|
|
51
|
+
}
|
|
52
|
+
return r;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Walk an evidence payload and enforce the §3.7 rule: decrypted
|
|
56
|
+
* content requires a valid {@link DisclosureAuthorization} signed
|
|
57
|
+
* by the affected user.
|
|
58
|
+
*
|
|
59
|
+
* Metadata-only evidence is always acceptable — postmark + seal
|
|
60
|
+
* data is verifiable from the sender's published domain key without
|
|
61
|
+
* disclosing user content.
|
|
62
|
+
*
|
|
63
|
+
* Sealed evidence with disclosed brief / enclosure requires:
|
|
64
|
+
*
|
|
65
|
+
* 1. An embedded `disclosure_authorization`;
|
|
66
|
+
* 2. The authorization's `scope` covers what's actually disclosed;
|
|
67
|
+
* 3. The authorization's signature verifies under the affected
|
|
68
|
+
* user's identity public key.
|
|
69
|
+
*
|
|
70
|
+
* Throws on the first violation.
|
|
71
|
+
*/
|
|
72
|
+
export async function validateEvidence(ev, userKeyLookup) {
|
|
73
|
+
if (ev.type === "envelope_metadata") {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (ev.type !== "sealed_evidence") {
|
|
77
|
+
throw new Error(`reputation: unknown evidence type ${JSON.stringify(ev.type)}`);
|
|
78
|
+
}
|
|
79
|
+
for (let i = 0; i < ev.envelopes.length; i++) {
|
|
80
|
+
const env = ev.envelopes[i];
|
|
81
|
+
const discloses = env.disclosed_brief !== undefined || env.disclosed_enclosure !== undefined;
|
|
82
|
+
if (!discloses) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (env.disclosure_authorization === undefined) {
|
|
86
|
+
throw new Error(`reputation: envelope[${i}]: decrypted content without disclosure authorization`);
|
|
87
|
+
}
|
|
88
|
+
const auth = env.disclosure_authorization;
|
|
89
|
+
if (env.disclosed_brief !== undefined && !authAllowsBrief(auth)) {
|
|
90
|
+
throw new Error(`reputation: envelope[${i}]: brief disclosure outside authorized scope ${JSON.stringify(auth.scope)}`);
|
|
91
|
+
}
|
|
92
|
+
if (env.disclosed_enclosure !== undefined &&
|
|
93
|
+
!authAllowsEnclosure(auth)) {
|
|
94
|
+
throw new Error(`reputation: envelope[${i}]: enclosure disclosure outside authorized scope ${JSON.stringify(auth.scope)}`);
|
|
95
|
+
}
|
|
96
|
+
if (userKeyLookup === null) {
|
|
97
|
+
throw new Error(`reputation: envelope[${i}]: sealed evidence not accepted (handler lacks user key lookup)`);
|
|
98
|
+
}
|
|
99
|
+
const pub = await userKeyLookup(auth.user);
|
|
100
|
+
if (pub === null || pub.length === 0) {
|
|
101
|
+
throw new Error(`reputation: envelope[${i}]: unknown user ${JSON.stringify(auth.user)} in disclosure authorization`);
|
|
102
|
+
}
|
|
103
|
+
if (!verifyDisclosureAuthorization(auth, pub)) {
|
|
104
|
+
throw new Error(`reputation: envelope[${i}]: disclosure authorization signature did not verify`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function isoSecond(d) {
|
|
109
|
+
return d.toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=abuse_report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abuse_report.js","sourceRoot":"","sources":["../../src/reputation/abuse_report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metric bucketing per REPUTATION.md §4.5.1 + §4.5.2.
|
|
3
|
+
*
|
|
4
|
+
* Counts published on the wire are rounded UP to the nearest power
|
|
5
|
+
* of two in the sequence 0, 1, 2, 4, 8, ..., 1048576. Above the cap
|
|
6
|
+
* they clamp to MaxMetricBucket. AbuseCategories are deduplicated
|
|
7
|
+
* (a receiver could otherwise read the array's length and recover
|
|
8
|
+
* the raw `abuse_reports` count, defeating the §4.5.1 bucketing).
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import type { AbuseCategory, Metrics } from "./types.js";
|
|
13
|
+
/**
|
|
14
|
+
* Round `n` up to the nearest power-of-two bucket per §4.5.1.
|
|
15
|
+
* Values above {@link MaxMetricBucket} clamp to MaxMetricBucket.
|
|
16
|
+
*/
|
|
17
|
+
export declare function bucketize(n: number): number;
|
|
18
|
+
/**
|
|
19
|
+
* Apply bucketing + abuse-category deduplication to `m` IN PLACE
|
|
20
|
+
* per §4.5.1 + §4.5.2. Called by signObservation before the
|
|
21
|
+
* canonical bytes are computed so the signed record carries
|
|
22
|
+
* bucketed counts and a deduplicated category set.
|
|
23
|
+
*/
|
|
24
|
+
export declare function applyBucketing(m: Metrics): void;
|
|
25
|
+
/**
|
|
26
|
+
* Return a new array of distinct non-empty categories in
|
|
27
|
+
* first-occurrence order. Returns `undefined` for empty input so
|
|
28
|
+
* the JSON omits the field entirely.
|
|
29
|
+
*/
|
|
30
|
+
export declare function dedupeAbuseCategories(cats: AbuseCategory[] | undefined): AbuseCategory[] | undefined;
|
|
31
|
+
//# sourceMappingURL=bucketize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bucketize.d.ts","sourceRoot":"","sources":["../../src/reputation/bucketize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGzD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAY3C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAiB/C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,aAAa,EAAE,GAAG,SAAS,GAChC,aAAa,EAAE,GAAG,SAAS,CAiB7B"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metric bucketing per REPUTATION.md §4.5.1 + §4.5.2.
|
|
3
|
+
*
|
|
4
|
+
* Counts published on the wire are rounded UP to the nearest power
|
|
5
|
+
* of two in the sequence 0, 1, 2, 4, 8, ..., 1048576. Above the cap
|
|
6
|
+
* they clamp to MaxMetricBucket. AbuseCategories are deduplicated
|
|
7
|
+
* (a receiver could otherwise read the array's length and recover
|
|
8
|
+
* the raw `abuse_reports` count, defeating the §4.5.1 bucketing).
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import { MaxMetricBucket } from "./types.js";
|
|
13
|
+
/**
|
|
14
|
+
* Round `n` up to the nearest power-of-two bucket per §4.5.1.
|
|
15
|
+
* Values above {@link MaxMetricBucket} clamp to MaxMetricBucket.
|
|
16
|
+
*/
|
|
17
|
+
export function bucketize(n) {
|
|
18
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
if (n >= MaxMetricBucket) {
|
|
22
|
+
return MaxMetricBucket;
|
|
23
|
+
}
|
|
24
|
+
let b = 1;
|
|
25
|
+
while (b < n) {
|
|
26
|
+
b <<= 1;
|
|
27
|
+
}
|
|
28
|
+
return b;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Apply bucketing + abuse-category deduplication to `m` IN PLACE
|
|
32
|
+
* per §4.5.1 + §4.5.2. Called by signObservation before the
|
|
33
|
+
* canonical bytes are computed so the signed record carries
|
|
34
|
+
* bucketed counts and a deduplicated category set.
|
|
35
|
+
*/
|
|
36
|
+
export function applyBucketing(m) {
|
|
37
|
+
m.envelopes_received = bucketize(m.envelopes_received);
|
|
38
|
+
m.envelopes_rejected = bucketize(m.envelopes_rejected);
|
|
39
|
+
m.abuse_reports = bucketize(m.abuse_reports);
|
|
40
|
+
if (m.unique_senders_observed !== undefined) {
|
|
41
|
+
m.unique_senders_observed = bucketize(m.unique_senders_observed);
|
|
42
|
+
}
|
|
43
|
+
if (m.handshakes_completed !== undefined) {
|
|
44
|
+
m.handshakes_completed = bucketize(m.handshakes_completed);
|
|
45
|
+
}
|
|
46
|
+
if (m.handshakes_rejected !== undefined) {
|
|
47
|
+
m.handshakes_rejected = bucketize(m.handshakes_rejected);
|
|
48
|
+
}
|
|
49
|
+
m.abuse_categories = dedupeAbuseCategories(m.abuse_categories);
|
|
50
|
+
if (m.abuse_categories === undefined) {
|
|
51
|
+
delete m.abuse_categories;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Return a new array of distinct non-empty categories in
|
|
56
|
+
* first-occurrence order. Returns `undefined` for empty input so
|
|
57
|
+
* the JSON omits the field entirely.
|
|
58
|
+
*/
|
|
59
|
+
export function dedupeAbuseCategories(cats) {
|
|
60
|
+
if (cats === undefined || cats.length === 0) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
const seen = new Set();
|
|
64
|
+
const out = [];
|
|
65
|
+
for (const c of cats) {
|
|
66
|
+
if (typeof c !== "string" || c === "") {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (seen.has(c)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
seen.add(c);
|
|
73
|
+
out.push(c);
|
|
74
|
+
}
|
|
75
|
+
return out.length === 0 ? undefined : out;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=bucketize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bucketize.js","sourceRoot":"","sources":["../../src/reputation/bucketize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,CAAC,IAAI,eAAe,EAAE,CAAC;QACzB,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACb,CAAC,KAAK,CAAC,CAAC;IACV,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,CAAU;IACvC,CAAC,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACvD,CAAC,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACvD,CAAC,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAC7C,IAAI,CAAC,CAAC,uBAAuB,KAAK,SAAS,EAAE,CAAC;QAC5C,CAAC,CAAC,uBAAuB,GAAG,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,CAAC,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;QACzC,CAAC,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,CAAC,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QACxC,CAAC,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAC3D,CAAC;IACD,CAAC,CAAC,gBAAgB,GAAG,qBAAqB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAC/D,IAAI,CAAC,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,CAAC,CAAC,gBAAgB,CAAC;IAC5B,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAiC;IAEjC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5C,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAiB,CAAC;IACtC,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAK,CAAY,KAAK,EAAE,EAAE,CAAC;YAClD,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAChB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACZ,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gossip-hash summary per REPUTATION.md §5.
|
|
3
|
+
*
|
|
4
|
+
* `computeGossipHash(domain, observations)` returns a stable digest
|
|
5
|
+
* over (domain, [{id, timestamp}, ...]) so two observers with the
|
|
6
|
+
* same observation set produce byte-identical hashes and can detect
|
|
7
|
+
* divergence cheaply.
|
|
8
|
+
*
|
|
9
|
+
* The hash covers only ids + timestamps, not full metric bodies, so
|
|
10
|
+
* a comparison remains meaningful when two observers report the
|
|
11
|
+
* same underlying events with slightly different metrics. Callers
|
|
12
|
+
* that want a full-body comparison walk the observations themselves.
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import type { GossipHash, Observation } from "./types.js";
|
|
17
|
+
/**
|
|
18
|
+
* Compute the publishable {@link GossipHash} for `domain` given
|
|
19
|
+
* `observations`. Throws when `domain` is empty. An empty
|
|
20
|
+
* `observations` slice is allowed (legitimate "I have no
|
|
21
|
+
* observations for this subject" publication).
|
|
22
|
+
*/
|
|
23
|
+
export declare function computeGossipHash(domain: string, observations: Observation[], now?: Date): GossipHash;
|
|
24
|
+
//# sourceMappingURL=gossip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gossip.d.ts","sourceRoot":"","sources":["../../src/reputation/gossip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,WAAW,EAAE,EAC3B,GAAG,GAAE,IAAiB,GACrB,UAAU,CA0BZ"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gossip-hash summary per REPUTATION.md §5.
|
|
3
|
+
*
|
|
4
|
+
* `computeGossipHash(domain, observations)` returns a stable digest
|
|
5
|
+
* over (domain, [{id, timestamp}, ...]) so two observers with the
|
|
6
|
+
* same observation set produce byte-identical hashes and can detect
|
|
7
|
+
* divergence cheaply.
|
|
8
|
+
*
|
|
9
|
+
* The hash covers only ids + timestamps, not full metric bodies, so
|
|
10
|
+
* a comparison remains meaningful when two observers report the
|
|
11
|
+
* same underlying events with slightly different metrics. Callers
|
|
12
|
+
* that want a full-body comparison walk the observations themselves.
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
17
|
+
import { marshal as canonicalMarshal } from "../canonical/index.js";
|
|
18
|
+
/**
|
|
19
|
+
* Compute the publishable {@link GossipHash} for `domain` given
|
|
20
|
+
* `observations`. Throws when `domain` is empty. An empty
|
|
21
|
+
* `observations` slice is allowed (legitimate "I have no
|
|
22
|
+
* observations for this subject" publication).
|
|
23
|
+
*/
|
|
24
|
+
export function computeGossipHash(domain, observations, now = new Date()) {
|
|
25
|
+
if (domain.trim() === "") {
|
|
26
|
+
throw new Error("reputation: gossip hash requires a domain");
|
|
27
|
+
}
|
|
28
|
+
// Stable order so two observers who hold the same set produce the
|
|
29
|
+
// same hash regardless of internal iteration order.
|
|
30
|
+
const entries = observations
|
|
31
|
+
.map((o) => ({ id: o.id, timestamp: o.timestamp }))
|
|
32
|
+
.sort((a, b) => {
|
|
33
|
+
if (a.id !== b.id) {
|
|
34
|
+
return a.id < b.id ? -1 : 1;
|
|
35
|
+
}
|
|
36
|
+
return a.timestamp < b.timestamp ? -1 : a.timestamp > b.timestamp ? 1 : 0;
|
|
37
|
+
});
|
|
38
|
+
const payload = {
|
|
39
|
+
domain: domain.trim().toLowerCase(),
|
|
40
|
+
entries,
|
|
41
|
+
};
|
|
42
|
+
const canonical = canonicalMarshal(payload);
|
|
43
|
+
const sum = sha256(canonical);
|
|
44
|
+
return {
|
|
45
|
+
domain: payload.domain,
|
|
46
|
+
hash: bytesToHex(sum),
|
|
47
|
+
algorithm: "sha256",
|
|
48
|
+
as_of: isoSecond(now),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function isoSecond(d) {
|
|
52
|
+
return d.toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
53
|
+
}
|
|
54
|
+
function bytesToHex(b) {
|
|
55
|
+
if (typeof Buffer !== "undefined") {
|
|
56
|
+
return Buffer.from(b).toString("hex");
|
|
57
|
+
}
|
|
58
|
+
let out = "";
|
|
59
|
+
for (let i = 0; i < b.length; i++) {
|
|
60
|
+
out += (b[i] ?? 0).toString(16).padStart(2, "0");
|
|
61
|
+
}
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=gossip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gossip.js","sourceRoot":"","sources":["../../src/reputation/gossip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAIpE;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAc,EACd,YAA2B,EAC3B,MAAY,IAAI,IAAI,EAAE;IAEtB,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IACD,kEAAkE;IAClE,oDAAoD;IACpD,MAAM,OAAO,GAAG,YAAY;SACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;SAClD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACb,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;YAClB,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IACL,MAAM,OAAO,GAAG;QACd,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,OAAO;KACR,CAAC;IACF,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAA6C,CAAC,CAAC;IAClF,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAC9B,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC;QACrB,SAAS,EAAE,QAAQ;QACnB,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC;KACtB,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,CAAO;IACxB,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,UAAU,CAAC,CAAa;IAC/B,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust-gossip publication HTTP client per REPUTATION.md §5.1.
|
|
3
|
+
*
|
|
4
|
+
* Observers publish their {@link TrustObservations} envelopes at:
|
|
5
|
+
*
|
|
6
|
+
* ```
|
|
7
|
+
* https://<observer>/.well-known/semp/reputation/<subject>
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* Fetching servers GET that URL, verify the envelope-level
|
|
11
|
+
* signature, and use the inner observations to make trust
|
|
12
|
+
* decisions. The fetcher is `fetch`-injectable so tests can stub
|
|
13
|
+
* the HTTPS round-trip; production callers omit `fetchImpl` and the
|
|
14
|
+
* fetcher uses Node 22+'s global `fetch`.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
import { type FetchLike } from "../discovery/index.js";
|
|
19
|
+
import { type TrustObservations } from "./types.js";
|
|
20
|
+
/**
|
|
21
|
+
* Maximum body the fetcher accepts from a remote observer. 1 MiB is
|
|
22
|
+
* enough for a substantial observation publication (hundreds of
|
|
23
|
+
* inner records) without letting a hostile observer feed us
|
|
24
|
+
* unbounded JSON.
|
|
25
|
+
*/
|
|
26
|
+
export declare const TrustGossipMaxBytes: number;
|
|
27
|
+
/** Options to {@link fetchTrustObservations}. */
|
|
28
|
+
export interface FetchTrustObservationsOptions {
|
|
29
|
+
/** Override the fetch implementation. Defaults to `globalThis.fetch`. */
|
|
30
|
+
fetchImpl?: FetchLike;
|
|
31
|
+
/** Optional cancellation signal. */
|
|
32
|
+
signal?: AbortSignal;
|
|
33
|
+
/**
|
|
34
|
+
* Per-request timeout in milliseconds. Defaults to 10 seconds —
|
|
35
|
+
* matches `discovery.fetchConfiguration`.
|
|
36
|
+
*/
|
|
37
|
+
timeoutMs?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Override the URL produced for `(observer, subject)`. Defaults to
|
|
40
|
+
* `https://<observer>${PublicationPath}<subject>`. Tests use this
|
|
41
|
+
* to point at an httptest server.
|
|
42
|
+
*/
|
|
43
|
+
urlFn?: (observer: string, subject: string) => string;
|
|
44
|
+
/**
|
|
45
|
+
* Override the byte cap. Defaults to {@link TrustGossipMaxBytes}.
|
|
46
|
+
*/
|
|
47
|
+
maxBytes?: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* GET the trust-gossip publication for `subject` from `observer`,
|
|
51
|
+
* verify the envelope-level signature with `observerPub`, and
|
|
52
|
+
* return the parsed envelope.
|
|
53
|
+
*
|
|
54
|
+
* Per-observation signatures inside `result.observations` are NOT
|
|
55
|
+
* verified — callers walk those and call
|
|
56
|
+
* {@link "./sign".verifyObservation} on each, because different
|
|
57
|
+
* observations in the same envelope MAY be signed under different
|
|
58
|
+
* key_ids (e.g. after a key rotation).
|
|
59
|
+
*
|
|
60
|
+
* Throws on transport failure, malformed JSON, body cap exceeded,
|
|
61
|
+
* unsigned envelope, or signature mismatch.
|
|
62
|
+
*/
|
|
63
|
+
export declare function fetchTrustObservations(observer: string, subject: string, observerPub: Uint8Array, opts?: FetchTrustObservationsOptions): Promise<TrustObservations>;
|
|
64
|
+
//# sourceMappingURL=gossip_fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gossip_fetch.d.ts","sourceRoot":"","sources":["../../src/reputation/gossip_fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,YAAY,CAAC;AAGrE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,QAAkB,CAAC;AAEnD,iDAAiD;AACjD,MAAM,WAAW,6BAA6B;IAC5C,yEAAyE;IACzE,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,oCAAoC;IACpC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACtD;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,UAAU,EACvB,IAAI,GAAE,6BAAkC,GACvC,OAAO,CAAC,iBAAiB,CAAC,CA+E5B"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust-gossip publication HTTP client per REPUTATION.md §5.1.
|
|
3
|
+
*
|
|
4
|
+
* Observers publish their {@link TrustObservations} envelopes at:
|
|
5
|
+
*
|
|
6
|
+
* ```
|
|
7
|
+
* https://<observer>/.well-known/semp/reputation/<subject>
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* Fetching servers GET that URL, verify the envelope-level
|
|
11
|
+
* signature, and use the inner observations to make trust
|
|
12
|
+
* decisions. The fetcher is `fetch`-injectable so tests can stub
|
|
13
|
+
* the HTTPS round-trip; production callers omit `fetchImpl` and the
|
|
14
|
+
* fetcher uses Node 22+'s global `fetch`.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
import {} from "../discovery/index.js";
|
|
19
|
+
import { PublicationPath } from "./types.js";
|
|
20
|
+
import { verifyTrustObservations } from "./sign.js";
|
|
21
|
+
/**
|
|
22
|
+
* Maximum body the fetcher accepts from a remote observer. 1 MiB is
|
|
23
|
+
* enough for a substantial observation publication (hundreds of
|
|
24
|
+
* inner records) without letting a hostile observer feed us
|
|
25
|
+
* unbounded JSON.
|
|
26
|
+
*/
|
|
27
|
+
export const TrustGossipMaxBytes = 1 * 1024 * 1024;
|
|
28
|
+
/**
|
|
29
|
+
* GET the trust-gossip publication for `subject` from `observer`,
|
|
30
|
+
* verify the envelope-level signature with `observerPub`, and
|
|
31
|
+
* return the parsed envelope.
|
|
32
|
+
*
|
|
33
|
+
* Per-observation signatures inside `result.observations` are NOT
|
|
34
|
+
* verified — callers walk those and call
|
|
35
|
+
* {@link "./sign".verifyObservation} on each, because different
|
|
36
|
+
* observations in the same envelope MAY be signed under different
|
|
37
|
+
* key_ids (e.g. after a key rotation).
|
|
38
|
+
*
|
|
39
|
+
* Throws on transport failure, malformed JSON, body cap exceeded,
|
|
40
|
+
* unsigned envelope, or signature mismatch.
|
|
41
|
+
*/
|
|
42
|
+
export async function fetchTrustObservations(observer, subject, observerPub, opts = {}) {
|
|
43
|
+
if (observer === "") {
|
|
44
|
+
throw new Error("reputation: empty observer");
|
|
45
|
+
}
|
|
46
|
+
if (subject === "") {
|
|
47
|
+
throw new Error("reputation: empty subject");
|
|
48
|
+
}
|
|
49
|
+
if (observerPub.length === 0) {
|
|
50
|
+
throw new Error("reputation: empty observer public key");
|
|
51
|
+
}
|
|
52
|
+
const url = opts.urlFn !== undefined
|
|
53
|
+
? opts.urlFn(observer, subject)
|
|
54
|
+
: `https://${observer}${PublicationPath}${encodeURIComponent(subject)}`;
|
|
55
|
+
const fetchFn = opts.fetchImpl ?? globalThis.fetch;
|
|
56
|
+
if (fetchFn === undefined) {
|
|
57
|
+
throw new Error("reputation: no fetch implementation available (Node 22+ or pass fetchImpl)");
|
|
58
|
+
}
|
|
59
|
+
const controller = new AbortController();
|
|
60
|
+
const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? 10_000);
|
|
61
|
+
// Wire the caller's signal through too so external cancellation
|
|
62
|
+
// propagates.
|
|
63
|
+
let externalSubscribed = false;
|
|
64
|
+
const onAbort = () => {
|
|
65
|
+
controller.abort();
|
|
66
|
+
};
|
|
67
|
+
if (opts.signal !== undefined) {
|
|
68
|
+
if (opts.signal.aborted) {
|
|
69
|
+
controller.abort();
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
73
|
+
externalSubscribed = true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
let resp;
|
|
77
|
+
try {
|
|
78
|
+
resp = await fetchFn(url, {
|
|
79
|
+
method: "GET",
|
|
80
|
+
headers: { Accept: "application/json" },
|
|
81
|
+
signal: controller.signal,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
clearTimeout(timer);
|
|
86
|
+
if (externalSubscribed) {
|
|
87
|
+
opts.signal.removeEventListener("abort", onAbort);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (!resp.ok) {
|
|
91
|
+
throw new Error(`reputation: ${url} returned HTTP ${resp.status}`);
|
|
92
|
+
}
|
|
93
|
+
const body = await resp.text();
|
|
94
|
+
const cap = opts.maxBytes ?? TrustGossipMaxBytes;
|
|
95
|
+
if (body.length > cap) {
|
|
96
|
+
throw new Error(`reputation: trust gossip body exceeds ${cap} bytes (got ${body.length})`);
|
|
97
|
+
}
|
|
98
|
+
let parsed;
|
|
99
|
+
try {
|
|
100
|
+
parsed = JSON.parse(body);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
throw new Error(`reputation: parse trust observations: ${err instanceof Error ? err.message : String(err)}`);
|
|
104
|
+
}
|
|
105
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
106
|
+
throw new Error("reputation: trust observations is not a JSON object");
|
|
107
|
+
}
|
|
108
|
+
const env = parsed;
|
|
109
|
+
if (!verifyTrustObservations(env, observerPub)) {
|
|
110
|
+
throw new Error("reputation: trust observations signature did not verify");
|
|
111
|
+
}
|
|
112
|
+
return env;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=gossip_fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gossip_fetch.js","sourceRoot":"","sources":["../../src/reputation/gossip_fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reputation layer per REPUTATION.md.
|
|
3
|
+
*
|
|
4
|
+
* Wire records (observation, trust-observations envelope, abuse
|
|
5
|
+
* report, disclosure authorization), bucketing + dedup helpers,
|
|
6
|
+
* sign / verify primitives, in-memory observation store with
|
|
7
|
+
* scoring, gossip hash, and PoW challenge issuer + ledger.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
export { type AbuseCategory, type AbuseReport, type Assessment, type DisclosureAuthorization, type DisclosureScope, type Evidence, type GossipHash, type Metrics, type Observation, type ReputationSignature, type SealedEnvelopeEvidence, type TrustObservations, type Window, AbuseReportType, MaxMetricBucket, ObservationType, ObservationsEnvelopeType, PublicationPath, Version, isKnownAbuseCategory, } from "./types.js";
|
|
12
|
+
export { applyBucketing, bucketize, dedupeAbuseCategories, } from "./bucketize.js";
|
|
13
|
+
export { SignatureAlgorithmEd25519, authAllowsBrief, authAllowsEnclosure, signDisclosureAuthorization, signObservation, signTrustObservations, validateAbuseReport, verifyDisclosureAuthorization, verifyObservation, verifyTrustObservations, } from "./sign.js";
|
|
14
|
+
export { type Score, ObservationStore, classifyScore, } from "./observation_store.js";
|
|
15
|
+
export { computeGossipHash } from "./gossip.js";
|
|
16
|
+
export { type PoWChallenge, ChallengeLedger, DefaultChallengeTTLMs, DifficultyBaseline, DifficultyHostile, DifficultyRelaxed, DifficultySuspicious, DomainAgeGateDays, MinPrefixBytes, PoWAlgorithm, challengePrefixBase64, difficultyForAge, difficultyForAssessment, issueChallenge, } from "./pow.js";
|
|
17
|
+
export { type WHOIS, MinDomainAgeMs, meetsMinAge, } from "./whois.js";
|
|
18
|
+
export { type AbuseReportInput, type UserKeyLookup, newAbuseReport, validateEvidence, } from "./abuse_report.js";
|
|
19
|
+
export { type FetchTrustObservationsOptions, TrustGossipMaxBytes, fetchTrustObservations, } from "./gossip_fetch.js";
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reputation/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,MAAM,EACX,eAAe,EACf,eAAe,EACf,eAAe,EACf,wBAAwB,EACxB,eAAe,EACf,OAAO,EACP,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,SAAS,EACT,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,yBAAyB,EACzB,eAAe,EACf,mBAAmB,EACnB,2BAA2B,EAC3B,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,6BAA6B,EAC7B,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,KAAK,KAAK,EACV,gBAAgB,EAChB,aAAa,GACd,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EACL,KAAK,YAAY,EACjB,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,GACf,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,KAAK,KAAK,EACV,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,cAAc,EACd,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,KAAK,6BAA6B,EAClC,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reputation layer per REPUTATION.md.
|
|
3
|
+
*
|
|
4
|
+
* Wire records (observation, trust-observations envelope, abuse
|
|
5
|
+
* report, disclosure authorization), bucketing + dedup helpers,
|
|
6
|
+
* sign / verify primitives, in-memory observation store with
|
|
7
|
+
* scoring, gossip hash, and PoW challenge issuer + ledger.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
export { AbuseReportType, MaxMetricBucket, ObservationType, ObservationsEnvelopeType, PublicationPath, Version, isKnownAbuseCategory, } from "./types.js";
|
|
12
|
+
export { applyBucketing, bucketize, dedupeAbuseCategories, } from "./bucketize.js";
|
|
13
|
+
export { SignatureAlgorithmEd25519, authAllowsBrief, authAllowsEnclosure, signDisclosureAuthorization, signObservation, signTrustObservations, validateAbuseReport, verifyDisclosureAuthorization, verifyObservation, verifyTrustObservations, } from "./sign.js";
|
|
14
|
+
export { ObservationStore, classifyScore, } from "./observation_store.js";
|
|
15
|
+
export { computeGossipHash } from "./gossip.js";
|
|
16
|
+
export { ChallengeLedger, DefaultChallengeTTLMs, DifficultyBaseline, DifficultyHostile, DifficultyRelaxed, DifficultySuspicious, DomainAgeGateDays, MinPrefixBytes, PoWAlgorithm, challengePrefixBase64, difficultyForAge, difficultyForAssessment, issueChallenge, } from "./pow.js";
|
|
17
|
+
export { MinDomainAgeMs, meetsMinAge, } from "./whois.js";
|
|
18
|
+
export { newAbuseReport, validateEvidence, } from "./abuse_report.js";
|
|
19
|
+
export { TrustGossipMaxBytes, fetchTrustObservations, } from "./gossip_fetch.js";
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reputation/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAcL,eAAe,EACf,eAAe,EACf,eAAe,EACf,wBAAwB,EACxB,eAAe,EACf,OAAO,EACP,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,SAAS,EACT,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,yBAAyB,EACzB,eAAe,EACf,mBAAmB,EACnB,2BAA2B,EAC3B,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,6BAA6B,EAC7B,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAEL,gBAAgB,EAChB,aAAa,GACd,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAEL,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,GACf,MAAM,UAAU,CAAC;AAElB,OAAO,EAEL,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAGL,cAAc,EACd,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAEL,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-domain signal ledger + Score derivation per REPUTATION.md §4.
|
|
3
|
+
*
|
|
4
|
+
* The store records raw counters as they happen (one call per
|
|
5
|
+
* handshake/envelope/abuse) and exposes a {@link Score} query that
|
|
6
|
+
* turns the counters into a Score + {@link Assessment} + the
|
|
7
|
+
* "currently suspicious" verdict operators plug into their PoW
|
|
8
|
+
* policy hook.
|
|
9
|
+
*
|
|
10
|
+
* Production deployments wrap a durable backend; this is the
|
|
11
|
+
* reference in-memory store.
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
import type { AbuseCategory, Assessment, Metrics } from "./types.js";
|
|
16
|
+
/** Derived reputation verdict per §4.6. */
|
|
17
|
+
export interface Score {
|
|
18
|
+
domain: string;
|
|
19
|
+
total_envelopes: number;
|
|
20
|
+
/** [0, 1]. Zero when total_envelopes is zero. */
|
|
21
|
+
abuse_rate: number;
|
|
22
|
+
/** [0, 1]. */
|
|
23
|
+
reject_rate: number;
|
|
24
|
+
/** [0, 1] over handshakes attempted. */
|
|
25
|
+
handshake_reject_rate: number;
|
|
26
|
+
/** First time any signal was recorded. `null` if unobserved. */
|
|
27
|
+
first_seen: Date | null;
|
|
28
|
+
/** Whole-day age, or -1 if first_seen is null. */
|
|
29
|
+
age_days: number;
|
|
30
|
+
assessment: Assessment;
|
|
31
|
+
}
|
|
32
|
+
/** In-memory {@link ObservationStore}. Single-process. */
|
|
33
|
+
export declare class ObservationStore {
|
|
34
|
+
private readonly domains;
|
|
35
|
+
private readonly firstSeen;
|
|
36
|
+
private readonly nowFn;
|
|
37
|
+
constructor(nowFn?: () => Date);
|
|
38
|
+
/** Record one handshake outcome. */
|
|
39
|
+
recordHandshake(domain: string, ok: boolean): void;
|
|
40
|
+
/** Record one envelope outcome. */
|
|
41
|
+
recordEnvelope(domain: string, accepted: boolean): void;
|
|
42
|
+
/**
|
|
43
|
+
* Record one abuse report. The caller is expected to have
|
|
44
|
+
* verified the report's authenticity and any embedded disclosure
|
|
45
|
+
* authorization before calling.
|
|
46
|
+
*/
|
|
47
|
+
recordAbuseReport(domain: string, category: AbuseCategory | ""): void;
|
|
48
|
+
/** Snapshot of the current counters as a publishable {@link Metrics}. */
|
|
49
|
+
metrics(domain: string): Metrics;
|
|
50
|
+
/** Compute the current {@link Score} for `domain`. */
|
|
51
|
+
score(domain: string): Score;
|
|
52
|
+
/** Clear all counters for `domain`. */
|
|
53
|
+
reset(domain: string): void;
|
|
54
|
+
/** Number of domains with at least one recorded signal. */
|
|
55
|
+
size(): number;
|
|
56
|
+
private touch;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Default scoring curve (REPUTATION.md §4.6 + §8.3.2):
|
|
60
|
+
*
|
|
61
|
+
* - abuse_rate ≥ 0.05 OR reject_rate ≥ 0.50 → hostile
|
|
62
|
+
* - abuse_rate ≥ 0.01 OR reject_rate ≥ 0.20 → suspicious
|
|
63
|
+
* - abuse_rate == 0 AND reject_rate < 0.05 AND total ≥ 100 → trusted
|
|
64
|
+
* - otherwise → neutral
|
|
65
|
+
*/
|
|
66
|
+
export declare function classifyScore(s: Score): Assessment;
|
|
67
|
+
//# sourceMappingURL=observation_store.d.ts.map
|