@joe-broadhead/messaging 0.0.0-stage → 0.7.1
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/CHANGELOG.md +220 -0
- package/LICENSE +21 -0
- package/NOTICE +12 -0
- package/README.md +36 -2
- package/dist/bin/messaging-mcp.js +26524 -0
- package/dist/bin/messaging-relay.js +19768 -0
- package/dist/bin/messaging.js +15465 -0
- package/dist/bin/messagingd.js +29449 -0
- package/dist/lib/core-testing.js +1 -0
- package/dist/lib/core.js +1 -0
- package/dist/lib/ipc-testing.js +1 -0
- package/dist/lib/ipc.js +1 -0
- package/dist/lib/modules/core/address.js +42 -0
- package/dist/lib/modules/core/agent/operations.js +595 -0
- package/dist/lib/modules/core/agent/present.js +244 -0
- package/dist/lib/modules/core/agent/text.js +79 -0
- package/dist/lib/modules/core/agent-tools.js +477 -0
- package/dist/lib/modules/core/b64u.js +20 -0
- package/dist/lib/modules/core/cards.js +55 -0
- package/dist/lib/modules/core/check.js +20 -0
- package/dist/lib/modules/core/consent.js +199 -0
- package/dist/lib/modules/core/contact-card.js +74 -0
- package/dist/lib/modules/core/conversation/context.js +80 -0
- package/dist/lib/modules/core/conversation/event.js +100 -0
- package/dist/lib/modules/core/conversation/ids.js +38 -0
- package/dist/lib/modules/core/conversation/link.js +35 -0
- package/dist/lib/modules/core/conversation/log.js +766 -0
- package/dist/lib/modules/core/conversation/ratchet.js +243 -0
- package/dist/lib/modules/core/conversation/seal.js +198 -0
- package/dist/lib/modules/core/delegation.js +174 -0
- package/dist/lib/modules/core/directory/device-log.js +258 -0
- package/dist/lib/modules/core/directory/epoch.js +103 -0
- package/dist/lib/modules/core/directory/handle.js +29 -0
- package/dist/lib/modules/core/directory/jelly-device.js +204 -0
- package/dist/lib/modules/core/directory/jelly-issuer.js +12 -0
- package/dist/lib/modules/core/directory/jelly-token.js +305 -0
- package/dist/lib/modules/core/directory/keys-statement.js +43 -0
- package/dist/lib/modules/core/directory/link.js +81 -0
- package/dist/lib/modules/core/directory/merkle-log.js +250 -0
- package/dist/lib/modules/core/directory/person-view.js +197 -0
- package/dist/lib/modules/core/directory/person.js +40 -0
- package/dist/lib/modules/core/directory/realm.js +59 -0
- package/dist/lib/modules/core/directory/smt.js +266 -0
- package/dist/lib/modules/core/envelope.js +320 -0
- package/dist/lib/modules/core/hash.js +5 -0
- package/dist/lib/modules/core/head.js +27 -0
- package/dist/lib/modules/core/identity.js +71 -0
- package/dist/lib/modules/core/index.js +53 -0
- package/dist/lib/modules/core/jcs.js +96 -0
- package/dist/lib/modules/core/jelly-host-double.js +35 -0
- package/dist/lib/modules/core/jelly-host.js +211 -0
- package/dist/lib/modules/core/keys.js +79 -0
- package/dist/lib/modules/core/peer-text.js +563 -0
- package/dist/lib/modules/core/realm.js +1 -0
- package/dist/lib/modules/core/roster.js +454 -0
- package/dist/lib/modules/core/schema/a2a.js +85 -0
- package/dist/lib/modules/core/schema/common.js +310 -0
- package/dist/lib/modules/core/schema/consent.js +120 -0
- package/dist/lib/modules/core/schema/conversation.js +292 -0
- package/dist/lib/modules/core/schema/delegation.js +58 -0
- package/dist/lib/modules/core/schema/directory-frames.js +270 -0
- package/dist/lib/modules/core/schema/directory.js +169 -0
- package/dist/lib/modules/core/schema/envelope.js +211 -0
- package/dist/lib/modules/core/schema/errors.js +104 -0
- package/dist/lib/modules/core/schema/index.js +16 -0
- package/dist/lib/modules/core/schema/ipc/consent.js +181 -0
- package/dist/lib/modules/core/schema/ipc/device.js +276 -0
- package/dist/lib/modules/core/schema/ipc/jelly.js +189 -0
- package/dist/lib/modules/core/schema/ipc/shapes.js +185 -0
- package/dist/lib/modules/core/schema/ipc/surfaces.js +223 -0
- package/dist/lib/modules/core/schema/ipc.js +451 -0
- package/dist/lib/modules/core/schema/jelly.js +122 -0
- package/dist/lib/modules/core/schema/realm.js +27 -0
- package/dist/lib/modules/core/schema/relay.js +112 -0
- package/dist/lib/modules/core/schema/roster.js +126 -0
- package/dist/lib/modules/core/sign.js +43 -0
- package/dist/lib/modules/core/task.js +37 -0
- package/dist/lib/modules/core/testing.js +21 -0
- package/dist/lib/modules/core/ulid.js +36 -0
- package/dist/lib/modules/core/version.js +6 -0
- package/dist/lib/modules/core/wire.js +255 -0
- package/dist/lib/modules/ipc/client.js +289 -0
- package/dist/lib/modules/ipc/framing.js +33 -0
- package/dist/lib/modules/ipc/index.js +6 -0
- package/dist/lib/modules/ipc/paths.js +102 -0
- package/dist/lib/modules/ipc/pipes.js +65 -0
- package/dist/lib/modules/ipc/rpc.js +8 -0
- package/dist/lib/modules/ipc/server.js +317 -0
- package/dist/lib/modules/ipc/testing.js +145 -0
- package/dist/lib/modules/ipc/trust.js +166 -0
- package/dist/lib/modules/ipc/windows-acl.js +275 -0
- package/dist/lib/modules/vendor/zod/index.js +7 -0
- package/dist/lib/modules/vendor/zod/v4/classic/checks.js +1 -0
- package/dist/lib/modules/vendor/zod/v4/classic/coerce.js +17 -0
- package/dist/lib/modules/vendor/zod/v4/classic/compat.js +31 -0
- package/dist/lib/modules/vendor/zod/v4/classic/deep-partial.js +13 -0
- package/dist/lib/modules/vendor/zod/v4/classic/errors.js +57 -0
- package/dist/lib/modules/vendor/zod/v4/classic/external.js +17 -0
- package/dist/lib/modules/vendor/zod/v4/classic/from-json-schema.js +881 -0
- package/dist/lib/modules/vendor/zod/v4/classic/in-out.js +36 -0
- package/dist/lib/modules/vendor/zod/v4/classic/iso.js +15 -0
- package/dist/lib/modules/vendor/zod/v4/classic/parse.js +16 -0
- package/dist/lib/modules/vendor/zod/v4/classic/schemas.js +1535 -0
- package/dist/lib/modules/vendor/zod/v4/core/api.js +1107 -0
- package/dist/lib/modules/vendor/zod/v4/core/checks.js +516 -0
- package/dist/lib/modules/vendor/zod/v4/core/compile.js +1866 -0
- package/dist/lib/modules/vendor/zod/v4/core/core.js +141 -0
- package/dist/lib/modules/vendor/zod/v4/core/doc.js +38 -0
- package/dist/lib/modules/vendor/zod/v4/core/errors.js +267 -0
- package/dist/lib/modules/vendor/zod/v4/core/index.js +19 -0
- package/dist/lib/modules/vendor/zod/v4/core/json-schema-generator.js +99 -0
- package/dist/lib/modules/vendor/zod/v4/core/json-schema-processors.js +843 -0
- package/dist/lib/modules/vendor/zod/v4/core/json-schema.js +1 -0
- package/dist/lib/modules/vendor/zod/v4/core/memoizer.js +311 -0
- package/dist/lib/modules/vendor/zod/v4/core/parse.js +175 -0
- package/dist/lib/modules/vendor/zod/v4/core/regexes.js +156 -0
- package/dist/lib/modules/vendor/zod/v4/core/registries.js +51 -0
- package/dist/lib/modules/vendor/zod/v4/core/schemas.js +2636 -0
- package/dist/lib/modules/vendor/zod/v4/core/to-json-schema.js +651 -0
- package/dist/lib/modules/vendor/zod/v4/core/util.js +873 -0
- package/dist/lib/modules/vendor/zod/v4/core/versions.js +5 -0
- package/dist/lib/modules/vendor/zod/v4/core/visit.js +169 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ar.js +111 -0
- package/dist/lib/modules/vendor/zod/v4/locales/az.js +110 -0
- package/dist/lib/modules/vendor/zod/v4/locales/be.js +168 -0
- package/dist/lib/modules/vendor/zod/v4/locales/bg.js +125 -0
- package/dist/lib/modules/vendor/zod/v4/locales/bn.js +113 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ca.js +112 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ckb.js +133 -0
- package/dist/lib/modules/vendor/zod/v4/locales/cs.js +116 -0
- package/dist/lib/modules/vendor/zod/v4/locales/da.js +120 -0
- package/dist/lib/modules/vendor/zod/v4/locales/de.js +113 -0
- package/dist/lib/modules/vendor/zod/v4/locales/el.js +112 -0
- package/dist/lib/modules/vendor/zod/v4/locales/en.js +125 -0
- package/dist/lib/modules/vendor/zod/v4/locales/eo.js +114 -0
- package/dist/lib/modules/vendor/zod/v4/locales/es.js +136 -0
- package/dist/lib/modules/vendor/zod/v4/locales/fa.js +119 -0
- package/dist/lib/modules/vendor/zod/v4/locales/fi.js +117 -0
- package/dist/lib/modules/vendor/zod/v4/locales/fr-CA.js +112 -0
- package/dist/lib/modules/vendor/zod/v4/locales/fr.js +129 -0
- package/dist/lib/modules/vendor/zod/v4/locales/gu.js +113 -0
- package/dist/lib/modules/vendor/zod/v4/locales/he.js +221 -0
- package/dist/lib/modules/vendor/zod/v4/locales/hi.js +111 -0
- package/dist/lib/modules/vendor/zod/v4/locales/hr.js +126 -0
- package/dist/lib/modules/vendor/zod/v4/locales/hu.js +113 -0
- package/dist/lib/modules/vendor/zod/v4/locales/hy.js +158 -0
- package/dist/lib/modules/vendor/zod/v4/locales/id.js +111 -0
- package/dist/lib/modules/vendor/zod/v4/locales/index.js +63 -0
- package/dist/lib/modules/vendor/zod/v4/locales/is.js +114 -0
- package/dist/lib/modules/vendor/zod/v4/locales/it.js +113 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ja.js +112 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ka.js +117 -0
- package/dist/lib/modules/vendor/zod/v4/locales/kh.js +5 -0
- package/dist/lib/modules/vendor/zod/v4/locales/km.js +115 -0
- package/dist/lib/modules/vendor/zod/v4/locales/kn.js +116 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ko.js +116 -0
- package/dist/lib/modules/vendor/zod/v4/locales/lt.js +207 -0
- package/dist/lib/modules/vendor/zod/v4/locales/mk.js +114 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ms.js +112 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ne.js +111 -0
- package/dist/lib/modules/vendor/zod/v4/locales/nl.js +115 -0
- package/dist/lib/modules/vendor/zod/v4/locales/nn.js +113 -0
- package/dist/lib/modules/vendor/zod/v4/locales/no.js +113 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ota.js +114 -0
- package/dist/lib/modules/vendor/zod/v4/locales/pl.js +114 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ps.js +119 -0
- package/dist/lib/modules/vendor/zod/v4/locales/pt-BR.js +143 -0
- package/dist/lib/modules/vendor/zod/v4/locales/pt.js +142 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ro.js +122 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ru.js +168 -0
- package/dist/lib/modules/vendor/zod/v4/locales/sk.js +116 -0
- package/dist/lib/modules/vendor/zod/v4/locales/sl.js +114 -0
- package/dist/lib/modules/vendor/zod/v4/locales/sv.js +115 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ta.js +115 -0
- package/dist/lib/modules/vendor/zod/v4/locales/tg.js +117 -0
- package/dist/lib/modules/vendor/zod/v4/locales/th.js +115 -0
- package/dist/lib/modules/vendor/zod/v4/locales/tk.js +107 -0
- package/dist/lib/modules/vendor/zod/v4/locales/tr.js +110 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ua.js +5 -0
- package/dist/lib/modules/vendor/zod/v4/locales/uk.js +113 -0
- package/dist/lib/modules/vendor/zod/v4/locales/ur.js +115 -0
- package/dist/lib/modules/vendor/zod/v4/locales/uz.js +113 -0
- package/dist/lib/modules/vendor/zod/v4/locales/vi.js +113 -0
- package/dist/lib/modules/vendor/zod/v4/locales/yo.js +112 -0
- package/dist/lib/modules/vendor/zod/v4/locales/zh-CN.js +114 -0
- package/dist/lib/modules/vendor/zod/v4/locales/zh-TW.js +112 -0
- package/dist/lib/testing-jelly-id.js +1219 -0
- package/dist/lib/zod.js +1 -0
- package/dist/spec/messaging-v1.md +3744 -0
- package/dist/third-party-notices.md +239 -0
- package/dist/third-party.json +88 -0
- package/dist/types/core/address.d.ts +16 -0
- package/dist/types/core/agent/operations.d.ts +129 -0
- package/dist/types/core/agent/present.d.ts +57 -0
- package/dist/types/core/agent/text.d.ts +62 -0
- package/dist/types/core/agent-tools.d.ts +966 -0
- package/dist/types/core/b64u.d.ts +6 -0
- package/dist/types/core/cards.d.ts +21 -0
- package/dist/types/core/check.d.ts +10 -0
- package/dist/types/core/consent.d.ts +132 -0
- package/dist/types/core/contact-card.d.ts +34 -0
- package/dist/types/core/conversation/context.d.ts +56 -0
- package/dist/types/core/conversation/event.d.ts +36 -0
- package/dist/types/core/conversation/ids.d.ts +18 -0
- package/dist/types/core/conversation/link.d.ts +16 -0
- package/dist/types/core/conversation/log.d.ts +142 -0
- package/dist/types/core/conversation/ratchet.d.ts +95 -0
- package/dist/types/core/conversation/seal.d.ts +47 -0
- package/dist/types/core/delegation.d.ts +71 -0
- package/dist/types/core/directory/device-log.d.ts +119 -0
- package/dist/types/core/directory/epoch.d.ts +53 -0
- package/dist/types/core/directory/handle.d.ts +11 -0
- package/dist/types/core/directory/jelly-device.d.ts +88 -0
- package/dist/types/core/directory/jelly-issuer.d.ts +8 -0
- package/dist/types/core/directory/jelly-token.d.ts +116 -0
- package/dist/types/core/directory/keys-statement.d.ts +22 -0
- package/dist/types/core/directory/link.d.ts +36 -0
- package/dist/types/core/directory/merkle-log.d.ts +40 -0
- package/dist/types/core/directory/person-view.d.ts +90 -0
- package/dist/types/core/directory/person.d.ts +8 -0
- package/dist/types/core/directory/realm.d.ts +23 -0
- package/dist/types/core/directory/smt.d.ts +52 -0
- package/dist/types/core/envelope.d.ts +68 -0
- package/dist/types/core/hash.d.ts +2 -0
- package/dist/types/core/head.d.ts +34 -0
- package/dist/types/core/identity.d.ts +35 -0
- package/dist/types/core/index.d.ts +45 -0
- package/dist/types/core/jcs.d.ts +12 -0
- package/dist/types/core/jelly-host-double.d.ts +21 -0
- package/dist/types/core/jelly-host.d.ts +86 -0
- package/dist/types/core/keys.d.ts +16 -0
- package/dist/types/core/peer-text.d.ts +87 -0
- package/dist/types/core/realm.d.ts +36 -0
- package/dist/types/core/roster.d.ts +146 -0
- package/dist/types/core/schema/a2a.d.ts +251 -0
- package/dist/types/core/schema/common.d.ts +328 -0
- package/dist/types/core/schema/consent.d.ts +140 -0
- package/dist/types/core/schema/conversation.d.ts +1657 -0
- package/dist/types/core/schema/delegation.d.ts +58 -0
- package/dist/types/core/schema/directory-frames.d.ts +1301 -0
- package/dist/types/core/schema/directory.d.ts +375 -0
- package/dist/types/core/schema/envelope.d.ts +756 -0
- package/dist/types/core/schema/errors.d.ts +142 -0
- package/dist/types/core/schema/index.d.ts +16 -0
- package/dist/types/core/schema/ipc/consent.d.ts +555 -0
- package/dist/types/core/schema/ipc/device.d.ts +735 -0
- package/dist/types/core/schema/ipc/jelly.d.ts +501 -0
- package/dist/types/core/schema/ipc/shapes.d.ts +414 -0
- package/dist/types/core/schema/ipc/surfaces.d.ts +680 -0
- package/dist/types/core/schema/ipc.d.ts +3146 -0
- package/dist/types/core/schema/jelly.d.ts +160 -0
- package/dist/types/core/schema/realm.d.ts +38 -0
- package/dist/types/core/schema/relay.d.ts +1134 -0
- package/dist/types/core/schema/roster.d.ts +347 -0
- package/dist/types/core/sign.d.ts +13 -0
- package/dist/types/core/task.d.ts +6 -0
- package/dist/types/core/testing.d.ts +19 -0
- package/dist/types/core/ulid.d.ts +5 -0
- package/dist/types/core/version.d.ts +6 -0
- package/dist/types/core/wire.d.ts +14 -0
- package/dist/types/ipc/client.d.ts +85 -0
- package/dist/types/ipc/framing.d.ts +12 -0
- package/dist/types/ipc/index.d.ts +6 -0
- package/dist/types/ipc/paths.d.ts +39 -0
- package/dist/types/ipc/pipes.d.ts +16 -0
- package/dist/types/ipc/rpc.d.ts +13 -0
- package/dist/types/ipc/server.d.ts +94 -0
- package/dist/types/ipc/testing.d.ts +89 -0
- package/dist/types/ipc/trust.d.ts +49 -0
- package/dist/types/ipc/windows-acl.d.ts +56 -0
- package/dist/types/testing/jelly-id.d.ts +518 -0
- package/dist/types/zod.d.ts +1 -0
- package/package.json +77 -4
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Jelly ID issuer double, for tests only: the issuing side of Jelly's resource-token contract v1.1
|
|
3
|
+
* (`jelly-resource-token-contract-v1.1.md` §3-§5, §9-§11; design `docs/design/people-and-consent.md` §2.2, §3.7,
|
|
4
|
+
* §3.10, §11), with Jelly's change of 2026-11-05: an unbindable `cnf_jwk` is
|
|
5
|
+
* `400 {error: "invalid_target", detail: "invalid_cnf_jwk"}`, and a plain `invalid_target` (no `detail`) still
|
|
6
|
+
* means "no such resource".
|
|
7
|
+
*
|
|
8
|
+
* The directory tests (`packages/relay/test/directory/`) and the end-to-end suites (`test/e2e/`) import it by
|
|
9
|
+
* relative path; other repositories' tests import `@joe-broadhead/messaging/testing/jelly-id`, which carries it as tsc
|
|
10
|
+
* builds it (`test/doubles/tsconfig.json`). Production code never imports it. It loads only Node built-ins
|
|
11
|
+
* (`node:crypto`, `node:http`).
|
|
12
|
+
*
|
|
13
|
+
* What it serves, in process (`mint`, `events`, `jwks`, …) and over HTTP once `JellyIdDouble.start()` listens:
|
|
14
|
+
*
|
|
15
|
+
* | Route | Contract |
|
|
16
|
+
* |---|---|
|
|
17
|
+
* | `GET /.well-known/oauth-authorization-server` | §2: `jelly_resources`, `jelly_account_events` |
|
|
18
|
+
* | `GET /.well-known/jwks.json` | §4-§5: the current public keys; a key leaves `jwksDropMs` after a rotation |
|
|
19
|
+
* | `GET /.well-known/jwks-history.json` | §11: every key ever published, with `nbf`, `retired_at`, `revoked_at` |
|
|
20
|
+
* | `POST /hosts/<hostId>/resource-tokens` | §3: the mint, with a host's RFC 7523 assertion and an optional `cnf_jwk` |
|
|
21
|
+
* | `POST /resource/accounts/events` | §10: the deletion feed, with a service's assertion (§9) and a cursor |
|
|
22
|
+
* | `POST /resource/device/code` | v1.2 §12.1: a device client asks for a code (only while a resource has `device_sign_in`) |
|
|
23
|
+
* | `POST /resource/device/token` | v1.2 §12.3: the device polls for its `src: "device"` token |
|
|
24
|
+
* | `POST /hosts/<hostId>/wake` | Jelly's A5 (hey-jelly#36, 7 Nov): a service wakes a sleeping host with its `jelly-wake+jwt`, once per `jti` |
|
|
25
|
+
*
|
|
26
|
+
* Device sign-in (§12) behaves as Jelly's contract v1.2 §12 is built in hey-jelly
|
|
27
|
+
* (`backend/control/src/broker/resource-device-routes.ts` and `protocol/contracts/src/jelly-id-device-sign-in.ts`, at
|
|
28
|
+
* the commit `jelly-device-sign-in.md` beside this file cites): the same answers, in the same order of checks, and
|
|
29
|
+
* never a `verification_uri_complete`. The consent page of §12.2 is in process: `consentPage(code, {account})` and
|
|
30
|
+
* `decide(code, {account}, "approve" | "deny")` (or `approve(code, account)`), as the person signed in at Jelly ID,
|
|
31
|
+
* having typed the code. `jelly-id-device.test.ts` checks the double against that excerpt's tables.
|
|
32
|
+
*
|
|
33
|
+
* Time comes from `options.now` (milliseconds), so a test can rotate a key, age a cursor past retention or let a
|
|
34
|
+
* token expire without waiting: `manualClock()` gives one.
|
|
35
|
+
*
|
|
36
|
+
* Test-only powers a real issuer does not have, for adversarial cases: `sign()` signs any header and claims with
|
|
37
|
+
* any key the double ever held (a "stolen" retired key), `mint()` takes `iat` and `kid` overrides, and `fail()`
|
|
38
|
+
* makes a route answer an error. `requests` records method, path and status of every HTTP request, never a body
|
|
39
|
+
* or a header (the bodies carry assertions and tokens).
|
|
40
|
+
*/
|
|
41
|
+
import { type KeyObject } from "node:crypto";
|
|
42
|
+
export declare const RESOURCE_TOKEN_TYP = "jelly-resource+jwt";
|
|
43
|
+
export declare const JWT_BEARER = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
|
|
44
|
+
/** §4: `exp = iat + 600`. */
|
|
45
|
+
export declare const TOKEN_TTL_S = 600;
|
|
46
|
+
/** §3: more than 120 tokens for one host in an hour is `429 slow_down`. */
|
|
47
|
+
export declare const MINTS_PER_HOUR = 120;
|
|
48
|
+
/** §9: a service assertion lives at most 300 s; times hold with 60 s of leeway. */
|
|
49
|
+
export declare const ASSERTION_MAX_S = 300;
|
|
50
|
+
export declare const LEEWAY_S = 60;
|
|
51
|
+
/** §10: an event is served once it is 60 s old; events and cursors are kept 90 days; at most 100 an answer. */
|
|
52
|
+
export declare const FEED_DELAY_MS = 60000;
|
|
53
|
+
export declare const FEED_RETENTION_MS: number;
|
|
54
|
+
export declare const FEED_PAGE = 100;
|
|
55
|
+
/** §11: `jwks.json` drops a key about ten minutes after a rotation. */
|
|
56
|
+
export declare const JWKS_DROP_MS: number;
|
|
57
|
+
/** Jelly's contract v1.2 §12 (`jelly-device-sign-in.md` beside this file): a service's device signs in through the browser. */
|
|
58
|
+
export declare const DEVICE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
|
|
59
|
+
/** §12.1, §12.6: a code lives 600 s; the device polls every 5 s, and each `slow_down` adds 5 s to the code's interval. */
|
|
60
|
+
export declare const DEVICE_CODE_TTL_S = 600;
|
|
61
|
+
export declare const DEVICE_INTERVAL_S = 5;
|
|
62
|
+
export declare const SLOW_DOWN_STEP_S = 5;
|
|
63
|
+
/** §12.6: the limits. Approvals are counted per account and resource (Jelly's `approve:<account>:<resource>` window). */
|
|
64
|
+
export declare const DEVICE_CODES_PER_ADDRESS_HOUR = 10;
|
|
65
|
+
export declare const DEVICE_CODES_WAITING_PER_CLIENT = 1000;
|
|
66
|
+
export declare const DEVICE_APPROVALS_PER_ACCOUNT_RESOURCE_DAY = 5;
|
|
67
|
+
/** §12.2: the page and the decision need a Jelly ID sign-in of the last 15 minutes. */
|
|
68
|
+
export declare const RECENT_SIGN_IN_MS: number;
|
|
69
|
+
export declare const LINK_ATTEMPTS = 10;
|
|
70
|
+
export declare const LINK_WINDOW_MS: number;
|
|
71
|
+
/** §9: a service's `jwks_uri` is believed for an hour, refetched for an unknown `kid` at most once a minute. */
|
|
72
|
+
export declare const SERVICE_JWKS_TTL_MS = 3600000;
|
|
73
|
+
export declare const SERVICE_JWKS_REFETCH_MS = 60000;
|
|
74
|
+
export declare const b64u: (bytes: Uint8Array | string) => string;
|
|
75
|
+
/** A clock a test moves by hand. */
|
|
76
|
+
export interface ManualClock {
|
|
77
|
+
(): number;
|
|
78
|
+
advance(ms: number): number;
|
|
79
|
+
set(ms: number): number;
|
|
80
|
+
}
|
|
81
|
+
export declare function manualClock(start?: number): ManualClock;
|
|
82
|
+
export interface Jwk {
|
|
83
|
+
kty: "OKP";
|
|
84
|
+
crv: "Ed25519";
|
|
85
|
+
x: string;
|
|
86
|
+
kid?: string;
|
|
87
|
+
alg?: "EdDSA";
|
|
88
|
+
use?: "sig";
|
|
89
|
+
}
|
|
90
|
+
/** A bare public `cnf` key: exactly `{kty, crv, x}` (§3). */
|
|
91
|
+
export interface CnfJwk {
|
|
92
|
+
kty: "OKP";
|
|
93
|
+
crv: "Ed25519";
|
|
94
|
+
x: string;
|
|
95
|
+
}
|
|
96
|
+
export interface Ed25519Pair {
|
|
97
|
+
privateKey: KeyObject;
|
|
98
|
+
publicKey: KeyObject;
|
|
99
|
+
/** The raw public key, base64url: a DeviceId when this pair is a device. */
|
|
100
|
+
x: string;
|
|
101
|
+
}
|
|
102
|
+
export declare function ed25519(): Ed25519Pair;
|
|
103
|
+
/** The `cnf_jwk` for a device's raw public key (base64url), as the plugin passes it to `token(name, {cnf})`. */
|
|
104
|
+
export declare const cnfOf: (x: string) => CnfJwk;
|
|
105
|
+
/** RFC 7638 thumbprint of an OKP key. */
|
|
106
|
+
export declare function thumbprint(jwk: CnfJwk): string;
|
|
107
|
+
/**
|
|
108
|
+
* §12.3: a key's fingerprint as the consent page shows it: the first six bytes of its RFC 7638 thumbprint, in
|
|
109
|
+
* lower-case hex, in three groups of four (`3fa9-1c07-e2b4`).
|
|
110
|
+
*/
|
|
111
|
+
export declare function keyFingerprint(x: string): string;
|
|
112
|
+
/** A compact JWS signed with Ed25519 over `b64u(header).b64u(payload)`. */
|
|
113
|
+
export declare function signJwt(header: Record<string, unknown>, claims: Record<string, unknown>, key: KeyObject): string;
|
|
114
|
+
export interface DecodedJwt {
|
|
115
|
+
header: Record<string, unknown>;
|
|
116
|
+
claims: Record<string, unknown>;
|
|
117
|
+
input: string;
|
|
118
|
+
signature: Buffer;
|
|
119
|
+
}
|
|
120
|
+
/** Splits a compact JWS. Returns undefined for anything that is not three base64url segments of JSON objects. */
|
|
121
|
+
export declare function decodeJwt(token: string): DecodedJwt | undefined;
|
|
122
|
+
/** Why 32 bytes are not a bindable Ed25519 public key, or undefined when they are. */
|
|
123
|
+
export declare function pointProblem(bytes: Uint8Array): string | undefined;
|
|
124
|
+
/** Why a `cnf_jwk` is not bindable (§3), or undefined when it is. Takes the form value (JSON text) or an object. */
|
|
125
|
+
export declare function cnfProblem(value: unknown): string | undefined;
|
|
126
|
+
export interface ResourceEntry {
|
|
127
|
+
/** `^[a-z][a-z0-9-]{0,31}$`: the name plugins ask for and the service's client id (§1, §9). */
|
|
128
|
+
name: string;
|
|
129
|
+
/** The token audience, e.g. `https://msg.toqanjelly.ai`. */
|
|
130
|
+
resource: string;
|
|
131
|
+
url: string;
|
|
132
|
+
/** §1, §9: the service's own public keys, inline (one or two, each with a `kid`). */
|
|
133
|
+
jwks?: {
|
|
134
|
+
keys: Jwk[];
|
|
135
|
+
};
|
|
136
|
+
/** §9: or an https URL to read them from (the double also accepts `http://127.0.0.1…`). */
|
|
137
|
+
jwks_uri?: string;
|
|
138
|
+
/** v1.2 §1, §12: this resource's device client may sign in through the browser. Default false. */
|
|
139
|
+
device_sign_in?: boolean;
|
|
140
|
+
}
|
|
141
|
+
/** One code of §12.1, as the double keeps it (Jelly keeps both codes hashed). */
|
|
142
|
+
export interface DeviceCode {
|
|
143
|
+
deviceCode: string;
|
|
144
|
+
userCode: string;
|
|
145
|
+
clientId: string;
|
|
146
|
+
resource: string;
|
|
147
|
+
cnf: CnfJwk;
|
|
148
|
+
label: string;
|
|
149
|
+
kind: string;
|
|
150
|
+
address: string;
|
|
151
|
+
/** Ms. */
|
|
152
|
+
createdAt: number;
|
|
153
|
+
expiresAt: number;
|
|
154
|
+
/** Seconds; grows by 5 on each `slow_down`. */
|
|
155
|
+
interval: number;
|
|
156
|
+
lastPoll?: number;
|
|
157
|
+
decision?: {
|
|
158
|
+
approved: true;
|
|
159
|
+
account: Account;
|
|
160
|
+
} | {
|
|
161
|
+
approved: false;
|
|
162
|
+
};
|
|
163
|
+
/** An approval collected (or refused at the exchange's live check): spent once. A denial is never spent. */
|
|
164
|
+
consumed: boolean;
|
|
165
|
+
}
|
|
166
|
+
/** What the consent page of §12.2 shows for a code. */
|
|
167
|
+
export interface ConsentPage {
|
|
168
|
+
service: {
|
|
169
|
+
name: string;
|
|
170
|
+
url: string;
|
|
171
|
+
};
|
|
172
|
+
device: {
|
|
173
|
+
label: string;
|
|
174
|
+
kind: string;
|
|
175
|
+
};
|
|
176
|
+
fingerprint: string;
|
|
177
|
+
userCode: string;
|
|
178
|
+
account: string;
|
|
179
|
+
asked: {
|
|
180
|
+
at: string;
|
|
181
|
+
address: string;
|
|
182
|
+
};
|
|
183
|
+
says: string;
|
|
184
|
+
}
|
|
185
|
+
export interface Account {
|
|
186
|
+
sub: string;
|
|
187
|
+
email?: string;
|
|
188
|
+
emailVerified: boolean;
|
|
189
|
+
name?: string;
|
|
190
|
+
state: "active" | "disabled" | "deleting" | "purged";
|
|
191
|
+
}
|
|
192
|
+
export interface Host {
|
|
193
|
+
id: string;
|
|
194
|
+
account: Account;
|
|
195
|
+
key: Ed25519Pair;
|
|
196
|
+
removed: boolean;
|
|
197
|
+
}
|
|
198
|
+
export interface IssuerKey {
|
|
199
|
+
kid: string;
|
|
200
|
+
key: Ed25519Pair;
|
|
201
|
+
/** Seconds: when it was first published. */
|
|
202
|
+
nbf: number;
|
|
203
|
+
/** Ms: when another key took over signing; the key leaves `jwks.json` `jwksDropMs` later. */
|
|
204
|
+
rotatedAt?: number;
|
|
205
|
+
/** Ms: when it left `jwks.json` (set by `retire`, or derived from `rotatedAt`). */
|
|
206
|
+
droppedAt?: number;
|
|
207
|
+
/** Seconds: when an operator revoked it. */
|
|
208
|
+
revokedAt?: number;
|
|
209
|
+
}
|
|
210
|
+
export interface AccountEvent {
|
|
211
|
+
id: string;
|
|
212
|
+
sub: string;
|
|
213
|
+
event: string;
|
|
214
|
+
/** ISO time of the purge. */
|
|
215
|
+
at: string;
|
|
216
|
+
/** Internal: the resource whose feed serves it, and the write order. */
|
|
217
|
+
resource: string;
|
|
218
|
+
seq: number;
|
|
219
|
+
atMs: number;
|
|
220
|
+
}
|
|
221
|
+
export interface Answer<T = Record<string, unknown>> {
|
|
222
|
+
status: number;
|
|
223
|
+
body: T;
|
|
224
|
+
headers: Record<string, string>;
|
|
225
|
+
}
|
|
226
|
+
export interface MintArgs {
|
|
227
|
+
host: Host | string;
|
|
228
|
+
resource: string;
|
|
229
|
+
/** The `cnf_jwk` form value: JSON text, or an object (serialized as given). */
|
|
230
|
+
cnf?: unknown;
|
|
231
|
+
/** Test-only: mint at another time (seconds). */
|
|
232
|
+
iat?: number;
|
|
233
|
+
/** Test-only: sign with this key (it must be one the double holds, current or not). */
|
|
234
|
+
kid?: string;
|
|
235
|
+
}
|
|
236
|
+
export type Route = "discovery" | "jwks" | "history" | "mint" | "events" | "device-code" | "device-token" | "wake";
|
|
237
|
+
/** Jelly's A5: a `jelly-wake+jwt` lives at most seven days; a host is woken at most 6 times an hour and 48 a day. */
|
|
238
|
+
export declare const WAKE_TICKET_MAX_S: number;
|
|
239
|
+
export declare const WAKES_PER_HOUR = 6;
|
|
240
|
+
export declare const WAKES_PER_DAY = 48;
|
|
241
|
+
export interface JellyIdDoubleOptions {
|
|
242
|
+
/** Jelly ID's issuer origin. `start()` defaults it to the listening origin. */
|
|
243
|
+
issuer?: string;
|
|
244
|
+
resources?: ResourceEntry[];
|
|
245
|
+
/** Milliseconds since the epoch. Default `Date.now`. */
|
|
246
|
+
now?: () => number;
|
|
247
|
+
/** Start with no signing key: the mint answers `503 temporarily_unavailable`. */
|
|
248
|
+
noKeys?: boolean;
|
|
249
|
+
mintsPerHour?: number;
|
|
250
|
+
feedPage?: number;
|
|
251
|
+
feedDelayMs?: number;
|
|
252
|
+
feedRetentionMs?: number;
|
|
253
|
+
jwksDropMs?: number;
|
|
254
|
+
/** §12: the poll interval a code answers with (seconds, default 5) and a code's life (default 600). */
|
|
255
|
+
deviceIntervalS?: number;
|
|
256
|
+
deviceCodeTtlS?: number;
|
|
257
|
+
}
|
|
258
|
+
export interface RequestRecord {
|
|
259
|
+
method: string;
|
|
260
|
+
path: string;
|
|
261
|
+
status: number;
|
|
262
|
+
}
|
|
263
|
+
export declare class JellyIdDouble {
|
|
264
|
+
#private;
|
|
265
|
+
issuer: string;
|
|
266
|
+
readonly resources: ResourceEntry[];
|
|
267
|
+
readonly now: () => number;
|
|
268
|
+
readonly keys: IssuerKey[];
|
|
269
|
+
readonly accounts: Map<string, Account>;
|
|
270
|
+
readonly hosts: Map<string, Host>;
|
|
271
|
+
readonly events: AccountEvent[];
|
|
272
|
+
/** HTTP requests seen: method, path (no query) and status only. */
|
|
273
|
+
readonly requests: RequestRecord[];
|
|
274
|
+
/** resource → sub → first mint (ms): the scope of the deletion feed (§3, §10). */
|
|
275
|
+
readonly minted: Map<string, Map<string, number>>;
|
|
276
|
+
/** Every token the mint issued, for tests that must check a log never shows one. */
|
|
277
|
+
readonly issued: string[];
|
|
278
|
+
/** Hosts woken (A5): which, when (ms), and the ticket's `jti`. */
|
|
279
|
+
readonly wakes: {
|
|
280
|
+
host: string;
|
|
281
|
+
at: number;
|
|
282
|
+
jti: string;
|
|
283
|
+
}[];
|
|
284
|
+
/** §12: every code asked for, by `device_code`. */
|
|
285
|
+
readonly deviceCodes: Map<string, DeviceCode>;
|
|
286
|
+
constructor(options?: JellyIdDoubleOptions);
|
|
287
|
+
/** Listens on 127.0.0.1 (a free port unless given); the issuer is the origin unless `options.issuer` is set. */
|
|
288
|
+
static start(options?: JellyIdDoubleOptions, port?: number): Promise<JellyIdDouble>;
|
|
289
|
+
get origin(): string;
|
|
290
|
+
get jwksUri(): string;
|
|
291
|
+
get historyUri(): string;
|
|
292
|
+
get eventsUri(): string;
|
|
293
|
+
/** v1.2 §12: the routes of §12.1 and §12.3, and the consent page of §12.2. */
|
|
294
|
+
get deviceCodeUri(): string;
|
|
295
|
+
get deviceTokenUri(): string;
|
|
296
|
+
get linkUri(): string;
|
|
297
|
+
close(): Promise<void>;
|
|
298
|
+
/** The key that signs now: the newest one not dropped or revoked. */
|
|
299
|
+
get signer(): IssuerKey | undefined;
|
|
300
|
+
addKey(kid?: string): IssuerKey;
|
|
301
|
+
/** A new key takes over signing; the old one stays in `jwks.json` for `jwksDropMs`, then only in the history. */
|
|
302
|
+
rotate(kid?: string): IssuerKey;
|
|
303
|
+
/** Drops a key from `jwks.json` now: its `retired_at` is now. */
|
|
304
|
+
retire(kid: string): void;
|
|
305
|
+
/** An operator revokes a key (`JELLY_ID_REVOKED_KEYS`): `revoked_at` in the history, gone from `jwks.json`. */
|
|
306
|
+
revoke(kid: string, atSeconds?: number): void;
|
|
307
|
+
/** `jwks.json`: the published keys, newest (the signer) first. Never a private member. */
|
|
308
|
+
jwks(): {
|
|
309
|
+
keys: Jwk[];
|
|
310
|
+
};
|
|
311
|
+
/** `jwks-history.json` (§11): every key ever published, oldest first; it never shrinks. */
|
|
312
|
+
history(): {
|
|
313
|
+
keys: (Jwk & {
|
|
314
|
+
nbf: number;
|
|
315
|
+
retired_at: number | null;
|
|
316
|
+
revoked_at?: number;
|
|
317
|
+
})[];
|
|
318
|
+
};
|
|
319
|
+
/**
|
|
320
|
+
* The RFC 8414 metadata. Like Jelly ID's in production, it names `device_authorization_endpoint`: the route that
|
|
321
|
+
* enrols *hosts* with a host's assertion (`/device/code`), which a service's device must not take for §12. The
|
|
322
|
+
* double does not serve it. §12's own two members appear only when a resource has `device_sign_in` (v1.2 §2).
|
|
323
|
+
*/
|
|
324
|
+
discovery(): Record<string, unknown>;
|
|
325
|
+
/** Test-only: signs anything with any key the double holds or held (a stolen key, a backdated token). */
|
|
326
|
+
sign(header: Record<string, unknown>, claims: Record<string, unknown>, kid?: string | undefined): string;
|
|
327
|
+
account(opts?: {
|
|
328
|
+
sub?: string;
|
|
329
|
+
email?: string;
|
|
330
|
+
name?: string;
|
|
331
|
+
emailVerified?: boolean;
|
|
332
|
+
}): Account;
|
|
333
|
+
/** Enrols a host owned by `account`, with its own Ed25519 key for its client assertions. */
|
|
334
|
+
host(account: Account, id?: string): Host;
|
|
335
|
+
/** The host's RFC 7523 client assertion (`iss = sub = hostId`, `aud` = the issuer). */
|
|
336
|
+
hostAssertion(host: Host, opts?: {
|
|
337
|
+
jti?: string;
|
|
338
|
+
iat?: number;
|
|
339
|
+
ttl?: number;
|
|
340
|
+
aud?: string;
|
|
341
|
+
key?: KeyObject;
|
|
342
|
+
}): string;
|
|
343
|
+
/**
|
|
344
|
+
* The host's wake ticket (Jelly's A5): a `jelly-wake+jwt` signed with its enrolled key, `iss` and `sub` the host, `aud`
|
|
345
|
+
* its wake URL, `svc` the service, a fresh `jti`, valid `ttl` seconds (default a day; Jelly allows seven).
|
|
346
|
+
*/
|
|
347
|
+
wakeTicket(host: Host, opts?: {
|
|
348
|
+
svc?: string;
|
|
349
|
+
ttl?: number;
|
|
350
|
+
iat?: number;
|
|
351
|
+
jti?: string;
|
|
352
|
+
aud?: string;
|
|
353
|
+
key?: KeyObject;
|
|
354
|
+
typ?: string;
|
|
355
|
+
}): string;
|
|
356
|
+
/** `<issuer>/hosts/<id>/wake`. */
|
|
357
|
+
wakeUrl(host: Host | string): string;
|
|
358
|
+
/**
|
|
359
|
+
* `POST /hosts/<hostId>/wake` as Jelly ID answers it (A5): `202` wakes the host and spends the ticket's `jti`; `401`
|
|
360
|
+
* for a ticket that is not this host's, has expired or was spent; `404` for no such host; `429` with `Retry-After`
|
|
361
|
+
* past the host's budget (6 an hour, 48 a day); `503` (by `fail("wake")`) spends nothing.
|
|
362
|
+
*/
|
|
363
|
+
wake(hostId: string, form: URLSearchParams): Answer;
|
|
364
|
+
disable(account: Account): void;
|
|
365
|
+
/** The person asks to delete: no more tokens (§10, "From the request on…"). No event yet. */
|
|
366
|
+
requestDeletion(account: Account): void;
|
|
367
|
+
/** The grace period ends: `account.deleted` for every service the account was minted a token for (§10). */
|
|
368
|
+
purge(account: Account): AccountEvent[];
|
|
369
|
+
/** Test-only: writes any event (an unknown kind, an unknown person) into one service's feed. */
|
|
370
|
+
emit({ sub, resource, event, atMs }: {
|
|
371
|
+
sub: string;
|
|
372
|
+
resource: string;
|
|
373
|
+
event?: string;
|
|
374
|
+
atMs?: number;
|
|
375
|
+
}): AccountEvent;
|
|
376
|
+
/** A service key pair and its public JWK (with `kid`), for `ResourceEntry.jwks` and `serviceAssertion`. */
|
|
377
|
+
static serviceKey(kid?: string): {
|
|
378
|
+
kid: string;
|
|
379
|
+
pair: Ed25519Pair;
|
|
380
|
+
jwk: Jwk;
|
|
381
|
+
};
|
|
382
|
+
/** A service's RFC 7523 assertion (§9): `iss = sub = name`, `aud` = the issuer. */
|
|
383
|
+
serviceAssertion(name: string, key: {
|
|
384
|
+
kid: string;
|
|
385
|
+
pair: Ed25519Pair;
|
|
386
|
+
}, opts?: {
|
|
387
|
+
jti?: string;
|
|
388
|
+
iat?: number;
|
|
389
|
+
ttl?: number;
|
|
390
|
+
aud?: string;
|
|
391
|
+
iss?: string;
|
|
392
|
+
sub?: string;
|
|
393
|
+
}): string;
|
|
394
|
+
/** The next `times` requests to `route` answer `status` with `body` (default a `temporarily_unavailable`). */
|
|
395
|
+
fail(route: Route, status?: number, body?: Record<string, unknown>, times?: number): void;
|
|
396
|
+
/**
|
|
397
|
+
* The mint as the HTTP route answers it, with the host's assertion checked (§3). `mint()` skips the assertion;
|
|
398
|
+
* use this to test `invalid_client`.
|
|
399
|
+
*/
|
|
400
|
+
mintWithAssertion(hostId: string, form: URLSearchParams): Answer;
|
|
401
|
+
/** Mints as an enrolled, owned host asked for it (the assertion is assumed good). */
|
|
402
|
+
mint(args: MintArgs): Answer;
|
|
403
|
+
/** `mint()` that returns the token or throws with the error code (and detail). */
|
|
404
|
+
token(args: MintArgs): string;
|
|
405
|
+
/** The deletion feed as the HTTP route answers it (§10). */
|
|
406
|
+
accountEvents(form: URLSearchParams): Promise<Answer>;
|
|
407
|
+
/**
|
|
408
|
+
* `POST /resource/device/code` (§12.1) as Jelly's route answers it, in its order of checks: every field present
|
|
409
|
+
* (a repeated one is missing), the client, the resource, the key, the label and kind, then the per-address and
|
|
410
|
+
* per-client limits. `address` is the client's address, for the per-address limit. Never `verification_uri_complete`.
|
|
411
|
+
*/
|
|
412
|
+
deviceAuthorize(form: URLSearchParams, address?: string): Answer;
|
|
413
|
+
/**
|
|
414
|
+
* The consent page of §12.2 for the person signed in as `account` (in `session`, signed in at `signedInAt`, default
|
|
415
|
+
* now), who typed `code` (`from: "typed"`, the default) or arrived with it from `/link?code=` (`from: "link"`). Errors:
|
|
416
|
+
* `account_inactive` (the live check), `type_the_code` (a code from a link is asked for again: "A sign-in code for a
|
|
417
|
+
* device cannot come from a link"), `sign_in_again` (a sign-in older than 15 minutes), `too_many_codes` (10 wrong
|
|
418
|
+
* codes in 15 minutes), `code_invalid` (unknown, decided or expired: "That code didn't work").
|
|
419
|
+
*/
|
|
420
|
+
consentPage(code: string, as: {
|
|
421
|
+
account: Account;
|
|
422
|
+
session?: string;
|
|
423
|
+
signedInAt?: number;
|
|
424
|
+
from?: "typed" | "link";
|
|
425
|
+
}): {
|
|
426
|
+
status: 200;
|
|
427
|
+
page: ConsentPage;
|
|
428
|
+
} | {
|
|
429
|
+
status: number;
|
|
430
|
+
error: string;
|
|
431
|
+
};
|
|
432
|
+
/**
|
|
433
|
+
* The person's decision on the consent page (`POST /link/device`, §12.2): `approve` or `deny`, once per code. Errors
|
|
434
|
+
* as `consentPage`, and `too_many_sign_ins` when the account approved 5 sign-ins to this resource in the day's window
|
|
435
|
+
* (§12.6): nothing is decided then, and the code waits on until it expires.
|
|
436
|
+
*/
|
|
437
|
+
decide(code: string, as: {
|
|
438
|
+
account: Account;
|
|
439
|
+
session?: string;
|
|
440
|
+
signedInAt?: number;
|
|
441
|
+
}, decision: "approve" | "deny"): {
|
|
442
|
+
status: 200;
|
|
443
|
+
decided: "approved" | "denied";
|
|
444
|
+
} | {
|
|
445
|
+
status: number;
|
|
446
|
+
error: string;
|
|
447
|
+
};
|
|
448
|
+
/** The person approves the code a device shows (test shorthand); throws on a refusal. */
|
|
449
|
+
approve(code: string, account: Account): void;
|
|
450
|
+
/**
|
|
451
|
+
* A whole sign-in through the browser in process (§12.1-§12.3): a code for `cnf` from `client` (the resource's
|
|
452
|
+
* name), approved by `account`, exchanged once. Returns the `src: "device"` token, or throws with the error code.
|
|
453
|
+
*/
|
|
454
|
+
signInToken(args: {
|
|
455
|
+
account: Account;
|
|
456
|
+
cnf: CnfJwk;
|
|
457
|
+
client?: string;
|
|
458
|
+
label?: string;
|
|
459
|
+
kind?: string;
|
|
460
|
+
}): string;
|
|
461
|
+
/**
|
|
462
|
+
* `POST /resource/device/token` (§12.3) as Jelly's route answers it, in its order of checks: the grant type, the
|
|
463
|
+
* client, the code (recording the poll: one sooner than the code's interval grows it by 5 s), the code's client,
|
|
464
|
+
* spent, denied, expired (decided or not), undecided (`slow_down` when early, else `authorization_pending`), then
|
|
465
|
+
* the approval is spent and the account checked live. A repeated field is a missing one.
|
|
466
|
+
*/
|
|
467
|
+
deviceToken(form: URLSearchParams): Answer;
|
|
468
|
+
/** The waiting or decided code whose `user_code` (as shown) is `shown`. */
|
|
469
|
+
codeOf(shown: string): DeviceCode | undefined;
|
|
470
|
+
}
|
|
471
|
+
/** `POST <issuer>/hosts/<hostId>/resource-tokens` as a host sends it (§3). */
|
|
472
|
+
export declare function requestToken(double: JellyIdDouble, host: Host, resource: string, cnf?: unknown, assertion?: string): Promise<{
|
|
473
|
+
status: number;
|
|
474
|
+
body: Record<string, unknown>;
|
|
475
|
+
cacheControl: string | null;
|
|
476
|
+
}>;
|
|
477
|
+
/** `POST <issuer>/resource/accounts/events` as a service sends it (§10). */
|
|
478
|
+
export declare function requestEvents(double: JellyIdDouble, assertion: string, cursor?: string): Promise<{
|
|
479
|
+
status: number;
|
|
480
|
+
body: Record<string, unknown>;
|
|
481
|
+
cacheControl: string | null;
|
|
482
|
+
}>;
|
|
483
|
+
/** `POST <issuer>/resource/device/code` (§12.2). */
|
|
484
|
+
export declare function requestDeviceCode(double: JellyIdDouble, fields: Record<string, string | string[]>): Promise<{
|
|
485
|
+
status: number;
|
|
486
|
+
body: Record<string, unknown>;
|
|
487
|
+
cacheControl: string | null;
|
|
488
|
+
}>;
|
|
489
|
+
/** `POST <issuer>/resource/device/token` (§12.4). */
|
|
490
|
+
export declare function requestDeviceToken(double: JellyIdDouble, fields: Record<string, string | string[]>): Promise<{
|
|
491
|
+
status: number;
|
|
492
|
+
body: Record<string, unknown>;
|
|
493
|
+
cacheControl: string | null;
|
|
494
|
+
}>;
|
|
495
|
+
export type AccessorErrorCode = "unavailable" | "not_enrolled" | "access_denied" | "invalid_target" | "invalid_request";
|
|
496
|
+
export interface JellyIdentityAccessor {
|
|
497
|
+
resources(): ReadonlyArray<{
|
|
498
|
+
name: string;
|
|
499
|
+
resource: string;
|
|
500
|
+
url: string;
|
|
501
|
+
}>;
|
|
502
|
+
token(name: string, options?: {
|
|
503
|
+
cnf?: CnfJwk;
|
|
504
|
+
}): Promise<{
|
|
505
|
+
accessToken: string;
|
|
506
|
+
expiresAt: number;
|
|
507
|
+
}>;
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* The accessor as Jelly's core plugin offers it on `host` (§6): tokens cached until 60 s before `exp`, single-flight
|
|
511
|
+
* per resource and bound key (RFC 7638 thumbprint, or none), and a token bound to one key never handed out for
|
|
512
|
+
* another key or for none. Rejections carry `code` (and, for an unbindable key, `detail: "invalid_cnf_jwk"`).
|
|
513
|
+
* `install()` puts it on `globalThis[Symbol.for("jelly.identity")]` and returns the undo.
|
|
514
|
+
*/
|
|
515
|
+
export declare function identityAccessor(double: JellyIdDouble, host: Host | undefined): JellyIdentityAccessor & {
|
|
516
|
+
install(): () => void;
|
|
517
|
+
mints: number;
|
|
518
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "zod";
|
package/package.json
CHANGED
|
@@ -1,6 +1,79 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@joe-broadhead/messaging",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.7.1",
|
|
4
|
+
"description": "Messaging: the relay, the per-machine daemon and its CLI, and the MCP server as bundled single files, plus the client libraries and the protocol spec. Zero dependencies.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Joe Broadhead",
|
|
8
|
+
"homepage": "https://github.com/joe-broadhead/messaging/tree/main/packages/messaging#readme",
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/joe-broadhead/messaging/issues"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/joe-broadhead/messaging.git",
|
|
15
|
+
"directory": "packages/messaging"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"a2a",
|
|
22
|
+
"agent-to-agent",
|
|
23
|
+
"messaging",
|
|
24
|
+
"mcp"
|
|
25
|
+
],
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=22.15.0"
|
|
28
|
+
},
|
|
29
|
+
"sideEffects": false,
|
|
30
|
+
"bin": {
|
|
31
|
+
"messaging": "./dist/bin/messaging.js",
|
|
32
|
+
"messagingd": "./dist/bin/messagingd.js",
|
|
33
|
+
"messaging-relay": "./dist/bin/messaging-relay.js",
|
|
34
|
+
"messaging-mcp": "./dist/bin/messaging-mcp.js"
|
|
35
|
+
},
|
|
36
|
+
"exports": {
|
|
37
|
+
"./core": {
|
|
38
|
+
"types": "./dist/types/core/index.d.ts",
|
|
39
|
+
"default": "./dist/lib/core.js"
|
|
40
|
+
},
|
|
41
|
+
"./core/testing": {
|
|
42
|
+
"types": "./dist/types/core/testing.d.ts",
|
|
43
|
+
"default": "./dist/lib/core-testing.js"
|
|
44
|
+
},
|
|
45
|
+
"./ipc": {
|
|
46
|
+
"types": "./dist/types/ipc/index.d.ts",
|
|
47
|
+
"default": "./dist/lib/ipc.js"
|
|
48
|
+
},
|
|
49
|
+
"./ipc/testing": {
|
|
50
|
+
"types": "./dist/types/ipc/testing.d.ts",
|
|
51
|
+
"default": "./dist/lib/ipc-testing.js"
|
|
52
|
+
},
|
|
53
|
+
"./testing/jelly-id": {
|
|
54
|
+
"types": "./dist/types/testing/jelly-id.d.ts",
|
|
55
|
+
"default": "./dist/lib/testing-jelly-id.js"
|
|
56
|
+
},
|
|
57
|
+
"./zod": {
|
|
58
|
+
"types": "./dist/types/zod.d.ts",
|
|
59
|
+
"default": "./dist/lib/zod.js"
|
|
60
|
+
},
|
|
61
|
+
"./bin/messaging.js": "./dist/bin/messaging.js",
|
|
62
|
+
"./bin/messagingd.js": "./dist/bin/messagingd.js",
|
|
63
|
+
"./spec/messaging-v1.md": "./dist/spec/messaging-v1.md",
|
|
64
|
+
"./third-party.json": "./dist/third-party.json",
|
|
65
|
+
"./package.json": "./package.json"
|
|
66
|
+
},
|
|
67
|
+
"files": [
|
|
68
|
+
"dist/bin/*.js",
|
|
69
|
+
"dist/lib/**/*.js",
|
|
70
|
+
"dist/types/**/*.d.ts",
|
|
71
|
+
"dist/spec/messaging-v1.md",
|
|
72
|
+
"dist/third-party.json",
|
|
73
|
+
"dist/third-party-notices.md",
|
|
74
|
+
"README.md",
|
|
75
|
+
"LICENSE",
|
|
76
|
+
"NOTICE",
|
|
77
|
+
"CHANGELOG.md"
|
|
78
|
+
]
|
|
79
|
+
}
|