jazz-tools 2.0.0-alpha.34 → 2.0.0-alpha.35

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 (292) hide show
  1. package/bin/docs-index.db +0 -0
  2. package/bin/docs-index.txt +111 -59
  3. package/bin/native/jazz-tools-darwin-arm64 +0 -0
  4. package/bin/native/jazz-tools-darwin-x64 +0 -0
  5. package/bin/native/jazz-tools-linux-arm64 +0 -0
  6. package/bin/native/jazz-tools-linux-x64 +0 -0
  7. package/dist/backend/create-jazz-context.d.ts +4 -0
  8. package/dist/backend/create-jazz-context.d.ts.map +1 -1
  9. package/dist/backend/create-jazz-context.js +6 -5
  10. package/dist/backend/create-jazz-context.js.map +1 -1
  11. package/dist/backend/create-jazz-context.test.js +49 -3
  12. package/dist/backend/create-jazz-context.test.js.map +1 -1
  13. package/dist/backend/index.d.ts +1 -1
  14. package/dist/backend/index.d.ts.map +1 -1
  15. package/dist/backend/index.js.map +1 -1
  16. package/dist/backend/request-auth.d.ts +2 -0
  17. package/dist/backend/request-auth.d.ts.map +1 -1
  18. package/dist/backend/request-auth.js +96 -15
  19. package/dist/backend/request-auth.js.map +1 -1
  20. package/dist/backend/request-auth.test.js +34 -6
  21. package/dist/backend/request-auth.test.js.map +1 -1
  22. package/dist/cli.d.ts +4 -0
  23. package/dist/cli.d.ts.map +1 -1
  24. package/dist/cli.js +83 -39
  25. package/dist/cli.js.map +1 -1
  26. package/dist/cli.test.js +199 -76
  27. package/dist/cli.test.js.map +1 -1
  28. package/dist/codegen/schema-reader.d.ts.map +1 -1
  29. package/dist/codegen/schema-reader.js +14 -0
  30. package/dist/codegen/schema-reader.js.map +1 -1
  31. package/dist/dev/dev-server.d.ts.map +1 -1
  32. package/dist/dev/dev-server.js +3 -0
  33. package/dist/dev/dev-server.js.map +1 -1
  34. package/dist/dev/expo.test.js +1 -1
  35. package/dist/dev/expo.test.js.map +1 -1
  36. package/dist/dev/inspector-link.d.ts +2 -0
  37. package/dist/dev/inspector-link.d.ts.map +1 -0
  38. package/dist/dev/inspector-link.js +10 -0
  39. package/dist/dev/inspector-link.js.map +1 -0
  40. package/dist/dev/managed-runtime.d.ts.map +1 -1
  41. package/dist/dev/managed-runtime.js +10 -1
  42. package/dist/dev/managed-runtime.js.map +1 -1
  43. package/dist/dev/next.d.ts.map +1 -1
  44. package/dist/dev/next.js +6 -0
  45. package/dist/dev/next.js.map +1 -1
  46. package/dist/dev/next.test.js +3 -1
  47. package/dist/dev/next.test.js.map +1 -1
  48. package/dist/dev/sveltekit.d.ts +9 -0
  49. package/dist/dev/sveltekit.d.ts.map +1 -1
  50. package/dist/dev/sveltekit.js +6 -0
  51. package/dist/dev/sveltekit.js.map +1 -1
  52. package/dist/dev/sveltekit.test.js +15 -1
  53. package/dist/dev/sveltekit.test.js.map +1 -1
  54. package/dist/dev/vite.d.ts.map +1 -1
  55. package/dist/dev/vite.js +2 -0
  56. package/dist/dev/vite.js.map +1 -1
  57. package/dist/dev/vite.test.js +4 -2
  58. package/dist/dev/vite.test.js.map +1 -1
  59. package/dist/dev-tools/extension-panel.d.ts.map +1 -1
  60. package/dist/dev-tools/extension-panel.js.map +1 -1
  61. package/dist/dev-tools/protocol.d.ts.map +1 -1
  62. package/dist/dev-tools/protocol.js +0 -1
  63. package/dist/dev-tools/protocol.js.map +1 -1
  64. package/dist/drivers/types.d.ts +2 -0
  65. package/dist/drivers/types.d.ts.map +1 -1
  66. package/dist/dsl.d.ts +8 -1
  67. package/dist/dsl.d.ts.map +1 -1
  68. package/dist/dsl.js +54 -0
  69. package/dist/dsl.js.map +1 -1
  70. package/dist/dsl.test.js +73 -0
  71. package/dist/dsl.test.js.map +1 -1
  72. package/dist/expo/auth-secret-store.d.ts +2 -1
  73. package/dist/expo/auth-secret-store.d.ts.map +1 -1
  74. package/dist/expo/auth-secret-store.js +1 -0
  75. package/dist/expo/auth-secret-store.js.map +1 -1
  76. package/dist/expo/index.d.ts +3 -0
  77. package/dist/expo/index.d.ts.map +1 -0
  78. package/dist/expo/index.js +3 -0
  79. package/dist/expo/index.js.map +1 -0
  80. package/dist/expo/use-local-first-auth.d.ts +3 -0
  81. package/dist/expo/use-local-first-auth.d.ts.map +1 -0
  82. package/dist/expo/use-local-first-auth.js +4 -0
  83. package/dist/expo/use-local-first-auth.js.map +1 -0
  84. package/dist/index.d.ts +1 -1
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js.map +1 -1
  87. package/dist/mcp/build-index.test.js +1 -1
  88. package/dist/mcp/build-index.test.js.map +1 -1
  89. package/dist/permissions/index.d.ts +3 -0
  90. package/dist/permissions/index.d.ts.map +1 -1
  91. package/dist/permissions/index.js +2 -1
  92. package/dist/permissions/index.js.map +1 -1
  93. package/dist/permissions/type-inference.test.js +23 -2
  94. package/dist/permissions/type-inference.test.js.map +1 -1
  95. package/dist/react/create-jazz-client.integration.test.js +5 -2
  96. package/dist/react/create-jazz-client.integration.test.js.map +1 -1
  97. package/dist/react/create-jazz-client.test.js +6 -1
  98. package/dist/react/create-jazz-client.test.js.map +1 -1
  99. package/dist/react/index.d.ts +2 -0
  100. package/dist/react/index.d.ts.map +1 -1
  101. package/dist/react/index.js +2 -0
  102. package/dist/react/index.js.map +1 -1
  103. package/dist/react/provider.d.ts +2 -1
  104. package/dist/react/provider.d.ts.map +1 -1
  105. package/dist/react/provider.js +2 -2
  106. package/dist/react/provider.js.map +1 -1
  107. package/dist/react/use-local-first-auth.d.ts +3 -0
  108. package/dist/react/use-local-first-auth.d.ts.map +1 -0
  109. package/dist/react/use-local-first-auth.js +4 -0
  110. package/dist/react/use-local-first-auth.js.map +1 -0
  111. package/dist/react-core/index.d.ts +2 -0
  112. package/dist/react-core/index.d.ts.map +1 -1
  113. package/dist/react-core/index.js +2 -0
  114. package/dist/react-core/index.js.map +1 -1
  115. package/dist/react-core/provider.d.ts +7 -3
  116. package/dist/react-core/provider.d.ts.map +1 -1
  117. package/dist/react-core/provider.js +67 -51
  118. package/dist/react-core/provider.js.map +1 -1
  119. package/dist/react-core/provider.onjwtexpired.test.d.ts +2 -0
  120. package/dist/react-core/provider.onjwtexpired.test.d.ts.map +1 -0
  121. package/dist/react-core/provider.onjwtexpired.test.js +47 -0
  122. package/dist/react-core/provider.onjwtexpired.test.js.map +1 -0
  123. package/dist/react-core/test-utils.d.ts +20 -0
  124. package/dist/react-core/test-utils.d.ts.map +1 -0
  125. package/dist/react-core/test-utils.js +34 -0
  126. package/dist/react-core/test-utils.js.map +1 -0
  127. package/dist/react-core/use-auth-state.d.ts +10 -0
  128. package/dist/react-core/use-auth-state.d.ts.map +1 -0
  129. package/dist/react-core/use-auth-state.js +14 -0
  130. package/dist/react-core/use-auth-state.js.map +1 -0
  131. package/dist/react-core/use-auth-state.test.d.ts +2 -0
  132. package/dist/react-core/use-auth-state.test.d.ts.map +1 -0
  133. package/dist/react-core/use-auth-state.test.js +42 -0
  134. package/dist/react-core/use-auth-state.test.js.map +1 -0
  135. package/dist/react-core/use-local-first-auth.d.ts +9 -0
  136. package/dist/react-core/use-local-first-auth.d.ts.map +1 -0
  137. package/dist/react-core/use-local-first-auth.js +54 -0
  138. package/dist/react-core/use-local-first-auth.js.map +1 -0
  139. package/dist/react-core/use-local-first-auth.test.d.ts +2 -0
  140. package/dist/react-core/use-local-first-auth.test.d.ts.map +1 -0
  141. package/dist/react-core/use-local-first-auth.test.js +78 -0
  142. package/dist/react-core/use-local-first-auth.test.js.map +1 -0
  143. package/dist/react-native/create-jazz-client.test.js +4 -2
  144. package/dist/react-native/create-jazz-client.test.js.map +1 -1
  145. package/dist/react-native/create-jazz-rn-runtime.d.ts.map +1 -1
  146. package/dist/react-native/create-jazz-rn-runtime.js.map +1 -1
  147. package/dist/react-native/db.d.ts.map +1 -1
  148. package/dist/react-native/db.js +3 -4
  149. package/dist/react-native/db.js.map +1 -1
  150. package/dist/react-native/db.test.js +3 -6
  151. package/dist/react-native/db.test.js.map +1 -1
  152. package/dist/react-native/jazz-rn-runtime-adapter.d.ts +11 -11
  153. package/dist/react-native/jazz-rn-runtime-adapter.d.ts.map +1 -1
  154. package/dist/react-native/jazz-rn-runtime-adapter.js +8 -35
  155. package/dist/react-native/jazz-rn-runtime-adapter.js.map +1 -1
  156. package/dist/react-native/jazz-rn-runtime-adapter.test.js +10 -27
  157. package/dist/react-native/jazz-rn-runtime-adapter.test.js.map +1 -1
  158. package/dist/runtime/anonymous-write-denied-error.d.ts +13 -0
  159. package/dist/runtime/anonymous-write-denied-error.d.ts.map +1 -0
  160. package/dist/runtime/anonymous-write-denied-error.js +58 -0
  161. package/dist/runtime/anonymous-write-denied-error.js.map +1 -0
  162. package/dist/runtime/anonymous-write-denied-error.test.d.ts +2 -0
  163. package/dist/runtime/anonymous-write-denied-error.test.d.ts.map +1 -0
  164. package/dist/runtime/anonymous-write-denied-error.test.js +56 -0
  165. package/dist/runtime/anonymous-write-denied-error.test.js.map +1 -0
  166. package/dist/runtime/auth-secret-store.d.ts +2 -1
  167. package/dist/runtime/auth-secret-store.d.ts.map +1 -1
  168. package/dist/runtime/auth-secret-store.js +1 -0
  169. package/dist/runtime/auth-secret-store.js.map +1 -1
  170. package/dist/runtime/auth-state.d.ts +5 -14
  171. package/dist/runtime/auth-state.d.ts.map +1 -1
  172. package/dist/runtime/auth-state.js +39 -35
  173. package/dist/runtime/auth-state.js.map +1 -1
  174. package/dist/runtime/auth-state.test.js +36 -5
  175. package/dist/runtime/auth-state.test.js.map +1 -1
  176. package/dist/runtime/client-session.d.ts +1 -1
  177. package/dist/runtime/client-session.d.ts.map +1 -1
  178. package/dist/runtime/client-session.js +15 -9
  179. package/dist/runtime/client-session.js.map +1 -1
  180. package/dist/runtime/client-session.test.js +31 -9
  181. package/dist/runtime/client-session.test.js.map +1 -1
  182. package/dist/runtime/client.d.ts +66 -29
  183. package/dist/runtime/client.d.ts.map +1 -1
  184. package/dist/runtime/client.for-request.test.js +122 -20
  185. package/dist/runtime/client.for-request.test.js.map +1 -1
  186. package/dist/runtime/client.js +186 -56
  187. package/dist/runtime/client.js.map +1 -1
  188. package/dist/runtime/client.mutations.test.js +50 -10
  189. package/dist/runtime/client.mutations.test.js.map +1 -1
  190. package/dist/runtime/client.test.js +2 -0
  191. package/dist/runtime/client.test.js.map +1 -1
  192. package/dist/runtime/context.d.ts +7 -3
  193. package/dist/runtime/context.d.ts.map +1 -1
  194. package/dist/runtime/db.anonymous.test.d.ts +2 -0
  195. package/dist/runtime/db.anonymous.test.d.ts.map +1 -0
  196. package/dist/runtime/db.anonymous.test.js +28 -0
  197. package/dist/runtime/db.anonymous.test.js.map +1 -0
  198. package/dist/runtime/db.auth-state.test.js +22 -25
  199. package/dist/runtime/db.auth-state.test.js.map +1 -1
  200. package/dist/runtime/db.browser-storage-scope.test.js +2 -5
  201. package/dist/runtime/db.browser-storage-scope.test.js.map +1 -1
  202. package/dist/runtime/db.d.ts +62 -19
  203. package/dist/runtime/db.d.ts.map +1 -1
  204. package/dist/runtime/db.js +173 -36
  205. package/dist/runtime/db.js.map +1 -1
  206. package/dist/runtime/db.local-first-auth.test.js +13 -3
  207. package/dist/runtime/db.local-first-auth.test.js.map +1 -1
  208. package/dist/runtime/db.persisted.test.js +1 -1
  209. package/dist/runtime/db.persisted.test.js.map +1 -1
  210. package/dist/runtime/db.schema-order.test.js +26 -9
  211. package/dist/runtime/db.schema-order.test.js.map +1 -1
  212. package/dist/runtime/db.transaction.test.js +106 -4
  213. package/dist/runtime/db.transaction.test.js.map +1 -1
  214. package/dist/runtime/db.transport.test.js +4 -5
  215. package/dist/runtime/db.transport.test.js.map +1 -1
  216. package/dist/runtime/file-storage.d.ts +2 -2
  217. package/dist/runtime/file-storage.d.ts.map +1 -1
  218. package/dist/runtime/file-storage.js +1 -1
  219. package/dist/runtime/file-storage.js.map +1 -1
  220. package/dist/runtime/file-storage.test.js +2 -1
  221. package/dist/runtime/file-storage.test.js.map +1 -1
  222. package/dist/runtime/index.d.ts +2 -2
  223. package/dist/runtime/index.d.ts.map +1 -1
  224. package/dist/runtime/index.js +1 -1
  225. package/dist/runtime/index.js.map +1 -1
  226. package/dist/runtime/introspection-fetch.d.ts +0 -1
  227. package/dist/runtime/introspection-fetch.d.ts.map +1 -1
  228. package/dist/runtime/introspection-fetch.js +2 -2
  229. package/dist/runtime/introspection-fetch.js.map +1 -1
  230. package/dist/runtime/napi.auth-failure.test.js +1 -1
  231. package/dist/runtime/napi.auth-failure.test.js.map +1 -1
  232. package/dist/runtime/napi.for-request.test.js +13 -3
  233. package/dist/runtime/napi.for-request.test.js.map +1 -1
  234. package/dist/runtime/napi.integration.test.js +5 -2
  235. package/dist/runtime/napi.integration.test.js.map +1 -1
  236. package/dist/runtime/permissions.repro.test.js +264 -5
  237. package/dist/runtime/permissions.repro.test.js.map +1 -1
  238. package/dist/runtime/recovery-phrase.integration.test.js +2 -2
  239. package/dist/runtime/recovery-phrase.integration.test.js.map +1 -1
  240. package/dist/runtime/runtime-config.d.ts.map +1 -1
  241. package/dist/runtime/runtime-config.js +8 -1
  242. package/dist/runtime/runtime-config.js.map +1 -1
  243. package/dist/runtime/schema-fetch.d.ts +9 -8
  244. package/dist/runtime/schema-fetch.d.ts.map +1 -1
  245. package/dist/runtime/schema-fetch.js +9 -10
  246. package/dist/runtime/schema-fetch.js.map +1 -1
  247. package/dist/runtime/schema-fetch.test.js +11 -8
  248. package/dist/runtime/schema-fetch.test.js.map +1 -1
  249. package/dist/runtime/sync-transport.d.ts +0 -8
  250. package/dist/runtime/sync-transport.d.ts.map +1 -1
  251. package/dist/runtime/sync-transport.js +0 -19
  252. package/dist/runtime/sync-transport.js.map +1 -1
  253. package/dist/runtime/url.d.ts +13 -6
  254. package/dist/runtime/url.d.ts.map +1 -1
  255. package/dist/runtime/url.js +51 -22
  256. package/dist/runtime/url.js.map +1 -1
  257. package/dist/runtime/url.test.js +20 -16
  258. package/dist/runtime/url.test.js.map +1 -1
  259. package/dist/runtime/worker-bridge.d.ts +0 -1
  260. package/dist/runtime/worker-bridge.d.ts.map +1 -1
  261. package/dist/runtime/worker-bridge.js +0 -1
  262. package/dist/runtime/worker-bridge.js.map +1 -1
  263. package/dist/runtime/worker-bridge.test.js +7 -3
  264. package/dist/runtime/worker-bridge.test.js.map +1 -1
  265. package/dist/schema.d.ts +3 -0
  266. package/dist/schema.d.ts.map +1 -1
  267. package/dist/schema.js.map +1 -1
  268. package/dist/subscriptions-orchestrator.integration.test.js +4 -4
  269. package/dist/subscriptions-orchestrator.integration.test.js.map +1 -1
  270. package/dist/subscriptions-orchestrator.test.js +4 -0
  271. package/dist/subscriptions-orchestrator.test.js.map +1 -1
  272. package/dist/svelte/create-jazz-client.test.js +2 -1
  273. package/dist/svelte/index.d.ts +1 -0
  274. package/dist/svelte/index.d.ts.map +1 -1
  275. package/dist/svelte/index.js +1 -0
  276. package/dist/testing/index.test.js +5 -5
  277. package/dist/testing/index.test.js.map +1 -1
  278. package/dist/vue/create-jazz-client.integration.test.js +4 -1
  279. package/dist/vue/create-jazz-client.integration.test.js.map +1 -1
  280. package/dist/vue/create-jazz-client.test.js +2 -1
  281. package/dist/vue/create-jazz-client.test.js.map +1 -1
  282. package/dist/worker/jazz-worker.d.ts +1 -2
  283. package/dist/worker/jazz-worker.d.ts.map +1 -1
  284. package/dist/worker/jazz-worker.js +3 -4
  285. package/dist/worker/jazz-worker.js.map +1 -1
  286. package/dist/worker/jazz-worker.test.d.ts +1 -1
  287. package/dist/worker/jazz-worker.test.js +3 -3
  288. package/dist/worker/jazz-worker.test.js.map +1 -1
  289. package/dist/worker/jazz-worker.ts +3 -4
  290. package/dist/worker/worker-protocol.d.ts +0 -1
  291. package/dist/worker/worker-protocol.d.ts.map +1 -1
  292. package/package.json +13 -11
package/bin/docs-index.db CHANGED
Binary file
@@ -2,13 +2,16 @@
2
2
  TITLE:Authentication
3
3
  DESCRIPTION:"How and when to use Jazz's auth modes, and how to manage JWT auth over the lifetime of a live client."
4
4
 
5
- Jazz has two auth modes: `local-first` and `external`. Local-first auth derives a stable identity from a device secret no server needed. Most multi-user apps will also use `external` authentication for production accounts.
5
+ Jazz has three auth modes: `anonymous`, `local-first`, and `external`. You pick the mode implicitly by what you pass in `DbConfig`: nothing for anonymous, `secret` for local-first, or `jwtToken` for external.
6
6
 
7
7
  | Mode | What it does | When to use it |
8
8
  | ------------- | ------------------------------------------------------ | ------------------------------------------------ |
9
+ | `anonymous` | Ephemeral read-only identity, no secret, no server | Public/marketing surfaces, try-before-anything |
9
10
  | `local-first` | Stable identity from a device secret, no server needed | Production offline-first apps, try-before-signup |
10
11
  | `external` | Validates a JWT from your auth provider via JWKS | Production apps with real user accounts |
11
12
 
13
+ Anonymous sessions can subscribe to queries but are **structurally denied writes** — every insert, update, and delete path checks the session's auth mode before any policy evaluation runs, and surfaces an `AnonymousWriteDeniedError` to the client. Gate reads the same way you gate any other access, via the permissions DSL (`session.where({ authMode: "anonymous" })`).
14
+
12
15
  ## Local-first auth
13
16
 
14
17
  Local-first auth lets users start using your app without signing up. They can later upgrade to an external provider while keeping their identity. See [Local-first auth](/docs/auth/local-first-auth) for the full guide.
@@ -89,7 +92,9 @@ For sign-in and sign-out, recreate `JazzProvider` or `Db` with a new auth config
89
92
 
90
93
  ```tsx
91
94
  const [jwtToken, setJwtToken] = useState<string | null>(readStoredJwt());
92
- const secret = use(BrowserAuthSecretStore.getOrCreateSecret());
95
+ const { secret, isLoading } = useLocalFirstAuth();
96
+
97
+ if (!jwtToken && (isLoading || !secret)) return <p>Loading…</p>;
93
98
 
94
99
  const config = jwtToken
95
100
  ? {
@@ -100,7 +105,7 @@ const config = jwtToken
100
105
  : {
101
106
  appId: "my-app",
102
107
  serverUrl: "https://sync.example.com",
103
- auth: { localFirstSecret: secret },
108
+ secret: secret!,
104
109
  };
105
110
 
106
111
  ;
@@ -120,14 +125,42 @@ recommended path for login, logout, and any principal change.
120
125
 
121
126
  ### Reacting to expiry and unauthenticated responses
122
127
 
123
- Jazz exposes first-class auth state on `Db`:
128
+ Auth state is flat:
124
129
 
125
130
  ```ts
126
- const stop = db.onAuthChanged(async (state) => {
127
- if (state.status !== "unauthenticated") return;
131
+ interface AuthState {
132
+ authMode: "anonymous" | "local-first" | "external";
133
+ session: Session | null;
134
+ error?: "expired" | "missing" | "invalid" | "disabled";
135
+ }
136
+ ```
128
137
 
129
- console.log(state.reason);
130
- // "expired" | "missing" | "invalid" | "disabled"
138
+ Presence of `error` indicates trouble; `authMode` and the last-known `session` are always available.
139
+
140
+ #### React: `onJWTExpired` prop
141
+
142
+ For JWT refresh, pass `onJWTExpired` to `JazzProvider`. Jazz calls it when the sync server rejects
143
+ the current token as expired, serialized so concurrent failed writes trigger a single refresh:
144
+
145
+ ```tsx
146
+ await fetchFreshJwt()}
147
+ >
148
+
149
+ ```
150
+
151
+ Read auth state from any component with `useAuthState()`:
152
+
153
+ ```ts
154
+ const { authMode, userId, claims, error } = useAuthState();
155
+ ```
156
+
157
+ #### TypeScript: `db.onAuthChanged`
158
+
159
+ Outside React, subscribe to auth-state changes on `Db`:
160
+
161
+ ```ts
162
+ const stop = db.onAuthChanged(async (state) => {
163
+ if (state.error !== "expired") return;
131
164
 
132
165
  const freshJwt = await getFreshJwtForCurrentUser().catch(() => null);
133
166
  if (freshJwt) {
@@ -140,22 +173,19 @@ const stop = db.onAuthChanged(async (state) => {
140
173
  });
141
174
  ```
142
175
 
143
- You can also read the current snapshot synchronously with `db.getAuthState()`.
176
+ Read the current snapshot synchronously with `db.getAuthState()`.
144
177
 
145
178
  When Jazz receives a structured unauthenticated response from the sync server, it:
146
179
 
147
- - transitions the client to `status: "unauthenticated"`
180
+ - sets `error` on the auth state
148
181
  - preserves the last known `session`
149
182
  - pauses authenticated sync and reconnects until the app either refreshes the same user's JWT with
150
183
  `db.updateAuthToken(...)` or recreates the client with a new auth config
151
184
 
152
- This means app code should treat `authState.status` as the source of truth for whether Jazz is
153
- currently authenticated.
154
-
155
- `useSession()` and `db.getAuthState().session` can still return the last known session while the
156
- auth state is unauthenticated. That's intentional: it keeps user-scoped UI and local authorship
157
- stable while your app refreshes or replaces the JWT. For signed-in vs signed-out UI, check
158
- `db.getAuthState().status` instead of only checking whether a session exists.
185
+ `useSession()` and `db.getAuthState().session` can still return the last known session while
186
+ `error` is set. That's intentional: it keeps user-scoped UI and local authorship stable while your
187
+ app refreshes or replaces the JWT. For signed-in vs signed-out UI, check whether `error` is set
188
+ (or the `authMode` you expect) instead of only whether a session exists.
159
189
 
160
190
  ### Server configuration
161
191
 
@@ -186,7 +216,7 @@ When the server receives a request, it tries each auth method in priority order
186
216
 
187
217
  Backend impersonation always takes precedence, so a backend service can reliably impersonate users even if the request also carries a JWT.
188
218
 
189
- On TypeScript backends, `await createJazzContext(...).forRequest(req)` follows the same rule set. Configure `jwksUrl` on the backend context to verify external JWTs there too.
219
+ On TypeScript backends, `await createJazzContext(...).forRequest(req)` follows the same rule set. Configure `jwksUrl` or `jwtPublicKey` on the backend context to verify external JWTs there too, but not both.
190
220
 
191
221
  ### Upgrading to external auth
192
222
 
@@ -210,12 +240,14 @@ Local-first auth lets users start using your app immediately — no sign-up, no
210
240
 
211
241
  ## Client setup
212
242
 
213
- Use `BrowserAuthSecretStore` to persist the user's secret across sessions. On first load it generates a new identity; on subsequent loads it reuses the stored one.
243
+ Use `useLocalFirstAuth()` to manage the user's secret. On first load it generates a new identity; on subsequent loads it reuses the stored one. It also exposes `login` and `signOut` for switching or clearing the local identity.
214
244
 
215
245
  ```tsx
216
246
 
217
247
  function App() {
218
- const secret = use(BrowserAuthSecretStore.getOrCreateSecret());
248
+ const { secret, isLoading } = useLocalFirstAuth();
249
+
250
+ if (isLoading || !secret) return <p>Loading…</p>;
219
251
 
220
252
  return (
221
253
 
@@ -349,36 +381,54 @@ On the server, a BetterAuth middleware hook intercepts sign-up requests, verifie
349
381
  The app switches between local-first auth and external JWT based on whether the user has a BetterAuth session:
350
382
 
351
383
  ```tsx
352
- function App() {
353
- const { data: authSession, isPending } = authClient.useSession();
354
- const [config, setConfig] = useState(null);
384
+ function useBetterAuthJWT() {
385
+ const { data, isPending } = authClient.useSession();
386
+ const [jwt, setJwt] = useState<string | null>(null);
387
+ const [isFetching, setIsFetching] = useState(false);
355
388
 
356
389
  useEffect(() => {
357
390
  if (isPending) return;
358
-
359
- async function resolveConfig() {
360
- const sharedConfig = {
361
- appId: process.env.NEXT_PUBLIC_JAZZ_APP_ID!,
362
- serverUrl: process.env.NEXT_PUBLIC_JAZZ_SERVER_URL!,
363
- };
364
-
365
- if (authSession?.session) {
366
- // User is signed in with BetterAuth — use their JWT
367
- const jwtToken = await getJwtFromBetterAuth();
368
- setConfig({ ...sharedConfig, jwtToken: jwtToken! });
369
- } else {
370
- // No external session — use local-first auth
371
- const secret = await BrowserAuthSecretStore.getOrCreateSecret();
372
- setConfig({ ...sharedConfig, auth: { localFirstSecret: secret } });
373
- }
391
+ if (!data?.session) {
392
+ setJwt(null);
393
+ return;
374
394
  }
395
+ setIsFetching(true);
396
+ void getJwtFromBetterAuth().then((token) => {
397
+ setJwt(token ?? null);
398
+ setIsFetching(false);
399
+ });
400
+ }, [isPending, data?.session?.id]);
375
401
 
376
- void resolveConfig();
377
- }, [isPending, authSession?.session]);
402
+ return {
403
+ isLoading: isPending || isFetching,
404
+ jwt,
405
+ getRefreshedJWT: () => getJwtFromBetterAuth(),
406
+ };
407
+ }
378
408
 
379
- if (isPending || !config) return null;
409
+ function App() {
410
+ const betterAuth = useBetterAuthJWT();
411
+ const { secret: localFirstSecret, isLoading: localFirstLoading } = useLocalFirstAuth();
412
+
413
+ // Only mint a local-first secret when there's no BetterAuth session.
414
+ const secret = !betterAuth.jwt ? (localFirstSecret ?? undefined) : undefined;
415
+
416
+ const config = useMemo(
417
+ () => ({
418
+ appId: process.env.NEXT_PUBLIC_JAZZ_APP_ID!,
419
+ serverUrl: process.env.NEXT_PUBLIC_JAZZ_SERVER_URL!,
420
+ jwtToken: betterAuth.jwt ?? undefined,
421
+ secret,
422
+ }),
423
+ [betterAuth.jwt, secret],
424
+ );
425
+
426
+ if (betterAuth.isLoading || (!betterAuth.jwt && localFirstLoading)) return <p>Loading auth…</p>;
380
427
 
381
428
  return (
429
+ betterAuth.getRefreshedJWT()}
430
+ fallback={<p>Loading Jazz DB…</p>}
431
+ >
382
432
 
383
433
  );
384
434
  }
@@ -391,7 +441,7 @@ You can restrict what local-first users can do until they sign up. Define an `is
391
441
  ```ts
392
442
 
393
443
  const isLocalFirstAuthMode = session.where({
394
- "claims.auth_mode": "local-first",
444
+ authMode: "local-first",
395
445
  });
396
446
 
397
447
  // Everyone can read
@@ -409,7 +459,7 @@ The BetterAuth example above uses a framework-specific middleware hook. With any
409
459
  1. Accepts `proofToken` alongside the sign-up credentials
410
460
  2. Verifies it with `verifyLocalFirstIdentityProof` from `jazz-napi`
411
461
  3. Stores the proven Jazz user ID linked to the new user account
412
- 4. Issues JWTs with either `sub: jazzId` or `jazz_principal_id: jazzId`
462
+ 4. Issues JWTs with `sub: jazzId`
413
463
 
414
464
  ```ts title="server.ts"
415
465
 
@@ -427,8 +477,7 @@ app.post("/signup", async (req, res) => {
427
477
  );
428
478
  if (!ok) return res.status(400).json({ error });
429
479
 
430
- // Store jazzUserId so you can include it in future JWTs as `sub`
431
- // or, for managed providers with provider-owned `sub`, as `jazz_principal_id`
480
+ // Store jazzUserId so you can mint future JWTs with it as `sub`.
432
481
  const user = await db.users.create({ email, password, jazzId: jazzUserId });
433
482
 
434
483
  res.json({ token: issueJwt({ sub: user.jazzId /* ... */ }) });
@@ -437,7 +486,7 @@ app.post("/signup", async (req, res) => {
437
486
 
438
487
  The `audience` string on the client and server must match. `jazz-napi` normalizes it internally, so any consistent string works.
439
488
 
440
- If your provider lets you control the JWT subject, you can set `sub` directly to the Jazz ID. Many managed providers keep `sub` fixed to their own user ID. In that case, call a dedicated `/link-jazz-identity` endpoint immediately after sign-up, store the Jazz ID in provider metadata or your own database, and mint or refresh JWTs with `jazz_principal_id: <jazzId>`. Jazz uses `jazz_principal_id` as `session.user_id` when present and falls back to `sub` otherwise.
489
+ Jazz uses the JWT `sub` claim as `session.user_id`. If your provider keeps `sub` fixed to its own user ID, add a `/link-jazz-identity` endpoint that stores the Jazz ID and mint the JWT with `sub: <jazzId>` yourself either via a custom `getSubject` hook on your provider or by issuing the JWT directly.
441
490
 
442
491
  ## Under the hood
443
492
 
@@ -906,6 +955,7 @@ edit metadata. Use the attribution helpers for this:
906
955
 
907
956
  const syntheticSession = {
908
957
  user_id: "user_123",
958
+ authMode: "external" as const,
909
959
  claims: {},
910
960
  };
911
961
 
@@ -1516,6 +1566,7 @@ Every backend needs an app ID, typed schema, and usually a permissions bundle. I
1516
1566
  backendSecret,
1517
1567
  adminSecret,
1518
1568
  jwksUrl,
1569
+ jwtPublicKey,
1519
1570
  allowLocalFirstAuth,
1520
1571
  env: "dev",
1521
1572
  userBranch: "main",
@@ -1551,7 +1602,7 @@ On the client side, queries automatically run as the logged-in user. On a server
1551
1602
 
1552
1603
  In TypeScript backends, create the context once with both `app` and `permissions`, then use `context.asBackend()` for server-owned work and `await context.forRequest(req)` when you need a bearer-JWT-scoped high-level `Db`.
1553
1604
 
1554
- `forRequest` reads authentication from standard HTTP headers, so `req` can be any object that exposes them: Express, Hono, Fastify, or a Web Fetch API `Request` all work. Configure `jwksUrl` on `createJazzContext(...)` if those bearer tokens come from an external IdP. Without `jwksUrl`, backend `forRequest()` only accepts Jazz self-signed tokens; set `allowLocalFirstAuth: false` to disable those too.
1605
+ `forRequest` reads authentication from standard HTTP headers, so `req` can be any object that exposes them: Express, Hono, Fastify, or a Web Fetch API `Request` all work. Configure `jwksUrl` or `jwtPublicKey` on `createJazzContext(...)` if those bearer tokens come from an external IdP, but do not set both at once. Without either one, backend `forRequest()` only accepts Jazz self-signed tokens; set `allowLocalFirstAuth: false` to disable those too.
1555
1606
 
1556
1607
  For embedded or local-only runtime setups where your backend is not connected to a server, use
1557
1608
  `context.db()` to get an unscoped, unauthenticated handle. This allows read/write access to the
@@ -2313,6 +2364,7 @@ const context = createJazzContext({
2313
2364
  serverUrl: process.env.JAZZ_SERVER_URL,
2314
2365
  backendSecret: process.env.JAZZ_BACKEND_SECRET,
2315
2366
  jwksUrl: process.env.JAZZ_JWKS_URL,
2367
+ jwtPublicKey: process.env.JAZZ_JWT_PUBLIC_KEY,
2316
2368
  allowLocalFirstAuth: process.env.JAZZ_ALLOW_LOCAL_FIRST_AUTH !== "false",
2317
2369
  });
2318
2370
 
@@ -2323,7 +2375,7 @@ const api = new Hono();
2323
2375
  - `app` is your typed schema export.
2324
2376
  - `permissions` is the server-side policy bundle.
2325
2377
  - `serverUrl` + `backendSecret` let request-scoped handles sync through a Jazz server.
2326
- - `jwksUrl` verifies external JWTs inside `await context.forRequest(req)`. Without it, the backend only accepts Jazz self-signed tokens unless you set `allowLocalFirstAuth: false`.
2378
+ - `jwksUrl` or `jwtPublicKey` verifies external JWTs inside `await context.forRequest(req)`. Without either one, the backend only accepts Jazz self-signed tokens unless you set `allowLocalFirstAuth: false`.
2327
2379
  - `dataPath` controls where local server state persists.
2328
2380
 
2329
2381
  Each route handler awaits `context.forRequest(c.req)` to get a database handle with [permissions](/docs/auth/permissions) scoped to the request.
@@ -2435,8 +2487,8 @@ curl -X DELETE http://localhost:3000/api/todos/<id> \
2435
2487
 
2436
2488
  `forRequest` verifies the caller's bearer token inside the backend context. The token above is a
2437
2489
  Jazz self-signed dev token, which works because `allowLocalFirstAuth` defaults to `true`. If you
2438
- want to accept external JWTs from your auth provider, also set `jwksUrl` so the backend can verify
2439
- them via JWKS.
2490
+ want to accept external JWTs from your auth provider, also set `jwksUrl` or `jwtPublicKey` so
2491
+ the backend can verify them.
2440
2492
 
2441
2493
  ## Authentication
2442
2494
 
@@ -3103,7 +3155,7 @@ Jazz supports external JWT-based authentication for production use. This recipe
3103
3155
  1. The user signs in with your auth provider and gets a JWT.
3104
3156
  2. Your client passes that JWT to Jazz.
3105
3157
  3. The Jazz server validates the JWT signature against the provider's JWKS endpoint.
3106
- 4. On success, Jazz derives `session.user_id` from `jazz_principal_id` when present, otherwise from the JWT's `sub` claim.
3158
+ 4. On success, Jazz uses the JWT's `sub` claim as `session.user_id`.
3107
3159
 
3108
3160
  If you're unfamiliar with JWTs and JWKS, see the [explainer on the Authentication page](/docs/auth/authentication#external-auth-for-production).
3109
3161
 
@@ -3250,7 +3302,7 @@ Any provider that issues JWTs and exposes a JWKS endpoint will work. The key pat
3250
3302
  | Auth0 | `https://<tenant>.auth0.com/.well-known/jwks.json` | `auth0\|<id>` |
3251
3303
  | Firebase | `https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com` | Firebase UID |
3252
3304
 
3253
- By default, the `sub` claim identifies the user. If your provider supports custom claims but keeps `sub` fixed to its own user ID, include `jazz_principal_id` in the JWT instead. Jazz uses `jazz_principal_id` as `session.user_id` when present and falls back to `sub` otherwise.
3305
+ Jazz uses the JWT `sub` claim as `session.user_id`. If your provider keeps `sub` fixed to its own user ID, mint the JWT with `sub` set to the Jazz user ID yourself either via a custom `getSubject` hook on the provider or by issuing the JWT directly from your server.
3254
3306
 
3255
3307
  Full working examples: [Better Auth chat](https://github.com/garden-co/jazz/tree/main/examples/auth-betterauth-chat), [WorkOS chat](https://github.com/garden-co/jazz/tree/main/examples/auth-workos-chat).
3256
3308
 
@@ -3732,11 +3784,11 @@ See [Writing Data](/docs/writing/writing-data#write-durability-tiers) for detail
3732
3784
 
3733
3785
  Read durability controls when the **first result** of a query or subscription is delivered.
3734
3786
 
3735
- | Option | Values | Default | What it does |
3736
- | -------------- | ------------------------------------ | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
3787
+ | Option | Values | Default | What it does |
3788
+ | -------------- | ----------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
3737
3789
  | `tier` | `"local"` \| `"edge"` \| `"global"` | Same as writes | How far the first result must come from before the query delivers. |
3738
- | `localUpdates` | `"immediate"` \| `"deferred"` | `"immediate"` | With `"immediate"`, your own local writes appear in the subscription while still waiting for the tier to confirm the initial snapshot. This only takes effect after the subscription has settled at least once. With `"deferred"`, all delivery is held until the tier confirms. |
3739
- | `propagation` | `"full"` \| `"local-only"` | `"full"` | With `"full"`, the subscription is sent to upstream servers, which push matching data back. With `"local-only"`, only local storage is queried&hairsp;—&hairsp;no server communication. |
3790
+ | `localUpdates` | `"immediate"` \| `"deferred"` | `"immediate"` | With `"immediate"`, your own local writes appear in the subscription while still waiting for the tier to confirm the initial snapshot. This only takes effect after the subscription has settled at least once. With `"deferred"`, all delivery is held until the tier confirms. |
3791
+ | `propagation` | `"full"` \| `"local-only"` | `"full"` | With `"full"`, the subscription is sent to upstream servers, which push matching data back. With `"local-only"`, only local storage is queried&hairsp;—&hairsp;no server communication. |
3740
3792
 
3741
3793
  These options apply to:
3742
3794
 
@@ -5351,7 +5403,7 @@ When using `insertDurable`, `updateDurable`, or `deleteDurable`, you can pass a
5351
5403
 
5352
5404
  | Tier | Resolves when | Default for |
5353
5405
  | -------- | ----------------------------------- | -------------- |
5354
- | `local` | Persisted to local OPFS | Browser/client |
5406
+ | `local` | Persisted to local OPFS | Browser/client |
5355
5407
  | `edge` | Acknowledged by nearest sync server | Backend/server |
5356
5408
  | `global` | Propagated to global core | — |
5357
5409
 
@@ -5445,4 +5497,4 @@ batch.update(app.todos, todoId, { done: true });
5445
5497
  console.log(batch.batchId());
5446
5498
  ```
5447
5499
 
5448
- Both builders can also issue persisted writes, expose `localBatchRecord()` / `localBatchRecords()`, and let you acknowledge replayable rejections by batch id.
5500
+ Both builders can also issue persisted writes, expose `localBatchRecord()` / `localBatchRecords()`, and let you acknowledge replayable rejections by batch id.
Binary file
Binary file
Binary file
Binary file
@@ -1,3 +1,4 @@
1
+ import type { JWK } from "jose";
1
2
  import type { WasmSchema } from "../drivers/types.js";
2
3
  import type { CompiledPermissions } from "../permissions/index.js";
3
4
  import { type RequestLike } from "../runtime/client.js";
@@ -10,6 +11,7 @@ export interface BackendQuerySchemaSource {
10
11
  _schema: WasmSchema;
11
12
  }
12
13
  export type BackendSchemaInput = WasmSchema | BackendSchemaSource | BackendQuerySchemaSource;
14
+ export type BackendJwtPublicKey = JWK | string;
13
15
  export type BackendDriver = {
14
16
  type: "persistent";
15
17
  /** Path to the Fjall file used by the server runtime. */
@@ -33,6 +35,8 @@ export type BackendContextConfig = Omit<AppContext, "schema" | "driver" | "clien
33
35
  tier?: "local" | "edge" | "global";
34
36
  /** JWKS endpoint used to verify external bearer JWTs in `forRequest()`. */
35
37
  jwksUrl?: string;
38
+ /** Single JWK object or PEM/JWK string used to verify external bearer JWTs in `forRequest()`. */
39
+ jwtPublicKey?: BackendJwtPublicKey;
36
40
  /** Whether local-first bearer JWTs are accepted in `forRequest()`. Defaults to `true`. */
37
41
  allowLocalFirstAuth?: boolean;
38
42
  } & BackendContextSchemaConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"create-jazz-context.d.ts","sourceRoot":"","sources":["../../src/backend/create-jazz-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-jazz-context.d.ts","sourceRoot":"","sources":["../../src/backend/create-jazz-context.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,9 @@ function assertValidBackendConfig(config) {
8
8
  if (config.driver.type === "memory" && !config.serverUrl) {
9
9
  throw new Error("driver.type='memory' requires serverUrl.");
10
10
  }
11
+ if (config.jwksUrl !== undefined && config.jwtPublicKey !== undefined) {
12
+ throw new Error("Backend auth config cannot set both jwksUrl and jwtPublicKey. Pick one external JWT verification mode.");
13
+ }
11
14
  }
12
15
  function isRecord(value) {
13
16
  return typeof value === "object" && value !== null;
@@ -81,7 +84,6 @@ export class JazzContext {
81
84
  appId: this.config.appId,
82
85
  schema,
83
86
  serverUrl: this.config.serverUrl,
84
- serverPathPrefix: this.config.serverPathPrefix,
85
87
  env: this.config.env,
86
88
  userBranch: this.config.userBranch,
87
89
  jwtToken: this.config.jwtToken,
@@ -97,7 +99,7 @@ export class JazzContext {
97
99
  backend_secret: this.config.backendSecret,
98
100
  admin_secret: this.config.adminSecret,
99
101
  jwt_token: this.config.jwtToken,
100
- }, this.config.serverPathPrefix);
102
+ });
101
103
  }
102
104
  return this.clientInstance;
103
105
  }
@@ -106,7 +108,6 @@ export class JazzContext {
106
108
  appId: this.config.appId,
107
109
  driver: this.config.driver.type === "memory" ? { type: "memory" } : { type: "persistent" },
108
110
  serverUrl: this.config.serverUrl,
109
- serverPathPrefix: this.config.serverPathPrefix,
110
111
  env: this.config.env,
111
112
  userBranch: this.config.userBranch,
112
113
  jwtToken: this.config.jwtToken,
@@ -116,8 +117,7 @@ export class JazzContext {
116
117
  wrapDb(client, session, attribution, backendScoped = false) {
117
118
  return createDbFromClient(this.buildDbConfig(), client, session, attribution, backendScoped
118
119
  ? {
119
- status: "authenticated",
120
- transport: "backend",
120
+ authMode: session?.authMode ?? "external",
121
121
  session: session ?? null,
122
122
  }
123
123
  : undefined);
@@ -176,6 +176,7 @@ export class JazzContext {
176
176
  return await resolveRequestSession(request, {
177
177
  appId: this.config.appId,
178
178
  jwksUrl: this.config.jwksUrl,
179
+ jwtPublicKey: this.config.jwtPublicKey,
179
180
  allowLocalFirstAuth: this.config.allowLocalFirstAuth,
180
181
  });
181
182
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create-jazz-context.js","sourceRoot":"","sources":["../../src/backend/create-jazz-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAoB,MAAM,sBAAsB,CAAC;AAEpE,OAAO,EAAE,kBAAkB,EAA0B,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAiD1D,SAAS,wBAAwB,CAAC,MAA4B;IAC5D,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC;QACrB,CAAC,CAAC,YAAY,IAAI,KAAK,CAAC;QACxB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAC5D,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAyB;IAC9C,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,IAAI,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACzE,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IACD,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,YAAY,IAAI,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/E,OAAO,KAAK,CAAC,UAAU,CAAC;IAC1B,CAAC;IAED,MAAM,IAAI,KAAK,CACb,sGAAsG,CACvG,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,WAAW;IACL,MAAM,CAA+B;IACrC,kBAAkB,CAAsB;IACjD,qBAAqB,CAAU;IAC/B,OAAO,CAAe;IACtB,cAAc,CAAc;IAEpC,YAAY,MAA4B;QACtC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG;YACZ,GAAG,MAAM;YACT,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,IAAI,IAAI;SACxD,CAAC;QACF,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAC;IACvC,CAAC;IAEO,aAAa,CAAC,MAA2B;QAC/C,MAAM,QAAQ,GAAG,MAAM,IAAI,IAAI,CAAC,kBAAkB,CAAC;QACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CACb,gJAAgJ,CACjJ,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW;YAC5B,CAAC,CAAC,8BAA8B,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;YACjE,CAAC,CAAC,MAAM,CAAC;IACb,CAAC;IAEO,YAAY,CAAC,MAAkB;QACrC,MAAM,UAAU,GAAG,sBAAsB,CAAC,MAAM,EAAE;YAChD,kBAAkB,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS;SAC1D,CAAC,CAAC;QACH,IAAI,CAAC,qBAAqB,GAAG,UAAU,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC;QAE5C,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC7C,IAAI,CAAC,OAAO,GAAG,IAAI,WAAW,CAC5B,UAAU,EACV,IAAI,CAAC,MAAM,CAAC,KAAK,EACjB,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,KAAK,EACxB,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,EAChC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAC3B,QAAQ,CACT,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,QAAQ,CACjC,UAAU,EACV,IAAI,CAAC,MAAM,CAAC,KAAK,EACjB,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,KAAK,EACxB,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,EAChC,QAAQ,CACT,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAe;YAC1B,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;YACxB,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;YAChC,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB;YAC9C,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG;YACpB,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU;YAClC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC9B,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa;YACxC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;YACpC,IAAI,EAAE,QAAQ;YACd,qBAAqB,EAAE,MAAM;SAC9B,CAAC;QAEF,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE3E,uEAAuE;QACvE,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAClC,IAAI,CAAC,MAAM,CAAC,SAAS,EACrB;gBACE,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa;gBACzC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;gBACrC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;aAChC,EACD,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAC7B,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAEO,aAAa;QACnB,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;YACxB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE;YAC1F,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;YAChC,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB;YAC9C,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG;YACpB,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU;YAClC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC9B,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;SACrC,CAAC;IACJ,CAAC;IAEO,MAAM,CACZ,MAAkB,EAClB,OAAiB,EACjB,WAAoB,EACpB,aAAa,GAAG,KAAK;QAErB,OAAO,kBAAkB,CACvB,IAAI,CAAC,aAAa,EAAE,EACpB,MAAM,EACN,OAAO,EACP,WAAW,EACX,aAAa;YACX,CAAC,CAAC;gBACE,MAAM,EAAE,eAAe;gBACvB,SAAS,EAAE,SAAS;gBACpB,OAAO,EAAE,OAAO,IAAI,IAAI;aACzB;YACH,CAAC,CAAC,SAAS,CACd,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,SAAS,CAAC,MAA2B;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,UAAU,GAAG,sBAAsB,CAAC,MAAM,EAAE;YAChD,kBAAkB,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS;SAC1D,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,IAAI,CAAC,qBAAqB,KAAK,UAAU,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,4GAA4G,CAC7G,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,EAAE,CAAC,MAA2B;QAC5B,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,MAA2B;QACnC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACrF,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,WAAmB,EAAE,MAA2B;QAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IAC3D,CAAC;IAED;;;OAGG;IACK,6BAA6B,CAAC,MAAkB;QACtD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,sFAAsF,CACvF,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,SAAS,EAAE,CAAC;IACrB,CAAC;IAEO,KAAK,CAAC,qBAAqB,CAAC,OAAoB;QACtD,OAAO,MAAM,qBAAqB,CAAC,OAAO,EAAE;YAC1C,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;YACxB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,mBAAmB,EAAE,IAAI,CAAC,MAAM,CAAC,mBAAmB;SACrD,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,OAAoB,EAAE,MAA2B;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACH,yBAAyB,CAAC,OAAgB,EAAE,MAA2B;QACrE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC/D,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,yBAAyB,CAAC,OAAoB,EAAE,MAA2B;QAC/E,OAAO,IAAI,CAAC,yBAAyB,CAAC,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3F,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,OAAgB,EAAE,MAA2B;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC;QAEnC,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC;QAEvC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,iBAAiB,CAAC,MAA4B;IAC5D,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"create-jazz-context.js","sourceRoot":"","sources":["../../src/backend/create-jazz-context.ts"],"names":[],"mappings":"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"}
@@ -150,6 +150,7 @@ describe("backend/create-jazz-context", () => {
150
150
  mocks.resolveRequestSession.mockResolvedValue({
151
151
  user_id: "u1",
152
152
  claims: {},
153
+ authMode: "external",
153
154
  });
154
155
  });
155
156
  it("BC-U01: lazily initializes runtime/client on first access", () => {
@@ -175,6 +176,21 @@ describe("backend/create-jazz-context", () => {
175
176
  });
176
177
  expect(mocks.runtimeCtor).toHaveBeenCalledWith(expect.any(String), "server-app", "dev", "main", "/tmp/jazz.db", "edge");
177
178
  });
179
+ it("BC-U01b: rejects configuring both jwksUrl and jwtPublicKey", () => {
180
+ expect(() => createJazzContext({
181
+ appId: "server-app",
182
+ app: { wasmSchema: SCHEMA_A },
183
+ permissions: {},
184
+ driver: { type: "persistent", dataPath: "/tmp/jazz.db" },
185
+ jwksUrl: "https://issuer.example/.well-known/jwks.json",
186
+ jwtPublicKey: {
187
+ kty: "oct",
188
+ kid: "static-kid",
189
+ alg: "HS256",
190
+ k: "c3RhdGljLXNlY3JldA",
191
+ },
192
+ })).toThrow(/jwksUrl.*jwtPublicKey|jwtPublicKey.*jwksUrl/i);
193
+ });
178
194
  it("BC-U02: supports high-level db/backend/request/session/attribution helpers", async () => {
179
195
  const context = createJazzContext({
180
196
  appId: "server-app",
@@ -187,7 +203,7 @@ describe("backend/create-jazz-context", () => {
187
203
  const req = {
188
204
  header: (name) => name === "authorization" ? `Bearer ${makeJwt({ sub: "u1" })}` : undefined,
189
205
  };
190
- const session = { user_id: "u1", claims: {} };
206
+ const session = { user_id: "u1", claims: {}, authMode: "external" };
191
207
  const db = context.db();
192
208
  const backendDb = context.asBackend();
193
209
  const requestDb = await context.forRequest(req);
@@ -206,7 +222,7 @@ describe("backend/create-jazz-context", () => {
206
222
  expect(requestDb).toEqual({
207
223
  kind: "scoped-db",
208
224
  client: mocks.clients[0],
209
- session: { user_id: "u1", claims: {} },
225
+ session: { user_id: "u1", claims: {}, authMode: "external" },
210
226
  });
211
227
  expect(sessionDb).toEqual({
212
228
  kind: "scoped-db",
@@ -253,7 +269,7 @@ describe("backend/create-jazz-context", () => {
253
269
  const req = {
254
270
  header: (name) => name === "authorization" ? `Bearer ${makeJwt({ sub: "u1" })}` : undefined,
255
271
  };
256
- const session = { user_id: "u1", claims: {} };
272
+ const session = { user_id: "u1", claims: {}, authMode: "external" };
257
273
  await expect(context.forRequest(req)).resolves.toBeDefined();
258
274
  expect(() => context.forSession(session)).not.toThrow();
259
275
  expect(() => context.withAttribution("u2")).not.toThrow();
@@ -280,6 +296,36 @@ describe("backend/create-jazz-context", () => {
280
296
  allowLocalFirstAuth: false,
281
297
  });
282
298
  });
299
+ it("BC-U03c: forwards jwtPublicKey into request session resolution", async () => {
300
+ const context = createJazzContext({
301
+ appId: "server-app",
302
+ app: { wasmSchema: SCHEMA_A },
303
+ permissions: {},
304
+ driver: { type: "persistent", dataPath: "/tmp/jazz.db" },
305
+ jwtPublicKey: {
306
+ kty: "oct",
307
+ kid: "static-kid",
308
+ alg: "HS256",
309
+ k: "c3RhdGljLXNlY3JldA",
310
+ },
311
+ allowLocalFirstAuth: false,
312
+ });
313
+ const req = {
314
+ header: (name) => name === "authorization" ? `Bearer ${makeJwt({ sub: "u1" })}` : undefined,
315
+ };
316
+ await context.forRequest(req);
317
+ expect(mocks.resolveRequestSession).toHaveBeenCalledWith(req, {
318
+ appId: "server-app",
319
+ jwksUrl: undefined,
320
+ jwtPublicKey: {
321
+ kty: "oct",
322
+ kid: "static-kid",
323
+ alg: "HS256",
324
+ k: "c3RhdGljLXNlY3JldA",
325
+ },
326
+ allowLocalFirstAuth: false,
327
+ });
328
+ });
283
329
  it("BC-U04: merges compiled permissions into the runtime schema", () => {
284
330
  const context = createJazzContext({
285
331
  appId: "server-app",