@estifanos-sh/convex-auth 0.0.2 → 0.0.4

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 (438) hide show
  1. package/README.md +29 -6
  2. package/dist/bin.js +2 -34
  3. package/dist/browser/index.d.ts +2 -2
  4. package/dist/browser/index.d.ts.map +1 -1
  5. package/dist/browser/index.js +15 -9
  6. package/dist/browser/index.js.map +1 -1
  7. package/dist/client/core/types.d.ts +68 -97
  8. package/dist/client/core/types.d.ts.map +1 -1
  9. package/dist/client/core/types.js.map +1 -1
  10. package/dist/client/errors.d.ts +15 -0
  11. package/dist/client/errors.d.ts.map +1 -0
  12. package/dist/client/errors.js +8 -1
  13. package/dist/client/errors.js.map +1 -1
  14. package/dist/client/factors/device.js +4 -4
  15. package/dist/client/factors/device.js.map +1 -1
  16. package/dist/client/factors/totp.js +20 -12
  17. package/dist/client/factors/totp.js.map +1 -1
  18. package/dist/client/factors/webauthn.js +6 -2
  19. package/dist/client/factors/webauthn.js.map +1 -1
  20. package/dist/client/index.d.ts +6 -3
  21. package/dist/client/index.d.ts.map +1 -1
  22. package/dist/client/index.js +13 -10
  23. package/dist/client/index.js.map +1 -1
  24. package/dist/component/_generated/api.d.ts +13 -3
  25. package/dist/component/_generated/api.d.ts.map +1 -1
  26. package/dist/component/_generated/api.js.map +1 -1
  27. package/dist/component/_generated/component.d.ts +365 -74
  28. package/dist/component/_generated/component.d.ts.map +1 -1
  29. package/dist/component/_generated/dataModel.d.ts +2 -2
  30. package/dist/component/_generated/dataModel.d.ts.map +1 -1
  31. package/dist/component/_generated/server.d.ts +13 -2
  32. package/dist/component/_generated/server.d.ts.map +1 -1
  33. package/dist/component/_generated/server.js +2 -1
  34. package/dist/component/_generated/server.js.map +1 -1
  35. package/dist/component/account.d.ts +52 -38
  36. package/dist/component/account.d.ts.map +1 -1
  37. package/dist/component/account.js +42 -23
  38. package/dist/component/account.js.map +1 -1
  39. package/dist/component/batch.d.ts +3 -0
  40. package/dist/component/batch.d.ts.map +1 -0
  41. package/dist/component/batch.js +17 -0
  42. package/dist/component/batch.js.map +1 -0
  43. package/dist/component/connection/audit.d.ts +30 -27
  44. package/dist/component/connection/audit.d.ts.map +1 -1
  45. package/dist/component/connection/audit.js +16 -23
  46. package/dist/component/connection/audit.js.map +1 -1
  47. package/dist/component/connection/cache.d.ts +6 -6
  48. package/dist/component/connection/cache.js +0 -1
  49. package/dist/component/connection/cache.js.map +1 -1
  50. package/dist/component/connection/domain/verification.d.ts +19 -19
  51. package/dist/component/connection/domain/verification.js +1 -2
  52. package/dist/component/connection/domain/verification.js.map +1 -1
  53. package/dist/component/connection/domain.d.ts +20 -20
  54. package/dist/component/connection/domain.js +1 -2
  55. package/dist/component/connection/domain.js.map +1 -1
  56. package/dist/component/connection/saml/assertion.d.ts +4 -4
  57. package/dist/component/connection/saml/assertion.js +0 -1
  58. package/dist/component/connection/saml/assertion.js.map +1 -1
  59. package/dist/component/connection/saml/request.d.ts +8 -9
  60. package/dist/component/connection/saml/request.d.ts.map +1 -1
  61. package/dist/component/connection/saml/request.js +0 -2
  62. package/dist/component/connection/saml/request.js.map +1 -1
  63. package/dist/component/connection/scim/config.d.ts +13 -13
  64. package/dist/component/connection/scim/config.d.ts.map +1 -1
  65. package/dist/component/connection/scim/config.js +2 -2
  66. package/dist/component/connection/scim/config.js.map +1 -1
  67. package/dist/component/connection/scim/identity.d.ts +122 -61
  68. package/dist/component/connection/scim/identity.d.ts.map +1 -1
  69. package/dist/component/connection/scim/identity.js +408 -60
  70. package/dist/component/connection/scim/identity.js.map +1 -1
  71. package/dist/component/connection/secret.d.ts +15 -15
  72. package/dist/component/connection/secret.d.ts.map +1 -1
  73. package/dist/component/connection/secret.js +2 -2
  74. package/dist/component/connection/secret.js.map +1 -1
  75. package/dist/component/connection/webhook/delivery.d.ts +69 -53
  76. package/dist/component/connection/webhook/delivery.d.ts.map +1 -1
  77. package/dist/component/connection/webhook/delivery.js +129 -172
  78. package/dist/component/connection/webhook/delivery.js.map +1 -1
  79. package/dist/component/connection/webhook/endpoint.d.ts +21 -21
  80. package/dist/component/connection/webhook/endpoint.d.ts.map +1 -1
  81. package/dist/component/connection/webhook/endpoint.js +2 -2
  82. package/dist/component/connection/webhook/endpoint.js.map +1 -1
  83. package/dist/component/connection/webhook/events.d.ts +26 -0
  84. package/dist/component/connection/webhook/events.d.ts.map +1 -0
  85. package/dist/component/connection/webhook/events.js +39 -0
  86. package/dist/component/connection/webhook/events.js.map +1 -0
  87. package/dist/component/connection.d.ts +39 -39
  88. package/dist/component/connection.d.ts.map +1 -1
  89. package/dist/component/connection.js +9 -9
  90. package/dist/component/connection.js.map +1 -1
  91. package/dist/component/context.d.ts +115 -0
  92. package/dist/component/context.d.ts.map +1 -0
  93. package/dist/component/context.js +49 -0
  94. package/dist/component/context.js.map +1 -0
  95. package/dist/component/convex.config.d.ts +2 -2
  96. package/dist/component/crons.d.ts +2 -2
  97. package/dist/component/documents.d.ts +1244 -0
  98. package/dist/component/documents.d.ts.map +1 -0
  99. package/dist/component/documents.js +44 -0
  100. package/dist/component/documents.js.map +1 -0
  101. package/dist/component/event.d.ts +142 -141
  102. package/dist/component/event.d.ts.map +1 -1
  103. package/dist/component/event.js +90 -119
  104. package/dist/component/event.js.map +1 -1
  105. package/dist/component/eventstream.d.ts +30 -0
  106. package/dist/component/eventstream.d.ts.map +1 -0
  107. package/dist/component/eventstream.js +60 -0
  108. package/dist/component/eventstream.js.map +1 -0
  109. package/dist/component/factor/device.d.ts +25 -24
  110. package/dist/component/factor/device.d.ts.map +1 -1
  111. package/dist/component/factor/device.js +7 -4
  112. package/dist/component/factor/device.js.map +1 -1
  113. package/dist/component/factor/passkey.d.ts +173 -85
  114. package/dist/component/factor/passkey.d.ts.map +1 -1
  115. package/dist/component/factor/passkey.js +138 -27
  116. package/dist/component/factor/passkey.js.map +1 -1
  117. package/dist/component/factor/totp.d.ts +56 -50
  118. package/dist/component/factor/totp.d.ts.map +1 -1
  119. package/dist/component/factor/totp.js +6 -5
  120. package/dist/component/factor/totp.js.map +1 -1
  121. package/dist/component/group/active.d.ts +326 -22
  122. package/dist/component/group/active.d.ts.map +1 -1
  123. package/dist/component/group/active.js +22 -13
  124. package/dist/component/group/active.js.map +1 -1
  125. package/dist/component/group/invite.d.ts +30 -30
  126. package/dist/component/group/invite.d.ts.map +1 -1
  127. package/dist/component/group/invite.js +2 -2
  128. package/dist/component/group/invite.js.map +1 -1
  129. package/dist/component/group/member.d.ts +36 -36
  130. package/dist/component/group/member.d.ts.map +1 -1
  131. package/dist/component/group/member.js +5 -3
  132. package/dist/component/group/member.js.map +1 -1
  133. package/dist/component/group.d.ts +49 -64
  134. package/dist/component/group.d.ts.map +1 -1
  135. package/dist/component/group.js +5 -3
  136. package/dist/component/group.js.map +1 -1
  137. package/dist/component/http.d.ts +2 -2
  138. package/dist/component/index.d.ts +0 -10
  139. package/dist/component/index.js +1 -3
  140. package/dist/component/limits.d.ts +5 -4
  141. package/dist/component/limits.d.ts.map +1 -1
  142. package/dist/component/limits.js +7 -4
  143. package/dist/component/limits.js.map +1 -1
  144. package/dist/component/maintenance.d.ts +6 -3
  145. package/dist/component/maintenance.d.ts.map +1 -1
  146. package/dist/component/maintenance.js +45 -6
  147. package/dist/component/maintenance.js.map +1 -1
  148. package/dist/component/model.d.ts +847 -1723
  149. package/dist/component/model.d.ts.map +1 -1
  150. package/dist/component/model.js +28 -317
  151. package/dist/component/model.js.map +1 -1
  152. package/dist/component/modules.d.ts +11 -5
  153. package/dist/component/modules.d.ts.map +1 -1
  154. package/dist/component/modules.js +4 -1
  155. package/dist/component/modules.js.map +1 -1
  156. package/dist/component/oauth/client.d.ts +20 -20
  157. package/dist/component/oauth/client.d.ts.map +1 -1
  158. package/dist/component/oauth/client.js +2 -2
  159. package/dist/component/oauth/client.js.map +1 -1
  160. package/dist/component/oauth/code.d.ts +14 -14
  161. package/dist/component/oauth/code.js +1 -2
  162. package/dist/component/oauth/code.js.map +1 -1
  163. package/dist/component/oauth/refresh.d.ts +20 -20
  164. package/dist/component/oauth/refresh.js +1 -2
  165. package/dist/component/oauth/refresh.js.map +1 -1
  166. package/dist/component/schema.d.ts +1148 -607
  167. package/dist/component/schema.d.ts.map +1 -1
  168. package/dist/component/schema.js +43 -15
  169. package/dist/component/schema.js.map +1 -1
  170. package/dist/component/session.d.ts +68 -32
  171. package/dist/component/session.d.ts.map +1 -1
  172. package/dist/component/session.js +118 -34
  173. package/dist/component/session.js.map +1 -1
  174. package/dist/component/token/continuation.d.ts +47 -18
  175. package/dist/component/token/continuation.d.ts.map +1 -1
  176. package/dist/component/token/continuation.js +76 -18
  177. package/dist/component/token/continuation.js.map +1 -1
  178. package/dist/component/token/enrollment.d.ts +42 -0
  179. package/dist/component/token/enrollment.d.ts.map +1 -0
  180. package/dist/component/token/enrollment.js +57 -0
  181. package/dist/component/token/enrollment.js.map +1 -0
  182. package/dist/component/token/pkce.d.ts +31 -24
  183. package/dist/component/token/pkce.d.ts.map +1 -1
  184. package/dist/component/token/pkce.js +15 -20
  185. package/dist/component/token/pkce.js.map +1 -1
  186. package/dist/component/token/refresh.d.ts +42 -35
  187. package/dist/component/token/refresh.d.ts.map +1 -1
  188. package/dist/component/token/refresh.js +16 -8
  189. package/dist/component/token/refresh.js.map +1 -1
  190. package/dist/component/token/verification.d.ts +34 -30
  191. package/dist/component/token/verification.d.ts.map +1 -1
  192. package/dist/component/token/verification.js +7 -6
  193. package/dist/component/token/verification.js.map +1 -1
  194. package/dist/component/user/email.d.ts +21 -21
  195. package/dist/component/user/email.d.ts.map +1 -1
  196. package/dist/component/user/email.js +2 -2
  197. package/dist/component/user/email.js.map +1 -1
  198. package/dist/component/user/key.d.ts +36 -36
  199. package/dist/component/user/key.d.ts.map +1 -1
  200. package/dist/component/user/key.js +2 -2
  201. package/dist/component/user/key.js.map +1 -1
  202. package/dist/component/user.d.ts +52 -48
  203. package/dist/component/user.d.ts.map +1 -1
  204. package/dist/component/user.js +157 -36
  205. package/dist/component/user.js.map +1 -1
  206. package/dist/expo/index.d.ts +4 -4
  207. package/dist/expo/index.d.ts.map +1 -1
  208. package/dist/expo/index.js +20 -13
  209. package/dist/expo/index.js.map +1 -1
  210. package/dist/node_modules/.pnpm/@opentelemetry_sdk-logs@0.214.0_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-logs/build/src/export/ReadableLogRecord.d.ts +2 -2
  211. package/dist/node_modules/.pnpm/@opentelemetry_sdk-logs@0.214.0_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-logs/build/src/export/SdkLogRecord.d.ts +1 -1
  212. package/dist/node_modules/.pnpm/@opentelemetry_sdk-metrics@2.6.1_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-metrics/build/src/MeterProvider.d.ts +2 -2
  213. package/dist/node_modules/.pnpm/@opentelemetry_sdk-metrics@2.6.1_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-metrics/build/src/export/MetricData.d.ts +1 -1
  214. package/dist/node_modules/.pnpm/@opentelemetry_sdk-trace-base@2.6.1_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-trace-base/build/src/Span.d.ts +1 -1
  215. package/dist/node_modules/.pnpm/@opentelemetry_sdk-trace-base@2.6.1_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-trace-base/build/src/export/ReadableSpan.d.ts +1 -1
  216. package/dist/node_modules/.pnpm/@opentelemetry_sdk-trace-base@2.6.1_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-trace-base/build/src/types.d.ts +1 -1
  217. package/dist/otel.d.ts +1 -1
  218. package/dist/providers/anonymous.d.ts +11 -5
  219. package/dist/providers/anonymous.d.ts.map +1 -1
  220. package/dist/providers/anonymous.js +4 -1
  221. package/dist/providers/anonymous.js.map +1 -1
  222. package/dist/providers/apple.d.ts +1 -1
  223. package/dist/providers/apple.js +19 -4
  224. package/dist/providers/apple.js.map +1 -1
  225. package/dist/providers/credentials.d.ts +22 -14
  226. package/dist/providers/credentials.d.ts.map +1 -1
  227. package/dist/providers/credentials.js +2 -0
  228. package/dist/providers/credentials.js.map +1 -1
  229. package/dist/providers/custom.d.ts +3 -3
  230. package/dist/providers/custom.d.ts.map +1 -1
  231. package/dist/providers/custom.js.map +1 -1
  232. package/dist/providers/email.d.ts +3 -3
  233. package/dist/providers/email.d.ts.map +1 -1
  234. package/dist/providers/email.js.map +1 -1
  235. package/dist/providers/github.d.ts +1 -1
  236. package/dist/providers/github.d.ts.map +1 -1
  237. package/dist/providers/github.js +9 -4
  238. package/dist/providers/github.js.map +1 -1
  239. package/dist/providers/google.d.ts +1 -1
  240. package/dist/providers/google.d.ts.map +1 -1
  241. package/dist/providers/google.js +9 -4
  242. package/dist/providers/google.js.map +1 -1
  243. package/dist/providers/microsoft.d.ts +1 -1
  244. package/dist/providers/microsoft.d.ts.map +1 -1
  245. package/dist/providers/microsoft.js +12 -4
  246. package/dist/providers/microsoft.js.map +1 -1
  247. package/dist/providers/password.d.ts +117 -15
  248. package/dist/providers/password.d.ts.map +1 -1
  249. package/dist/providers/password.js +71 -26
  250. package/dist/providers/password.js.map +1 -1
  251. package/dist/providers/phone.d.ts +4 -3
  252. package/dist/providers/phone.d.ts.map +1 -1
  253. package/dist/providers/phone.js.map +1 -1
  254. package/dist/providers/webauthn.d.ts.map +1 -1
  255. package/dist/providers/webauthn.js +6 -0
  256. package/dist/providers/webauthn.js.map +1 -1
  257. package/dist/react/index.d.ts +40 -41
  258. package/dist/react/index.d.ts.map +1 -1
  259. package/dist/react/index.js +27 -52
  260. package/dist/react/index.js.map +1 -1
  261. package/dist/server/auth.d.ts +224 -126
  262. package/dist/server/auth.d.ts.map +1 -1
  263. package/dist/server/auth.js +44 -25
  264. package/dist/server/auth.js.map +1 -1
  265. package/dist/server/component/factor/db.js +13 -6
  266. package/dist/server/component/factor/db.js.map +1 -1
  267. package/dist/server/config.d.ts +2 -1
  268. package/dist/server/connection/domain.d.ts +4 -65
  269. package/dist/server/connection/domain.d.ts.map +1 -1
  270. package/dist/server/connection/domain.js +29 -5
  271. package/dist/server/connection/domain.js.map +1 -1
  272. package/dist/server/connection/group/service.js +7 -5
  273. package/dist/server/connection/group/service.js.map +1 -1
  274. package/dist/server/connection/http.js +136 -291
  275. package/dist/server/connection/http.js.map +1 -1
  276. package/dist/server/connection/oidc.js +8 -17
  277. package/dist/server/connection/oidc.js.map +1 -1
  278. package/dist/server/connection/policy/domain.js +4 -1
  279. package/dist/server/connection/policy/domain.js.map +1 -1
  280. package/dist/server/connection/policy.js +14 -13
  281. package/dist/server/connection/policy.js.map +1 -1
  282. package/dist/server/connection/provision.js +5 -19
  283. package/dist/server/connection/provision.js.map +1 -1
  284. package/dist/server/connection/saml/encoding.js +2 -6
  285. package/dist/server/connection/saml/encoding.js.map +1 -1
  286. package/dist/server/connection/saml/signature.js +2 -2
  287. package/dist/server/connection/saml/signature.js.map +1 -1
  288. package/dist/server/connection/saml/xmldsig.js +1 -1
  289. package/dist/server/connection/saml/xmldsig.js.map +1 -1
  290. package/dist/server/connection/webhook.js +4 -36
  291. package/dist/server/connection/webhook.js.map +1 -1
  292. package/dist/server/context.d.ts +2 -2
  293. package/dist/server/context.d.ts.map +1 -1
  294. package/dist/server/context.js +35 -24
  295. package/dist/server/context.js.map +1 -1
  296. package/dist/server/contract.d.ts.map +1 -1
  297. package/dist/server/contract.js +6 -14
  298. package/dist/server/contract.js.map +1 -1
  299. package/dist/server/core.js +46 -1
  300. package/dist/server/core.js.map +1 -1
  301. package/dist/server/cors.d.ts +2 -2
  302. package/dist/server/cors.d.ts.map +1 -1
  303. package/dist/server/crypto.js.map +1 -1
  304. package/dist/server/db.js +6 -2
  305. package/dist/server/db.js.map +1 -1
  306. package/dist/server/device.js +1 -1
  307. package/dist/server/domains/account.d.ts +9 -1
  308. package/dist/server/domains/account.d.ts.map +1 -1
  309. package/dist/server/domains/account.js +21 -9
  310. package/dist/server/domains/account.js.map +1 -1
  311. package/dist/server/domains/context.js +34 -0
  312. package/dist/server/domains/context.js.map +1 -0
  313. package/dist/server/domains/factor.d.ts +3 -2
  314. package/dist/server/domains/factor.d.ts.map +1 -1
  315. package/dist/server/domains/factor.js.map +1 -1
  316. package/dist/server/domains/group.js.map +1 -1
  317. package/dist/server/domains/invite.js.map +1 -1
  318. package/dist/server/domains/key.js.map +1 -1
  319. package/dist/server/domains/member.js.map +1 -1
  320. package/dist/server/domains/session.js.map +1 -1
  321. package/dist/server/domains/user.js.map +1 -1
  322. package/dist/server/env.js +2 -22
  323. package/dist/server/env.js.map +1 -1
  324. package/dist/server/events.d.ts +3 -1
  325. package/dist/server/events.d.ts.map +1 -1
  326. package/dist/server/events.js +6 -6
  327. package/dist/server/events.js.map +1 -1
  328. package/dist/server/facade.d.ts +1 -33
  329. package/dist/server/facade.d.ts.map +1 -1
  330. package/dist/server/facade.js +1 -2
  331. package/dist/server/facade.js.map +1 -1
  332. package/dist/server/http.d.ts +1 -0
  333. package/dist/server/http.d.ts.map +1 -1
  334. package/dist/server/http.js +4 -4
  335. package/dist/server/http.js.map +1 -1
  336. package/dist/server/identity/claims.js +1 -1
  337. package/dist/server/identity/convex.d.ts +2 -0
  338. package/dist/server/identity/convex.d.ts.map +1 -1
  339. package/dist/server/index.d.ts +6 -9
  340. package/dist/server/index.js +2 -4
  341. package/dist/server/limits.js +23 -2
  342. package/dist/server/limits.js.map +1 -1
  343. package/dist/server/mutations/calls.js +3 -2
  344. package/dist/server/mutations/credentials/signin.js +7 -3
  345. package/dist/server/mutations/credentials/signin.js.map +1 -1
  346. package/dist/server/mutations/enrollment.js +87 -0
  347. package/dist/server/mutations/enrollment.js.map +1 -0
  348. package/dist/server/mutations/invalidate.js +5 -10
  349. package/dist/server/mutations/invalidate.js.map +1 -1
  350. package/dist/server/mutations/oauth.js +3 -3
  351. package/dist/server/mutations/oauth.js.map +1 -1
  352. package/dist/server/mutations/refresh.js +1 -0
  353. package/dist/server/mutations/refresh.js.map +1 -1
  354. package/dist/server/mutations/register.js +52 -21
  355. package/dist/server/mutations/register.js.map +1 -1
  356. package/dist/server/mutations/retrieve.js +4 -1
  357. package/dist/server/mutations/retrieve.js.map +1 -1
  358. package/dist/server/mutations/signin.js +2 -2
  359. package/dist/server/mutations/signin.js.map +1 -1
  360. package/dist/server/mutations/store.js +6 -1
  361. package/dist/server/mutations/store.js.map +1 -1
  362. package/dist/server/mutations/verify.js +6 -4
  363. package/dist/server/mutations/verify.js.map +1 -1
  364. package/dist/server/oauth/client.d.ts +1 -1
  365. package/dist/server/oauth/client.js.map +1 -1
  366. package/dist/server/oauth/code.d.ts +1 -1
  367. package/dist/server/oauth/code.js.map +1 -1
  368. package/dist/server/oauth/factory.js +89 -13
  369. package/dist/server/oauth/factory.js.map +1 -1
  370. package/dist/server/oauth/handlers.js +2 -2
  371. package/dist/server/oauth/runtime.js +24 -9
  372. package/dist/server/oauth/runtime.js.map +1 -1
  373. package/dist/server/preload.d.ts.map +1 -1
  374. package/dist/server/preload.js +14 -11
  375. package/dist/server/preload.js.map +1 -1
  376. package/dist/server/runtime.d.ts +236 -148
  377. package/dist/server/runtime.d.ts.map +1 -1
  378. package/dist/server/runtime.js +92 -44
  379. package/dist/server/runtime.js.map +1 -1
  380. package/dist/server/session/lifecycle.d.ts +2 -1
  381. package/dist/server/session/lifecycle.d.ts.map +1 -1
  382. package/dist/server/session/lifecycle.js +29 -10
  383. package/dist/server/session/lifecycle.js.map +1 -1
  384. package/dist/server/signin/flow.js +2 -2
  385. package/dist/server/signin/flow.js.map +1 -1
  386. package/dist/server/telemetry.js +1 -1
  387. package/dist/server/tokens.js +6 -3
  388. package/dist/server/tokens.js.map +1 -1
  389. package/dist/server/totp.js +4 -3
  390. package/dist/server/totp.js.map +1 -1
  391. package/dist/server/types.d.ts +131 -45
  392. package/dist/server/types.d.ts.map +1 -1
  393. package/dist/server/user/account.js +0 -1
  394. package/dist/server/user/account.js.map +1 -1
  395. package/dist/server/validators.d.ts +930 -944
  396. package/dist/server/validators.d.ts.map +1 -1
  397. package/dist/server/validators.js +66 -39
  398. package/dist/server/validators.js.map +1 -1
  399. package/dist/server/webauthn.js +60 -29
  400. package/dist/server/webauthn.js.map +1 -1
  401. package/dist/shared/brand.d.ts +3 -7
  402. package/dist/shared/brand.d.ts.map +1 -1
  403. package/dist/shared/params.d.ts +78 -0
  404. package/dist/shared/params.d.ts.map +1 -0
  405. package/dist/shared/results.d.ts +13 -1
  406. package/dist/shared/results.d.ts.map +1 -1
  407. package/dist/svelte/context.svelte.d.ts +23 -12
  408. package/dist/svelte/context.svelte.d.ts.map +1 -1
  409. package/dist/svelte/context.svelte.js +20 -13
  410. package/dist/svelte/index.d.ts +1 -4
  411. package/dist/svelte/index.d.ts.map +1 -1
  412. package/dist/svelte/index.js +1 -4
  413. package/dist/test.d.ts +1204 -611
  414. package/dist/test.d.ts.map +1 -1
  415. package/dist/test.js +50 -1
  416. package/dist/test.js.map +1 -1
  417. package/package.json +5 -14
  418. package/dist/_generated/component.d.ts +0 -3074
  419. package/dist/_generated/component.d.ts.map +0 -1
  420. package/dist/component/functions.d.ts +0 -9
  421. package/dist/component/functions.d.ts.map +0 -1
  422. package/dist/component/functions.js +0 -3
  423. package/dist/core/index.d.ts +0 -533
  424. package/dist/core/index.d.ts.map +0 -1
  425. package/dist/core/index.js +0 -86
  426. package/dist/core/index.js.map +0 -1
  427. package/dist/model.js.map +0 -1
  428. package/dist/server/env.d.ts +0 -28
  429. package/dist/server/env.d.ts.map +0 -1
  430. package/dist/svelte/AuthLoading.svelte +0 -13
  431. package/dist/svelte/AuthLoading.svelte.d.ts +0 -8
  432. package/dist/svelte/AuthLoading.svelte.d.ts.map +0 -1
  433. package/dist/svelte/SignedIn.svelte +0 -14
  434. package/dist/svelte/SignedIn.svelte.d.ts +0 -8
  435. package/dist/svelte/SignedIn.svelte.d.ts.map +0 -1
  436. package/dist/svelte/SignedOut.svelte +0 -13
  437. package/dist/svelte/SignedOut.svelte.d.ts +0 -8
  438. package/dist/svelte/SignedOut.svelte.d.ts.map +0 -1
@@ -1,13 +1,13 @@
1
1
  import { ErrorCode } from "../../shared/codes.js";
2
2
  import { log } from "../log.js";
3
3
  import { convexError } from "../errors.js";
4
- import { getScimIdentity, getScimIdentityByConnectionAndUser, getScimIdentityByMappedGroup, insertUser, listScimIdentitiesByConnection, provisionScimUser, removeScimIdentity, updateUser, upsertScimIdentity } from "../contract.js";
4
+ import { addConnectionRoutes, convertErrorsToResponse, getCookies } from "../http.js";
5
+ import { redirectToParamCookie, useRedirectToParam } from "../cookies.js";
6
+ import { getScimIdentityByConnectionAndUser, getScimIdentityByMappedGroup, listScimIdentitiesByConnection, provisionScimGroup, provisionScimUser, revokeScimGroup, revokeScimUser, updateScimGroup, updateScimUser } from "../contract.js";
5
7
  import { finalizeNormalizedProfile, normalizeStringArray } from "./profile.js";
6
- import { SCIM_GROUP_SCHEMA_ID, SCIM_USER_SCHEMA_ID, decodeGroupOidcState, encodeGroupOidcState, groupOidcProviderId, groupSamlProviderId } from "./shared.js";
8
+ import { SCIM_GROUP_SCHEMA_ID, SCIM_USER_SCHEMA_ID, decodeGroupOidcState, encodeGroupOidcState, groupSamlProviderId } from "./shared.js";
7
9
  import { createGroupConnectionOidcRuntime } from "./oidc.js";
8
10
  import { resolveProvisionedRoleIds } from "./policy.js";
9
- import { addConnectionRoutes, convertErrorsToResponse, getCookies } from "../http.js";
10
- import { redirectToParamCookie, useRedirectToParam } from "../cookies.js";
11
11
  import { redirectAbsoluteUrl, setURLSearchParam } from "../redirects.js";
12
12
  import { createOAuthAuthorizationURL, handleOAuthCallback } from "../oauth/runtime.js";
13
13
  import { parseScimListRequest, scimError, scimJson, serializeScimGroup, serializeScimUser } from "./scim.js";
@@ -35,6 +35,8 @@ async function getOidcCallbackParams(request) {
35
35
  * warning is logged rather than silently returning a partial first page.
36
36
  */
37
37
  const SCIM_COLLECT_LIMIT = 5e3;
38
+ /** Maximum members accepted by one authoritative SCIM group replacement. */
39
+ const SCIM_GROUP_MEMBERSHIP_BATCH_SIZE = 100;
38
40
  /**
39
41
  * Lifetime of a persisted pending SAML AuthnRequest. Bounds how long an ACS
40
42
  * response can accept the request; comfortably covers IdP round-trips and the
@@ -53,6 +55,14 @@ const SCIM_FILTER_OPERATORS = {
53
55
  sw: (values, filterValue) => values.some((value) => value.startsWith(filterValue)),
54
56
  ew: (values, filterValue) => values.some((value) => value.endsWith(filterValue))
55
57
  };
58
+ /** @internal Post-commit SCIM notifications must never make a committed write retryable. */
59
+ async function notifyScimAfterProvision(notify) {
60
+ try {
61
+ await notify?.();
62
+ } catch (error) {
63
+ console.error("[auth] SCIM afterProvision hook failed after commit", error);
64
+ }
65
+ }
56
66
  function addGroupHttpRuntime(deps) {
57
67
  if (!deps.hasConnection) return;
58
68
  const { http, auth, config, requireEnv, loadActiveConnectionSamlOrThrow, loadConnectionOidcOrThrow, getGroupConnectionScimContext, loadGroupPolicyOrThrow, emitGroupAuthEvent, generateRandomString, inviteTokenAlphabet: INVITE_TOKEN_ALPHABET, callUserOAuth, callVerifierSignature, sharedOidcRedirectURI } = deps;
@@ -252,16 +262,6 @@ function addGroupHttpRuntime(deps) {
252
262
  if (typeof value === "boolean") return [String(value)];
253
263
  return [];
254
264
  };
255
- const applyUserProvisioningPatch = (args) => {
256
- const mode = args.policy.updateProfileFromScim ?? "always";
257
- if (mode === "never") return {};
258
- if (mode === "always") return args.nextUser;
259
- return Object.fromEntries(Object.entries(args.nextUser).filter(([key, value]) => {
260
- if (value === void 0) return false;
261
- const current = args.currentUser[key];
262
- return current === void 0 || current === null || current === "";
263
- }));
264
- };
265
265
  const filterScimCollection = (items, filter, filters) => {
266
266
  if (!filter) return items;
267
267
  const accessor = filters[filter.attribute];
@@ -510,40 +510,35 @@ function addGroupHttpRuntime(deps) {
510
510
  });
511
511
  return out;
512
512
  };
513
- /**
514
- * Fully enumerate a group's active members for an authoritative
515
- * (destructive) membership replace. Unlike {@link collectMembers}, this
516
- * refuses to truncate: a `replace` diffs the incoming set against the
517
- * current set and removes the difference, so a partial read would
518
- * silently drop overflow members. Throws {@link scimCollectOverflow} past
519
- * the collect limit so the caller fails the reconcile (413) rather than
520
- * completing a partial authoritative replace.
521
- */
513
+ /** Read a bounded complete snapshot for an authoritative membership replace. */
522
514
  const collectMembersForReplace = async (ctx$1, where) => {
523
- const first = await auth.member.list(ctx$1, {
515
+ const result = await auth.member.list(ctx$1, {
524
516
  where,
525
517
  paginationOpts: {
526
- numItems: 200,
518
+ numItems: SCIM_GROUP_MEMBERSHIP_BATCH_SIZE,
527
519
  cursor: null
528
520
  }
529
521
  });
530
- const out = [...first.page];
531
- let cursor = first.continueCursor;
532
- let done = first.isDone;
533
- while (!done) {
534
- if (out.length > SCIM_COLLECT_LIMIT) throw scimCollectOverflow();
535
- const next = await auth.member.list(ctx$1, {
536
- where,
537
- paginationOpts: {
538
- numItems: 200,
539
- cursor
540
- }
522
+ if (!result.isDone) throw scimCollectOverflow();
523
+ return result.page;
524
+ };
525
+ const assertScimMembershipBatchSize = (memberIds) => {
526
+ let count = 0;
527
+ for (const _memberId of memberIds) {
528
+ count += 1;
529
+ if (count > SCIM_GROUP_MEMBERSHIP_BATCH_SIZE) throw scimCollectOverflow();
530
+ }
531
+ };
532
+ const completeScimGroupReplacement = async (state$1, args) => {
533
+ let cursor;
534
+ for (;;) {
535
+ const result = await updateScimGroup(state$1.ctx, config.component.connection, {
536
+ ...args,
537
+ cursor
541
538
  });
542
- out.push(...next.page);
543
- done = next.isDone;
544
- cursor = next.continueCursor;
539
+ if (result.isDone) return;
540
+ cursor = result.continueCursor;
545
541
  }
546
- return out;
547
542
  };
548
543
  const collectGroups = async (ctx$1, where) => {
549
544
  const first = await auth.group.list(ctx$1, {
@@ -574,26 +569,6 @@ function addGroupHttpRuntime(deps) {
574
569
  });
575
570
  return out;
576
571
  };
577
- const userInConnectionScope = async (state$1, userId) => {
578
- if (await getScimIdentityByConnectionAndUser(state$1.ctx, config.component.connection, {
579
- connectionId: state$1.connection._id,
580
- userId
581
- })) return true;
582
- return (await auth.member.list(state$1.ctx, {
583
- where: {
584
- groupId: state$1.connection.groupId,
585
- userId
586
- },
587
- paginationOpts: {
588
- numItems: 1,
589
- cursor: null
590
- }
591
- })).page[0] !== void 0;
592
- };
593
- const firstInvalidScimMember = async (state$1, userIds) => {
594
- for (const userId of userIds) if (!await auth.user.get(state$1.ctx, { id: userId }) || !await userInConnectionScope(state$1, userId)) return userId;
595
- return null;
596
- };
597
572
  const handleUsersGet = async (state$1) => {
598
573
  if (state$1.parsedPath.resourceId) {
599
574
  const userId = state$1.parsedPath.resourceId;
@@ -693,7 +668,6 @@ function addGroupHttpRuntime(deps) {
693
668
  profile: extracted
694
669
  }) ?? extracted;
695
670
  const externalId = provisionProfile.externalId;
696
- const providerId = state$1.connection.protocol === "oidc" ? groupOidcProviderId(state$1.connection._id) : groupSamlProviderId(state$1.connection._id);
697
671
  const provisionedRoleIds = resolveProvisionedRoleIds({
698
672
  policy: state$1.policy,
699
673
  groups: provisionProfile.groups,
@@ -709,71 +683,27 @@ function addGroupHttpRuntime(deps) {
709
683
  ...typeof provisionProfile.phone === "string" ? { phoneVerificationTime: Date.now() } : {},
710
684
  ...provisionProfile.extend ? { extend: provisionProfile.extend } : {}
711
685
  };
712
- const { userId, created } = externalId ? await provisionScimUser(state$1.ctx, config.component.connection, {
686
+ const { userId, created } = await provisionScimUser(state$1.ctx, config.component.connection, {
713
687
  connectionId: state$1.connection._id,
714
- groupId: state$1.connection.groupId,
715
688
  externalId,
716
- provider: providerId,
717
689
  userData,
690
+ profileUpdate: state$1.policy.provisioning.user.updateProfileFromScim,
691
+ roleIds: provisionedRoleIds,
718
692
  active: provisionProfile.active !== false,
719
693
  raw: body,
720
694
  lastProvisionedAt: Date.now()
721
- }) : {
722
- userId: await insertUser(state$1.ctx, config.component.user, userData),
723
- created: true
724
- };
725
- const existingUser = created ? null : await auth.user.get(state$1.ctx, { id: userId });
726
- if (!created && existingUser === null) throw new ConvexError({
727
- code: ErrorCode.ACCOUNT_NOT_FOUND,
728
- message: "The SCIM identity references a user that no longer exists."
729
695
  });
730
- if (existingUser) {
731
- const nextUserData = {
732
- name: provisionProfile.name,
733
- firstName: provisionProfile.firstName,
734
- lastName: provisionProfile.lastName,
735
- email: provisionProfile.email,
736
- phone: provisionProfile.phone,
737
- ...provisionProfile.extend ? { extend: provisionProfile.extend } : {}
738
- };
739
- if (typeof provisionProfile.email === "string") nextUserData.emailVerificationTime = Date.now();
740
- if (typeof provisionProfile.phone === "string") nextUserData.phoneVerificationTime = Date.now();
741
- const patchData = applyUserProvisioningPatch({
742
- currentUser: existingUser,
743
- nextUser: nextUserData,
744
- policy: state$1.policy.provisioning.user,
745
- source: "scim"
746
- });
747
- if (Object.keys(patchData).length > 0) await updateUser(state$1.ctx, config.component.user, {
748
- userId,
749
- patch: patchData
750
- });
751
- }
752
- const resolution = await auth.member.get(state$1.ctx, {
753
- groupId: state$1.connection.groupId,
754
- userId
755
- });
756
- if (resolution.membership) await auth.member.update(state$1.ctx, {
757
- id: resolution.membership._id,
758
- patch: { status: body.active === false ? "inactive" : "active" }
759
- });
760
- else await auth.member.create(state$1.ctx, { data: {
761
- groupId: state$1.connection.groupId,
762
- userId,
763
- roleIds: provisionedRoleIds,
764
- status: provisionProfile.active === false ? "inactive" : "active"
765
- } });
766
696
  await state$1.recordScimEvent(created ? "connection.scim.user.provisioned" : "connection.scim.user.updated", "success", {
767
697
  type: "user",
768
698
  id: userId
769
699
  });
770
700
  const createdUser = await auth.user.get(state$1.ctx, { id: userId });
771
- await config.connection?.hooks?.afterProvision?.({
701
+ await notifyScimAfterProvision(async () => config.connection?.hooks?.afterProvision?.({
772
702
  protocol: "scim",
773
703
  connectionId: state$1.connection._id,
774
704
  profile: provisionProfile,
775
705
  userId
776
- });
706
+ }));
777
707
  const location = `${state$1.url.origin}${state$1.url.pathname}/${userId}`;
778
708
  return scimJson(serializeScimUser({
779
709
  id: userId,
@@ -793,11 +723,7 @@ function addGroupHttpRuntime(deps) {
793
723
  connectionId: state$1.connection._id,
794
724
  userId
795
725
  });
796
- const existingMembership = await auth.member.get(state$1.ctx, {
797
- groupId: state$1.connection.groupId,
798
- userId
799
- });
800
- if (!existingIdentity && !existingMembership.membership) return scimError(404, "notFound", "User not found.");
726
+ if (!existingIdentity) return scimError(404, "notFound", "User not found.");
801
727
  const body = await readScimJson(state$1.request);
802
728
  const extractedBase = extractScimProfile(state$1.scimConfig, body);
803
729
  const extracted = await config.connection?.hooks?.profileResolved?.({
@@ -866,34 +792,18 @@ function addGroupHttpRuntime(deps) {
866
792
  unsupportedScimPatch();
867
793
  }
868
794
  }
869
- const nextPatchData = applyUserProvisioningPatch({
870
- currentUser: existingUser,
871
- nextUser: patchData,
872
- policy: state$1.policy.provisioning.user,
873
- source: "scim"
874
- });
875
- if (Object.keys(nextPatchData).length > 0) await updateUser(state$1.ctx, config.component.user, {
876
- userId,
877
- patch: nextPatchData
878
- });
879
- const resolution = existingMembership;
880
- if (resolution.membership) await auth.member.update(state$1.ctx, {
881
- id: resolution.membership._id,
882
- patch: {
883
- roleIds: resolveProvisionedRoleIds({
884
- policy: state$1.policy,
885
- groups: provisionProfile.groups,
886
- roles: provisionProfile.roles
887
- }),
888
- status: provisionProfile.active === false || nextActive === false ? "inactive" : "active"
889
- }
890
- });
891
- await upsertScimIdentity(state$1.ctx, config.component.connection, {
795
+ const resolvedExternalId = externalId ?? existingIdentity.externalId;
796
+ await updateScimUser(state$1.ctx, config.component.connection, {
892
797
  connectionId: state$1.connection._id,
893
- groupId: state$1.connection.groupId,
894
- resourceType: "user",
895
- externalId: externalId ?? existingIdentity?.externalId ?? userId,
896
798
  userId,
799
+ externalId: resolvedExternalId,
800
+ userData: patchData,
801
+ profileUpdate: state$1.policy.provisioning.user.updateProfileFromScim,
802
+ roleIds: resolveProvisionedRoleIds({
803
+ policy: state$1.policy,
804
+ groups: provisionProfile.groups,
805
+ roles: provisionProfile.roles
806
+ }),
897
807
  active: provisionProfile.active !== false && nextActive !== false,
898
808
  raw: body,
899
809
  lastProvisionedAt: Date.now()
@@ -903,12 +813,12 @@ function addGroupHttpRuntime(deps) {
903
813
  id: userId
904
814
  });
905
815
  const updatedUser = await auth.user.get(state$1.ctx, { id: userId });
906
- await config.connection?.hooks?.afterProvision?.({
816
+ await notifyScimAfterProvision(async () => config.connection?.hooks?.afterProvision?.({
907
817
  protocol: "scim",
908
818
  connectionId: state$1.connection._id,
909
819
  profile: provisionProfile,
910
820
  userId
911
- });
821
+ }));
912
822
  const location = `${state$1.url.origin}${state$1.url.pathname}`;
913
823
  return scimJson(serializeScimUser({
914
824
  id: userId,
@@ -922,35 +832,22 @@ function addGroupHttpRuntime(deps) {
922
832
  const missing = requireScimResourceId(state$1.parsedPath.resourceId, "User");
923
833
  if (missing) return missing;
924
834
  const userId = state$1.parsedPath.resourceId;
925
- const identity = await getScimIdentityByConnectionAndUser(state$1.ctx, config.component.connection, {
835
+ if (!await getScimIdentityByConnectionAndUser(state$1.ctx, config.component.connection, {
926
836
  connectionId: state$1.connection._id,
927
837
  userId
838
+ })) return scimError(404, "notFound", "User not found.");
839
+ const { cleanupPending } = await revokeScimUser(state$1.ctx, config.component.connection, {
840
+ connectionId: state$1.connection._id,
841
+ userId,
842
+ mode: state$1.policy.provisioning.deprovision.mode
928
843
  });
929
- if (!identity) return scimError(404, "notFound", "User not found.");
930
- const resolution = await auth.member.get(state$1.ctx, {
931
- groupId: state$1.connection.groupId,
932
- userId
933
- });
934
- if (resolution.membership) await auth.member.remove(state$1.ctx, { id: resolution.membership._id });
935
- const { revoked } = await state$1.ctx.runMutation(config.component.session.revokeForUser, { userId });
936
- if (revoked > 0) await state$1.recordScimEvent("session.invalidated", "success", {
844
+ await state$1.recordScimEvent("session.invalidated", "success", {
937
845
  type: "user",
938
846
  id: userId
939
847
  }, {
940
848
  userId,
941
- reason: "connection_deprovision"
942
- });
943
- if (state$1.policy.provisioning.deprovision.mode === "hard") await removeScimIdentity(state$1.ctx, config.component.connection, identity._id);
944
- else await upsertScimIdentity(state$1.ctx, config.component.connection, {
945
- connectionId: identity.connectionId,
946
- groupId: identity.groupId,
947
- resourceType: identity.resourceType,
948
- externalId: identity.externalId,
949
- userId: identity.userId,
950
- mappedGroupId: identity.mappedGroupId,
951
- active: false,
952
- raw: identity.raw,
953
- lastProvisionedAt: Date.now()
849
+ reason: "connection_deprovision",
850
+ cleanupPending
954
851
  });
955
852
  await state$1.recordScimEvent("connection.scim.user.deactivated", "success", {
956
853
  type: "user",
@@ -1031,78 +928,41 @@ function addGroupHttpRuntime(deps) {
1031
928
  };
1032
929
  const handleGroupsPost = async (state$1) => {
1033
930
  const body = await readScimJson(state$1.request);
1034
- const externalId = typeof body.externalId === "string" ? body.externalId : void 0;
1035
- const existingIdentity = externalId ? await getScimIdentity(state$1.ctx, config.component.connection, {
1036
- connectionId: state$1.connection._id,
1037
- resourceType: "group",
1038
- externalId
1039
- }) : null;
1040
- const existingGroup = existingIdentity?.mappedGroupId ? await auth.group.get(state$1.ctx, { id: existingIdentity.mappedGroupId }) : null;
1041
- const created = existingGroup === null;
1042
- const provisionedRoleIds = resolveProvisionedRoleIds({
1043
- policy: state$1.policy,
1044
- groups: typeof body.displayName === "string" ? [body.displayName] : void 0,
1045
- roles: pickStringArray(body.roles)
1046
- });
1047
- const groupId = existingGroup?._id ? existingGroup._id : await auth.group.create(state$1.ctx, { data: {
1048
- name: typeof body.displayName === "string" ? body.displayName : "Group",
1049
- parentGroupId: state$1.connection.groupId,
1050
- type: "organization"
1051
- } });
1052
- if (!created && existingGroup) {
1053
- const location$1 = `${state$1.url.origin}${state$1.url.pathname}/${groupId}`;
1054
- return scimJson(serializeScimGroup({
1055
- id: groupId,
1056
- group: existingGroup,
1057
- externalId,
1058
- location: location$1,
1059
- members: (await collectMembers(state$1.ctx, {
1060
- groupId,
1061
- status: "active"
1062
- })).map((member) => ({ value: member.userId }))
1063
- }), 200, { Location: location$1 });
1064
- }
1065
- await upsertScimIdentity(state$1.ctx, config.component.connection, {
1066
- connectionId: state$1.connection._id,
1067
- groupId: state$1.connection.groupId,
1068
- resourceType: "group",
1069
- externalId: externalId ?? groupId,
1070
- mappedGroupId: groupId,
1071
- active: true,
1072
- raw: body,
1073
- lastProvisionedAt: Date.now()
1074
- });
1075
- const currentMembers = await collectMembersForReplace(state$1.ctx, {
1076
- groupId,
1077
- status: "active"
1078
- });
1079
- const currentByUserId = new Map(currentMembers.map((member) => [member.userId, member]));
1080
- const nextUserIds = new Set((Array.isArray(body.members) ? body.members : []).map((member) => String(member.value)));
1081
- const toAddUserIds = [...nextUserIds].filter((userId) => !currentByUserId.has(userId));
1082
- const invalidMember = await firstInvalidScimMember(state$1, toAddUserIds);
1083
- if (invalidMember !== null) return scimError(400, "invalidValue", `Group member user not found: ${invalidMember}`);
1084
- for (const member of currentMembers) if (!nextUserIds.has(member.userId)) await auth.member.remove(state$1.ctx, { id: member._id });
1085
- for (const userId of toAddUserIds) await auth.member.create(state$1.ctx, { data: {
1086
- groupId,
1087
- userId,
1088
- roleIds: provisionedRoleIds,
1089
- status: "active"
1090
- } });
931
+ const memberIds = (Array.isArray(body.members) ? body.members : []).map((member) => String(member.value));
932
+ assertScimMembershipBatchSize(memberIds);
933
+ const externalIdForGroup = typeof body.externalId === "string" ? body.externalId : void 0;
934
+ let cursor;
935
+ let provisioned;
936
+ let created = false;
937
+ do {
938
+ provisioned = await provisionScimGroup(state$1.ctx, config.component.connection, {
939
+ connectionId: state$1.connection._id,
940
+ externalId: externalIdForGroup,
941
+ name: typeof body.displayName === "string" ? body.displayName : "Group",
942
+ memberIds,
943
+ roleIds: resolveProvisionedRoleIds({
944
+ policy: state$1.policy,
945
+ groups: typeof body.displayName === "string" ? [body.displayName] : void 0,
946
+ roles: pickStringArray(body.roles)
947
+ }),
948
+ raw: body,
949
+ cursor
950
+ });
951
+ created ||= provisioned.created;
952
+ cursor = provisioned.continueCursor;
953
+ } while (!provisioned.isDone);
1091
954
  await state$1.recordScimEvent(created ? "connection.scim.group.provisioned" : "connection.scim.group.updated", "success", {
1092
955
  type: "group",
1093
- id: groupId
956
+ id: provisioned.groupId
1094
957
  });
1095
- const group = await auth.group.get(state$1.ctx, { id: groupId });
1096
- const location = `${state$1.url.origin}${state$1.url.pathname}/${groupId}`;
958
+ const group = await auth.group.get(state$1.ctx, { id: provisioned.groupId });
959
+ const location = `${state$1.url.origin}${state$1.url.pathname}/${provisioned.groupId}`;
1097
960
  return scimJson(serializeScimGroup({
1098
- id: groupId,
961
+ id: provisioned.groupId,
1099
962
  group: group ?? {},
1100
- externalId,
963
+ externalId: externalIdForGroup,
1101
964
  location,
1102
- members: (await collectMembers(state$1.ctx, {
1103
- groupId,
1104
- status: "active"
1105
- })).map((member) => ({ value: member.userId }))
965
+ members: memberIds.map((value) => ({ value }))
1106
966
  }), created ? 201 : 200, { Location: location });
1107
967
  };
1108
968
  const handleGroupsPatch = async (state$1) => {
@@ -1111,96 +971,74 @@ function addGroupHttpRuntime(deps) {
1111
971
  const groupId = state$1.parsedPath.resourceId;
1112
972
  const identity = await getScimIdentityByMappedGroup(state$1.ctx, config.component.connection, groupId);
1113
973
  if (!identity || identity.connectionId !== state$1.connection._id) return scimError(404, "notFound", "Group not found.");
974
+ const group = await auth.group.get(state$1.ctx, { id: groupId });
975
+ if (!group) return scimError(404, "notFound", "Group not found.");
976
+ const currentMembers = await collectMembersForReplace(state$1.ctx, { groupId });
977
+ const nextMemberIds = new Set(currentMembers.map((member) => member.userId));
978
+ let name = typeof group.name === "string" ? group.name : "Group";
1114
979
  const body = await readScimJson(state$1.request);
1115
980
  const operations = Array.isArray(body.Operations) ? body.Operations : unsupportedScimPatch();
1116
981
  for (const operation of operations) {
1117
982
  const op = typeof operation.op === "string" ? operation.op.toLowerCase() : "replace";
1118
983
  if (operation.path === void 0 && op === "replace" && typeof operation.value === "object" && operation.value !== null) {
1119
984
  const value = operation.value;
1120
- if (typeof value.displayName === "string") await auth.group.update(state$1.ctx, {
1121
- id: groupId,
1122
- patch: { name: value.displayName }
1123
- });
985
+ if (typeof value.displayName === "string") name = value.displayName;
986
+ if (Array.isArray(value.members)) {
987
+ nextMemberIds.clear();
988
+ for (const member of value.members) nextMemberIds.add(String(member.value));
989
+ }
1124
990
  continue;
1125
991
  }
1126
992
  if (operation.path === "displayName") {
1127
993
  if (op !== "replace" && op !== "add") unsupportedScimPatch();
1128
- await auth.group.update(state$1.ctx, {
1129
- id: groupId,
1130
- patch: { name: operation.value }
1131
- });
994
+ if (typeof operation.value === "string") name = operation.value;
995
+ else unsupportedScimPatch();
1132
996
  continue;
1133
997
  }
1134
998
  if (operation.path === "members" && op === "add") {
1135
999
  const addUserIds = (Array.isArray(operation.value) ? operation.value : []).map((member) => String(member.value));
1136
- const invalidMember = await firstInvalidScimMember(state$1, addUserIds);
1137
- if (invalidMember !== null) return scimError(400, "invalidValue", `Group member user not found: ${invalidMember}`);
1138
- for (const userId of addUserIds) if (!(await auth.member.get(state$1.ctx, {
1139
- groupId,
1140
- userId
1141
- })).membership) await auth.member.create(state$1.ctx, { data: {
1142
- groupId,
1143
- userId,
1144
- roleIds: resolveProvisionedRoleIds({
1145
- policy: state$1.policy,
1146
- groups: typeof body.displayName === "string" ? [body.displayName] : void 0,
1147
- roles: pickStringArray(body.roles)
1148
- }),
1149
- status: "active"
1150
- } });
1000
+ for (const userId of addUserIds) nextMemberIds.add(userId);
1151
1001
  continue;
1152
1002
  }
1153
1003
  if (operation.path === "members" && op === "replace") {
1154
- const currentMembers = await collectMembersForReplace(state$1.ctx, {
1155
- groupId,
1156
- status: "active"
1157
- });
1158
- const currentUserIds = new Set(currentMembers.map((member) => member.userId));
1159
- const nextUserIds = new Set((Array.isArray(operation.value) ? operation.value : []).map((member) => String(member.value)));
1160
- const toAddUserIds = [...nextUserIds].filter((userId) => !currentUserIds.has(userId));
1161
- const invalidMember = await firstInvalidScimMember(state$1, toAddUserIds);
1162
- if (invalidMember !== null) return scimError(400, "invalidValue", `Group member user not found: ${invalidMember}`);
1163
- for (const member of currentMembers) if (!nextUserIds.has(member.userId)) await auth.member.remove(state$1.ctx, { id: member._id });
1164
- for (const userId of toAddUserIds) await auth.member.create(state$1.ctx, { data: {
1165
- groupId,
1166
- userId,
1167
- roleIds: resolveProvisionedRoleIds({
1168
- policy: state$1.policy,
1169
- groups: typeof body.displayName === "string" ? [body.displayName] : void 0,
1170
- roles: pickStringArray(body.roles)
1171
- }),
1172
- status: "active"
1173
- } });
1004
+ nextMemberIds.clear();
1005
+ for (const member of Array.isArray(operation.value) ? operation.value : []) nextMemberIds.add(String(member.value));
1174
1006
  continue;
1175
1007
  }
1176
1008
  if (typeof operation.path === "string" && op === "remove" && operation.path.startsWith("members[")) {
1177
1009
  const userId = operation.path.match(/^members\[value eq "([^"]+)"\]$/)?.[1];
1178
- if (userId) {
1179
- const resolution = await auth.member.get(state$1.ctx, {
1180
- groupId,
1181
- userId
1182
- });
1183
- if (resolution.membership) await auth.member.remove(state$1.ctx, { id: resolution.membership._id });
1184
- }
1010
+ if (userId) nextMemberIds.delete(userId);
1185
1011
  continue;
1186
1012
  }
1187
1013
  unsupportedScimPatch();
1188
1014
  }
1015
+ assertScimMembershipBatchSize(nextMemberIds);
1016
+ await completeScimGroupReplacement(state$1, {
1017
+ connectionId: state$1.connection._id,
1018
+ groupId,
1019
+ name,
1020
+ memberIds: [...nextMemberIds],
1021
+ roleIds: resolveProvisionedRoleIds({
1022
+ policy: state$1.policy,
1023
+ groups: [name],
1024
+ roles: pickStringArray(body.roles)
1025
+ }),
1026
+ raw: body
1027
+ });
1189
1028
  await state$1.recordScimEvent("connection.scim.group.updated", "success", {
1190
1029
  type: "group",
1191
1030
  id: groupId
1192
1031
  });
1193
- const group = await auth.group.get(state$1.ctx, { id: groupId });
1194
1032
  const location = `${state$1.url.origin}${state$1.url.pathname}`;
1195
- const members = await collectMembers(state$1.ctx, {
1196
- groupId,
1197
- status: "active"
1198
- });
1199
1033
  return scimJson(serializeScimGroup({
1200
1034
  id: groupId,
1201
- group: group ?? {},
1035
+ group: {
1036
+ ...group,
1037
+ name
1038
+ },
1039
+ externalId: identity.externalId,
1202
1040
  location,
1203
- members: members.map((member) => ({ value: member.userId }))
1041
+ members: [...nextMemberIds].map((value) => ({ value }))
1204
1042
  }), 200, { Location: location });
1205
1043
  };
1206
1044
  const handleGroupsDelete = async (state$1) => {
@@ -1209,8 +1047,16 @@ function addGroupHttpRuntime(deps) {
1209
1047
  const groupId = state$1.parsedPath.resourceId;
1210
1048
  const identity = await getScimIdentityByMappedGroup(state$1.ctx, config.component.connection, groupId);
1211
1049
  if (!identity || identity.connectionId !== state$1.connection._id) return scimError(404, "notFound", "Group not found.");
1212
- await auth.group.remove(state$1.ctx, { id: groupId });
1213
- await removeScimIdentity(state$1.ctx, config.component.connection, identity._id);
1050
+ let cursor;
1051
+ for (;;) {
1052
+ const result = await revokeScimGroup(state$1.ctx, config.component.connection, {
1053
+ connectionId: state$1.connection._id,
1054
+ groupId,
1055
+ cursor
1056
+ });
1057
+ if (result.isDone) break;
1058
+ cursor = result.continueCursor;
1059
+ }
1214
1060
  await state$1.recordScimEvent("connection.scim.group.deactivated", "success", {
1215
1061
  type: "group",
1216
1062
  id: groupId
@@ -1396,7 +1242,6 @@ function addGroupHttpRuntime(deps) {
1396
1242
  await ctx.runMutation(config.component.connection.saml.request.create, {
1397
1243
  connectionId: connection._id,
1398
1244
  requestId: signInRequest.requestId,
1399
- createdAt: nowMs,
1400
1245
  expiresAt: nowMs + SAML_LOGIN_REQUEST_TTL_MS
1401
1246
  });
1402
1247
  const redirectTo = url.searchParams.get("redirectTo");