@wizeworks/lens-cloud 0.3.0-alpha.1 → 0.3.0-alpha.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 (423) hide show
  1. package/README.md +58 -5
  2. package/dist/alerts/evaluate.d.ts.map +1 -1
  3. package/dist/alerts/evaluate.js +20 -6
  4. package/dist/alerts/evaluate.js.map +1 -1
  5. package/dist/alerts/notify.d.ts +13 -2
  6. package/dist/alerts/notify.d.ts.map +1 -1
  7. package/dist/alerts/notify.js +22 -16
  8. package/dist/alerts/notify.js.map +1 -1
  9. package/dist/app.d.ts +16 -2
  10. package/dist/app.d.ts.map +1 -1
  11. package/dist/auth/auth.d.ts +51 -0
  12. package/dist/auth/auth.d.ts.map +1 -0
  13. package/dist/auth/auth.js +63 -0
  14. package/dist/auth/auth.js.map +1 -0
  15. package/dist/auth/bridge.d.ts +7 -0
  16. package/dist/auth/bridge.d.ts.map +1 -0
  17. package/dist/auth/bridge.js +39 -0
  18. package/dist/auth/bridge.js.map +1 -0
  19. package/dist/auth/crypto.d.ts +0 -5
  20. package/dist/auth/crypto.d.ts.map +1 -1
  21. package/dist/auth/crypto.js +3 -20
  22. package/dist/auth/crypto.js.map +1 -1
  23. package/dist/auth/delete-user.d.ts +16 -0
  24. package/dist/auth/delete-user.d.ts.map +1 -0
  25. package/dist/auth/delete-user.js +21 -0
  26. package/dist/auth/delete-user.js.map +1 -0
  27. package/dist/auth/deps.d.ts +27 -0
  28. package/dist/auth/deps.d.ts.map +1 -0
  29. package/dist/auth/deps.js +3 -0
  30. package/dist/auth/deps.js.map +1 -0
  31. package/dist/auth/email-token.d.ts +8 -0
  32. package/dist/auth/email-token.d.ts.map +1 -0
  33. package/dist/auth/email-token.js +15 -0
  34. package/dist/auth/email-token.js.map +1 -0
  35. package/dist/auth/hooks.d.ts +4 -0
  36. package/dist/auth/hooks.d.ts.map +1 -0
  37. package/dist/auth/hooks.js +143 -0
  38. package/dist/auth/hooks.js.map +1 -0
  39. package/dist/auth/join-scope.d.ts +7 -0
  40. package/dist/auth/join-scope.d.ts.map +1 -0
  41. package/dist/auth/join-scope.js +17 -0
  42. package/dist/auth/join-scope.js.map +1 -0
  43. package/dist/auth/options.d.ts +17 -0
  44. package/dist/auth/options.d.ts.map +1 -0
  45. package/dist/auth/options.js +98 -0
  46. package/dist/auth/options.js.map +1 -0
  47. package/dist/auth/password.d.ts +10 -0
  48. package/dist/auth/password.d.ts.map +1 -0
  49. package/dist/auth/password.js +22 -0
  50. package/dist/auth/password.js.map +1 -0
  51. package/dist/auth/plugins.d.ts +4 -0
  52. package/dist/auth/plugins.d.ts.map +1 -0
  53. package/dist/auth/plugins.js +45 -0
  54. package/dist/auth/plugins.js.map +1 -0
  55. package/dist/auth/principal.d.ts +8 -3
  56. package/dist/auth/principal.d.ts.map +1 -1
  57. package/dist/auth/principal.js +13 -8
  58. package/dist/auth/principal.js.map +1 -1
  59. package/dist/auth/roles.d.ts +43 -3
  60. package/dist/auth/roles.d.ts.map +1 -1
  61. package/dist/auth/roles.js +15 -6
  62. package/dist/auth/roles.js.map +1 -1
  63. package/dist/auth/schema-names.d.ts +130 -0
  64. package/dist/auth/schema-names.d.ts.map +1 -0
  65. package/dist/auth/schema-names.js +53 -0
  66. package/dist/auth/schema-names.js.map +1 -0
  67. package/dist/auth/secret.d.ts +12 -0
  68. package/dist/auth/secret.d.ts.map +1 -0
  69. package/dist/auth/secret.js +32 -0
  70. package/dist/auth/secret.js.map +1 -0
  71. package/dist/auth/security-notices.d.ts +34 -0
  72. package/dist/auth/security-notices.d.ts.map +1 -0
  73. package/dist/auth/security-notices.js +81 -0
  74. package/dist/auth/security-notices.js.map +1 -0
  75. package/dist/auth/signup.d.ts +23 -0
  76. package/dist/auth/signup.d.ts.map +1 -0
  77. package/dist/auth/signup.js +61 -0
  78. package/dist/auth/signup.js.map +1 -0
  79. package/dist/auth/sso.d.ts +21 -0
  80. package/dist/auth/sso.d.ts.map +1 -0
  81. package/dist/auth/sso.js +35 -0
  82. package/dist/auth/sso.js.map +1 -0
  83. package/dist/auth/wire.d.ts +16 -0
  84. package/dist/auth/wire.d.ts.map +1 -0
  85. package/dist/auth/wire.js +47 -0
  86. package/dist/auth/wire.js.map +1 -0
  87. package/dist/changes.d.ts +15 -0
  88. package/dist/changes.d.ts.map +1 -0
  89. package/dist/changes.js +45 -0
  90. package/dist/changes.js.map +1 -0
  91. package/dist/cli-args.d.ts +1 -1
  92. package/dist/cli-args.d.ts.map +1 -1
  93. package/dist/cli-args.js +66 -14
  94. package/dist/cli-args.js.map +1 -1
  95. package/dist/cli.js +22 -2
  96. package/dist/cli.js.map +1 -1
  97. package/dist/config.d.ts +30 -4
  98. package/dist/config.d.ts.map +1 -1
  99. package/dist/config.js +37 -0
  100. package/dist/config.js.map +1 -1
  101. package/dist/copy-cli.d.ts +3 -0
  102. package/dist/copy-cli.d.ts.map +1 -0
  103. package/dist/copy-cli.js +24 -0
  104. package/dist/copy-cli.js.map +1 -0
  105. package/dist/db/db.d.ts +7 -2
  106. package/dist/db/db.d.ts.map +1 -1
  107. package/dist/db/db.js +28 -10
  108. package/dist/db/db.js.map +1 -1
  109. package/dist/db/migrate.d.ts +2 -2
  110. package/dist/db/migrate.d.ts.map +1 -1
  111. package/dist/db/migrate.js +15 -5
  112. package/dist/db/migrate.js.map +1 -1
  113. package/dist/db/schema-auth.d.ts +2 -0
  114. package/dist/db/schema-auth.d.ts.map +1 -0
  115. package/dist/db/schema-auth.js +93 -0
  116. package/dist/db/schema-auth.js.map +1 -0
  117. package/dist/db/schema-mail.d.ts +2 -0
  118. package/dist/db/schema-mail.d.ts.map +1 -0
  119. package/dist/db/schema-mail.js +8 -0
  120. package/dist/db/schema-mail.js.map +1 -0
  121. package/dist/db/schema-notify.d.ts +2 -0
  122. package/dist/db/schema-notify.d.ts.map +1 -0
  123. package/dist/db/schema-notify.js +26 -0
  124. package/dist/db/schema-notify.js.map +1 -0
  125. package/dist/db/schema-search.d.ts +2 -0
  126. package/dist/db/schema-search.d.ts.map +1 -0
  127. package/dist/db/schema-search.js +16 -0
  128. package/dist/db/schema-search.js.map +1 -0
  129. package/dist/db/schema-sso.d.ts +2 -0
  130. package/dist/db/schema-sso.d.ts.map +1 -0
  131. package/dist/db/schema-sso.js +17 -0
  132. package/dist/db/schema-sso.js.map +1 -0
  133. package/dist/db/schema.d.ts.map +1 -1
  134. package/dist/db/schema.js +10 -0
  135. package/dist/db/schema.js.map +1 -1
  136. package/dist/db/trigram.d.ts +4 -0
  137. package/dist/db/trigram.d.ts.map +1 -0
  138. package/dist/db/trigram.js +34 -0
  139. package/dist/db/trigram.js.map +1 -0
  140. package/dist/http/http.d.ts +2 -0
  141. package/dist/http/http.d.ts.map +1 -1
  142. package/dist/http/http.js +7 -3
  143. package/dist/http/http.js.map +1 -1
  144. package/dist/jobs.d.ts +1 -1
  145. package/dist/jobs.d.ts.map +1 -1
  146. package/dist/jobs.js +23 -11
  147. package/dist/jobs.js.map +1 -1
  148. package/dist/mail/blocks.d.ts +14 -0
  149. package/dist/mail/blocks.d.ts.map +1 -0
  150. package/dist/mail/blocks.js +35 -0
  151. package/dist/mail/blocks.js.map +1 -0
  152. package/dist/mail/content.d.ts +68 -0
  153. package/dist/mail/content.d.ts.map +1 -0
  154. package/dist/mail/content.js +6 -0
  155. package/dist/mail/content.js.map +1 -0
  156. package/dist/mail/emails-digest.d.ts +10 -0
  157. package/dist/mail/emails-digest.d.ts.map +1 -0
  158. package/dist/mail/emails-digest.js +55 -0
  159. package/dist/mail/emails-digest.js.map +1 -0
  160. package/dist/mail/emails-health.d.ts +6 -0
  161. package/dist/mail/emails-health.d.ts.map +1 -0
  162. package/dist/mail/emails-health.js +36 -0
  163. package/dist/mail/emails-health.js.map +1 -0
  164. package/dist/mail/emails-security.d.ts +14 -0
  165. package/dist/mail/emails-security.d.ts.map +1 -0
  166. package/dist/mail/emails-security.js +27 -0
  167. package/dist/mail/emails-security.js.map +1 -0
  168. package/dist/mail/emails-team.d.ts +11 -0
  169. package/dist/mail/emails-team.d.ts.map +1 -0
  170. package/dist/mail/emails-team.js +45 -0
  171. package/dist/mail/emails-team.js.map +1 -0
  172. package/dist/mail/emails.d.ts +9 -0
  173. package/dist/mail/emails.d.ts.map +1 -0
  174. package/dist/mail/emails.js +49 -0
  175. package/dist/mail/emails.js.map +1 -0
  176. package/dist/mail/layout.d.ts +6 -0
  177. package/dist/mail/layout.d.ts.map +1 -0
  178. package/dist/mail/layout.js +10 -0
  179. package/dist/mail/layout.js.map +1 -0
  180. package/dist/mail/mailer.d.ts +25 -0
  181. package/dist/mail/mailer.d.ts.map +1 -0
  182. package/dist/mail/mailer.js +50 -0
  183. package/dist/mail/mailer.js.map +1 -0
  184. package/dist/mail/preview.d.ts +6 -0
  185. package/dist/mail/preview.d.ts.map +1 -0
  186. package/dist/mail/preview.js +26 -0
  187. package/dist/mail/preview.js.map +1 -0
  188. package/dist/mail/resend.d.ts +13 -0
  189. package/dist/mail/resend.d.ts.map +1 -0
  190. package/dist/mail/resend.js +34 -0
  191. package/dist/mail/resend.js.map +1 -0
  192. package/dist/mail/samples.d.ts +3 -0
  193. package/dist/mail/samples.d.ts.map +1 -0
  194. package/dist/mail/samples.js +63 -0
  195. package/dist/mail/samples.js.map +1 -0
  196. package/dist/mail/stop-route.d.ts +4 -0
  197. package/dist/mail/stop-route.d.ts.map +1 -0
  198. package/dist/mail/stop-route.js +41 -0
  199. package/dist/mail/stop-route.js.map +1 -0
  200. package/dist/mail/svix.d.ts +8 -0
  201. package/dist/mail/svix.d.ts.map +1 -0
  202. package/dist/mail/svix.js +17 -0
  203. package/dist/mail/svix.js.map +1 -0
  204. package/dist/mail/templates.d.ts +12 -0
  205. package/dist/mail/templates.d.ts.map +1 -0
  206. package/dist/mail/templates.js +18 -0
  207. package/dist/mail/templates.js.map +1 -0
  208. package/dist/mail/text.d.ts +4 -0
  209. package/dist/mail/text.d.ts.map +1 -0
  210. package/dist/mail/text.js +17 -0
  211. package/dist/mail/text.js.map +1 -0
  212. package/dist/mail/theme.d.ts +32 -0
  213. package/dist/mail/theme.d.ts.map +1 -0
  214. package/dist/mail/theme.js +27 -0
  215. package/dist/mail/theme.js.map +1 -0
  216. package/dist/mail/unsubscribe.d.ts +14 -0
  217. package/dist/mail/unsubscribe.d.ts.map +1 -0
  218. package/dist/mail/unsubscribe.js +39 -0
  219. package/dist/mail/unsubscribe.js.map +1 -0
  220. package/dist/mail/webhook.d.ts +5 -0
  221. package/dist/mail/webhook.d.ts.map +1 -0
  222. package/dist/mail/webhook.js +41 -0
  223. package/dist/mail/webhook.js.map +1 -0
  224. package/dist/notify/digest-data.d.ts +32 -0
  225. package/dist/notify/digest-data.d.ts.map +1 -0
  226. package/dist/notify/digest-data.js +31 -0
  227. package/dist/notify/digest-data.js.map +1 -0
  228. package/dist/notify/digest.d.ts +17 -0
  229. package/dist/notify/digest.d.ts.map +1 -0
  230. package/dist/notify/digest.js +76 -0
  231. package/dist/notify/digest.js.map +1 -0
  232. package/dist/notify/health.d.ts +6 -0
  233. package/dist/notify/health.d.ts.map +1 -0
  234. package/dist/notify/health.js +42 -0
  235. package/dist/notify/health.js.map +1 -0
  236. package/dist/notify/team-describe.d.ts +22 -0
  237. package/dist/notify/team-describe.d.ts.map +1 -0
  238. package/dist/notify/team-describe.js +67 -0
  239. package/dist/notify/team-describe.js.map +1 -0
  240. package/dist/notify/team.d.ts +6 -0
  241. package/dist/notify/team.d.ts.map +1 -0
  242. package/dist/notify/team.js +56 -0
  243. package/dist/notify/team.js.map +1 -0
  244. package/dist/repo/alerts.d.ts +6 -2
  245. package/dist/repo/alerts.d.ts.map +1 -1
  246. package/dist/repo/alerts.js.map +1 -1
  247. package/dist/repo/auth-prune.d.ts +4 -0
  248. package/dist/repo/auth-prune.d.ts.map +1 -0
  249. package/dist/repo/auth-prune.js +8 -0
  250. package/dist/repo/auth-prune.js.map +1 -0
  251. package/dist/repo/mail-prefs.d.ts +35 -0
  252. package/dist/repo/mail-prefs.d.ts.map +1 -0
  253. package/dist/repo/mail-prefs.js +34 -0
  254. package/dist/repo/mail-prefs.js.map +1 -0
  255. package/dist/repo/orgs.d.ts +15 -25
  256. package/dist/repo/orgs.d.ts.map +1 -1
  257. package/dist/repo/orgs.js +18 -60
  258. package/dist/repo/orgs.js.map +1 -1
  259. package/dist/repo/services.d.ts +6 -0
  260. package/dist/repo/services.d.ts.map +1 -0
  261. package/dist/repo/services.js +16 -0
  262. package/dist/repo/services.js.map +1 -0
  263. package/dist/repo/suppressions.d.ts +8 -0
  264. package/dist/repo/suppressions.d.ts.map +1 -0
  265. package/dist/repo/suppressions.js +16 -0
  266. package/dist/repo/suppressions.js.map +1 -0
  267. package/dist/repo/trace-join.d.ts +9 -0
  268. package/dist/repo/trace-join.d.ts.map +1 -0
  269. package/dist/repo/trace-join.js +35 -0
  270. package/dist/repo/trace-join.js.map +1 -0
  271. package/dist/repo/trace-read.d.ts +6 -13
  272. package/dist/repo/trace-read.d.ts.map +1 -1
  273. package/dist/repo/trace-read.js +8 -3
  274. package/dist/repo/trace-read.js.map +1 -1
  275. package/dist/repo/trace-write.d.ts +5 -1
  276. package/dist/repo/trace-write.d.ts.map +1 -1
  277. package/dist/repo/trace-write.js +11 -2
  278. package/dist/repo/trace-write.js.map +1 -1
  279. package/dist/repo/users.d.ts +5 -16
  280. package/dist/repo/users.d.ts.map +1 -1
  281. package/dist/repo/users.js +2 -60
  282. package/dist/repo/users.js.map +1 -1
  283. package/dist/routes/alerts.d.ts.map +1 -1
  284. package/dist/routes/alerts.js +23 -6
  285. package/dist/routes/alerts.js.map +1 -1
  286. package/dist/routes/changes.d.ts +4 -0
  287. package/dist/routes/changes.d.ts.map +1 -0
  288. package/dist/routes/changes.js +19 -0
  289. package/dist/routes/changes.js.map +1 -0
  290. package/dist/routes/data.d.ts.map +1 -1
  291. package/dist/routes/data.js +24 -9
  292. package/dist/routes/data.js.map +1 -1
  293. package/dist/routes/index.d.ts.map +1 -1
  294. package/dist/routes/index.js +8 -2
  295. package/dist/routes/index.js.map +1 -1
  296. package/dist/routes/ingest.d.ts.map +1 -1
  297. package/dist/routes/ingest.js +7 -2
  298. package/dist/routes/ingest.js.map +1 -1
  299. package/dist/routes/mcp.d.ts.map +1 -1
  300. package/dist/routes/mcp.js +42 -25
  301. package/dist/routes/mcp.js.map +1 -1
  302. package/dist/routes/me.d.ts +4 -0
  303. package/dist/routes/me.d.ts.map +1 -0
  304. package/dist/routes/me.js +37 -0
  305. package/dist/routes/me.js.map +1 -0
  306. package/dist/routes/metrics.d.ts +2 -2
  307. package/dist/routes/metrics.d.ts.map +1 -1
  308. package/dist/routes/metrics.js +2 -3
  309. package/dist/routes/metrics.js.map +1 -1
  310. package/dist/routes/models.d.ts +2 -0
  311. package/dist/routes/models.d.ts.map +1 -1
  312. package/dist/routes/models.js +10 -5
  313. package/dist/routes/models.js.map +1 -1
  314. package/dist/routes/notify.d.ts +4 -0
  315. package/dist/routes/notify.d.ts.map +1 -0
  316. package/dist/routes/notify.js +55 -0
  317. package/dist/routes/notify.js.map +1 -0
  318. package/dist/routes/orgs.d.ts.map +1 -1
  319. package/dist/routes/orgs.js +34 -53
  320. package/dist/routes/orgs.js.map +1 -1
  321. package/dist/routes/projects.d.ts.map +1 -1
  322. package/dist/routes/projects.js +5 -3
  323. package/dist/routes/projects.js.map +1 -1
  324. package/dist/routes/search.d.ts +4 -0
  325. package/dist/routes/search.d.ts.map +1 -0
  326. package/dist/routes/search.js +33 -0
  327. package/dist/routes/search.js.map +1 -0
  328. package/dist/routes/shares.d.ts.map +1 -1
  329. package/dist/routes/shares.js +8 -5
  330. package/dist/routes/shares.js.map +1 -1
  331. package/dist/server.d.ts +2 -0
  332. package/dist/server.d.ts.map +1 -1
  333. package/dist/server.js +59 -16
  334. package/dist/server.js.map +1 -1
  335. package/dist/settle.d.ts +7 -6
  336. package/dist/settle.d.ts.map +1 -1
  337. package/dist/settle.js +30 -13
  338. package/dist/settle.js.map +1 -1
  339. package/dist/telemetry/cached.d.ts +11 -0
  340. package/dist/telemetry/cached.d.ts.map +1 -0
  341. package/dist/telemetry/cached.js +30 -0
  342. package/dist/telemetry/cached.js.map +1 -0
  343. package/dist/telemetry/ch/admin.d.ts +10 -0
  344. package/dist/telemetry/ch/admin.d.ts.map +1 -0
  345. package/dist/telemetry/ch/admin.js +65 -0
  346. package/dist/telemetry/ch/admin.js.map +1 -0
  347. package/dist/telemetry/ch/http.d.ts +19 -0
  348. package/dist/telemetry/ch/http.d.ts.map +1 -0
  349. package/dist/telemetry/ch/http.js +91 -0
  350. package/dist/telemetry/ch/http.js.map +1 -0
  351. package/dist/telemetry/ch/metrics.d.ts +10 -0
  352. package/dist/telemetry/ch/metrics.d.ts.map +1 -0
  353. package/dist/telemetry/ch/metrics.js +61 -0
  354. package/dist/telemetry/ch/metrics.js.map +1 -0
  355. package/dist/telemetry/ch/queries.d.ts +19 -0
  356. package/dist/telemetry/ch/queries.d.ts.map +1 -0
  357. package/dist/telemetry/ch/queries.js +30 -0
  358. package/dist/telemetry/ch/queries.js.map +1 -0
  359. package/dist/telemetry/ch/queue.d.ts +34 -0
  360. package/dist/telemetry/ch/queue.d.ts.map +1 -0
  361. package/dist/telemetry/ch/queue.js +79 -0
  362. package/dist/telemetry/ch/queue.js.map +1 -0
  363. package/dist/telemetry/ch/read.d.ts +12 -0
  364. package/dist/telemetry/ch/read.d.ts.map +1 -0
  365. package/dist/telemetry/ch/read.js +72 -0
  366. package/dist/telemetry/ch/read.js.map +1 -0
  367. package/dist/telemetry/ch/schema-facts.d.ts +6 -0
  368. package/dist/telemetry/ch/schema-facts.d.ts.map +1 -0
  369. package/dist/telemetry/ch/schema-facts.js +49 -0
  370. package/dist/telemetry/ch/schema-facts.js.map +1 -0
  371. package/dist/telemetry/ch/schema-raw.d.ts +8 -0
  372. package/dist/telemetry/ch/schema-raw.d.ts.map +1 -0
  373. package/dist/telemetry/ch/schema-raw.js +35 -0
  374. package/dist/telemetry/ch/schema-raw.js.map +1 -0
  375. package/dist/telemetry/ch/schema-rollups.d.ts +2 -0
  376. package/dist/telemetry/ch/schema-rollups.d.ts.map +1 -0
  377. package/dist/telemetry/ch/schema-rollups.js +61 -0
  378. package/dist/telemetry/ch/schema-rollups.js.map +1 -0
  379. package/dist/telemetry/ch/schema.d.ts +12 -0
  380. package/dist/telemetry/ch/schema.d.ts.map +1 -0
  381. package/dist/telemetry/ch/schema.js +25 -0
  382. package/dist/telemetry/ch/schema.js.map +1 -0
  383. package/dist/telemetry/ch/settle-rows.d.ts +13 -0
  384. package/dist/telemetry/ch/settle-rows.d.ts.map +1 -0
  385. package/dist/telemetry/ch/settle-rows.js +67 -0
  386. package/dist/telemetry/ch/settle-rows.js.map +1 -0
  387. package/dist/telemetry/ch/settle.d.ts +7 -0
  388. package/dist/telemetry/ch/settle.d.ts.map +1 -0
  389. package/dist/telemetry/ch/settle.js +96 -0
  390. package/dist/telemetry/ch/settle.js.map +1 -0
  391. package/dist/telemetry/ch/store.d.ts +16 -0
  392. package/dist/telemetry/ch/store.d.ts.map +1 -0
  393. package/dist/telemetry/ch/store.js +65 -0
  394. package/dist/telemetry/ch/store.js.map +1 -0
  395. package/dist/telemetry/ch/util.d.ts +20 -0
  396. package/dist/telemetry/ch/util.d.ts.map +1 -0
  397. package/dist/telemetry/ch/util.js +45 -0
  398. package/dist/telemetry/ch/util.js.map +1 -0
  399. package/dist/telemetry/ch/write.d.ts +11 -0
  400. package/dist/telemetry/ch/write.d.ts.map +1 -0
  401. package/dist/telemetry/ch/write.js +59 -0
  402. package/dist/telemetry/ch/write.js.map +1 -0
  403. package/dist/telemetry/copy.d.ts +9 -0
  404. package/dist/telemetry/copy.d.ts.map +1 -0
  405. package/dist/telemetry/copy.js +60 -0
  406. package/dist/telemetry/copy.js.map +1 -0
  407. package/dist/telemetry/index.d.ts +11 -0
  408. package/dist/telemetry/index.d.ts.map +1 -0
  409. package/dist/telemetry/index.js +21 -0
  410. package/dist/telemetry/index.js.map +1 -0
  411. package/dist/telemetry/pg-store.d.ts +5 -0
  412. package/dist/telemetry/pg-store.d.ts.map +1 -0
  413. package/dist/telemetry/pg-store.js +78 -0
  414. package/dist/telemetry/pg-store.js.map +1 -0
  415. package/dist/telemetry/store.d.ts +74 -0
  416. package/dist/telemetry/store.d.ts.map +1 -0
  417. package/dist/telemetry/store.js +2 -0
  418. package/dist/telemetry/store.js.map +1 -0
  419. package/package.json +20 -6
  420. package/dist/routes/auth.d.ts +0 -4
  421. package/dist/routes/auth.d.ts.map +0 -1
  422. package/dist/routes/auth.js +0 -106
  423. package/dist/routes/auth.js.map +0 -1
package/README.md CHANGED
@@ -11,7 +11,8 @@ npx @wizeworks/lens-cloud
11
11
  POSTGRES_PASSWORD=<a long secret> docker compose -f deploy/docker-compose.cloud.yml up -d
12
12
  ```
13
13
 
14
- Open http://localhost:5970/_wizelens/ and create the first account. Make an ingest key on the Team page, then on each app:
14
+ The cloud prints a one-time setup link while it has no account. Open it and create the first account. Make an ingest key on the
15
+ Team page, then on each app:
15
16
 
16
17
  ```bash
17
18
  WIZELENS_HUB=http://localhost:5970
@@ -29,9 +30,55 @@ WIZELENS_HUB_TOKEN=wl_ik_...
29
30
  | `--signup <invite\|open>` | `WIZELENS_CLOUD_SIGNUP` | `invite` |
30
31
  | `--retention-days <n>` | `WIZELENS_CLOUD_RETENTION_DAYS` | `30` |
31
32
  | `--allow-private-webhooks` | `WIZELENS_CLOUD_ALLOW_PRIVATE_WEBHOOKS=1` | off |
32
-
33
- Put it behind https. With an https public URL, the sign-in cookie is marked secure. PGlite is for trials and tests; use Postgres
34
- for real teams. Check a running cloud end to end with `node scripts/cloud-smoke.mjs <url>` from the repo (it needs a fresh database).
33
+ | `--auth-secret <text>` | `WIZELENS_CLOUD_AUTH_SECRET` | required with Postgres (32+ random characters; `2:new,1:old` rotates) |
34
+ | `--resend-api-key <key>` | `WIZELENS_CLOUD_RESEND_API_KEY` | none: mail through the [Resend](https://resend.com) API (`re_…`) |
35
+ | `--resend-webhook-secret <s>` | `WIZELENS_CLOUD_RESEND_WEBHOOK_SECRET` | none: the `whsec_…` secret of the Resend webhook (see below) |
36
+ | `--smtp-url <url>` | `WIZELENS_CLOUD_SMTP_URL` | none: or mail over SMTP (`smtp://user:pass@host:587` or `smtps://…:465`) |
37
+ | `--mail-from <address>` | `WIZELENS_CLOUD_MAIL_FROM` | `WizeLens <no-reply@<public host>>` |
38
+ | `--mail-reply-to <address>` | `WIZELENS_CLOUD_MAIL_REPLY_TO` | none: replies go to the sender |
39
+ | `--trust-proxy` | `WIZELENS_CLOUD_TRUST_PROXY=1` | off (client address from the last `X-Forwarded-For` entry) |
40
+ | `--setup-token <text>` | `WIZELENS_CLOUD_SETUP_TOKEN` | random, printed at start while no account exists |
41
+ | `--[no-]check-pwned-passwords` | `WIZELENS_CLOUD_CHECK_PWNED=1\|0` | on with Postgres, off with PGlite |
42
+ | `--sso-origins <list>` | `WIZELENS_CLOUD_SSO_ORIGINS` | none: identity provider origins for OIDC single sign-on, comma separated (`https://acme.okta.com`) |
43
+
44
+ Put it behind https, and set `--public-url` to the https address: cookies are then Secure, and passkeys and email links use it.
45
+ Sending mail needs `--public-url`. Without `--resend-api-key` or `--smtp-url`, nobody gets email: reset and invite links are in
46
+ the log, and email addresses are not confirmed. PGlite is for trials and tests; use Postgres for real teams.
47
+
48
+ ## Email
49
+
50
+ Use Resend or SMTP, not both. With Resend, each email is sent with an idempotency key and tried up to 4 times on 429 and 5xx answers.
51
+ Add a Resend webhook to `<public-url>/_wizelens/api/mail/resend` with the events `email.bounced` and `email.complained`, and set
52
+ `--resend-webhook-secret` to its signing secret. The cloud checks the signature, then keeps a suppression list: after a hard bounce
53
+ no mail goes to that address, and after a spam complaint only mail the person asked for (confirm, reset, change, delete) goes
54
+ there. Confirming the address again by link clears it.
55
+
56
+ What the cloud sends, beyond sign-in links and invites:
57
+
58
+ - **Security notices**, always, to the person: password changed, email changed (to the old address), two-step sign-in on or off,
59
+ passkey added or removed, new backup codes, and a sign-in on a browser and system the account never used.
60
+ - **Team changes**, to owners and admins: members invited, joined, left, removed, or given a new role (that member hears too), keys,
61
+ single sign-on, projects, share links, and settings. One email per batch, without the reader's own changes. A deleted
62
+ organization is told to every member.
63
+ - **Project health**, to owners and admins: a project that sends data in most hours went quiet for 2 hours, and when it is back.
64
+ - **Alerts**, from alert rules.
65
+ - **Digests**, per person and project: daily, weekly (Mondays), and monthly (the 1st), at the person's hour and time zone. Weekly
66
+ is on by default. Each has requests, error rate, average and p95 time, SQL queries, alerts fired, top errors, the slowest
67
+ endpoints, and insights. Projects with no traffic get none.
68
+
69
+ Team, health, and digest emails carry a one-click stop link (`List-Unsubscribe`, RFC 8058). People pick all of it on the Account
70
+ page. `pnpm --filter @wizeworks/lens-cloud email:preview <folder>` writes every email to HTML and text.
71
+
72
+ ## Accounts
73
+
74
+ Sign-in is [Better Auth](https://better-auth.com) (pinned to one version): email and password, passkeys, two-step codes from an
75
+ authenticator app with backup codes, password reset and email confirm by link, sessions per device (sign out one or all),
76
+ organizations with owner, admin, member, and viewer roles, email invites, single sign-on per organization (OIDC or SAML, after a
77
+ DNS proof of the email domain; Team page), and account deletion. Sign-in tries are limited per
78
+ client address across all instances. Existing accounts keep working after the upgrade; everyone signs in once more. See
79
+ `docs/CONTRACT.md`, "Tenancy and access".
80
+
81
+ Check a running cloud end to end with `node scripts/cloud-smoke.mjs <url> <setup token>` from the repo (a fresh database, no SMTP).
35
82
 
36
83
  ## Stats
37
84
 
@@ -57,7 +104,13 @@ one metric: `{ "metric": "metric", "metricName": "process.cpu.utilization", "met
57
104
  ```ts
58
105
  import { createCloud } from "@wizeworks/lens-cloud";
59
106
 
60
- const cloud = await createCloud({ database: process.env.DATABASE_URL, publicUrl: "https://wizelens.example.com" });
107
+ const cloud = await createCloud({
108
+ database: process.env.DATABASE_URL,
109
+ publicUrl: "https://wizelens.example.com",
110
+ authSecret: process.env.WIZELENS_CLOUD_AUTH_SECRET,
111
+ resendApiKey: process.env.WIZELENS_CLOUD_RESEND_API_KEY,
112
+ resendWebhookSecret: process.env.WIZELENS_CLOUD_RESEND_WEBHOOK_SECRET,
113
+ });
61
114
  console.log(await cloud.listen());
62
115
  ```
63
116
 
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/alerts/evaluate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAY,KAAK,SAAS,EAAgC,MAAM,mBAAmB,CAAC;AAG3F,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAyCnD,6CAA6C;AAC7C,wBAAsB,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKvI;AAED,8FAA8F;AAC9F,wBAAsB,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7F;AAED,gFAAgF;AAChF,wBAAsB,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAK9D"}
1
+ {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/alerts/evaluate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAY,KAAK,SAAS,EAAgC,MAAM,mBAAmB,CAAC;AAI3F,OAAO,EAAW,KAAK,MAAM,EAAe,MAAM,aAAa,CAAC;AAsDhE,6CAA6C;AAC7C,wBAAsB,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKvI;AAED,8FAA8F;AAC9F,wBAAsB,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7F;AAED,gFAAgF;AAChF,wBAAsB,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAK9D"}
@@ -1,12 +1,13 @@
1
1
  import { alertBreached, alignNow, alertContext, alertMessage, alertPage, computePage, metricAlertMessage, metricAlertUnit, metricAlertValueOf } from "@wizeworks/lens-core";
2
2
  import { addEvent, enabledRules, saveEvaluation } from "../repo/alerts.js";
3
- import { loadMetricAlertData } from "../repo/metric-read.js";
4
- import { cloudExecutor, projectRetentionMs } from "../scale-exec.js";
3
+ import { projectRetentionMs } from "../scale-exec.js";
4
+ import { alertMail } from "../mail/templates.js";
5
+ import { memberEmails } from "../repo/users.js";
5
6
  import { deliver } from "./notify.js";
6
7
  /** Names for the notice: project and the dashboard link. */
7
8
  async function noticeOf(app, rule, state, value, now) {
8
9
  const [p] = await app.db.query("SELECT name FROM projects WHERE id = $1", [rule.projectId]);
9
- const base = app.config.publicUrl ?? `http://localhost:${app.config.port}`;
10
+ const base = app.baseUrl();
10
11
  return {
11
12
  rule: rule.name,
12
13
  project: p?.name ?? rule.projectId,
@@ -22,7 +23,7 @@ async function noticeOf(app, rule, state, value, now) {
22
23
  async function measureMetric(app, rule, now) {
23
24
  const at = alignNow(now);
24
25
  const q = { projectId: rule.projectId, env: rule.env || undefined, service: rule.metricService || undefined };
25
- const data = await loadMetricAlertData(app.db, q, rule.metricName, { from: at - rule.windowMs, to: at }, at);
26
+ const data = await app.telemetry.metricAlertData(q, rule.metricName, { from: at - rule.windowMs, to: at }, at);
26
27
  const stat = rule.metricStat || "avg";
27
28
  return { value: metricAlertValueOf(data, stat), sample: data.series[0], stat };
28
29
  }
@@ -38,12 +39,25 @@ async function measure(app, rule, now) {
38
39
  if (rule.metric === "metric")
39
40
  return (await measureMetric(app, rule, now)).value;
40
41
  const retentionMs = await projectRetentionMs(app.db, rule.projectId, app.config.retentionDays);
41
- return computePage(alertPage(rule.metric), alertContext(rule.windowMs, alignNow(now)), cloudExecutor(app.db, rule.projectId, retentionMs, rule.env || undefined));
42
+ return computePage(alertPage(rule.metric), alertContext(rule.windowMs, alignNow(now)), app.telemetry.executor(rule.projectId, retentionMs, rule.env || undefined));
43
+ }
44
+ /** Webhooks, Slack, and email. Email goes only to addresses that still belong to confirmed members of the organization. */
45
+ async function outboxOf(app, projectId) {
46
+ const [p] = await app.db.query("SELECT org_id FROM projects WHERE id = $1", [projectId]);
47
+ const members = new Set(p ? await memberEmails(app.db, p.org_id, app.mailer.live) : []);
48
+ const email = (to, n) => {
49
+ const ok = to.filter((e) => members.has(e));
50
+ for (const addr of ok)
51
+ app.mailer.send(alertMail(addr, n));
52
+ const note = app.mailer.live ? `sent to ${ok.length}` : "mail is not set up (see the cloud log)";
53
+ return `email: ${note}${ok.length < to.length ? `, ${to.length - ok.length} no longer members` : ""}`;
54
+ };
55
+ return { http: app.config.fetch, allowPrivate: app.config.allowPrivateWebhooks, email };
42
56
  }
43
57
  /** Send a notice and keep it as an event. */
44
58
  export async function notify(app, rule, state, value, now) {
45
59
  const notice = await noticeOf(app, rule, state, value, now);
46
- const delivery = await deliver(rule.channels, notice, app.config.fetch, app.config.allowPrivateWebhooks);
60
+ const delivery = await deliver(rule.channels, notice, await outboxOf(app, rule.projectId));
47
61
  await addEvent(app.db, rule, { kind: state, value, message: notice.message, timeMs: now, delivery });
48
62
  return delivery;
49
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/alerts/evaluate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/alerts/evaluate.ts"],"names":[],"mappings":"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"}
@@ -10,8 +10,19 @@ export interface Notice {
10
10
  /** Link to the project in the dashboard. */
11
11
  url: string;
12
12
  }
13
+ /** How notices leave: HTTP for webhooks and Slack, and a mail function that sends to the members still allowed and says what it did. */
14
+ export interface Outbox {
15
+ http: typeof fetch;
16
+ allowPrivate: boolean;
17
+ email: (to: readonly string[], n: Notice) => string;
18
+ }
13
19
  /** A webhook may not point into the service's own network (cloud metadata, databases). Self-hosts can allow it. */
14
20
  export declare function checkTarget(url: string, allowPrivate: boolean): Promise<string | null>;
15
- /** Send to every channel. Returns one line per channel, for the event's delivery note. */
16
- export declare function deliver(channels: readonly Channel[], n: Notice, http: typeof fetch, allowPrivate: boolean): Promise<string>;
21
+ /** The notice in words, for Slack and email. */
22
+ export declare function noticeLines(n: Notice): {
23
+ subject: string;
24
+ lines: string[];
25
+ };
26
+ /** Send to every channel. Returns one line per channel, for the delivery note of the event. */
27
+ export declare function deliver(channels: readonly Channel[], n: Notice, out: Outbox): Promise<string>;
17
28
  //# sourceMappingURL=notify.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../src/alerts/notify.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;CACb;AAKD,mHAAmH;AACnH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAY5F;AASD,0FAA0F;AAC1F,wBAAsB,OAAO,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAcjI"}
1
+ {"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../src/alerts/notify.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;CACb;AAID,wIAAwI;AACxI,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,OAAO,KAAK,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,CAAC,EAAE,EAAE,SAAS,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CACrD;AAKD,mHAAmH;AACnH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAY5F;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAG3E;AAoBD,+FAA+F;AAC/F,wBAAsB,OAAO,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGnG"}
@@ -20,27 +20,33 @@ export async function checkTarget(url, allowPrivate) {
20
20
  return "The host name does not resolve.";
21
21
  return addresses.some(isPrivate) ? "Webhooks cannot point at private or local addresses." : null;
22
22
  }
23
+ /** The notice in words, for Slack and email. */
24
+ export function noticeLines(n) {
25
+ const verb = n.state === "fired" ? "Alert" : n.state === "resolved" ? "Resolved" : "Test";
26
+ return { subject: `${verb}: ${n.rule} (${n.project})`, lines: [`${verb}: ${n.rule} in ${n.project}.`, n.message] };
27
+ }
23
28
  function bodyOf(channel, n) {
24
29
  if (channel.kind === "webhook")
25
30
  return n;
26
31
  const icon = n.state === "fired" ? ":rotating_light:" : n.state === "resolved" ? ":white_check_mark:" : ":bell:";
27
- const verb = n.state === "fired" ? "Alert" : n.state === "resolved" ? "Resolved" : "Test";
28
- return { text: `${icon} *${verb}: ${n.rule}* (${n.project})\n${n.message}\n<${n.url}|Open WizeLens>` };
32
+ const { subject } = noticeLines(n);
33
+ return { text: `${icon} *${subject}*\n${n.message}\n<${n.url}|Open WizeLens>` };
34
+ }
35
+ async function post(c, n, out) {
36
+ const problem = await checkTarget(c.url, out.allowPrivate);
37
+ if (problem)
38
+ return `${c.kind}: ${problem}`;
39
+ try {
40
+ const res = await out.http(c.url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(bodyOf(c, n)), signal: AbortSignal.timeout(5000), redirect: "error" });
41
+ return `${c.kind}: ${res.ok ? "sent" : `HTTP ${res.status}`}`;
42
+ }
43
+ catch (err) {
44
+ return `${c.kind}: ${err instanceof Error ? err.message : "failed"}`;
45
+ }
29
46
  }
30
- /** Send to every channel. Returns one line per channel, for the event's delivery note. */
31
- export async function deliver(channels, n, http, allowPrivate) {
32
- const results = await Promise.all(channels.map(async (c) => {
33
- const problem = await checkTarget(c.url, allowPrivate);
34
- if (problem)
35
- return `${c.kind}: ${problem}`;
36
- try {
37
- const res = await http(c.url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(bodyOf(c, n)), signal: AbortSignal.timeout(5000), redirect: "error" });
38
- return `${c.kind}: ${res.ok ? "sent" : `HTTP ${res.status}`}`;
39
- }
40
- catch (err) {
41
- return `${c.kind}: ${err instanceof Error ? err.message : "failed"}`;
42
- }
43
- }));
47
+ /** Send to every channel. Returns one line per channel, for the delivery note of the event. */
48
+ export async function deliver(channels, n, out) {
49
+ const results = await Promise.all(channels.map(async (c) => (c.kind === "email" ? out.email(c.to, n) : post(c, n, out))));
44
50
  return results.join("; ") || "no channels";
45
51
  }
46
52
  //# sourceMappingURL=notify.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"notify.js","sourceRoot":"","sources":["../../src/alerts/notify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"notify.js","sourceRoot":"","sources":["../../src/alerts/notify.ts"],"names":[],"mappings":"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"}
package/dist/app.d.ts CHANGED
@@ -1,15 +1,29 @@
1
1
  import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { WizeAuth } from "./auth/auth.js";
3
+ import type { AuthSecret } from "./auth/secret.js";
4
+ import type { Changes } from "./changes.js";
2
5
  import type { CloudConfig } from "./config.js";
3
6
  import type { Db } from "./db/db.js";
4
7
  import type { RouteCtx } from "./http/router.js";
8
+ import type { Mailer } from "./mail/mailer.js";
9
+ import type { TelemetryStore } from "./telemetry/store.js";
5
10
  /** Everything a request handler needs. */
6
11
  export interface CloudApp {
7
12
  db: Db;
13
+ /** Spans, logs, metrics, and stats: Postgres in small mode, ClickHouse in scale mode. */
14
+ telemetry: TelemetryStore;
8
15
  config: CloudConfig;
9
16
  version: string;
10
17
  startedMs: number;
11
- /** The address for links: the public URL, or the one this request came in on. */
12
- baseUrl(req: IncomingMessage): string;
18
+ mailer: Mailer;
19
+ /** The auth secrets, newest first, for signed mail links. */
20
+ secrets: readonly AuthSecret[];
21
+ /** Better Auth. Ready once the cloud listens (its address goes into links and cookie checks). */
22
+ readonly auth: WizeAuth;
23
+ /** New data per project, for open dashboards. */
24
+ changes: Changes;
25
+ /** The address for links: the public URL, or the address the cloud listens on. */
26
+ baseUrl(req?: IncomingMessage): string;
13
27
  }
14
28
  export interface Ctx extends RouteCtx {
15
29
  app: CloudApp;
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,0CAA0C;AAC1C,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,EAAE,CAAC;IACP,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,OAAO,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC;CACvC;AAED,MAAM,WAAW,GAAI,SAAQ,QAAQ;IACnC,GAAG,EAAE,QAAQ,CAAC;CACf;AAED,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,0CAA0C;AAC1C,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,EAAE,CAAC;IACP,yFAAyF;IACzF,SAAS,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,iGAAiG;IACjG,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,kFAAkF;IAClF,OAAO,CAAC,GAAG,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,GAAI,SAAQ,QAAQ;IACnC,GAAG,EAAE,QAAQ,CAAC;CACf;AAED,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { type BetterAuthOptions } from "better-auth";
2
+ import type { AuthDeps } from "./deps.js";
3
+ /** The parts of Better Auth the cloud calls itself; the dashboard reaches the rest through `api/auth/*`. */
4
+ export interface WizeAuth {
5
+ handler: (request: Request) => Promise<Response>;
6
+ options: BetterAuthOptions;
7
+ api: {
8
+ getSession(a: {
9
+ headers: Headers;
10
+ }): Promise<{
11
+ user: SessionUser;
12
+ session: {
13
+ id: string;
14
+ };
15
+ } | null>;
16
+ verifyPassword(a: {
17
+ body: {
18
+ password: string;
19
+ };
20
+ headers: Headers;
21
+ }): Promise<unknown>;
22
+ createOrganization(a: {
23
+ body: {
24
+ name: string;
25
+ slug: string;
26
+ userId: string;
27
+ };
28
+ }): Promise<{
29
+ id: string;
30
+ name: string;
31
+ slug: string;
32
+ } | null>;
33
+ };
34
+ }
35
+ interface SessionUser {
36
+ id: string;
37
+ email: string;
38
+ name: string;
39
+ emailVerified: boolean;
40
+ twoFactorEnabled?: boolean | null;
41
+ }
42
+ /** Better Auth for the cloud: accounts, sessions, 2FA, passkeys, SSO, organizations, members, and invites (docs/CONTRACT.md, "Tenancy and access"). */
43
+ export declare function createAuth(deps: AuthDeps): WizeAuth;
44
+ /** A new organization with `userId` as owner, the cloud's default retention, a first project, and an audit line. */
45
+ export declare function createOrgFor(auth: WizeAuth, deps: Pick<AuthDeps, "db" | "retentionDays">, userId: string, name: string): Promise<{
46
+ id: string;
47
+ name: string;
48
+ slug: string;
49
+ }>;
50
+ export {};
51
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AA4C1C,4GAA4G;AAC5G,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjD,OAAO,EAAE,iBAAiB,CAAC;IAC3B,GAAG,EAAE;QACH,UAAU,CAAC,CAAC,EAAE;YAAE,OAAO,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO,CAAC;YAAE,IAAI,EAAE,WAAW,CAAC;YAAC,OAAO,EAAE;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,GAAG,IAAI,CAAC,CAAC;QACpG,cAAc,CAAC,CAAC,EAAE;YAAE,IAAI,EAAE;gBAAE,QAAQ,EAAE,MAAM,CAAA;aAAE,CAAC;YAAC,OAAO,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACtF,kBAAkB,CAAC,CAAC,EAAE;YAAE,IAAI,EAAE;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAC;gBAAC,MAAM,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,GAAG,OAAO,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC,CAAC;KAC7I,CAAC;CACH;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC;AAED,uJAAuJ;AACvJ,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAGnD;AAED,oHAAoH;AACpH,wBAAsB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAWlL"}
@@ -0,0 +1,63 @@
1
+ import { betterAuth } from "better-auth";
2
+ import { audit } from "../repo/audit.js";
3
+ import { freeSlug } from "../repo/orgs.js";
4
+ import { createProject } from "../repo/projects.js";
5
+ import { beforeDeleteUser } from "./delete-user.js";
6
+ import { authHooks } from "./hooks.js";
7
+ import { advancedOptions, AUTH_BASE_PATH, passwordAuth, rateLimitOptions, sessionOptions, userOptions } from "./options.js";
8
+ import { authPlugins } from "./plugins.js";
9
+ import { securityDbHooks } from "./security-notices.js";
10
+ import { afterSignup, confirmSsoEmail } from "./signup.js";
11
+ const ALWAYS_OFF = ["/sign-in/social", "/link-social", "/get-access-token", "/refresh-token", "/account-info", "/delete-user/callback", "/update-session"];
12
+ /** Invite ids are link secrets: no route lists them (managers see them on our Team page), nor, without real mail, by "their" email. */
13
+ const disabledPaths = (deps) => [
14
+ ...ALWAYS_OFF,
15
+ "/organization/list-invitations",
16
+ "/organization/get-full-organization",
17
+ ...(deps.mailer.live ? [] : ["/organization/list-user-invitations"]),
18
+ ];
19
+ /** Sign-up (first organization, SSO email) and security notices (new device, two-step sign-in, changed email). */
20
+ function databaseHooksOf(deps, createOrg) {
21
+ const notices = securityDbHooks(deps);
22
+ return { session: notices.session, user: { create: { before: confirmSsoEmail, after: afterSignup(deps, createOrg) }, update: notices.user?.update } };
23
+ }
24
+ function build(deps, createOrg) {
25
+ return betterAuth({
26
+ appName: "WizeLens",
27
+ baseURL: deps.publicUrl,
28
+ basePath: AUTH_BASE_PATH,
29
+ secrets: deps.secrets,
30
+ trustedOrigins: [...deps.trustedOrigins, ...deps.ssoOrigins],
31
+ telemetry: { enabled: false },
32
+ disabledPaths: disabledPaths(deps),
33
+ database: deps.db.authDatabase,
34
+ user: userOptions(deps, beforeDeleteUser(deps.db)),
35
+ ...passwordAuth(deps),
36
+ ...sessionOptions(),
37
+ rateLimit: rateLimitOptions(),
38
+ advanced: advancedOptions(deps),
39
+ databaseHooks: databaseHooksOf(deps, createOrg),
40
+ hooks: authHooks(deps),
41
+ plugins: authPlugins(deps),
42
+ });
43
+ }
44
+ /** Better Auth for the cloud: accounts, sessions, 2FA, passkeys, SSO, organizations, members, and invites (docs/CONTRACT.md, "Tenancy and access"). */
45
+ export function createAuth(deps) {
46
+ const auth = build(deps, (userId, name) => createOrgFor(auth, deps, userId, name));
47
+ return auth;
48
+ }
49
+ /** A new organization with `userId` as owner, the cloud's default retention, a first project, and an audit line. */
50
+ export async function createOrgFor(auth, deps, userId, name) {
51
+ const clean = name.trim().slice(0, 100) || "My organization";
52
+ const org = await auth.api.createOrganization({ body: { name: clean, slug: await freeSlug(deps.db, clean), userId } });
53
+ if (!org)
54
+ throw new Error("Could not create the organization.");
55
+ const now = Date.now();
56
+ await deps.db.tx(async (q) => {
57
+ await q.query("UPDATE orgs SET retention_days = $1 WHERE id = $2", [deps.retentionDays, org.id]);
58
+ await createProject(q, org.id, "My app", now);
59
+ await audit(q, org.id, `user:${userId}`, "org.create", { name: clean }, now);
60
+ });
61
+ return { id: org.id, name: org.name, slug: org.slug };
62
+ }
63
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { WizeAuth } from "./auth.js";
3
+ /** The caller's address: the socket, or (behind a proxy we run) the last address that proxy added to X-Forwarded-For. */
4
+ export declare function clientIp(req: IncomingMessage, trustProxy: boolean): string;
5
+ /** Better Auth below `/_wizelens/api/auth/`: our dashboard header on changes, a body limit, and our own client-address header. */
6
+ export declare function authHandler(auth: WizeAuth, trustProxy: boolean): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
7
+ //# sourceMappingURL=bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/auth/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAU1C,yHAAyH;AACzH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,CAI1E;AAOD,kIAAkI;AAClI,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,SAE1C,eAAe,OAAO,cAAc,KAAG,OAAO,CAAC,IAAI,CAAC,CAaxE"}
@@ -0,0 +1,39 @@
1
+ import { toNodeHandler } from "better-auth/node";
2
+ import { AUTH_BASE_PATH, CLIENT_IP_HEADER } from "./options.js";
3
+ const SAFE = new Set(["GET", "HEAD", "OPTIONS"]);
4
+ /** Paths an outside party posts to (sign-in providers), which cannot send the dashboard header. None are on yet; SSO adds them. */
5
+ const EXTERNAL = [/^\/callback\/[^/]+$/, /^\/sso\/callback(\/[^/]+)?$/, /^\/sso\/saml2\/sp\/(acs|slo)\/[^/]+$/];
6
+ const IP_HEADERS = ["x-forwarded-for", "x-real-ip", "cf-connecting-ip", "true-client-ip", "forwarded", CLIENT_IP_HEADER];
7
+ const MAX_BODY = 64 * 1024;
8
+ const MAX_EXTERNAL_BODY = 1024 * 1024;
9
+ /** The caller's address: the socket, or (behind a proxy we run) the last address that proxy added to X-Forwarded-For. */
10
+ export function clientIp(req, trustProxy) {
11
+ const forwarded = String(req.headers["x-forwarded-for"] ?? "").split(",").map((s) => s.trim()).filter(Boolean);
12
+ const ip = trustProxy && forwarded.length ? forwarded[forwarded.length - 1] : (req.socket.remoteAddress ?? "");
13
+ return ip.replace(/^::ffff:/, "");
14
+ }
15
+ function deny(res, status, message) {
16
+ res.writeHead(status, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-store" });
17
+ res.end(JSON.stringify({ error: message, message }));
18
+ }
19
+ /** Better Auth below `/_wizelens/api/auth/`: our dashboard header on changes, a body limit, and our own client-address header. */
20
+ export function authHandler(auth, trustProxy) {
21
+ const handler = toNodeHandler(auth);
22
+ return async (req, res) => {
23
+ const path = new URL(req.url ?? "/", "http://cloud.local").pathname.slice(AUTH_BASE_PATH.length);
24
+ const external = EXTERNAL.some((r) => r.test(path));
25
+ if (!SAFE.has(req.method ?? "GET")) {
26
+ if (!external && req.headers["x-wizelens-client"] !== "dashboard")
27
+ return deny(res, 403, "Missing the X-WizeLens-Client header.");
28
+ const length = Number(req.headers["content-length"] ?? 0);
29
+ if (req.headers["transfer-encoding"] || length > (external ? MAX_EXTERNAL_BODY : MAX_BODY))
30
+ return deny(res, 413, "The body is too large.");
31
+ }
32
+ const ip = clientIp(req, trustProxy);
33
+ for (const h of IP_HEADERS)
34
+ delete req.headers[h];
35
+ req.headers[CLIENT_IP_HEADER] = ip;
36
+ await handler(req, res);
37
+ };
38
+ }
39
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/auth/bridge.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,5 @@
1
- /** "scrypt$<salt>$<hash>", both base64url. */
2
- export declare function hashPassword(password: string): Promise<string>;
3
- export declare function checkPassword(password: string, stored: string): Promise<boolean>;
4
1
  /** Kinds of secret tokens. The prefix tells a person what a token is for. */
5
2
  export declare const TOKEN_PREFIX: {
6
- readonly session: "wl_s_";
7
- readonly invite: "wl_inv_";
8
3
  readonly ingest: "wl_ik_";
9
4
  readonly read: "wl_rk_";
10
5
  readonly share: "wl_sh_";
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/auth/crypto.ts"],"names":[],"mappings":"AAOA,8CAA8C;AAC9C,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIpE;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMtF;AAED,6EAA6E;AAC7E,eAAO,MAAM,YAAY;aAAK,OAAO,EAAE,OAAO;aAAE,MAAM,EAAE,SAAS;aAAE,MAAM,EAAE,QAAQ;aAAE,IAAI,EAAE,QAAQ;aAAE,KAAK,EAAE,QAAQ;CAAW,CAAC;AAChI,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,YAAY,CAAC;AAElD,mDAAmD;AACnD,eAAO,MAAM,QAAQ,SAAU,SAAS,KAAG,MAAyE,CAAC;AAErH,eAAO,MAAM,SAAS,UAAW,MAAM,KAAG,MAA0D,CAAC;AAErG,eAAO,MAAM,KAAK,QAAO,MAAsB,CAAC;AAEhD,iFAAiF;AACjF,eAAO,MAAM,MAAM,SAAU,MAAM,KAAG,MAMX,CAAC"}
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/auth/crypto.ts"],"names":[],"mappings":"AAIA,6EAA6E;AAC7E,eAAO,MAAM,YAAY;aAAK,MAAM,EAAE,QAAQ;aAAE,IAAI,EAAE,QAAQ;aAAE,KAAK,EAAE,QAAQ;CAAW,CAAC;AAC3F,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,YAAY,CAAC;AAElD,mDAAmD;AACnD,eAAO,MAAM,QAAQ,SAAU,SAAS,KAAG,MAAyE,CAAC;AAErH,eAAO,MAAM,SAAS,UAAW,MAAM,KAAG,MAA0D,CAAC;AAErG,eAAO,MAAM,KAAK,QAAO,MAAsB,CAAC;AAEhD,iFAAiF;AACjF,eAAO,MAAM,MAAM,SAAU,MAAM,KAAG,MAMX,CAAC"}
@@ -1,24 +1,7 @@
1
- import { createHash, randomBytes, randomUUID, scrypt, timingSafeEqual } from "node:crypto";
2
- import { promisify } from "node:util";
3
- const scryptAsync = promisify(scrypt);
4
- const SCRYPT = { N: 16384, r: 8, p: 1, maxmem: 64 * 1024 * 1024 };
5
- const KEY_LENGTH = 32;
6
- /** "scrypt$<salt>$<hash>", both base64url. */
7
- export async function hashPassword(password) {
8
- const salt = randomBytes(16);
9
- const key = await scryptAsync(password, salt, KEY_LENGTH, SCRYPT);
10
- return `scrypt$${salt.toString("base64url")}$${key.toString("base64url")}`;
11
- }
12
- export async function checkPassword(password, stored) {
13
- const [kind, salt, hash] = stored.split("$");
14
- if (kind !== "scrypt" || !salt || !hash)
15
- return false;
16
- const expected = Buffer.from(hash, "base64url");
17
- const key = await scryptAsync(password, Buffer.from(salt, "base64url"), expected.length, SCRYPT);
18
- return key.length === expected.length && timingSafeEqual(key, expected);
19
- }
1
+ import { createHash, randomBytes, randomUUID } from "node:crypto";
2
+ // Our own secrets: data-plane keys and share links. Passwords, sessions, and invites are Better Auth's.
20
3
  /** Kinds of secret tokens. The prefix tells a person what a token is for. */
21
- export const TOKEN_PREFIX = { session: "wl_s_", invite: "wl_inv_", ingest: "wl_ik_", read: "wl_rk_", share: "wl_sh_" };
4
+ export const TOKEN_PREFIX = { ingest: "wl_ik_", read: "wl_rk_", share: "wl_sh_" };
22
5
  /** A new random token. Only its hash is stored. */
23
6
  export const newToken = (kind) => `${TOKEN_PREFIX[kind]}${randomBytes(24).toString("base64url")}`;
24
7
  export const hashToken = (token) => createHash("sha256").update(token).digest("hex");
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/auth/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAyF,CAAC;AAC9H,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;AAClE,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB,8CAA8C;AAC9C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,IAAI,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAClE,OAAO,UAAU,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,MAAc;IAClE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjG,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AAC1E,CAAC;AAED,6EAA6E;AAC7E,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAW,CAAC;AAGhI,mDAAmD;AACnD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAe,EAAU,EAAE,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;AAErH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAErG,MAAM,CAAC,MAAM,KAAK,GAAG,GAAW,EAAE,CAAC,UAAU,EAAE,CAAC;AAEhD,iFAAiF;AACjF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAU,EAAE,CAC7C,IAAI;KACD,WAAW,EAAE;KACb,SAAS,CAAC,MAAM,CAAC;KACjB,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;KAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;KACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC"}
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/auth/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAElE,wGAAwG;AAExG,6EAA6E;AAC7E,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAW,CAAC;AAG3F,mDAAmD;AACnD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAe,EAAU,EAAE,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;AAErH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAErG,MAAM,CAAC,MAAM,KAAK,GAAG,GAAW,EAAE,CAAC,UAAU,EAAE,CAAC;AAEhD,iFAAiF;AACjF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAU,EAAE,CAC7C,IAAI;KACD,WAAW,EAAE;KACb,SAAS,CAAC,MAAM,CAAC;KACjB,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;KAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;KACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { Db, Queryable } from "../db/db.js";
2
+ export interface OwnedOrg {
3
+ id: string;
4
+ name: string;
5
+ owners: number;
6
+ members: number;
7
+ }
8
+ /** Organizations the person owns, with how many owners and members each has. */
9
+ export declare const ownedOrgs: (q: Queryable, userId: string) => Promise<OwnedOrg[]>;
10
+ /** Organizations that would be left without an owner: they block deleting the account. */
11
+ export declare const blockingOrgs: (orgs: readonly OwnedOrg[]) => OwnedOrg[];
12
+ /** Before an account goes: refuse while it is the last owner of a team; delete the organizations it is alone in, with their data. */
13
+ export declare function beforeDeleteUser(db: Db): (user: {
14
+ id: string;
15
+ }) => Promise<void>;
16
+ //# sourceMappingURL=delete-user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-user.d.ts","sourceRoot":"","sources":["../../src/auth/delete-user.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGjD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,gFAAgF;AAChF,eAAO,MAAM,SAAS,MAAO,SAAS,UAAU,MAAM,KAAG,OAAO,CAAC,QAAQ,EAAE,CAOxE,CAAC;AAEJ,0FAA0F;AAC1F,eAAO,MAAM,YAAY,SAAU,SAAS,QAAQ,EAAE,eAAwD,CAAC;AAE/G,qIAAqI;AACrI,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,EAAE,UACjB;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,KAAG,OAAO,CAAC,IAAI,CAAC,CAMnD"}
@@ -0,0 +1,21 @@
1
+ import { APIError } from "better-auth/api";
2
+ import { deleteOrgEverything } from "../repo/orgs.js";
3
+ /** Organizations the person owns, with how many owners and members each has. */
4
+ export const ownedOrgs = (q, userId) => q.query(`SELECT o.id, o.name,
5
+ (SELECT count(*)::int FROM members x WHERE x.org_id = o.id AND x.role = 'owner') AS owners,
6
+ (SELECT count(*)::int FROM members x WHERE x.org_id = o.id) AS members
7
+ FROM members m JOIN orgs o ON o.id = m.org_id WHERE m.user_id = $1 AND m.role = 'owner' ORDER BY o.name`, [userId]);
8
+ /** Organizations that would be left without an owner: they block deleting the account. */
9
+ export const blockingOrgs = (orgs) => orgs.filter((o) => o.owners === 1 && o.members > 1);
10
+ /** Before an account goes: refuse while it is the last owner of a team; delete the organizations it is alone in, with their data. */
11
+ export function beforeDeleteUser(db) {
12
+ return async (user) => {
13
+ const orgs = await ownedOrgs(db, user.id);
14
+ const blocked = blockingOrgs(orgs);
15
+ if (blocked.length)
16
+ throw new APIError("BAD_REQUEST", { message: `Make someone else an owner of ${blocked.map((o) => o.name).join(", ")} first, or delete it.` });
17
+ for (const o of orgs.filter((x) => x.members === 1))
18
+ await db.tx((q) => deleteOrgEverything(q, o.id));
19
+ };
20
+ }
21
+ //# sourceMappingURL=delete-user.js.map