@raybase/core 0.0.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (435) hide show
  1. package/LICENSE +21 -0
  2. package/dist/.admin-build/AdminApp.css +2 -0
  3. package/dist/.admin-build/AdminApp.js +77 -0
  4. package/dist/.admin-docs-build/AdminDocsApp.css +2 -0
  5. package/dist/.admin-docs-build/AdminDocsApp.js +45 -0
  6. package/dist/actions.d.ts +347 -0
  7. package/dist/actions.d.ts.map +1 -0
  8. package/dist/actions.js +661 -0
  9. package/dist/actions.js.map +1 -0
  10. package/dist/admin-assets/admin.7738f50720a8ed7b.css +2 -0
  11. package/dist/admin-assets/admin.8678cb61db34dc81.js +77 -0
  12. package/dist/admin-boot.d.ts +94 -0
  13. package/dist/admin-boot.d.ts.map +1 -0
  14. package/dist/admin-boot.js +139 -0
  15. package/dist/admin-boot.js.map +1 -0
  16. package/dist/admin-docs-content.d.ts +95 -0
  17. package/dist/admin-docs-content.d.ts.map +1 -0
  18. package/dist/admin-docs-content.js +463 -0
  19. package/dist/admin-docs-content.js.map +1 -0
  20. package/dist/admin-docs-ui.d.ts +11 -0
  21. package/dist/admin-docs-ui.d.ts.map +1 -0
  22. package/dist/admin-docs-ui.js +23 -0
  23. package/dist/admin-docs-ui.js.map +1 -0
  24. package/dist/admin-kit.d.ts +29 -0
  25. package/dist/admin-kit.js +1557 -0
  26. package/dist/admin-role.d.ts +8 -0
  27. package/dist/admin-role.d.ts.map +1 -0
  28. package/dist/admin-role.js +22 -0
  29. package/dist/admin-role.js.map +1 -0
  30. package/dist/admin-ui.d.ts +3 -0
  31. package/dist/admin-ui.d.ts.map +1 -0
  32. package/dist/admin-ui.js +16 -0
  33. package/dist/admin-ui.js.map +1 -0
  34. package/dist/agent-ai-chat.d.ts +127 -0
  35. package/dist/agent-ai-chat.d.ts.map +1 -0
  36. package/dist/agent-ai-chat.js +5975 -0
  37. package/dist/agent-ai-chat.js.map +1 -0
  38. package/dist/agent-chapter-archive.d.ts +214 -0
  39. package/dist/agent-chapter-archive.d.ts.map +1 -0
  40. package/dist/agent-chapter-archive.js +696 -0
  41. package/dist/agent-chapter-archive.js.map +1 -0
  42. package/dist/agent-chapter-search.d.ts +116 -0
  43. package/dist/agent-chapter-search.d.ts.map +1 -0
  44. package/dist/agent-chapter-search.js +605 -0
  45. package/dist/agent-chapter-search.js.map +1 -0
  46. package/dist/agent-chapter-tools.d.ts +45 -0
  47. package/dist/agent-chapter-tools.d.ts.map +1 -0
  48. package/dist/agent-chapter-tools.js +344 -0
  49. package/dist/agent-chapter-tools.js.map +1 -0
  50. package/dist/agent-chapters.d.ts +228 -0
  51. package/dist/agent-chapters.d.ts.map +1 -0
  52. package/dist/agent-chapters.js +737 -0
  53. package/dist/agent-chapters.js.map +1 -0
  54. package/dist/agent-data-parts.d.ts +167 -0
  55. package/dist/agent-data-parts.d.ts.map +1 -0
  56. package/dist/agent-data-parts.js +68 -0
  57. package/dist/agent-data-parts.js.map +1 -0
  58. package/dist/agent-errors.d.ts +41 -0
  59. package/dist/agent-errors.d.ts.map +1 -0
  60. package/dist/agent-errors.js +191 -0
  61. package/dist/agent-errors.js.map +1 -0
  62. package/dist/agent-follow-up-store.d.ts +273 -0
  63. package/dist/agent-follow-up-store.d.ts.map +1 -0
  64. package/dist/agent-follow-up-store.js +703 -0
  65. package/dist/agent-follow-up-store.js.map +1 -0
  66. package/dist/agent-follow-ups.d.ts +314 -0
  67. package/dist/agent-follow-ups.d.ts.map +1 -0
  68. package/dist/agent-follow-ups.js +840 -0
  69. package/dist/agent-follow-ups.js.map +1 -0
  70. package/dist/agent-memory.d.ts +323 -0
  71. package/dist/agent-memory.d.ts.map +1 -0
  72. package/dist/agent-memory.js +1270 -0
  73. package/dist/agent-memory.js.map +1 -0
  74. package/dist/agent-message-parts.d.ts +58 -0
  75. package/dist/agent-message-parts.d.ts.map +1 -0
  76. package/dist/agent-message-parts.js +163 -0
  77. package/dist/agent-message-parts.js.map +1 -0
  78. package/dist/agent-remote-mcp-credentials.d.ts +154 -0
  79. package/dist/agent-remote-mcp-credentials.d.ts.map +1 -0
  80. package/dist/agent-remote-mcp-credentials.js +287 -0
  81. package/dist/agent-remote-mcp-credentials.js.map +1 -0
  82. package/dist/agent-remote-mcp-crypto.d.ts +32 -0
  83. package/dist/agent-remote-mcp-crypto.d.ts.map +1 -0
  84. package/dist/agent-remote-mcp-crypto.js +101 -0
  85. package/dist/agent-remote-mcp-crypto.js.map +1 -0
  86. package/dist/agent-remote-mcp-install.d.ts +299 -0
  87. package/dist/agent-remote-mcp-install.d.ts.map +1 -0
  88. package/dist/agent-remote-mcp-install.js +785 -0
  89. package/dist/agent-remote-mcp-install.js.map +1 -0
  90. package/dist/agent-remote-mcp-oauth.d.ts +73 -0
  91. package/dist/agent-remote-mcp-oauth.d.ts.map +1 -0
  92. package/dist/agent-remote-mcp-oauth.js +344 -0
  93. package/dist/agent-remote-mcp-oauth.js.map +1 -0
  94. package/dist/agent-remote-mcp-transport.d.ts +46 -0
  95. package/dist/agent-remote-mcp-transport.d.ts.map +1 -0
  96. package/dist/agent-remote-mcp-transport.js +225 -0
  97. package/dist/agent-remote-mcp-transport.js.map +1 -0
  98. package/dist/agent-remote-mcp.d.ts +147 -0
  99. package/dist/agent-remote-mcp.d.ts.map +1 -0
  100. package/dist/agent-remote-mcp.js +681 -0
  101. package/dist/agent-remote-mcp.js.map +1 -0
  102. package/dist/agent-room-redaction.d.ts +66 -0
  103. package/dist/agent-room-redaction.d.ts.map +1 -0
  104. package/dist/agent-room-redaction.js +264 -0
  105. package/dist/agent-room-redaction.js.map +1 -0
  106. package/dist/agent-rooms.d.ts +209 -0
  107. package/dist/agent-rooms.d.ts.map +1 -0
  108. package/dist/agent-rooms.js +244 -0
  109. package/dist/agent-rooms.js.map +1 -0
  110. package/dist/agent-runtime.d.ts +541 -0
  111. package/dist/agent-runtime.d.ts.map +1 -0
  112. package/dist/agent-runtime.js +4260 -0
  113. package/dist/agent-runtime.js.map +1 -0
  114. package/dist/agent-skill-archive.d.ts +20 -0
  115. package/dist/agent-skill-archive.d.ts.map +1 -0
  116. package/dist/agent-skill-archive.js +316 -0
  117. package/dist/agent-skill-archive.js.map +1 -0
  118. package/dist/agent-skill-discovery.d.ts +96 -0
  119. package/dist/agent-skill-discovery.d.ts.map +1 -0
  120. package/dist/agent-skill-discovery.js +464 -0
  121. package/dist/agent-skill-discovery.js.map +1 -0
  122. package/dist/agent-skill-format.d.ts +57 -0
  123. package/dist/agent-skill-format.d.ts.map +1 -0
  124. package/dist/agent-skill-format.js +238 -0
  125. package/dist/agent-skill-format.js.map +1 -0
  126. package/dist/agent-skill-import.d.ts +64 -0
  127. package/dist/agent-skill-import.d.ts.map +1 -0
  128. package/dist/agent-skill-import.js +295 -0
  129. package/dist/agent-skill-import.js.map +1 -0
  130. package/dist/agent-skill-publish.d.ts +51 -0
  131. package/dist/agent-skill-publish.d.ts.map +1 -0
  132. package/dist/agent-skill-publish.js +136 -0
  133. package/dist/agent-skill-publish.js.map +1 -0
  134. package/dist/agent-skill-store.d.ts +252 -0
  135. package/dist/agent-skill-store.d.ts.map +1 -0
  136. package/dist/agent-skill-store.js +514 -0
  137. package/dist/agent-skill-store.js.map +1 -0
  138. package/dist/agent-skills.d.ts +85 -0
  139. package/dist/agent-skills.d.ts.map +1 -0
  140. package/dist/agent-skills.js +291 -0
  141. package/dist/agent-skills.js.map +1 -0
  142. package/dist/agent-transcript-pager.d.ts +77 -0
  143. package/dist/agent-transcript-pager.d.ts.map +1 -0
  144. package/dist/agent-transcript-pager.js +210 -0
  145. package/dist/agent-transcript-pager.js.map +1 -0
  146. package/dist/agent-user-data-parts.d.ts +20 -0
  147. package/dist/agent-user-data-parts.d.ts.map +1 -0
  148. package/dist/agent-user-data-parts.js +161 -0
  149. package/dist/agent-user-data-parts.js.map +1 -0
  150. package/dist/agent-user-transcript.d.ts +46 -0
  151. package/dist/agent-user-transcript.d.ts.map +1 -0
  152. package/dist/agent-user-transcript.js +106 -0
  153. package/dist/agent-user-transcript.js.map +1 -0
  154. package/dist/agent-voice-notes.d.ts +15 -0
  155. package/dist/agent-voice-notes.d.ts.map +1 -0
  156. package/dist/agent-voice-notes.js +17 -0
  157. package/dist/agent-voice-notes.js.map +1 -0
  158. package/dist/agent-wakes.d.ts +213 -0
  159. package/dist/agent-wakes.d.ts.map +1 -0
  160. package/dist/agent-wakes.js +534 -0
  161. package/dist/agent-wakes.js.map +1 -0
  162. package/dist/agent.d.ts +1780 -0
  163. package/dist/agent.d.ts.map +1 -0
  164. package/dist/agent.js +3123 -0
  165. package/dist/agent.js.map +1 -0
  166. package/dist/ai.d.ts +583 -0
  167. package/dist/ai.d.ts.map +1 -0
  168. package/dist/ai.js +1858 -0
  169. package/dist/ai.js.map +1 -0
  170. package/dist/app-manifest.d.ts +255 -0
  171. package/dist/app-manifest.d.ts.map +1 -0
  172. package/dist/app-manifest.js +372 -0
  173. package/dist/app-manifest.js.map +1 -0
  174. package/dist/app-users.d.ts +30 -0
  175. package/dist/app-users.d.ts.map +1 -0
  176. package/dist/app-users.js +91 -0
  177. package/dist/app-users.js.map +1 -0
  178. package/dist/audit-archive.d.ts +85 -0
  179. package/dist/audit-archive.d.ts.map +1 -0
  180. package/dist/audit-archive.js +178 -0
  181. package/dist/audit-archive.js.map +1 -0
  182. package/dist/audit.d.ts +54 -0
  183. package/dist/audit.d.ts.map +1 -0
  184. package/dist/audit.js +95 -0
  185. package/dist/audit.js.map +1 -0
  186. package/dist/auth-logger.d.ts +28 -0
  187. package/dist/auth-logger.d.ts.map +1 -0
  188. package/dist/auth-logger.js +53 -0
  189. package/dist/auth-logger.js.map +1 -0
  190. package/dist/auth-password-secret.d.ts +59 -0
  191. package/dist/auth-password-secret.d.ts.map +1 -0
  192. package/dist/auth-password-secret.js +409 -0
  193. package/dist/auth-password-secret.js.map +1 -0
  194. package/dist/auth-schema.d.ts +120 -0
  195. package/dist/auth-schema.d.ts.map +1 -0
  196. package/dist/auth-schema.js +285 -0
  197. package/dist/auth-schema.js.map +1 -0
  198. package/dist/auth.d.ts +321 -0
  199. package/dist/auth.d.ts.map +1 -0
  200. package/dist/auth.js +1562 -0
  201. package/dist/auth.js.map +1 -0
  202. package/dist/backup-archive.d.ts +257 -0
  203. package/dist/backup-archive.d.ts.map +1 -0
  204. package/dist/backup-archive.js +2068 -0
  205. package/dist/backup-archive.js.map +1 -0
  206. package/dist/backup-crypto.d.ts +313 -0
  207. package/dist/backup-crypto.d.ts.map +1 -0
  208. package/dist/backup-crypto.js +693 -0
  209. package/dist/backup-crypto.js.map +1 -0
  210. package/dist/backup-format.d.ts +200 -0
  211. package/dist/backup-format.d.ts.map +1 -0
  212. package/dist/backup-format.js +1247 -0
  213. package/dist/backup-format.js.map +1 -0
  214. package/dist/cli.d.ts +9 -0
  215. package/dist/cli.d.ts.map +1 -0
  216. package/dist/cli.js +15 -0
  217. package/dist/cli.js.map +1 -0
  218. package/dist/clock.d.ts +35 -0
  219. package/dist/clock.d.ts.map +1 -0
  220. package/dist/clock.js +83 -0
  221. package/dist/clock.js.map +1 -0
  222. package/dist/data-client.d.ts +187 -0
  223. package/dist/data-client.d.ts.map +1 -0
  224. package/dist/data-client.js +590 -0
  225. package/dist/data-client.js.map +1 -0
  226. package/dist/data-secrets.d.ts +164 -0
  227. package/dist/data-secrets.d.ts.map +1 -0
  228. package/dist/data-secrets.js +383 -0
  229. package/dist/data-secrets.js.map +1 -0
  230. package/dist/db.d.ts +453 -0
  231. package/dist/db.d.ts.map +1 -0
  232. package/dist/db.js +324 -0
  233. package/dist/db.js.map +1 -0
  234. package/dist/dev-activity.d.ts +48 -0
  235. package/dist/dev-activity.d.ts.map +1 -0
  236. package/dist/dev-activity.js +50 -0
  237. package/dist/dev-activity.js.map +1 -0
  238. package/dist/do.d.ts +429 -0
  239. package/dist/do.d.ts.map +1 -0
  240. package/dist/do.js +4526 -0
  241. package/dist/do.js.map +1 -0
  242. package/dist/email.d.ts +137 -0
  243. package/dist/email.d.ts.map +1 -0
  244. package/dist/email.js +527 -0
  245. package/dist/email.js.map +1 -0
  246. package/dist/generated/admin-assets.d.ts +16 -0
  247. package/dist/generated/admin-assets.d.ts.map +1 -0
  248. package/dist/generated/admin-assets.js +16 -0
  249. package/dist/generated/admin-assets.js.map +1 -0
  250. package/dist/generated/admin-docs-assets.d.ts +3 -0
  251. package/dist/generated/admin-docs-assets.d.ts.map +1 -0
  252. package/dist/generated/admin-docs-assets.js +3 -0
  253. package/dist/generated/admin-docs-assets.js.map +1 -0
  254. package/dist/handoff-consumer.d.ts +79 -0
  255. package/dist/handoff-consumer.d.ts.map +1 -0
  256. package/dist/handoff-consumer.js +300 -0
  257. package/dist/handoff-consumer.js.map +1 -0
  258. package/dist/handoff.d.ts +70 -0
  259. package/dist/handoff.d.ts.map +1 -0
  260. package/dist/handoff.js +228 -0
  261. package/dist/handoff.js.map +1 -0
  262. package/dist/host-auth.d.ts +47 -0
  263. package/dist/host-auth.d.ts.map +1 -0
  264. package/dist/host-auth.js +59 -0
  265. package/dist/host-auth.js.map +1 -0
  266. package/dist/host-user.d.ts +15 -0
  267. package/dist/host-user.d.ts.map +1 -0
  268. package/dist/host-user.js +23 -0
  269. package/dist/host-user.js.map +1 -0
  270. package/dist/html.d.ts +35 -0
  271. package/dist/html.d.ts.map +1 -0
  272. package/dist/html.js +634 -0
  273. package/dist/html.js.map +1 -0
  274. package/dist/http-error.d.ts +13 -0
  275. package/dist/http-error.d.ts.map +1 -0
  276. package/dist/http-error.js +15 -0
  277. package/dist/http-error.js.map +1 -0
  278. package/dist/imports.d.ts +219 -0
  279. package/dist/imports.d.ts.map +1 -0
  280. package/dist/imports.js +571 -0
  281. package/dist/imports.js.map +1 -0
  282. package/dist/index.d.ts +78 -0
  283. package/dist/index.d.ts.map +1 -0
  284. package/dist/index.js +76 -0
  285. package/dist/index.js.map +1 -0
  286. package/dist/inference-tape.d.ts +64 -0
  287. package/dist/inference-tape.d.ts.map +1 -0
  288. package/dist/inference-tape.js +278 -0
  289. package/dist/inference-tape.js.map +1 -0
  290. package/dist/internal.d.ts +15 -0
  291. package/dist/internal.d.ts.map +1 -0
  292. package/dist/internal.js +48 -0
  293. package/dist/internal.js.map +1 -0
  294. package/dist/jobs.d.ts +796 -0
  295. package/dist/jobs.d.ts.map +1 -0
  296. package/dist/jobs.js +538 -0
  297. package/dist/jobs.js.map +1 -0
  298. package/dist/json-schema.d.ts +91 -0
  299. package/dist/json-schema.d.ts.map +1 -0
  300. package/dist/json-schema.js +884 -0
  301. package/dist/json-schema.js.map +1 -0
  302. package/dist/knowledge.d.ts +33 -0
  303. package/dist/knowledge.d.ts.map +1 -0
  304. package/dist/knowledge.js +348 -0
  305. package/dist/knowledge.js.map +1 -0
  306. package/dist/local-dev-chrome.d.ts +29 -0
  307. package/dist/local-dev-chrome.d.ts.map +1 -0
  308. package/dist/local-dev-chrome.js +514 -0
  309. package/dist/local-dev-chrome.js.map +1 -0
  310. package/dist/local-dev-personas.d.ts +15 -0
  311. package/dist/local-dev-personas.d.ts.map +1 -0
  312. package/dist/local-dev-personas.js +46 -0
  313. package/dist/local-dev-personas.js.map +1 -0
  314. package/dist/mcp.d.ts +567 -0
  315. package/dist/mcp.d.ts.map +1 -0
  316. package/dist/mcp.js +2480 -0
  317. package/dist/mcp.js.map +1 -0
  318. package/dist/modules.d.ts +145 -0
  319. package/dist/modules.d.ts.map +1 -0
  320. package/dist/modules.js +164 -0
  321. package/dist/modules.js.map +1 -0
  322. package/dist/notification-client.d.ts +94 -0
  323. package/dist/notification-client.d.ts.map +1 -0
  324. package/dist/notification-client.js +127 -0
  325. package/dist/notification-client.js.map +1 -0
  326. package/dist/notifications.d.ts +447 -0
  327. package/dist/notifications.d.ts.map +1 -0
  328. package/dist/notifications.js +1625 -0
  329. package/dist/notifications.js.map +1 -0
  330. package/dist/operator-data-query.d.ts +117 -0
  331. package/dist/operator-data-query.d.ts.map +1 -0
  332. package/dist/operator-data-query.js +431 -0
  333. package/dist/operator-data-query.js.map +1 -0
  334. package/dist/operator-mcp.d.ts +63 -0
  335. package/dist/operator-mcp.d.ts.map +1 -0
  336. package/dist/operator-mcp.js +2828 -0
  337. package/dist/operator-mcp.js.map +1 -0
  338. package/dist/outbound-https.d.ts +24 -0
  339. package/dist/outbound-https.d.ts.map +1 -0
  340. package/dist/outbound-https.js +172 -0
  341. package/dist/outbound-https.js.map +1 -0
  342. package/dist/pitr.d.ts +60 -0
  343. package/dist/pitr.d.ts.map +1 -0
  344. package/dist/pitr.js +94 -0
  345. package/dist/pitr.js.map +1 -0
  346. package/dist/platform.d.ts +199 -0
  347. package/dist/platform.d.ts.map +1 -0
  348. package/dist/platform.js +196 -0
  349. package/dist/platform.js.map +1 -0
  350. package/dist/policies.d.ts +115 -0
  351. package/dist/policies.d.ts.map +1 -0
  352. package/dist/policies.js +158 -0
  353. package/dist/policies.js.map +1 -0
  354. package/dist/principal.d.ts +143 -0
  355. package/dist/principal.d.ts.map +1 -0
  356. package/dist/principal.js +174 -0
  357. package/dist/principal.js.map +1 -0
  358. package/dist/realtime.d.ts +280 -0
  359. package/dist/realtime.d.ts.map +1 -0
  360. package/dist/realtime.js +578 -0
  361. package/dist/realtime.js.map +1 -0
  362. package/dist/retrieval.d.ts +263 -0
  363. package/dist/retrieval.d.ts.map +1 -0
  364. package/dist/retrieval.js +602 -0
  365. package/dist/retrieval.js.map +1 -0
  366. package/dist/runtime-error-client.d.ts +10 -0
  367. package/dist/runtime-error-client.d.ts.map +1 -0
  368. package/dist/runtime-error-client.js +70 -0
  369. package/dist/runtime-error-client.js.map +1 -0
  370. package/dist/runtime-errors.d.ts +180 -0
  371. package/dist/runtime-errors.d.ts.map +1 -0
  372. package/dist/runtime-errors.js +572 -0
  373. package/dist/runtime-errors.js.map +1 -0
  374. package/dist/schema.d.ts +434 -0
  375. package/dist/schema.d.ts.map +1 -0
  376. package/dist/schema.js +232 -0
  377. package/dist/schema.js.map +1 -0
  378. package/dist/search.d.ts +216 -0
  379. package/dist/search.d.ts.map +1 -0
  380. package/dist/search.js +785 -0
  381. package/dist/search.js.map +1 -0
  382. package/dist/settings.d.ts +191 -0
  383. package/dist/settings.d.ts.map +1 -0
  384. package/dist/settings.js +478 -0
  385. package/dist/settings.js.map +1 -0
  386. package/dist/sql.d.ts +7 -0
  387. package/dist/sql.d.ts.map +1 -0
  388. package/dist/sql.js +30 -0
  389. package/dist/sql.js.map +1 -0
  390. package/dist/storage-client.d.ts +69 -0
  391. package/dist/storage-client.d.ts.map +1 -0
  392. package/dist/storage-client.js +469 -0
  393. package/dist/storage-client.js.map +1 -0
  394. package/dist/storage.d.ts +21 -0
  395. package/dist/storage.d.ts.map +1 -0
  396. package/dist/storage.js +82 -0
  397. package/dist/storage.js.map +1 -0
  398. package/dist/subject-domains.d.ts +15 -0
  399. package/dist/subject-domains.d.ts.map +1 -0
  400. package/dist/subject-domains.js +38 -0
  401. package/dist/subject-domains.js.map +1 -0
  402. package/dist/support.d.ts +132 -0
  403. package/dist/support.d.ts.map +1 -0
  404. package/dist/support.js +483 -0
  405. package/dist/support.js.map +1 -0
  406. package/dist/system-tables.d.ts +12 -0
  407. package/dist/system-tables.d.ts.map +1 -0
  408. package/dist/system-tables.js +225 -0
  409. package/dist/system-tables.js.map +1 -0
  410. package/dist/test.d.ts +57 -0
  411. package/dist/test.d.ts.map +1 -0
  412. package/dist/test.js +454 -0
  413. package/dist/test.js.map +1 -0
  414. package/dist/vite.d.ts +82 -0
  415. package/dist/vite.d.ts.map +1 -0
  416. package/dist/vite.js +82 -0
  417. package/dist/vite.js.map +1 -0
  418. package/dist/webpush-crypto.d.ts +39 -0
  419. package/dist/webpush-crypto.d.ts.map +1 -0
  420. package/dist/webpush-crypto.js +213 -0
  421. package/dist/webpush-crypto.js.map +1 -0
  422. package/dist/webpush-private.d.ts +11 -0
  423. package/dist/webpush-private.d.ts.map +1 -0
  424. package/dist/webpush-private.js +11 -0
  425. package/dist/webpush-private.js.map +1 -0
  426. package/dist/webpush.d.ts +86 -0
  427. package/dist/webpush.d.ts.map +1 -0
  428. package/dist/webpush.js +375 -0
  429. package/dist/webpush.js.map +1 -0
  430. package/dist/worker.d.ts +185 -0
  431. package/dist/worker.d.ts.map +1 -0
  432. package/dist/worker.js +13021 -0
  433. package/dist/worker.js.map +1 -0
  434. package/package.json +161 -8
  435. package/README.md +0 -3
@@ -0,0 +1,693 @@
1
+ export const backupProviderLimits = {
2
+ identifierBytes: 128,
3
+ wrappedKeyRecords: 16,
4
+ wrappedKeyBytes: 16 * 1024,
5
+ saltBytes: 128,
6
+ metadataBytes: 16 * 1024,
7
+ metadataDepth: 8,
8
+ metadataProperties: 128,
9
+ providerStateBytes: 64 * 1024,
10
+ participantDirectoryPageRecords: 100,
11
+ restoreInputRecords: 16,
12
+ restoreInputValueBytes: 32 * 1024,
13
+ restoreInputAggregateBytes: 64 * 1024
14
+ };
15
+ /**
16
+ * Stable, audit-safe backup failure. Callers may surface `code` and `message`;
17
+ * provider exceptions and secret-bearing values must not be attached to it.
18
+ */
19
+ export class RaybaseBackupError extends Error {
20
+ code;
21
+ constructor(code, message) {
22
+ super(message);
23
+ this.name = "RaybaseBackupError";
24
+ this.code = code;
25
+ }
26
+ }
27
+ const textEncoder = new TextEncoder();
28
+ const base64UrlAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
29
+ const base64UrlPattern = /^[A-Za-z0-9_-]+$/;
30
+ const identifierPattern = /^[A-Za-z0-9][A-Za-z0-9._:/-]*$/;
31
+ function fail(message, code = "BACKUP_PROVIDER_ENVELOPE_INVALID") {
32
+ throw new RaybaseBackupError(code, message);
33
+ }
34
+ function plainObject(value, label) {
35
+ if (!value || typeof value !== "object" || Array.isArray(value) || ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
36
+ return fail(`${label} must be a plain serializable object`);
37
+ }
38
+ const prototype = Object.getPrototypeOf(value);
39
+ if (prototype !== Object.prototype && prototype !== null) {
40
+ return fail(`${label} must be a plain serializable object`);
41
+ }
42
+ return value;
43
+ }
44
+ function boundedIdentifier(value, label) {
45
+ if (typeof value !== "string" || !identifierPattern.test(value) || textEncoder.encode(value).byteLength > backupProviderLimits.identifierBytes) {
46
+ return fail(`${label} is invalid or exceeds ${backupProviderLimits.identifierBytes} bytes`);
47
+ }
48
+ return value;
49
+ }
50
+ function boundedBase64Url(value, label, maxBytes) {
51
+ if (typeof value !== "string" || !value || !base64UrlPattern.test(value)) {
52
+ return fail(`${label} must be valid unpadded base64url data`);
53
+ }
54
+ const remainder = value.length % 4;
55
+ if (remainder === 1)
56
+ return fail(`${label} must be valid unpadded base64url data`);
57
+ const decodedBytes = Math.floor(value.length * 3 / 4);
58
+ if (decodedBytes > maxBytes)
59
+ return fail(`${label} exceeds ${maxBytes} decoded bytes`);
60
+ const finalSextet = base64UrlAlphabet.indexOf(value[value.length - 1]);
61
+ if ((remainder === 2 && (finalSextet & 0b1111) !== 0) ||
62
+ (remainder === 3 && (finalSextet & 0b11) !== 0)) {
63
+ return fail(`${label} must use canonical unpadded base64url encoding`);
64
+ }
65
+ return value;
66
+ }
67
+ function assertOnlyKeys(value, allowed, label) {
68
+ const allowedSet = new Set(allowed);
69
+ const extra = Object.keys(value).find((key) => !allowedSet.has(key));
70
+ if (extra)
71
+ fail(`${label} contains unsupported field ${extra}`);
72
+ }
73
+ function normalizeJsonValue(value, state, label) {
74
+ if (value === null || typeof value === "string" || typeof value === "boolean")
75
+ return value;
76
+ if (typeof value === "number") {
77
+ if (!Number.isFinite(value))
78
+ fail(`${label} contains a non-finite number`);
79
+ return value;
80
+ }
81
+ if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
82
+ return fail(`${label} cannot contain raw byte or key material`);
83
+ }
84
+ if (Array.isArray(value)) {
85
+ if (state.depth >= backupProviderLimits.metadataDepth)
86
+ fail(`${label} exceeds the metadata depth limit`, "BACKUP_LIMIT_EXCEEDED");
87
+ return value.map((item, index) => normalizeJsonValue(item, { ...state, depth: state.depth + 1 }, `${label}[${index}]`));
88
+ }
89
+ const object = plainObject(value, label);
90
+ if (state.depth >= backupProviderLimits.metadataDepth)
91
+ fail(`${label} exceeds the metadata depth limit`, "BACKUP_LIMIT_EXCEEDED");
92
+ const output = {};
93
+ for (const key of Object.keys(object).sort()) {
94
+ state.propertyCount.value += 1;
95
+ if (state.propertyCount.value > backupProviderLimits.metadataProperties) {
96
+ fail(`${label} exceeds the metadata property limit`, "BACKUP_LIMIT_EXCEEDED");
97
+ }
98
+ output[key] = normalizeJsonValue(object[key], { ...state, depth: state.depth + 1 }, `${label}.${key}`);
99
+ }
100
+ return output;
101
+ }
102
+ export function validateBackupJsonMetadata(value, label = "Backup provider metadata") {
103
+ const normalized = normalizeJsonValue(value, { depth: 0, propertyCount: { value: 0 } }, label);
104
+ if (textEncoder.encode(JSON.stringify(normalized)).byteLength > backupProviderLimits.metadataBytes) {
105
+ fail(`${label} exceeds ${backupProviderLimits.metadataBytes} bytes`, "BACKUP_LIMIT_EXCEEDED");
106
+ }
107
+ return normalized;
108
+ }
109
+ function validateKdfDescriptor(value) {
110
+ const object = plainObject(value, "Backup KDF descriptor");
111
+ const algorithm = object.algorithm;
112
+ if (algorithm === "HKDF-SHA-256") {
113
+ assertOnlyKeys(object, ["algorithm", "version", "salt", "info", "outputBytes"], "Backup KDF descriptor");
114
+ if (object.version !== 1 || object.outputBytes !== 32)
115
+ fail("HKDF descriptor version/output length is unsupported");
116
+ if (typeof object.info !== "string" || !object.info || textEncoder.encode(object.info).byteLength > 512) {
117
+ fail("HKDF info is invalid");
118
+ }
119
+ return {
120
+ algorithm,
121
+ version: 1,
122
+ salt: boundedBase64Url(object.salt, "HKDF salt", backupProviderLimits.saltBytes),
123
+ info: object.info,
124
+ outputBytes: 32
125
+ };
126
+ }
127
+ if (algorithm === "PBKDF2-SHA-256") {
128
+ assertOnlyKeys(object, ["algorithm", "version", "salt", "iterations", "outputBytes"], "Backup KDF descriptor");
129
+ if (!Number.isInteger(object.version) || object.version < 1)
130
+ fail("PBKDF2 descriptor version is invalid");
131
+ if (!Number.isInteger(object.iterations) || object.iterations < 1)
132
+ fail("PBKDF2 iteration count is invalid");
133
+ if (object.outputBytes !== 32)
134
+ fail("PBKDF2 output length is unsupported");
135
+ return {
136
+ algorithm,
137
+ version: object.version,
138
+ salt: boundedBase64Url(object.salt, "PBKDF2 salt", backupProviderLimits.saltBytes),
139
+ iterations: object.iterations,
140
+ outputBytes: 32
141
+ };
142
+ }
143
+ if (algorithm === "provider-defined") {
144
+ assertOnlyKeys(object, ["algorithm", "version", "name", "parameters"], "Backup KDF descriptor");
145
+ if (!Number.isInteger(object.version) || object.version < 1)
146
+ fail("Provider KDF version is invalid");
147
+ const descriptor = {
148
+ algorithm,
149
+ version: object.version,
150
+ name: boundedIdentifier(object.name, "Provider KDF name")
151
+ };
152
+ if (object.parameters !== undefined)
153
+ descriptor.parameters = validateBackupJsonMetadata(object.parameters, "Provider KDF parameters");
154
+ return descriptor;
155
+ }
156
+ return fail("Backup KDF algorithm is unsupported");
157
+ }
158
+ function validateWrappedKey(value, index) {
159
+ const object = plainObject(value, `Wrapped key record ${index}`);
160
+ assertOnlyKeys(object, ["id", "algorithm", "wrappedKey", "nonce", "shareId", "metadata"], `Wrapped key record ${index}`);
161
+ const record = {
162
+ id: boundedIdentifier(object.id, `Wrapped key record ${index} id`),
163
+ algorithm: boundedIdentifier(object.algorithm, `Wrapped key record ${index} algorithm`),
164
+ wrappedKey: boundedBase64Url(object.wrappedKey, `Wrapped key record ${index} ciphertext`, backupProviderLimits.wrappedKeyBytes)
165
+ };
166
+ if (object.nonce !== undefined)
167
+ record.nonce = boundedBase64Url(object.nonce, `Wrapped key record ${index} nonce`, 64);
168
+ if (object.shareId !== undefined)
169
+ record.shareId = boundedIdentifier(object.shareId, `Wrapped key record ${index} share id`);
170
+ if (object.metadata !== undefined)
171
+ record.metadata = validateBackupJsonMetadata(object.metadata, `Wrapped key record ${index} metadata`);
172
+ return record;
173
+ }
174
+ /**
175
+ * Validate and clone an untrusted provider envelope before it is serialized.
176
+ */
177
+ export function validateBackupKeyEnvelope(value) {
178
+ const object = plainObject(value, "Backup key envelope");
179
+ assertOnlyKeys(object, ["version", "providerId", "providerMode", "kekKeyId", "wrapAlgorithm", "kdf", "wrappedKeys", "threshold", "metadata"], "Backup key envelope");
180
+ if (object.version !== 1)
181
+ fail("Backup key envelope version is unsupported");
182
+ if (object.providerMode !== "material" && object.providerMode !== "wrapping")
183
+ fail("Backup provider mode is unsupported");
184
+ if (object.wrapAlgorithm !== "AES-256-GCM" && object.wrapAlgorithm !== "provider-defined")
185
+ fail("Backup wrap algorithm is unsupported");
186
+ if (!Array.isArray(object.wrappedKeys) || object.wrappedKeys.length < 1 || object.wrappedKeys.length > backupProviderLimits.wrappedKeyRecords) {
187
+ fail(`Backup key envelope must contain 1-${backupProviderLimits.wrappedKeyRecords} wrapped key records`);
188
+ }
189
+ const wrappedKeys = object.wrappedKeys.map(validateWrappedKey);
190
+ const ids = new Set(wrappedKeys.map((record) => record.id));
191
+ if (ids.size !== wrappedKeys.length)
192
+ fail("Backup wrapped key record ids must be unique");
193
+ const envelope = {
194
+ version: 1,
195
+ providerId: boundedIdentifier(object.providerId, "Backup provider id"),
196
+ providerMode: object.providerMode,
197
+ kekKeyId: boundedIdentifier(object.kekKeyId, "Backup KEK key id"),
198
+ wrapAlgorithm: object.wrapAlgorithm,
199
+ wrappedKeys
200
+ };
201
+ if (object.kdf !== undefined)
202
+ envelope.kdf = validateKdfDescriptor(object.kdf);
203
+ if (object.metadata !== undefined)
204
+ envelope.metadata = validateBackupJsonMetadata(object.metadata);
205
+ if (object.threshold !== undefined) {
206
+ const threshold = plainObject(object.threshold, "Backup threshold descriptor");
207
+ assertOnlyKeys(threshold, ["requiredShares", "totalShares"], "Backup threshold descriptor");
208
+ if (!Number.isInteger(threshold.requiredShares) ||
209
+ !Number.isInteger(threshold.totalShares) ||
210
+ threshold.requiredShares < 1 ||
211
+ threshold.totalShares < threshold.requiredShares) {
212
+ fail("Backup threshold descriptor is invalid");
213
+ }
214
+ const shareIds = wrappedKeys.map((record) => record.shareId).filter((shareId) => Boolean(shareId));
215
+ if (wrappedKeys.length !== threshold.totalShares || new Set(shareIds).size !== threshold.totalShares) {
216
+ fail("Backup threshold envelope does not contain every declared share", "BACKUP_THRESHOLD_UNMET");
217
+ }
218
+ envelope.threshold = {
219
+ requiredShares: threshold.requiredShares,
220
+ totalShares: threshold.totalShares
221
+ };
222
+ }
223
+ if (envelope.providerMode === "material") {
224
+ if (!envelope.kdf || envelope.kdf.algorithm !== "HKDF-SHA-256")
225
+ fail("Material provider envelopes require an HKDF descriptor");
226
+ if (envelope.wrapAlgorithm !== "AES-256-GCM" || envelope.wrappedKeys.length !== 1 || envelope.threshold) {
227
+ fail("Material provider envelope shape is invalid");
228
+ }
229
+ }
230
+ return envelope;
231
+ }
232
+ export const deploymentBackupProviderId = "raybase.deployment-secret";
233
+ export const backupDekBytes = 32;
234
+ export const backupKekMaterialMinBytes = 32;
235
+ export const backupKekMaterialMaxBytes = 128;
236
+ function ownedBuffer(value) {
237
+ const copy = new Uint8Array(value.byteLength);
238
+ copy.set(value);
239
+ return copy.buffer;
240
+ }
241
+ function encodeBase64Url(value) {
242
+ let binary = "";
243
+ for (const byte of value)
244
+ binary += String.fromCharCode(byte);
245
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
246
+ }
247
+ function decodeBase64Url(value, label, maxBytes = backupKekMaterialMaxBytes) {
248
+ boundedBase64Url(value, label, maxBytes);
249
+ const padded = `${value.replace(/-/g, "+").replace(/_/g, "/")}${"=".repeat((4 - value.length % 4) % 4)}`;
250
+ try {
251
+ const bytes = Uint8Array.from(atob(padded), (character) => character.charCodeAt(0));
252
+ if (bytes.byteLength > maxBytes)
253
+ fail(`${label} exceeds ${maxBytes} decoded bytes`);
254
+ return bytes;
255
+ }
256
+ catch {
257
+ return fail(`${label} must be valid unpadded base64url data`);
258
+ }
259
+ }
260
+ /** Validate opaque request-only provider input and return fresh Core-owned copies. */
261
+ export function validateBackupRestoreProviderInput(value) {
262
+ if (value === undefined || value === null)
263
+ return Object.freeze([]);
264
+ if (!Array.isArray(value) || value.length > backupProviderLimits.restoreInputRecords) {
265
+ fail(`Backup restore provider input supports at most ${backupProviderLimits.restoreInputRecords} records`, "BACKUP_LIMIT_EXCEEDED");
266
+ }
267
+ const copies = [];
268
+ let aggregateBytes = 0;
269
+ try {
270
+ for (const [index, candidate] of value.entries()) {
271
+ const object = plainObject(candidate, `Backup restore provider input record ${index}`);
272
+ assertOnlyKeys(object, ["id", "value"], `Backup restore provider input record ${index}`);
273
+ const id = boundedIdentifier(object.id, `Backup restore provider input record ${index} id`);
274
+ if (!(object.value instanceof Uint8Array)) {
275
+ fail("Backup restore provider input values must be bytes");
276
+ }
277
+ if (object.value.byteLength > backupProviderLimits.restoreInputValueBytes) {
278
+ fail("Backup restore provider input value exceeds its byte limit", "BACKUP_LIMIT_EXCEEDED");
279
+ }
280
+ aggregateBytes += object.value.byteLength;
281
+ if (aggregateBytes > backupProviderLimits.restoreInputAggregateBytes) {
282
+ fail("Backup restore provider input exceeds its aggregate byte limit", "BACKUP_LIMIT_EXCEEDED");
283
+ }
284
+ copies.push(Object.freeze({ id, value: object.value.slice() }));
285
+ }
286
+ if (new Set(copies.map((entry) => entry.id)).size !== copies.length) {
287
+ fail("Backup restore provider input ids must be unique");
288
+ }
289
+ return Object.freeze(copies);
290
+ }
291
+ catch (error) {
292
+ for (const entry of copies)
293
+ entry.value.fill(0);
294
+ throw error;
295
+ }
296
+ }
297
+ /** Decode the canonical JSON-facing base64url representation into mutable bytes. */
298
+ export function decodeBackupRestoreProviderInput(value) {
299
+ if (value === undefined || value === null)
300
+ return Object.freeze([]);
301
+ if (!Array.isArray(value) || value.length > backupProviderLimits.restoreInputRecords) {
302
+ fail(`Backup restore provider input supports at most ${backupProviderLimits.restoreInputRecords} records`, "BACKUP_LIMIT_EXCEEDED");
303
+ }
304
+ const decoded = [];
305
+ try {
306
+ for (const [index, candidate] of value.entries()) {
307
+ const object = plainObject(candidate, `Backup restore provider input record ${index}`);
308
+ assertOnlyKeys(object, ["id", "value"], `Backup restore provider input record ${index}`);
309
+ const id = boundedIdentifier(object.id, `Backup restore provider input record ${index} id`);
310
+ if (typeof object.value !== "string")
311
+ fail("Backup restore provider input values must be canonical base64url strings");
312
+ decoded.push(Object.freeze({
313
+ id,
314
+ value: decodeBase64Url(object.value, `Backup restore provider input record ${index} value`, backupProviderLimits.restoreInputValueBytes)
315
+ }));
316
+ }
317
+ const validated = validateBackupRestoreProviderInput(decoded);
318
+ for (const entry of decoded)
319
+ entry.value.fill(0);
320
+ return validated;
321
+ }
322
+ catch (error) {
323
+ for (const entry of decoded)
324
+ entry.value.fill(0);
325
+ throw error;
326
+ }
327
+ }
328
+ export function clearBackupRestoreProviderInput(value) {
329
+ for (const entry of value ?? [])
330
+ entry.value.fill(0);
331
+ }
332
+ /**
333
+ * Stable provider-owned inner-ciphertext AAD. It binds provider material to
334
+ * the archive identity without including the mutable envelope payload.
335
+ */
336
+ export function createBackupProviderAad(context, providerId) {
337
+ return textEncoder.encode(JSON.stringify({
338
+ domain: "raybase-backup-provider-aad-v1",
339
+ archiveId: context.archiveId,
340
+ product: context.product,
341
+ target: context.target,
342
+ targetId: context.targetId,
343
+ createdAt: context.createdAt,
344
+ providerId: boundedIdentifier(providerId, "Backup provider id")
345
+ }));
346
+ }
347
+ function randomBytes(byteLength, source) {
348
+ const value = source ? source(byteLength) : crypto.getRandomValues(new Uint8Array(byteLength));
349
+ if (!(value instanceof Uint8Array) || value.byteLength !== byteLength) {
350
+ fail(`Backup randomness source must return exactly ${byteLength} bytes`, "BACKUP_LIMIT_EXCEEDED");
351
+ }
352
+ return value.slice();
353
+ }
354
+ function backupProviderFailure(code, message) {
355
+ return new RaybaseBackupError(code, message);
356
+ }
357
+ function safeProviderError(error, fallbackCode, fallbackMessage) {
358
+ if (error instanceof RaybaseBackupError) {
359
+ const safeMessages = {
360
+ BACKUP_THRESHOLD_UNMET: "The backup key provider did not recover the required shares",
361
+ BACKUP_KEY_UNAVAILABLE: "The backup key version is unavailable",
362
+ BACKUP_PROVIDER_ENVELOPE_INVALID: "The backup key provider returned an invalid envelope",
363
+ BACKUP_ARCHIVE_CORRUPT: "The provider-wrapped archive key failed authentication",
364
+ BACKUP_ARCHIVE_IDENTITY_MISMATCH: "The provider-wrapped archive key does not match this restore target",
365
+ BACKUP_LIMIT_EXCEEDED: "The backup key provider exceeded a Core safety limit"
366
+ };
367
+ const message = safeMessages[error.code];
368
+ if (message) {
369
+ return backupProviderFailure(error.code, message);
370
+ }
371
+ }
372
+ return backupProviderFailure(fallbackCode, fallbackMessage);
373
+ }
374
+ async function deploymentKeyId(secretBytes) {
375
+ const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", ownedBuffer(secretBytes)));
376
+ try {
377
+ return `deployment-${encodeBase64Url(digest.subarray(0, 16))}`;
378
+ }
379
+ finally {
380
+ digest.fill(0);
381
+ }
382
+ }
383
+ function validateKekMaterial(value) {
384
+ if (!(value instanceof Uint8Array)) {
385
+ throw backupProviderFailure("BACKUP_PROVIDER_UNAVAILABLE", "The backup key provider returned invalid key material");
386
+ }
387
+ if (value.byteLength < backupKekMaterialMinBytes || value.byteLength > backupKekMaterialMaxBytes) {
388
+ value.fill(0);
389
+ throw backupProviderFailure("BACKUP_PROVIDER_UNAVAILABLE", `Backup KEK material must contain ${backupKekMaterialMinBytes}-${backupKekMaterialMaxBytes} bytes`);
390
+ }
391
+ return value;
392
+ }
393
+ /**
394
+ * Build Core's deployment-secret material provider. Secrets are canonical
395
+ * unpadded base64url values containing at least 256 bits of high-entropy
396
+ * material. Raw decoded keys are created per operation and then zeroed by the
397
+ * wrapping helpers; the provider closure retains only the configured strings.
398
+ */
399
+ export async function createDeploymentBackupKeyProvider(options) {
400
+ const configured = [options.currentSecret, ...(options.retainedSecrets ?? [])];
401
+ if (configured.length === 0) {
402
+ throw backupProviderFailure("BACKUP_ENCRYPTION_NOT_CONFIGURED", "RAYBASE_BACKUPS_KEY is not configured");
403
+ }
404
+ const keyIds = [];
405
+ for (const [index, encoded] of configured.entries()) {
406
+ let bytes;
407
+ try {
408
+ bytes = decodeBase64Url(encoded, index === 0 ? "RAYBASE_BACKUPS_KEY" : `Retained backup key ${index}`);
409
+ }
410
+ catch {
411
+ throw backupProviderFailure("BACKUP_ENCRYPTION_NOT_CONFIGURED", `${index === 0 ? "RAYBASE_BACKUPS_KEY" : `Retained backup key ${index}`} must be canonical base64url high-entropy key material`);
412
+ }
413
+ try {
414
+ if (bytes.byteLength < backupKekMaterialMinBytes) {
415
+ throw backupProviderFailure("BACKUP_ENCRYPTION_NOT_CONFIGURED", `Backup deployment secrets must contain at least ${backupKekMaterialMinBytes} decoded bytes`);
416
+ }
417
+ keyIds.push(await deploymentKeyId(bytes));
418
+ }
419
+ finally {
420
+ bytes.fill(0);
421
+ }
422
+ }
423
+ if (new Set(keyIds).size !== keyIds.length) {
424
+ throw backupProviderFailure("BACKUP_ENCRYPTION_NOT_CONFIGURED", "Backup deployment key versions must be unique");
425
+ }
426
+ const currentKeyId = keyIds[0];
427
+ const keyIndex = new Map(keyIds.map((keyId, index) => [keyId, index]));
428
+ return {
429
+ mode: "material",
430
+ id: deploymentBackupProviderId,
431
+ async resolveKek(request) {
432
+ if (request.context.signal.aborted) {
433
+ throw backupProviderFailure("BACKUP_PROVIDER_UNAVAILABLE", "Backup key resolution was aborted");
434
+ }
435
+ const keyId = request.kekKeyId ?? currentKeyId;
436
+ const index = keyIndex.get(keyId);
437
+ if (index === undefined) {
438
+ throw backupProviderFailure("BACKUP_KEY_UNAVAILABLE", `Backup key version ${keyId} is unavailable`);
439
+ }
440
+ const keyMaterial = decodeBase64Url(configured[index], `Backup deployment key ${keyId}`);
441
+ validateKekMaterial(keyMaterial);
442
+ return { kekKeyId: keyId, keyMaterial };
443
+ }
444
+ };
445
+ }
446
+ function keyDerivationContext(context, providerId, kekKeyId) {
447
+ return textEncoder.encode(JSON.stringify({
448
+ domain: "raybase-backup-kek-v1",
449
+ archiveId: context.archiveId,
450
+ product: context.product,
451
+ target: context.target,
452
+ targetId: context.targetId,
453
+ createdAt: context.createdAt,
454
+ providerId,
455
+ kekKeyId
456
+ }));
457
+ }
458
+ async function keyDerivationInfo(context, providerId, kekKeyId) {
459
+ const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", ownedBuffer(keyDerivationContext(context, providerId, kekKeyId))));
460
+ try {
461
+ return `raybase-backup-kek-v1:${encodeBase64Url(digest)}`;
462
+ }
463
+ finally {
464
+ digest.fill(0);
465
+ }
466
+ }
467
+ function wrapAdditionalData(context, providerId, kekKeyId) {
468
+ return textEncoder.encode(JSON.stringify({
469
+ domain: "raybase-backup-dek-wrap-v1",
470
+ archiveId: context.archiveId,
471
+ product: context.product,
472
+ target: context.target,
473
+ targetId: context.targetId,
474
+ createdAt: context.createdAt,
475
+ providerId,
476
+ kekKeyId,
477
+ wrappedKeyId: "dek"
478
+ }));
479
+ }
480
+ async function deriveKek(keyMaterial, salt, info, usage) {
481
+ const inputKey = await crypto.subtle.importKey("raw", ownedBuffer(keyMaterial), "HKDF", false, ["deriveKey"]);
482
+ return crypto.subtle.deriveKey({
483
+ name: "HKDF",
484
+ hash: "SHA-256",
485
+ salt: ownedBuffer(salt),
486
+ info: ownedBuffer(textEncoder.encode(info))
487
+ }, inputKey, { name: "AES-GCM", length: 256 }, false, [usage]);
488
+ }
489
+ async function resolveMaterial(provider, context, kekKeyId) {
490
+ let resolution;
491
+ try {
492
+ resolution = await provider.resolveKek({ context, ...(kekKeyId ? { kekKeyId } : {}) });
493
+ }
494
+ catch (error) {
495
+ throw safeProviderError(error, kekKeyId ? "BACKUP_KEY_UNAVAILABLE" : "BACKUP_PROVIDER_UNAVAILABLE", kekKeyId ? "The backup key version is unavailable" : "The backup key provider could not resolve key material");
496
+ }
497
+ if (!resolution || typeof resolution.kekKeyId !== "string") {
498
+ if (resolution?.keyMaterial instanceof Uint8Array)
499
+ resolution.keyMaterial.fill(0);
500
+ throw backupProviderFailure("BACKUP_PROVIDER_UNAVAILABLE", "The backup key provider returned an invalid key version");
501
+ }
502
+ validateKekMaterial(resolution.keyMaterial);
503
+ return resolution;
504
+ }
505
+ function selectProviderForWrap(providers) {
506
+ if (providers.keyProvider?.id === deploymentBackupProviderId) {
507
+ throw backupProviderFailure("BACKUP_PROVIDER_ENVELOPE_INVALID", `App backup providers cannot use the reserved provider id ${deploymentBackupProviderId}`);
508
+ }
509
+ if (providers.deploymentProvider && providers.deploymentProvider.id !== deploymentBackupProviderId) {
510
+ throw backupProviderFailure("BACKUP_PROVIDER_ENVELOPE_INVALID", "The deployment backup provider id is invalid");
511
+ }
512
+ const provider = providers.keyProvider ?? providers.deploymentProvider;
513
+ if (!provider) {
514
+ throw backupProviderFailure("BACKUP_ENCRYPTION_NOT_CONFIGURED", "Encrypted backups require an app key provider or RAYBASE_BACKUPS_KEY");
515
+ }
516
+ return provider;
517
+ }
518
+ function selectProviderForUnwrap(providers, envelope) {
519
+ if (providers.keyProvider?.id === deploymentBackupProviderId) {
520
+ throw backupProviderFailure("BACKUP_PROVIDER_ENVELOPE_INVALID", `App backup providers cannot use the reserved provider id ${deploymentBackupProviderId}`);
521
+ }
522
+ if (providers.deploymentProvider && providers.deploymentProvider.id !== deploymentBackupProviderId) {
523
+ throw backupProviderFailure("BACKUP_PROVIDER_ENVELOPE_INVALID", "The deployment backup provider id is invalid");
524
+ }
525
+ const provider = [providers.keyProvider, providers.deploymentProvider]
526
+ .find((candidate) => candidate?.id === envelope.providerId);
527
+ if (!provider) {
528
+ throw backupProviderFailure("BACKUP_PROVIDER_UNAVAILABLE", `Backup key provider ${envelope.providerId} is unavailable`);
529
+ }
530
+ if (provider.mode !== envelope.providerMode) {
531
+ throw backupProviderFailure("BACKUP_PROVIDER_ENVELOPE_INVALID", "Backup provider mode does not match its envelope");
532
+ }
533
+ return provider;
534
+ }
535
+ /**
536
+ * Wrap a caller-owned 32-byte data-encryption key through the selected
537
+ * provider. Core never zeroes the caller's buffer, but it does overwrite all
538
+ * transient provider material and copies it hands to app wrapping providers.
539
+ */
540
+ export async function wrapBackupDek(input) {
541
+ if (!(input.dek instanceof Uint8Array) || input.dek.byteLength !== backupDekBytes) {
542
+ throw backupProviderFailure("BACKUP_PROVIDER_ENVELOPE_INVALID", `Backup DEKs must contain exactly ${backupDekBytes} bytes`);
543
+ }
544
+ const provider = selectProviderForWrap(input.providers);
545
+ if (provider.mode === "wrapping") {
546
+ const providerDek = input.dek.slice();
547
+ try {
548
+ let rawEnvelope;
549
+ try {
550
+ rawEnvelope = await provider.wrapDek({
551
+ context: input.context,
552
+ dek: providerDek,
553
+ participants: Object.freeze([...(input.participants ?? [])])
554
+ });
555
+ }
556
+ catch (error) {
557
+ throw safeProviderError(error, "BACKUP_PROVIDER_UNAVAILABLE", "The backup key provider could not wrap the archive key");
558
+ }
559
+ const envelope = validateBackupKeyEnvelope(rawEnvelope);
560
+ if (envelope.providerId !== provider.id || envelope.providerMode !== "wrapping") {
561
+ throw backupProviderFailure("BACKUP_PROVIDER_ENVELOPE_INVALID", "Backup provider identity does not match its envelope");
562
+ }
563
+ return envelope;
564
+ }
565
+ finally {
566
+ providerDek.fill(0);
567
+ }
568
+ }
569
+ const resolution = await resolveMaterial(provider, input.context);
570
+ const salt = randomBytes(32, input.randomSource);
571
+ const nonce = randomBytes(12, input.randomSource);
572
+ try {
573
+ const info = await keyDerivationInfo(input.context, provider.id, resolution.kekKeyId);
574
+ const kek = await deriveKek(resolution.keyMaterial, salt, info, "encrypt");
575
+ const ciphertext = new Uint8Array(await crypto.subtle.encrypt({
576
+ name: "AES-GCM",
577
+ iv: ownedBuffer(nonce),
578
+ additionalData: ownedBuffer(wrapAdditionalData(input.context, provider.id, resolution.kekKeyId)),
579
+ tagLength: 128
580
+ }, kek, ownedBuffer(input.dek)));
581
+ try {
582
+ return validateBackupKeyEnvelope({
583
+ version: 1,
584
+ providerId: provider.id,
585
+ providerMode: "material",
586
+ kekKeyId: resolution.kekKeyId,
587
+ wrapAlgorithm: "AES-256-GCM",
588
+ kdf: {
589
+ algorithm: "HKDF-SHA-256",
590
+ version: 1,
591
+ salt: encodeBase64Url(salt),
592
+ info,
593
+ outputBytes: 32
594
+ },
595
+ wrappedKeys: [{
596
+ id: "dek",
597
+ algorithm: "AES-256-GCM",
598
+ wrappedKey: encodeBase64Url(ciphertext),
599
+ nonce: encodeBase64Url(nonce)
600
+ }]
601
+ });
602
+ }
603
+ finally {
604
+ ciphertext.fill(0);
605
+ }
606
+ }
607
+ finally {
608
+ resolution.keyMaterial.fill(0);
609
+ salt.fill(0);
610
+ nonce.fill(0);
611
+ }
612
+ }
613
+ /**
614
+ * Resolve and unwrap an archive DEK. The returned mutable buffer is owned by
615
+ * the caller and must be overwritten immediately after importing it into a
616
+ * non-extractable `CryptoKey`.
617
+ */
618
+ export async function unwrapBackupDek(input) {
619
+ const envelope = validateBackupKeyEnvelope(input.envelope);
620
+ const provider = selectProviderForUnwrap(input.providers, envelope);
621
+ if (provider.mode === "wrapping") {
622
+ const providerInput = validateBackupRestoreProviderInput(input.providerInput);
623
+ let dek;
624
+ try {
625
+ dek = await provider.unwrapDek({ context: input.context, envelope, providerInput });
626
+ }
627
+ catch (error) {
628
+ throw safeProviderError(error, "BACKUP_PROVIDER_UNAVAILABLE", "The backup key provider could not unwrap the archive key");
629
+ }
630
+ finally {
631
+ clearBackupRestoreProviderInput(providerInput);
632
+ }
633
+ if (!(dek instanceof Uint8Array) || dek.byteLength !== backupDekBytes) {
634
+ if (dek instanceof Uint8Array)
635
+ dek.fill(0);
636
+ throw backupProviderFailure("BACKUP_PROVIDER_ENVELOPE_INVALID", `Backup providers must return exactly ${backupDekBytes} DEK bytes`);
637
+ }
638
+ const ownedDek = dek.slice();
639
+ dek.fill(0);
640
+ return ownedDek;
641
+ }
642
+ const resolution = await resolveMaterial(provider, input.context, envelope.kekKeyId);
643
+ try {
644
+ if (resolution.kekKeyId !== envelope.kekKeyId) {
645
+ throw backupProviderFailure("BACKUP_KEY_UNAVAILABLE", "The backup key provider returned the wrong historical key version");
646
+ }
647
+ const kdf = envelope.kdf;
648
+ const wrapped = envelope.wrappedKeys[0];
649
+ if (!kdf || kdf.algorithm !== "HKDF-SHA-256" || !wrapped?.nonce) {
650
+ throw backupProviderFailure("BACKUP_PROVIDER_ENVELOPE_INVALID", "The material-provider envelope is incomplete");
651
+ }
652
+ const expectedInfo = await keyDerivationInfo(input.context, provider.id, envelope.kekKeyId);
653
+ if (kdf.info !== expectedInfo) {
654
+ throw backupProviderFailure("BACKUP_ARCHIVE_IDENTITY_MISMATCH", "The wrapped archive key does not match the restore target");
655
+ }
656
+ const salt = decodeBase64Url(kdf.salt, "Backup HKDF salt", backupProviderLimits.saltBytes);
657
+ const nonce = decodeBase64Url(wrapped.nonce, "Backup DEK wrap nonce", 64);
658
+ const ciphertext = decodeBase64Url(wrapped.wrappedKey, "Wrapped backup DEK", backupProviderLimits.wrappedKeyBytes);
659
+ try {
660
+ const kek = await deriveKek(resolution.keyMaterial, salt, kdf.info, "decrypt");
661
+ let plaintext;
662
+ try {
663
+ plaintext = await crypto.subtle.decrypt({
664
+ name: "AES-GCM",
665
+ iv: ownedBuffer(nonce),
666
+ additionalData: ownedBuffer(wrapAdditionalData(input.context, provider.id, envelope.kekKeyId)),
667
+ tagLength: 128
668
+ }, kek, ownedBuffer(ciphertext));
669
+ }
670
+ catch {
671
+ throw backupProviderFailure("BACKUP_ARCHIVE_CORRUPT", "The wrapped archive key failed authentication");
672
+ }
673
+ const dek = new Uint8Array(plaintext);
674
+ if (dek.byteLength !== backupDekBytes) {
675
+ dek.fill(0);
676
+ throw backupProviderFailure("BACKUP_PROVIDER_ENVELOPE_INVALID", "The wrapped archive key has an invalid length");
677
+ }
678
+ return dek;
679
+ }
680
+ finally {
681
+ salt.fill(0);
682
+ nonce.fill(0);
683
+ ciphertext.fill(0);
684
+ }
685
+ }
686
+ finally {
687
+ resolution.keyMaterial.fill(0);
688
+ }
689
+ }
690
+ export function generateBackupDek(randomSource) {
691
+ return randomBytes(backupDekBytes, randomSource);
692
+ }
693
+ //# sourceMappingURL=backup-crypto.js.map