@book.dev/sdk 1.60.0 → 1.64.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/account.d.ts +11 -0
  2. package/dist/account.js +27 -0
  3. package/dist/account.js.map +1 -1
  4. package/dist/ai.d.ts +10 -0
  5. package/dist/ai.js +12 -0
  6. package/dist/ai.js.map +1 -1
  7. package/dist/authorize.d.ts +104 -0
  8. package/dist/authorize.js +151 -0
  9. package/dist/authorize.js.map +1 -0
  10. package/dist/authors.d.ts +26 -0
  11. package/dist/authors.js +81 -0
  12. package/dist/authors.js.map +1 -0
  13. package/dist/backup.d.ts +39 -0
  14. package/dist/backup.js +15 -0
  15. package/dist/backup.js.map +1 -1
  16. package/dist/client.d.ts +124 -3
  17. package/dist/client.js +106 -9
  18. package/dist/client.js.map +1 -1
  19. package/dist/connection.d.ts +23 -0
  20. package/dist/connection.js +56 -0
  21. package/dist/connection.js.map +1 -1
  22. package/dist/forwarding/index.d.ts +2 -1
  23. package/dist/forwarding/index.js +2 -1
  24. package/dist/forwarding/index.js.map +1 -1
  25. package/dist/forwarding/rosterAssertion.d.ts +49 -0
  26. package/dist/forwarding/rosterAssertion.js +89 -0
  27. package/dist/forwarding/rosterAssertion.js.map +1 -0
  28. package/dist/forwarding/tunnelClient.js +11 -1
  29. package/dist/forwarding/tunnelClient.js.map +1 -1
  30. package/dist/forwarding/tunnelProtocol.d.ts +11 -0
  31. package/dist/forwarding/tunnelProtocol.js +11 -0
  32. package/dist/forwarding/tunnelProtocol.js.map +1 -1
  33. package/dist/identity.d.ts +185 -0
  34. package/dist/identity.js +181 -0
  35. package/dist/identity.js.map +1 -0
  36. package/dist/index.d.ts +13 -9
  37. package/dist/index.js +9 -5
  38. package/dist/index.js.map +1 -1
  39. package/dist/provenance.d.ts +155 -0
  40. package/dist/provenance.js +23 -0
  41. package/dist/provenance.js.map +1 -0
  42. package/dist/routes.d.ts +53 -0
  43. package/dist/routes.js +50 -0
  44. package/dist/routes.js.map +1 -1
  45. package/dist/suggestions.d.ts +17 -2
  46. package/dist/types.d.ts +91 -0
  47. package/dist/types.js +9 -0
  48. package/dist/types.js.map +1 -1
  49. package/package.json +6 -1
@@ -0,0 +1,89 @@
1
+ // Per-instance roster assertion (OB-199 — "bind instance ↔ workspace").
2
+ //
3
+ // When a managed instance pulls its bound workspace's roster from the account
4
+ // (`GET /api/workspaces/:id/roster`), it must prove it is the SITE that owns the
5
+ // binding — not an end user. It does so by signing a short-lived assertion with
6
+ // the site's device private key (the same key that double-gates the forwarding
7
+ // tunnel attach). The account verifies the signature against the Site row's
8
+ // registered public key and that the site is bound to the workspace.
9
+ //
10
+ // The signing half runs ONLY where the private key lives — the desktop's OS
11
+ // keychain — so the raw key never enters the (separate) data-server process. The
12
+ // verify half mirrors the relay's `verifyWithSiteKey`; it is provided here so the
13
+ // account can adopt one canonical implementation and so the contract is testable
14
+ // end-to-end (sign → verify) without the account repo.
15
+ //
16
+ // Runtime-agnostic (Web Crypto via {@link signWithSiteKey}/{@link verifyWithSiteKey}).
17
+ import { b64uDecodeString, b64uEncodeString } from './encoding';
18
+ import { signWithSiteKey, verifyWithSiteKey } from './siteKey';
19
+ /** The assertion payload version tag — also the signed-message prefix. */
20
+ export const ROSTER_ASSERTION_VERSION = 'openbook.roster.v1';
21
+ /** Default freshness window for a roster assertion (±5 min — the account's window). */
22
+ export const ROSTER_ASSERTION_SKEW_MS = 5 * 60 * 1000;
23
+ /**
24
+ * The exact bytes signed/verified: `openbook.roster.v1.<base64url(payloadJson)>`.
25
+ * Order and separators are fixed so the site and the account never disagree. The
26
+ * base64url payload carries no `.`, so it never collides with the version prefix's
27
+ * dots when the account reconstructs the message from the assertion's first half.
28
+ */
29
+ function rosterAssertionMessage(payloadB64) {
30
+ return `${ROSTER_ASSERTION_VERSION}.${payloadB64}`;
31
+ }
32
+ /**
33
+ * Mint a fresh signed roster assertion bearer for `Authorization: Bearer <…>`.
34
+ * Returns `base64url(payloadJson) + '.' + base64url(ed25519Sig)`. Stamps `ts` at
35
+ * call time, so mint one PER fetch (the account's freshness window is ±5 min).
36
+ */
37
+ export async function signRosterAssertion(input) {
38
+ const ts = input.now ? input.now() : Date.now();
39
+ const payload = {
40
+ v: ROSTER_ASSERTION_VERSION,
41
+ pub: input.publicKey,
42
+ workspaceId: input.workspaceId,
43
+ ts,
44
+ };
45
+ const payloadB64 = b64uEncodeString(JSON.stringify(payload));
46
+ const signature = await signWithSiteKey(input.privateKey, rosterAssertionMessage(payloadB64));
47
+ return `${payloadB64}.${signature}`;
48
+ }
49
+ /**
50
+ * Verify a roster assertion (the account side, mirrored here for one canonical
51
+ * impl + end-to-end tests). Returns the parsed payload on success, or `null` on
52
+ * ANY failure — bad framing, wrong version/workspace/pub, a stale `ts`, or a bad
53
+ * signature. Never throws (so it can sit directly in an auth gate).
54
+ */
55
+ export async function verifyRosterAssertion(input) {
56
+ try {
57
+ const dot = input.assertion.indexOf('.');
58
+ if (dot <= 0 || dot === input.assertion.length - 1)
59
+ return null;
60
+ const payloadB64 = input.assertion.slice(0, dot);
61
+ const signature = input.assertion.slice(dot + 1);
62
+ if (signature.includes('.'))
63
+ return null; // exactly two base64url parts
64
+ const parsed = JSON.parse(b64uDecodeString(payloadB64));
65
+ if (typeof parsed !== 'object' || parsed === null)
66
+ return null;
67
+ const payload = parsed;
68
+ if (payload.v !== ROSTER_ASSERTION_VERSION)
69
+ return null;
70
+ if (typeof payload.pub !== 'string' || payload.pub !== input.publicKey)
71
+ return null;
72
+ if (typeof payload.workspaceId !== 'string' || payload.workspaceId !== input.workspaceId)
73
+ return null;
74
+ if (typeof payload.ts !== 'number' || !Number.isFinite(payload.ts))
75
+ return null;
76
+ const now = input.now ?? Date.now();
77
+ const skewMs = input.skewMs ?? ROSTER_ASSERTION_SKEW_MS;
78
+ if (Math.abs(now - payload.ts) > skewMs)
79
+ return null;
80
+ const ok = await verifyWithSiteKey(input.publicKey, rosterAssertionMessage(payloadB64), signature);
81
+ if (!ok)
82
+ return null;
83
+ return { v: ROSTER_ASSERTION_VERSION, pub: payload.pub, workspaceId: payload.workspaceId, ts: payload.ts };
84
+ }
85
+ catch {
86
+ return null;
87
+ }
88
+ }
89
+ //# sourceMappingURL=rosterAssertion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rosterAssertion.js","sourceRoot":"","sources":["../../src/forwarding/rosterAssertion.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@
10
10
  import { globalFetch } from '../client';
11
11
  import { buildRelayAttachMessage } from './challenge';
12
12
  import { signWithSiteKey } from './siteKey';
13
- import { decodeBody, decodeControl, encodeBody, encodeControl } from './tunnelProtocol';
13
+ import { decodeBody, decodeControl, encodeBody, encodeControl, FORWARDED_HEADER } from './tunnelProtocol';
14
14
  export class TunnelClient {
15
15
  constructor(opts) {
16
16
  this.opts = opts;
@@ -164,12 +164,22 @@ export class TunnelClient {
164
164
  }
165
165
  const url = `${this.opts.localOrigin.replace(/\/$/, '')}${frame.path}`;
166
166
  const headers = new Headers();
167
+ const forwardedLk = FORWARDED_HEADER.toLowerCase();
167
168
  for (const [k, v] of frame.headers) {
168
169
  const lk = k.toLowerCase();
169
170
  if (lk === 'host' || lk === 'connection' || lk === 'content-length')
170
171
  continue;
172
+ // Drop any inbound copy of the forwarded marker — it is OURS to assert, never
173
+ // client-supplied. The origin's exposure backstop trusts it precisely because
174
+ // only this client sets it (OB-209).
175
+ if (lk === forwardedLk)
176
+ continue;
171
177
  headers.append(k, v);
172
178
  }
179
+ // Mark every forwarded request as exposed. Set unconditionally (after the strip
180
+ // above) so the origin can fail closed on the tunnelled path while the instance
181
+ // is still unclaimed, even if the UI claim-on-publish guard were bypassed.
182
+ headers.set(FORWARDED_HEADER, '1');
173
183
  const init = { method: frame.method, headers, signal: controller.signal };
174
184
  if (hasBody) {
175
185
  init.body = body;
@@ -1 +1 @@
1
- {"version":3,"file":"tunnelClient.js","sourceRoot":"","sources":["../../src/forwarding/tunnelClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tunnelClient.js","sourceRoot":"","sources":["../../src/forwarding/tunnelClient.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Marks a request as having arrived through the tunnel — i.e. an EXPOSED inbound
3
+ * request, not a loopback/IPC one (OB-209). Forwarding is an outbound tunnel: the
4
+ * instance stays on loopback, so a forwarded request bypasses the boot exposure
5
+ * backstop (`assertExposureSafe`, which only guards a listener bind). The tunnel
6
+ * client SETS this on every request it forwards (overriding any inbound value — it
7
+ * is never client-supplied), so the origin can recognise the exposed path and fail
8
+ * closed while the instance is still unclaimed (where `authorize()` rule-0 would
9
+ * otherwise serve anonymous world-write). Loopback requests never carry it.
10
+ */
11
+ export declare const FORWARDED_HEADER = "X-OpenBook-Forwarded";
1
12
  export type ControlFrame = {
2
13
  t: 'challenge';
3
14
  nonce: string;
@@ -3,6 +3,17 @@
3
3
  // request id. Control frames are JSON (WS text); body chunks are binary (WS
4
4
  // binary) prefixed with the id, so large payloads and SSE stream without base64
5
5
  // overhead. Shared by the relay (open.book.pub) and the tunnel client below.
6
+ /**
7
+ * Marks a request as having arrived through the tunnel — i.e. an EXPOSED inbound
8
+ * request, not a loopback/IPC one (OB-209). Forwarding is an outbound tunnel: the
9
+ * instance stays on loopback, so a forwarded request bypasses the boot exposure
10
+ * backstop (`assertExposureSafe`, which only guards a listener bind). The tunnel
11
+ * client SETS this on every request it forwards (overriding any inbound value — it
12
+ * is never client-supplied), so the origin can recognise the exposed path and fail
13
+ * closed while the instance is still unclaimed (where `authorize()` rule-0 would
14
+ * otherwise serve anonymous world-write). Loopback requests never carry it.
15
+ */
16
+ export const FORWARDED_HEADER = 'X-OpenBook-Forwarded';
6
17
  export function encodeControl(frame) {
7
18
  return JSON.stringify(frame);
8
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tunnelProtocol.js","sourceRoot":"","sources":["../../src/forwarding/tunnelProtocol.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,6EAA6E;AAC7E,4EAA4E;AAC5E,gFAAgF;AAChF,6EAA6E;AAiB7E,MAAM,UAAU,aAAa,CAAC,KAAmB;IAC/C,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAiB,CAAC;QAC3C,OAAO,CAAC,IAAI,OAAQ,CAAmB,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,UAAU,CAAC,EAAU,EAAE,KAAiB;IACtD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IACvD,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAClB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAe;IACxC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACtE,OAAO,EAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAC,CAAC;AAChE,CAAC"}
1
+ {"version":3,"file":"tunnelProtocol.js","sourceRoot":"","sources":["../../src/forwarding/tunnelProtocol.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,6EAA6E;AAC7E,4EAA4E;AAC5E,gFAAgF;AAChF,6EAA6E;AAE7E;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;AAiBvD,MAAM,UAAU,aAAa,CAAC,KAAmB;IAC/C,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAiB,CAAC;QAC3C,OAAO,CAAC,IAAI,OAAQ,CAAmB,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,UAAU,CAAC,EAAU,EAAE,KAAiB;IACtD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IACvD,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAClB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAe;IACxC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACtE,OAAO,EAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Verifiable user identity for multi-user OpenBook (OB-165).
3
+ *
4
+ * A user proves who they are with a compact **JWS** (JSON Web Signature) signed
5
+ * by a trusted **issuer** (account.book.pub, or any federated issuer) using
6
+ * **Ed25519 / `alg: EdDSA`** — the same primitive the forwarding site keys and
7
+ * plugin provenance already use, so this adds no dependency. The data server
8
+ * verifies the assertion against the issuer's published JWKS (which it caches,
9
+ * so verification works offline and on any federated instance), then attributes
10
+ * every change to the resulting {@link Principal}.
11
+ *
12
+ * Design: see `docs/multi-user-and-backups-2026-06.md`. This module is
13
+ * isomorphic (Web Crypto only) so it runs in the server, the desktop app, the
14
+ * web shell, and tests alike.
15
+ */
16
+ /** How an actor's identity was established for a given request/change. */
17
+ export type VerifiedVia =
18
+ /** A fresh, signature-verified identity JWS from a trusted issuer. */
19
+ 'jws'
20
+ /** Unauthenticated (or self-named) guest. */
21
+ | 'guest'
22
+ /** A well-formed JWS that no longer verifies fresh (e.g. expired while
23
+ * offline). The claimed identity is recorded but flagged as not vouched-for. */
24
+ | 'unverified'
25
+ /** Attribution carried in from another instance via the sync/merge path
26
+ * (OB-170) — vouched for by the originating instance, not re-verified here. */
27
+ | 'synced'
28
+ /** In-process caller (the embedded `LocalDataClient`) — implicitly the local
29
+ * owner; there is no request to carry a credential. */
30
+ | 'local';
31
+ export type PrincipalKind = 'user' | 'guest';
32
+ /** The actor behind a request, resolved by the server and stamped onto changes. */
33
+ export interface Principal {
34
+ kind: PrincipalKind;
35
+ /** Stable, globally-meaningful id. Users: `iss#sub`. Guests: `guest:<name|anon>`. */
36
+ subject: string;
37
+ /** The issuer URL that vouched for a user (empty for guests/local). */
38
+ issuer: string;
39
+ /** Human-readable display name, when known. */
40
+ name: string;
41
+ /**
42
+ * The single **active-persona email** (lowercased), when the issuer asserts one
43
+ * (OB-182 §1.1/§3). Net-new threading from the verified `email` claim — there is
44
+ * never an `emails[]` array (Fork 4/5): one token carries exactly one persona
45
+ * facet. Only ever *trusted* for persona / email-ACL matching when the principal
46
+ * is `verifiedVia==='jws'` AND `issuer === config.emailAuthority` (the
47
+ * `emailIsAuthoritative` gate, B1); on any other principal it is at most an
48
+ * attribution hint. Absent when the issuer asserts no email. */
49
+ email?: string;
50
+ verifiedVia: VerifiedVia;
51
+ /** Which signed credential authorized this (users only): issuer key id + assertion id. */
52
+ assertion?: {
53
+ kid?: string;
54
+ jti?: string;
55
+ };
56
+ }
57
+ /** A guest principal with an optional display name. */
58
+ export declare function guestPrincipal(name?: string): Principal;
59
+ /** The implicit local owner (in-process / loopback desktop). */
60
+ export declare function localPrincipal(name?: string): Principal;
61
+ /** Stable short id for a principal — the value embedded in CRDT edit origins. */
62
+ export declare function principalId(p: Principal): string;
63
+ /** JOSE header of an identity assertion. */
64
+ export interface IdentityHeader {
65
+ alg: 'EdDSA';
66
+ typ?: string;
67
+ /** Issuer key id — selects the verifying key from the issuer's JWKS. */
68
+ kid?: string;
69
+ }
70
+ /** Claims carried by an identity assertion (a JWT-shaped payload). */
71
+ export interface IdentityClaims {
72
+ /** Issuer URL (the authenticating source). */
73
+ iss: string;
74
+ /** Stable user id within the issuer. */
75
+ sub: string;
76
+ /** Display name. */
77
+ name?: string;
78
+ /** Email, when the issuer chooses to assert it. */
79
+ email?: string;
80
+ /** Issued-at (epoch seconds). */
81
+ iat?: number;
82
+ /** Expiry (epoch seconds). */
83
+ exp?: number;
84
+ /** Not-before (epoch seconds). */
85
+ nbf?: number;
86
+ /** Unique assertion id — recorded with each change for traceability. */
87
+ jti?: string;
88
+ /**
89
+ * Audience — the data server this assertion is scoped to (OB-177). When
90
+ * present, a verifier MUST reject the token unless `aud` names *itself*, so a
91
+ * server the user connected to can't replay their identity to a different
92
+ * server (confused-deputy / token redirection). Absent on unscoped tokens
93
+ * (the single-server model, where exactly one server trusts the issuer).
94
+ */
95
+ aud?: string;
96
+ }
97
+ /** An Ed25519 public key in JWK form (`kty:'OKP'`, raw 32-byte `x`, base64url). */
98
+ export interface Jwk {
99
+ kty: 'OKP';
100
+ crv: 'Ed25519';
101
+ /** Raw 32-byte public key, base64url. */
102
+ x: string;
103
+ kid?: string;
104
+ use?: 'sig';
105
+ alg?: 'EdDSA';
106
+ }
107
+ /** A set of public keys an issuer publishes (the cached, offline-verifiable set). */
108
+ export interface Jwks {
109
+ keys: Jwk[];
110
+ }
111
+ /** An issuer signing keypair (dev/test issuer, or the account service). */
112
+ export interface IdentityKeypair {
113
+ /** The public key as a JWK (publish in the JWKS). */
114
+ publicJwk: Jwk;
115
+ /** PKCS#8 private key, base64url — kept secret by the issuer. */
116
+ privateKey: string;
117
+ }
118
+ /**
119
+ * Mint a fresh issuer keypair (Ed25519). Used by the dev issuer and tests; the
120
+ * real issuer (account.book.pub) holds the equivalent and rotates `kid`s.
121
+ */
122
+ export declare function mintIdentityKeypair(kid?: string): Promise<IdentityKeypair>;
123
+ /**
124
+ * Sign an identity assertion (issuer side / dev / tests). Produces a compact
125
+ * EdDSA JWS: `base64url(header).base64url(claims).base64url(sig)`.
126
+ */
127
+ export declare function signIdentity(privateKeyPkcs8: string, claims: IdentityClaims, kid?: string): Promise<string>;
128
+ /**
129
+ * Decode an assertion's header + claims **without** verifying the signature.
130
+ * For client-side display, and for the server's "claimed-but-unverified"
131
+ * provenance fallback. Never use this to make a trust decision.
132
+ */
133
+ export declare function decodeIdentity(jws: string): {
134
+ header: IdentityHeader;
135
+ claims: IdentityClaims;
136
+ } | null;
137
+ /** Reason an assertion failed to verify (for logging / the unverified fallback). */
138
+ export type VerifyFailure = 'malformed' | 'unsupported-alg' | 'unknown-key' | 'bad-signature' | 'expired' | 'not-yet-valid' | 'untrusted-issuer' | 'wrong-audience';
139
+ export type VerifyResult = {
140
+ ok: true;
141
+ claims: IdentityClaims;
142
+ header: IdentityHeader;
143
+ } | {
144
+ ok: false;
145
+ reason: VerifyFailure;
146
+ claims?: IdentityClaims;
147
+ };
148
+ export interface VerifyOptions {
149
+ /** Allowed clock skew, in seconds (covers minor offsets + short offline). Default 60. */
150
+ clockToleranceSec?: number;
151
+ /** Current time in epoch ms (injectable for tests). Default `Date.now()`. */
152
+ nowMs?: number;
153
+ /** If set, the `iss` claim must be one of these (issuer-rooted federation). */
154
+ allowedIssuers?: string[];
155
+ /**
156
+ * This data server's own audience identifier (OB-177). When a token carries an
157
+ * `aud`, it must equal this — otherwise the token was scoped to a *different*
158
+ * server and is rejected (`wrong-audience`). Leave unset only for the
159
+ * single-server model, where the issuer never sets `aud`.
160
+ */
161
+ audience?: string;
162
+ /**
163
+ * Require every token to be audience-bound to {@link audience}: an unscoped
164
+ * (no-`aud`) token is rejected. Set on a multi-server deployment so a server
165
+ * can't be handed an unscoped, freely-replayable assertion.
166
+ */
167
+ requireAudience?: boolean;
168
+ }
169
+ /**
170
+ * Verify an identity assertion against an issuer's JWKS. Pure + offline: the
171
+ * caller supplies the (cached) key set, so no network call happens here.
172
+ *
173
+ * Returns `{ok:true, claims}` only on a fresh, signature-valid, in-window,
174
+ * trusted-issuer assertion. On failure returns a reason (and the decoded claims
175
+ * when they parsed, so the server can record a claimed-but-unverified identity).
176
+ */
177
+ export declare function verifyIdentity(jws: string, jwks: Jwks, opts?: VerifyOptions): Promise<VerifyResult>;
178
+ /** Build a verified user principal from validated claims. */
179
+ export declare function principalFromClaims(claims: IdentityClaims, header?: IdentityHeader): Principal;
180
+ /**
181
+ * Build a claimed-but-unverified principal from an assertion that parsed but
182
+ * didn't verify fresh (e.g. expired while offline). Provenance still names the
183
+ * claimed subject, flagged `unverified`.
184
+ */
185
+ export declare function unverifiedPrincipalFromClaims(claims: IdentityClaims): Principal;
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Verifiable user identity for multi-user OpenBook (OB-165).
3
+ *
4
+ * A user proves who they are with a compact **JWS** (JSON Web Signature) signed
5
+ * by a trusted **issuer** (account.book.pub, or any federated issuer) using
6
+ * **Ed25519 / `alg: EdDSA`** — the same primitive the forwarding site keys and
7
+ * plugin provenance already use, so this adds no dependency. The data server
8
+ * verifies the assertion against the issuer's published JWKS (which it caches,
9
+ * so verification works offline and on any federated instance), then attributes
10
+ * every change to the resulting {@link Principal}.
11
+ *
12
+ * Design: see `docs/multi-user-and-backups-2026-06.md`. This module is
13
+ * isomorphic (Web Crypto only) so it runs in the server, the desktop app, the
14
+ * web shell, and tests alike.
15
+ */
16
+ import { b64uDecode, b64uEncode, b64uDecodeString, b64uEncodeString, utf8 } from './forwarding/encoding';
17
+ const ED25519 = { name: 'Ed25519' };
18
+ /** A guest principal with an optional display name. */
19
+ export function guestPrincipal(name = '') {
20
+ const label = name.trim();
21
+ return {
22
+ kind: 'guest',
23
+ subject: label ? `guest:${label}` : 'guest:anonymous',
24
+ issuer: '',
25
+ name: label,
26
+ verifiedVia: 'guest',
27
+ };
28
+ }
29
+ /** The implicit local owner (in-process / loopback desktop). */
30
+ export function localPrincipal(name = 'Local') {
31
+ return { kind: 'user', subject: 'local:owner', issuer: 'local', name, verifiedVia: 'local' };
32
+ }
33
+ /** Stable short id for a principal — the value embedded in CRDT edit origins. */
34
+ export function principalId(p) {
35
+ return p.subject;
36
+ }
37
+ /**
38
+ * Mint a fresh issuer keypair (Ed25519). Used by the dev issuer and tests; the
39
+ * real issuer (account.book.pub) holds the equivalent and rotates `kid`s.
40
+ */
41
+ export async function mintIdentityKeypair(kid = 'dev-1') {
42
+ const kp = (await crypto.subtle.generateKey(ED25519, true, ['sign', 'verify']));
43
+ const raw = new Uint8Array(await crypto.subtle.exportKey('raw', kp.publicKey));
44
+ const priv = new Uint8Array(await crypto.subtle.exportKey('pkcs8', kp.privateKey));
45
+ return {
46
+ publicJwk: { kty: 'OKP', crv: 'Ed25519', x: b64uEncode(raw), kid, use: 'sig', alg: 'EdDSA' },
47
+ privateKey: b64uEncode(priv),
48
+ };
49
+ }
50
+ /**
51
+ * Sign an identity assertion (issuer side / dev / tests). Produces a compact
52
+ * EdDSA JWS: `base64url(header).base64url(claims).base64url(sig)`.
53
+ */
54
+ export async function signIdentity(privateKeyPkcs8, claims, kid) {
55
+ const header = { alg: 'EdDSA', typ: 'JWT', ...(kid ? { kid } : {}) };
56
+ const signingInput = `${b64uEncodeString(JSON.stringify(header))}.${b64uEncodeString(JSON.stringify(claims))}`;
57
+ const key = await crypto.subtle.importKey('pkcs8', b64uDecode(privateKeyPkcs8), ED25519, false, ['sign']);
58
+ const sig = await crypto.subtle.sign(ED25519, key, utf8(signingInput));
59
+ return `${signingInput}.${b64uEncode(new Uint8Array(sig))}`;
60
+ }
61
+ /**
62
+ * Decode an assertion's header + claims **without** verifying the signature.
63
+ * For client-side display, and for the server's "claimed-but-unverified"
64
+ * provenance fallback. Never use this to make a trust decision.
65
+ */
66
+ export function decodeIdentity(jws) {
67
+ const parts = jws.split('.');
68
+ if (parts.length !== 3)
69
+ return null;
70
+ try {
71
+ const header = JSON.parse(b64uDecodeString(parts[0]));
72
+ const claims = JSON.parse(b64uDecodeString(parts[1]));
73
+ if (!claims || typeof claims.iss !== 'string' || typeof claims.sub !== 'string')
74
+ return null;
75
+ return { header, claims };
76
+ }
77
+ catch {
78
+ return null;
79
+ }
80
+ }
81
+ /**
82
+ * Verify an identity assertion against an issuer's JWKS. Pure + offline: the
83
+ * caller supplies the (cached) key set, so no network call happens here.
84
+ *
85
+ * Returns `{ok:true, claims}` only on a fresh, signature-valid, in-window,
86
+ * trusted-issuer assertion. On failure returns a reason (and the decoded claims
87
+ * when they parsed, so the server can record a claimed-but-unverified identity).
88
+ */
89
+ export async function verifyIdentity(jws, jwks, opts = {}) {
90
+ const decoded = decodeIdentity(jws);
91
+ if (!decoded)
92
+ return { ok: false, reason: 'malformed' };
93
+ const { header, claims } = decoded;
94
+ if (header.alg !== 'EdDSA')
95
+ return { ok: false, reason: 'unsupported-alg', claims };
96
+ if (opts.allowedIssuers && !opts.allowedIssuers.includes(claims.iss)) {
97
+ return { ok: false, reason: 'untrusted-issuer', claims };
98
+ }
99
+ // Pick candidate keys: the kid-matched one, else every key (kid is a hint).
100
+ const candidates = header.kid ? jwks.keys.filter((k) => k.kid === header.kid) : jwks.keys;
101
+ if (candidates.length === 0)
102
+ return { ok: false, reason: 'unknown-key', claims };
103
+ const parts = jws.split('.');
104
+ const signingInput = utf8(`${parts[0]}.${parts[1]}`);
105
+ const sig = b64uDecode(parts[2]);
106
+ let verified = false;
107
+ for (const jwk of candidates) {
108
+ try {
109
+ const key = await crypto.subtle.importKey('raw', b64uDecode(jwk.x), ED25519, false, ['verify']);
110
+ if (await crypto.subtle.verify(ED25519, key, sig, signingInput)) {
111
+ verified = true;
112
+ break;
113
+ }
114
+ }
115
+ catch {
116
+ // Malformed key — try the next candidate.
117
+ }
118
+ }
119
+ if (!verified)
120
+ return { ok: false, reason: 'bad-signature', claims };
121
+ // Time window (after the signature is proven, so we can distinguish expired
122
+ // from forged). Tolerance covers clock skew and short offline spells.
123
+ const tol = opts.clockToleranceSec ?? 60;
124
+ const now = Math.floor((opts.nowMs ?? Date.now()) / 1000);
125
+ if (typeof claims.nbf === 'number' && now + tol < claims.nbf) {
126
+ return { ok: false, reason: 'not-yet-valid', claims };
127
+ }
128
+ if (typeof claims.exp === 'number' && now - tol > claims.exp) {
129
+ return { ok: false, reason: 'expired', claims };
130
+ }
131
+ // Audience binding (OB-177). A scoped token must name THIS server; an unscoped
132
+ // token is accepted only when the server doesn't demand scoping. Checked after
133
+ // the signature so a forged `aud` can't pass — `aud` is inside the signed payload.
134
+ if (typeof claims.aud === 'string' && claims.aud.length > 0) {
135
+ if (!opts.audience || claims.aud !== opts.audience) {
136
+ return { ok: false, reason: 'wrong-audience', claims };
137
+ }
138
+ }
139
+ else if (opts.requireAudience) {
140
+ return { ok: false, reason: 'wrong-audience', claims };
141
+ }
142
+ return { ok: true, claims, header };
143
+ }
144
+ /** The active-persona email (lowercased) carried by an assertion, if any. */
145
+ function personaEmail(claims) {
146
+ const email = claims.email?.trim().toLowerCase();
147
+ return email ? email : undefined;
148
+ }
149
+ /** Build a verified user principal from validated claims. */
150
+ export function principalFromClaims(claims, header) {
151
+ const email = personaEmail(claims);
152
+ return {
153
+ kind: 'user',
154
+ subject: `${claims.iss}#${claims.sub}`,
155
+ issuer: claims.iss,
156
+ name: claims.name ?? '',
157
+ ...(email ? { email } : {}),
158
+ verifiedVia: 'jws',
159
+ assertion: { kid: header?.kid, jti: claims.jti },
160
+ };
161
+ }
162
+ /**
163
+ * Build a claimed-but-unverified principal from an assertion that parsed but
164
+ * didn't verify fresh (e.g. expired while offline). Provenance still names the
165
+ * claimed subject, flagged `unverified`.
166
+ */
167
+ export function unverifiedPrincipalFromClaims(claims) {
168
+ const email = personaEmail(claims);
169
+ return {
170
+ kind: 'user',
171
+ subject: `${claims.iss}#${claims.sub}`,
172
+ issuer: claims.iss,
173
+ name: claims.name ?? '',
174
+ // Carried for attribution only — an unverified principal is never `jws`, so
175
+ // `emailIsAuthoritative` is false and this email never drives a grant (B1/N8).
176
+ ...(email ? { email } : {}),
177
+ verifiedVia: 'unverified',
178
+ assertion: { jti: claims.jti },
179
+ };
180
+ }
181
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,23 +1,27 @@
1
- export type { PageSnapshot, PageMeta, StoredPage, PageInput, ServerInfo, ServerControls } from './types';
2
- export { emptyPageSnapshot } from './types';
3
- export { API, type ApiError } from './routes';
4
- export type { DataClient, PageSubscription, FetchLike, LiveSourceLike, HttpDataClientOptions } from './client';
1
+ export type { PageSnapshot, PageMeta, StoredPage, PageInput, ServerInfo, ServerControls, PageVisibility, Visibility, MemberRole, MemberStatus, MemberSource, AclLevel, Member, PageAcl, } from './types';
2
+ export { emptyPageSnapshot, PAGE_VISIBILITIES } from './types';
3
+ export { API, type ApiError, type CompactResult } from './routes';
4
+ export type { DataClient, PageSubscription, FetchLike, LiveSourceLike, HttpDataClientOptions, IdentityCredential } from './client';
5
5
  export { HttpDataClient } from './client';
6
- export { ForwardingClient, TunnelClient, MemoryKeyStore, mintSiteKeypair, signWithSiteKey, type KeyStore, type SiteIdentity, type ForwardingClientOptions, type TunnelStatus, } from './forwarding';
6
+ export { ForwardingClient, TunnelClient, MemoryKeyStore, mintSiteKeypair, signWithSiteKey, verifyWithSiteKey, FORWARDED_HEADER, signRosterAssertion, verifyRosterAssertion, ROSTER_ASSERTION_VERSION, ROSTER_ASSERTION_SKEW_MS, type KeyStore, type SiteIdentity, type ForwardingClientOptions, type TunnelStatus, type RosterAssertionPayload, type SignRosterAssertionInput, type VerifyRosterAssertionInput, } from './forwarding';
7
7
  export type { DatabasePropertyType, NumberFormat, NumberDisplay, StatusGroup, RollupFunction, RollupConfig, RelationCardinality, DatabaseSelectOption, DatabaseProperty, DateRange, LocationValue, PropertyGroup, RowTemplate, DatabaseViewType, ChartAggregate, SummaryType, FilterOperator, FilterConjunction, DatabaseFilter, DatabaseFilterGroup, FilterNode, SortDirection, DatabaseSort, DatabaseView, DatabaseMetric, ColorRule, DatabaseSchema, StoredDatabase, DatabaseInput, DatabaseUpdate, DatabaseRow, RowInput, RowUpdate, RowGroup, ChartDatum, ChartSeries, ChartSegment, ChartGroup, ChartMatrix, DateSpan, GraphNode, GraphEdge, DependencyGraph, InverseUpdate, RowTreeNode, } from './database';
8
8
  export { TITLE_PROPERTY_ID, SELECT_COLORS, NO_VALUE_GROUP, STATUS_GROUPS, RELATIVE_DATE_OPS, projectExports, rowValue, matchesFilter, rowMatchesCondition, applyView, viewFilterRoot, isFilterGroup, shortId, defaultDatabaseSchema, defaultView, defaultStatusOptions, removeProperty, formatNumber, formatUniqueId, numberProgress, groupRows, groupRowsBy, groupRowsByParent, PARENT_GROUP_ID, NO_PARENT_GROUP, aggregateRows, aggregateMatrix, CHART_TOTAL_SERIES, summarizeColumn, dateStart, dateEnd, parseDay, rowDateSpan, rowLocation, asLocation, dependencyGraph, syncInverseUpdates, relationSides, buildRowTree, flattenRowTree, isImageUrl, firstImageUrl, coverImageUrl, } from './database';
9
9
  export { evaluateFormula, formulaReferences, FormulaError, type FormulaValue, type FormulaResolver, } from './formula';
10
10
  export { OWNER_PROPERTY_ID, VERIFICATION_PROPERTY_ID, BACKLINKS_PROPERTY_ID, THEME_PROPERTY_ID, COVER_PROPERTY_ID, FONTS_PROPERTY_ID, ICON_PROPERTY_ID, FULLWIDTH_PROPERTY_ID, SYSTEM_PAGE_PROPERTIES, isVerified, verificationExpired, isVerificationActive, makeVerification, extractMentionIds, propertiesReferencePage, type VerificationValue, } from './pageProperties';
11
- export { getServerUrlOverride, setServerUrlOverride, getServerTokenOverride, setServerTokenOverride, isMixedContentBlocked } from './connection';
11
+ export { getServerUrlOverride, setServerUrlOverride, getServerTokenOverride, setServerTokenOverride, getIdentityCredential, setIdentityToken, setGuestName, getForwardingAudience, setForwardingAudience, isMixedContentBlocked } from './connection';
12
12
  export { AccountClient, AccountError, DEFAULT_ACCOUNT_URL, getAccountUrlOverride, setAccountUrlOverride, resolveAccountUrl, type AccountSettings, } from './account';
13
+ export { guestPrincipal, localPrincipal, principalId, mintIdentityKeypair, signIdentity, decodeIdentity, verifyIdentity, principalFromClaims, unverifiedPrincipalFromClaims, type Principal, type PrincipalKind, type VerifiedVia, type IdentityHeader, type IdentityClaims, type Jwk, type Jwks, type IdentityKeypair, type VerifyOptions, type VerifyResult, type VerifyFailure, } from './identity';
14
+ export { DEFAULT_INSTANCE_CONFIG, type GuestAccess, type TrustedIssuerConfig, type InstanceConfig, type InstanceInfo, type StoredEdit, type WorkspaceBinding, type WorkspaceRoster, type WorkspaceRosterEntry, } from './provenance';
15
+ export { authorize, isEmailAuthoritative, type Role, type EffectiveVisibility, type AclEntry, type AccessPage, type AccessCtx, type Decision, } from './authorize';
13
16
  export { snapshotText, paragraphBlocks, textSnapshot, appendTextToSnapshot, appendBlocksToSnapshot, type AppendBlock } from './content';
14
17
  export { snapshotBlocks, contentHash, computeBlockMtimes, stampSnapshotMtimes, latestBlockMtime, type BlockDigest, } from './mtime';
18
+ export { computeBlockAuthors, stampSnapshotAuthors, latestSnapshotAuthor } from './authors';
15
19
  export { pageToBookHtml, bookHtmlToPage, readBookHtmlMeta, slugify, type BookPageRecord, } from './bookfile';
16
20
  export { spaceToBookFiles, parseBookFolder, SPACE_BUNDLE_FILE, type BookFolderFile, type SpaceSnapshot, } from './bookFolder';
17
21
  export { canonicalDigest, generateRegistryKeys, signPlugin, verifyPlugin, validateManifest, OPENBOOK_REGISTRY, type PluginManifest, type PluginAgentTool, type PluginPackage, type PluginSignature, type StoredPlugin, } from './plugins';
18
22
  export { buildSampleDocument, seedSampleDocument, SAMPLE_DOCUMENT_NAME } from './sampleDocument';
19
- export type { CommentRun, SuggestionAuthorKind, SuggestionKind, SuggestionStatus, SuggestionTarget, StoredSuggestion, SuggestionInput, SuggestionUpdate, StoredComment, CommentInput, } from './suggestions';
23
+ export type { CommentRun, AuthoredIdentity, SuggestionAuthorKind, SuggestionKind, SuggestionStatus, SuggestionTarget, StoredSuggestion, SuggestionInput, SuggestionUpdate, StoredComment, CommentInput, } from './suggestions';
20
24
  export { PAGE_TEMPLATES, instantiateTemplate, type PageTemplate } from './templates';
21
- export { BACKUP_VERSION, remapBundle, type SpaceBackup, type ImportMode, type ImportRequest, type ImportResult, } from './backup';
25
+ export { BACKUP_VERSION, BACKUP_CADENCES, BACKUP_CADENCE_MS, DEFAULT_BACKUP_CONFIG, remapBundle, type SpaceBackup, type ImportMode, type ImportRequest, type ImportResult, type BackupCadence, type BackupConfig, type BackupCadenceStatus, type BackupStatus, } from './backup';
22
26
  export type { AgentChatEvent, AgentChatMessage, AgentChatOptions, AgentProposal, InterviewStep, AiProvider, AiConfig, AiProviderSettings, AiEffort, AiSkill, AiStatus, AiSearchResult, AiSearchResponse, AiTasksResponse, AiStreamEvent, } from './ai';
23
- export { providerSettings } from './ai';
27
+ export { providerSettings, isPaidProvider } from './ai';