@robelest/convex-auth 0.0.4-preview.13 → 0.0.4-preview.16

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 (328) hide show
  1. package/README.md +140 -9
  2. package/dist/bin.cjs +5957 -5478
  3. package/dist/client/index.d.ts +3 -7
  4. package/dist/client/index.d.ts.map +1 -1
  5. package/dist/client/index.js +27 -26
  6. package/dist/client/index.js.map +1 -1
  7. package/dist/component/_generated/api.d.ts +14 -0
  8. package/dist/component/_generated/api.d.ts.map +1 -1
  9. package/dist/component/_generated/api.js.map +1 -1
  10. package/dist/component/_generated/component.d.ts +1672 -24
  11. package/dist/component/_generated/component.d.ts.map +1 -1
  12. package/dist/component/convex.config.d.ts +2 -2
  13. package/dist/component/convex.config.d.ts.map +1 -1
  14. package/dist/component/index.d.ts +1 -1
  15. package/dist/component/index.js +2 -2
  16. package/dist/component/model.d.ts +153 -0
  17. package/dist/component/model.d.ts.map +1 -0
  18. package/dist/component/model.js +343 -0
  19. package/dist/component/model.js.map +1 -0
  20. package/dist/component/providers/sso.d.ts +1 -1
  21. package/dist/component/public/enterprise.d.ts +54 -0
  22. package/dist/component/public/enterprise.d.ts.map +1 -0
  23. package/dist/component/public/enterprise.js +515 -0
  24. package/dist/component/public/enterprise.js.map +1 -0
  25. package/dist/component/public/factors.d.ts +52 -0
  26. package/dist/component/public/factors.d.ts.map +1 -0
  27. package/dist/component/public/factors.js +285 -0
  28. package/dist/component/public/factors.js.map +1 -0
  29. package/dist/component/public/groups.d.ts +116 -0
  30. package/dist/component/public/groups.d.ts.map +1 -0
  31. package/dist/component/public/groups.js +596 -0
  32. package/dist/component/public/groups.js.map +1 -0
  33. package/dist/component/public/identity.d.ts +93 -0
  34. package/dist/component/public/identity.d.ts.map +1 -0
  35. package/dist/component/public/identity.js +426 -0
  36. package/dist/component/public/identity.js.map +1 -0
  37. package/dist/component/public/keys.d.ts +41 -0
  38. package/dist/component/public/keys.d.ts.map +1 -0
  39. package/dist/component/public/keys.js +157 -0
  40. package/dist/component/public/keys.js.map +1 -0
  41. package/dist/component/public/shared.d.ts +26 -0
  42. package/dist/component/public/shared.d.ts.map +1 -0
  43. package/dist/component/public/shared.js +32 -0
  44. package/dist/component/public/shared.js.map +1 -0
  45. package/dist/component/public.d.ts +9 -321
  46. package/dist/component/public.d.ts.map +1 -1
  47. package/dist/component/public.js +6 -2145
  48. package/dist/component/schema.d.ts +406 -260
  49. package/dist/component/schema.js +37 -32
  50. package/dist/component/schema.js.map +1 -1
  51. package/dist/component/server/auth.d.ts +161 -15
  52. package/dist/component/server/auth.d.ts.map +1 -1
  53. package/dist/component/server/auth.js +100 -7
  54. package/dist/component/server/auth.js.map +1 -1
  55. package/dist/component/server/cookies.js +3 -0
  56. package/dist/component/server/cookies.js.map +1 -1
  57. package/dist/component/server/db.js +1 -0
  58. package/dist/component/server/db.js.map +1 -1
  59. package/dist/component/server/device.js +3 -1
  60. package/dist/component/server/device.js.map +1 -1
  61. package/dist/component/server/domains/core.js +629 -0
  62. package/dist/component/server/domains/core.js.map +1 -0
  63. package/dist/component/server/domains/sso.js +884 -0
  64. package/dist/component/server/domains/sso.js.map +1 -0
  65. package/dist/component/server/factory.d.ts +136 -0
  66. package/dist/component/server/factory.d.ts.map +1 -0
  67. package/dist/component/server/factory.js +1134 -0
  68. package/dist/component/server/factory.js.map +1 -0
  69. package/dist/component/server/fx.js +2 -1
  70. package/dist/component/server/fx.js.map +1 -1
  71. package/dist/component/server/http.js +287 -0
  72. package/dist/component/server/http.js.map +1 -0
  73. package/dist/component/server/identity.js +13 -0
  74. package/dist/component/server/identity.js.map +1 -0
  75. package/dist/component/server/keys.js +4 -0
  76. package/dist/component/server/keys.js.map +1 -1
  77. package/dist/component/server/mutations/account.js +1 -1
  78. package/dist/component/server/mutations/index.js +2 -2
  79. package/dist/component/server/mutations/index.js.map +1 -1
  80. package/dist/component/server/mutations/invalidate.js +1 -1
  81. package/dist/component/server/mutations/oauth.js +10 -7
  82. package/dist/component/server/mutations/oauth.js.map +1 -1
  83. package/dist/component/server/mutations/refresh.js +1 -1
  84. package/dist/component/server/mutations/register.js +1 -1
  85. package/dist/component/server/mutations/retrieve.js +1 -1
  86. package/dist/component/server/mutations/signature.js +1 -1
  87. package/dist/component/server/mutations/store.js +6 -3
  88. package/dist/component/server/mutations/store.js.map +1 -1
  89. package/dist/component/server/mutations/verify.js +1 -1
  90. package/dist/component/server/oauth.js +3 -0
  91. package/dist/component/server/oauth.js.map +1 -1
  92. package/dist/component/server/passkey.js +3 -2
  93. package/dist/component/server/passkey.js.map +1 -1
  94. package/dist/component/server/provider.js +2 -0
  95. package/dist/component/server/provider.js.map +1 -1
  96. package/dist/component/server/providers.js +10 -0
  97. package/dist/component/server/providers.js.map +1 -1
  98. package/dist/component/server/ratelimit.js +3 -0
  99. package/dist/component/server/ratelimit.js.map +1 -1
  100. package/dist/component/server/redirects.js +2 -0
  101. package/dist/component/server/redirects.js.map +1 -1
  102. package/dist/component/server/refresh.js +5 -0
  103. package/dist/component/server/refresh.js.map +1 -1
  104. package/dist/component/server/sessions.js +5 -0
  105. package/dist/component/server/sessions.js.map +1 -1
  106. package/dist/component/server/signin.js +2 -1
  107. package/dist/component/server/signin.js.map +1 -1
  108. package/dist/component/server/sso.js +166 -19
  109. package/dist/component/server/sso.js.map +1 -1
  110. package/dist/component/server/tokens.js +1 -0
  111. package/dist/component/server/tokens.js.map +1 -1
  112. package/dist/component/server/totp.js +4 -2
  113. package/dist/component/server/totp.js.map +1 -1
  114. package/dist/component/server/types.d.ts +106 -38
  115. package/dist/component/server/types.d.ts.map +1 -1
  116. package/dist/component/server/types.js.map +1 -1
  117. package/dist/component/server/users.js +1 -0
  118. package/dist/component/server/users.js.map +1 -1
  119. package/dist/component/server/utils.js +44 -2
  120. package/dist/component/server/utils.js.map +1 -1
  121. package/dist/providers/anonymous.d.ts +1 -1
  122. package/dist/providers/credentials.d.ts +1 -1
  123. package/dist/providers/password.d.ts +1 -1
  124. package/dist/providers/sso.d.ts +1 -1
  125. package/dist/providers/sso.js.map +1 -1
  126. package/dist/server/auth.d.ts +163 -17
  127. package/dist/server/auth.d.ts.map +1 -1
  128. package/dist/server/auth.js +100 -7
  129. package/dist/server/auth.js.map +1 -1
  130. package/dist/server/cookies.d.ts +1 -38
  131. package/dist/server/cookies.js +3 -0
  132. package/dist/server/cookies.js.map +1 -1
  133. package/dist/server/db.d.ts +1 -125
  134. package/dist/server/db.js +1 -0
  135. package/dist/server/db.js.map +1 -1
  136. package/dist/server/device.d.ts +1 -24
  137. package/dist/server/device.js +3 -1
  138. package/dist/server/device.js.map +1 -1
  139. package/dist/server/domains/core.d.ts +434 -0
  140. package/dist/server/domains/core.d.ts.map +1 -0
  141. package/dist/server/domains/core.js +629 -0
  142. package/dist/server/domains/core.js.map +1 -0
  143. package/dist/server/domains/sso.d.ts +409 -0
  144. package/dist/server/domains/sso.d.ts.map +1 -0
  145. package/dist/server/domains/sso.js +884 -0
  146. package/dist/server/domains/sso.js.map +1 -0
  147. package/dist/server/enterpriseValidators.d.ts +1 -0
  148. package/dist/server/enterpriseValidators.js +60 -0
  149. package/dist/server/enterpriseValidators.js.map +1 -0
  150. package/dist/server/factory.d.ts +136 -0
  151. package/dist/server/factory.d.ts.map +1 -0
  152. package/dist/server/factory.js +1134 -0
  153. package/dist/server/factory.js.map +1 -0
  154. package/dist/server/fx.d.ts +1 -16
  155. package/dist/server/fx.d.ts.map +1 -1
  156. package/dist/server/fx.js +1 -0
  157. package/dist/server/fx.js.map +1 -1
  158. package/dist/server/http.d.ts +59 -0
  159. package/dist/server/http.d.ts.map +1 -0
  160. package/dist/server/http.js +287 -0
  161. package/dist/server/http.js.map +1 -0
  162. package/dist/server/identity.d.ts +1 -0
  163. package/dist/server/identity.js +13 -0
  164. package/dist/server/identity.js.map +1 -0
  165. package/dist/server/index.d.ts +468 -1
  166. package/dist/server/index.d.ts.map +1 -1
  167. package/dist/server/index.js +530 -36
  168. package/dist/server/index.js.map +1 -1
  169. package/dist/server/keys.d.ts +1 -57
  170. package/dist/server/keys.js +4 -0
  171. package/dist/server/keys.js.map +1 -1
  172. package/dist/server/mutations/account.d.ts +7 -7
  173. package/dist/server/mutations/account.d.ts.map +1 -1
  174. package/dist/server/mutations/code.d.ts +13 -13
  175. package/dist/server/mutations/code.d.ts.map +1 -1
  176. package/dist/server/mutations/index.d.ts +107 -107
  177. package/dist/server/mutations/index.d.ts.map +1 -1
  178. package/dist/server/mutations/index.js +1 -1
  179. package/dist/server/mutations/index.js.map +1 -1
  180. package/dist/server/mutations/invalidate.d.ts +5 -5
  181. package/dist/server/mutations/invalidate.d.ts.map +1 -1
  182. package/dist/server/mutations/oauth.d.ts +10 -10
  183. package/dist/server/mutations/oauth.d.ts.map +1 -1
  184. package/dist/server/mutations/oauth.js +9 -6
  185. package/dist/server/mutations/oauth.js.map +1 -1
  186. package/dist/server/mutations/refresh.d.ts +4 -4
  187. package/dist/server/mutations/register.d.ts +12 -12
  188. package/dist/server/mutations/register.d.ts.map +1 -1
  189. package/dist/server/mutations/retrieve.d.ts +7 -7
  190. package/dist/server/mutations/signature.d.ts +5 -5
  191. package/dist/server/mutations/signin.d.ts +6 -6
  192. package/dist/server/mutations/signin.d.ts.map +1 -1
  193. package/dist/server/mutations/signout.d.ts +1 -1
  194. package/dist/server/mutations/store.d.ts +3 -2
  195. package/dist/server/mutations/store.d.ts.map +1 -1
  196. package/dist/server/mutations/store.js +6 -3
  197. package/dist/server/mutations/store.js.map +1 -1
  198. package/dist/server/mutations/verifier.d.ts +1 -1
  199. package/dist/server/mutations/verify.d.ts +11 -11
  200. package/dist/server/mutations/verify.d.ts.map +1 -1
  201. package/dist/server/oauth.d.ts +1 -59
  202. package/dist/server/oauth.js +3 -0
  203. package/dist/server/oauth.js.map +1 -1
  204. package/dist/server/passkey.d.ts.map +1 -1
  205. package/dist/server/passkey.js +3 -2
  206. package/dist/server/passkey.js.map +1 -1
  207. package/dist/server/provider.d.ts +1 -14
  208. package/dist/server/provider.d.ts.map +1 -1
  209. package/dist/server/provider.js +2 -0
  210. package/dist/server/provider.js.map +1 -1
  211. package/dist/server/providers.js +10 -0
  212. package/dist/server/providers.js.map +1 -1
  213. package/dist/server/ratelimit.d.ts +1 -22
  214. package/dist/server/ratelimit.js +3 -0
  215. package/dist/server/ratelimit.js.map +1 -1
  216. package/dist/server/redirects.d.ts +1 -10
  217. package/dist/server/redirects.js +2 -0
  218. package/dist/server/redirects.js.map +1 -1
  219. package/dist/server/refresh.d.ts +1 -37
  220. package/dist/server/refresh.js +5 -0
  221. package/dist/server/refresh.js.map +1 -1
  222. package/dist/server/sessions.d.ts +1 -28
  223. package/dist/server/sessions.js +5 -0
  224. package/dist/server/sessions.js.map +1 -1
  225. package/dist/server/signin.d.ts +1 -55
  226. package/dist/server/signin.js +2 -1
  227. package/dist/server/signin.js.map +1 -1
  228. package/dist/server/sso.d.ts +1 -348
  229. package/dist/server/sso.js +165 -18
  230. package/dist/server/sso.js.map +1 -1
  231. package/dist/server/templates.d.ts +1 -21
  232. package/dist/server/templates.js +1 -0
  233. package/dist/server/templates.js.map +1 -1
  234. package/dist/server/tokens.d.ts +1 -11
  235. package/dist/server/tokens.js +1 -0
  236. package/dist/server/tokens.js.map +1 -1
  237. package/dist/server/totp.d.ts +1 -23
  238. package/dist/server/totp.js +4 -2
  239. package/dist/server/totp.js.map +1 -1
  240. package/dist/server/types.d.ts +114 -77
  241. package/dist/server/types.d.ts.map +1 -1
  242. package/dist/server/types.js.map +1 -1
  243. package/dist/server/users.d.ts +1 -31
  244. package/dist/server/users.js +1 -0
  245. package/dist/server/users.js.map +1 -1
  246. package/dist/server/utils.d.ts +1 -27
  247. package/dist/server/utils.js +44 -2
  248. package/dist/server/utils.js.map +1 -1
  249. package/dist/server/version.d.ts +1 -1
  250. package/dist/server/version.js +1 -1
  251. package/dist/server/version.js.map +1 -1
  252. package/package.json +4 -5
  253. package/src/cli/bin.ts +5 -0
  254. package/src/cli/index.ts +22 -9
  255. package/src/cli/keys.ts +3 -0
  256. package/src/client/index.ts +36 -37
  257. package/src/component/_generated/api.ts +14 -0
  258. package/src/component/_generated/component.ts +2106 -9
  259. package/src/component/index.ts +3 -1
  260. package/src/component/model.ts +441 -0
  261. package/src/component/public/enterprise.ts +753 -0
  262. package/src/component/public/factors.ts +332 -0
  263. package/src/component/public/groups.ts +932 -0
  264. package/src/component/public/identity.ts +566 -0
  265. package/src/component/public/keys.ts +209 -0
  266. package/src/component/public/shared.ts +119 -0
  267. package/src/component/public.ts +5 -2965
  268. package/src/component/schema.ts +68 -63
  269. package/src/providers/sso.ts +1 -1
  270. package/src/server/auth.ts +413 -18
  271. package/src/server/cookies.ts +3 -0
  272. package/src/server/db.ts +3 -0
  273. package/src/server/device.ts +3 -1
  274. package/src/server/domains/core.ts +1071 -0
  275. package/src/server/domains/sso.ts +1749 -0
  276. package/src/server/enterpriseValidators.ts +93 -0
  277. package/src/server/factory.ts +2181 -0
  278. package/src/server/fx.ts +1 -0
  279. package/src/server/http.ts +529 -0
  280. package/src/server/identity.ts +18 -0
  281. package/src/server/index.ts +806 -40
  282. package/src/server/keys.ts +4 -0
  283. package/src/server/mutations/index.ts +1 -1
  284. package/src/server/mutations/oauth.ts +36 -8
  285. package/src/server/mutations/store.ts +6 -3
  286. package/src/server/oauth.ts +6 -0
  287. package/src/server/passkey.ts +3 -2
  288. package/src/server/provider.ts +2 -0
  289. package/src/server/providers.ts +20 -0
  290. package/src/server/ratelimit.ts +3 -0
  291. package/src/server/redirects.ts +2 -0
  292. package/src/server/refresh.ts +5 -0
  293. package/src/server/sessions.ts +5 -0
  294. package/src/server/signin.ts +1 -0
  295. package/src/server/sso.ts +259 -17
  296. package/src/server/templates.ts +1 -0
  297. package/src/server/tokens.ts +1 -0
  298. package/src/server/totp.ts +4 -2
  299. package/src/server/types.ts +178 -83
  300. package/src/server/users.ts +1 -0
  301. package/src/server/utils.ts +71 -1
  302. package/src/server/version.ts +1 -1
  303. package/dist/component/public.js.map +0 -1
  304. package/dist/component/server/implementation.d.ts +0 -1264
  305. package/dist/component/server/implementation.d.ts.map +0 -1
  306. package/dist/component/server/implementation.js +0 -2365
  307. package/dist/component/server/implementation.js.map +0 -1
  308. package/dist/server/cookies.d.ts.map +0 -1
  309. package/dist/server/db.d.ts.map +0 -1
  310. package/dist/server/device.d.ts.map +0 -1
  311. package/dist/server/implementation.d.ts +0 -1264
  312. package/dist/server/implementation.d.ts.map +0 -1
  313. package/dist/server/implementation.js +0 -2365
  314. package/dist/server/implementation.js.map +0 -1
  315. package/dist/server/keys.d.ts.map +0 -1
  316. package/dist/server/oauth.d.ts.map +0 -1
  317. package/dist/server/ratelimit.d.ts.map +0 -1
  318. package/dist/server/redirects.d.ts.map +0 -1
  319. package/dist/server/refresh.d.ts.map +0 -1
  320. package/dist/server/sessions.d.ts.map +0 -1
  321. package/dist/server/signin.d.ts.map +0 -1
  322. package/dist/server/sso.d.ts.map +0 -1
  323. package/dist/server/templates.d.ts.map +0 -1
  324. package/dist/server/tokens.d.ts.map +0 -1
  325. package/dist/server/totp.d.ts.map +0 -1
  326. package/dist/server/users.d.ts.map +0 -1
  327. package/dist/server/utils.d.ts.map +0 -1
  328. package/src/server/implementation.ts +0 -5336
@@ -1,7 +1,7 @@
1
1
  import { Fx } from "@robelest/fx";
2
2
  import { sha256 } from "@oslojs/crypto/sha2";
3
3
  import { decodeBase64urlIgnorePadding, encodeBase64urlNoPadding } from "@oslojs/encoding";
4
- import { createRemoteJWKSet, decodeProtectedHeader, jwtVerify } from "jose";
4
+ import { createRemoteJWKSet, customFetch, decodeProtectedHeader, jwtVerify } from "jose";
5
5
  import { Constants, IdentityProvider, ServiceProvider, setSchemaValidator } from "@robelest/samlify";
6
6
  import { decodeIdToken } from "arctic";
7
7
 
@@ -10,20 +10,28 @@ const _samlifyPermissiveValidator = { validate: (_xml) => Promise.resolve("OK")
10
10
  function ensureSamlifyValidator() {
11
11
  setSchemaValidator(_samlifyPermissiveValidator);
12
12
  }
13
+ /** @internal */
13
14
  const SCIM_USER_SCHEMA_ID = "urn:ietf:params:scim:schemas:core:2.0:User";
15
+ /** @internal */
14
16
  const SCIM_GROUP_SCHEMA_ID = "urn:ietf:params:scim:schemas:core:2.0:Group";
17
+ /** @internal */
15
18
  const ENTERPRISE_OIDC_PROVIDER_PREFIX = "enterprise:oidc:";
19
+ /** @internal */
16
20
  const ENTERPRISE_SAML_PROVIDER_PREFIX = "enterprise:saml:";
17
21
  const OIDC_JWKS_CACHE = /* @__PURE__ */ new Map();
22
+ /** @internal */
18
23
  function normalizeDomain(domain) {
19
24
  return domain.trim().toLowerCase().replace(/^@+/, "");
20
25
  }
26
+ /** @internal */
21
27
  function enterpriseOidcProviderId(enterpriseId) {
22
28
  return `${ENTERPRISE_OIDC_PROVIDER_PREFIX}${enterpriseId}`;
23
29
  }
30
+ /** @internal */
24
31
  function enterpriseSamlProviderId(enterpriseId) {
25
32
  return `${ENTERPRISE_SAML_PROVIDER_PREFIX}${enterpriseId}`;
26
33
  }
34
+ /** @internal */
27
35
  function getEnterpriseSamlUrls(opts) {
28
36
  const root = opts.rootUrl.replace(/\/$/, "");
29
37
  return {
@@ -32,6 +40,7 @@ function getEnterpriseSamlUrls(opts) {
32
40
  sloUrl: `${root}/api/auth/sso/${opts.source.id}/saml/slo`
33
41
  };
34
42
  }
43
+ /** @internal */
35
44
  function getEnterpriseOidcUrls(opts) {
36
45
  const root = opts.rootUrl.replace(/\/$/, "");
37
46
  return {
@@ -39,25 +48,120 @@ function getEnterpriseOidcUrls(opts) {
39
48
  callbackUrl: `${root}/api/auth/sso/${opts.enterpriseId}/oidc/callback`
40
49
  };
41
50
  }
51
+ /** @internal */
42
52
  function isEnterpriseSamlSourceActive(source) {
43
53
  return source.status === "active";
44
54
  }
55
+ /** @internal */
45
56
  function isEnterpriseProviderId(providerId) {
46
57
  return providerId.startsWith(ENTERPRISE_OIDC_PROVIDER_PREFIX) || providerId.startsWith(ENTERPRISE_SAML_PROVIDER_PREFIX);
47
58
  }
48
59
  const asRecord = (value) => typeof value === "object" && value !== null ? value : null;
60
+ /** @internal */
61
+ const DEFAULT_ENTERPRISE_POLICY = {
62
+ version: 1,
63
+ identity: { accountLinking: {
64
+ oidc: "verifiedEmail",
65
+ saml: "verifiedEmail"
66
+ } },
67
+ provisioning: {
68
+ scimReuse: { user: "externalId" },
69
+ jit: {
70
+ mode: "createUserAndMembership",
71
+ defaultRoleIds: []
72
+ },
73
+ deprovision: { mode: "soft" }
74
+ }
75
+ };
76
+ /** @internal */
77
+ function normalizeEnterprisePolicy(policy) {
78
+ const input = asRecord(policy) ?? {};
79
+ const accountLinking = asRecord((asRecord(input.identity) ?? {}).accountLinking) ?? {};
80
+ const provisioning = asRecord(input.provisioning) ?? {};
81
+ const scimReuse = asRecord(provisioning.scimReuse) ?? {};
82
+ const jit = asRecord(provisioning.jit) ?? {};
83
+ const deprovision = asRecord(provisioning.deprovision) ?? {};
84
+ const extend = asRecord(input.extend) ?? void 0;
85
+ return {
86
+ version: 1,
87
+ identity: { accountLinking: {
88
+ oidc: accountLinking.oidc === "none" ? "none" : DEFAULT_ENTERPRISE_POLICY.identity.accountLinking.oidc,
89
+ saml: accountLinking.saml === "none" ? "none" : DEFAULT_ENTERPRISE_POLICY.identity.accountLinking.saml
90
+ } },
91
+ provisioning: {
92
+ scimReuse: { user: scimReuse.user === "none" ? "none" : DEFAULT_ENTERPRISE_POLICY.provisioning.scimReuse.user },
93
+ jit: {
94
+ mode: jit.mode === "off" || jit.mode === "createUser" || jit.mode === "createUserAndMembership" ? jit.mode : DEFAULT_ENTERPRISE_POLICY.provisioning.jit.mode,
95
+ defaultRoleIds: Array.isArray(jit.defaultRoleIds) ? Array.from(new Set(jit.defaultRoleIds.filter((value) => typeof value === "string" && value.length > 0))) : typeof jit.defaultRole === "string" && jit.defaultRole.length > 0 ? [jit.defaultRole] : DEFAULT_ENTERPRISE_POLICY.provisioning.jit.defaultRoleIds
96
+ },
97
+ deprovision: { mode: deprovision.mode === "hard" ? "hard" : DEFAULT_ENTERPRISE_POLICY.provisioning.deprovision.mode }
98
+ },
99
+ ...extend ? { extend } : {}
100
+ };
101
+ }
102
+ /** @internal */
103
+ function patchEnterprisePolicy(current, patch) {
104
+ const base = normalizeEnterprisePolicy(current);
105
+ return normalizeEnterprisePolicy({
106
+ ...base,
107
+ ...patch,
108
+ identity: {
109
+ ...base.identity,
110
+ ...patch.identity,
111
+ accountLinking: {
112
+ ...base.identity.accountLinking,
113
+ ...patch.identity?.accountLinking
114
+ }
115
+ },
116
+ provisioning: {
117
+ ...base.provisioning,
118
+ ...patch.provisioning,
119
+ scimReuse: {
120
+ ...base.provisioning.scimReuse,
121
+ ...patch.provisioning?.scimReuse
122
+ },
123
+ jit: {
124
+ ...base.provisioning.jit,
125
+ ...patch.provisioning?.jit
126
+ },
127
+ deprovision: {
128
+ ...base.provisioning.deprovision,
129
+ ...patch.provisioning?.deprovision
130
+ }
131
+ },
132
+ extend: patch.extend === void 0 ? base.extend : {
133
+ ...base.extend,
134
+ ...patch.extend
135
+ }
136
+ });
137
+ }
49
138
  const getProtocolConfig = (config, protocol) => {
50
139
  const base = asRecord(config);
51
140
  const direct = base?.[protocol];
52
141
  const viaProtocols = asRecord(base?.protocols)?.[protocol];
53
142
  return asRecord(direct) ?? asRecord(viaProtocols) ?? {};
54
143
  };
144
+ /** @internal */
55
145
  function getOidcConfig(config) {
56
146
  return getProtocolConfig(config, "oidc");
57
147
  }
148
+ /** @internal */
149
+ function getPublicOidcConfig(config) {
150
+ const { clientSecret: _clientSecret, ...publicOidc } = getOidcConfig(config);
151
+ return publicOidc;
152
+ }
153
+ /** @internal */
154
+ function withOidcSecretState(config, hasClientSecret) {
155
+ return {
156
+ ...config,
157
+ hasClientSecret
158
+ };
159
+ }
160
+ /** @internal */
58
161
  function getSamlConfig(config) {
59
162
  return getProtocolConfig(config, "saml");
60
163
  }
164
+ /** @internal */
61
165
  function upsertProtocolConfig(config, protocol, protocolConfig) {
62
166
  const base = asRecord(config) ?? {};
63
167
  const protocols = asRecord(base.protocols) ?? {};
@@ -70,6 +174,7 @@ function upsertProtocolConfig(config, protocol, protocolConfig) {
70
174
  protocols
71
175
  };
72
176
  }
177
+ /** @internal */
73
178
  function createSamlPostBindingResponse(opts) {
74
179
  const fields = [`<input type="hidden" name="${opts.parameter}" value="${opts.value.replace(/"/g, "&quot;")}" />`, opts.relayState ? `<input type="hidden" name="RelayState" value="${opts.relayState.replace(/"/g, "&quot;")}" />` : ""].join("");
75
180
  return new Response(`<!doctype html><html><body><form method="POST" action="${opts.endpoint}">${fields}</form><script>document.forms[0].submit();<\/script></body></html>`, {
@@ -77,6 +182,7 @@ function createSamlPostBindingResponse(opts) {
77
182
  headers: { "Content-Type": "text/html; charset=utf-8" }
78
183
  });
79
184
  }
185
+ /** @internal */
80
186
  function decodeRelayState(value) {
81
187
  if (!value) return {};
82
188
  try {
@@ -85,6 +191,7 @@ function decodeRelayState(value) {
85
191
  return {};
86
192
  }
87
193
  }
194
+ /** @internal */
88
195
  function encodeEnterpriseSamlRelayState(value) {
89
196
  return encodeBase64urlNoPadding(new TextEncoder().encode(JSON.stringify({
90
197
  source: `${value.source.kind}:${value.source.id}`,
@@ -94,6 +201,7 @@ function encodeEnterpriseSamlRelayState(value) {
94
201
  redirectTo: value.redirectTo
95
202
  })));
96
203
  }
204
+ /** @internal */
97
205
  function decodeEnterpriseSamlRelayStateOrThrow(value) {
98
206
  if (!value) throw new Error("Missing SAML RelayState.");
99
207
  const decoded = decodeRelayState(value);
@@ -112,6 +220,7 @@ function decodeEnterpriseSamlRelayStateOrThrow(value) {
112
220
  redirectTo: typeof decoded.redirectTo === "string" ? decoded.redirectTo : void 0
113
221
  };
114
222
  }
223
+ /** @internal */
115
224
  async function readRequestBody(request) {
116
225
  const contentType = request.headers.get("Content-Type") ?? "";
117
226
  if (contentType.includes("application/x-www-form-urlencoded") || contentType.includes("multipart/form-data")) {
@@ -124,6 +233,7 @@ async function readRequestBody(request) {
124
233
  }
125
234
  return {};
126
235
  }
236
+ /** @internal */
127
237
  async function readEnterpriseSamlHttpRequest(request) {
128
238
  const url = new URL(request.url);
129
239
  const body = await readRequestBody(request);
@@ -140,9 +250,10 @@ async function readEnterpriseSamlHttpRequest(request) {
140
250
  async function discoverOidcConfiguration(config) {
141
251
  const discoveryUrl = typeof config.discoveryUrl === "string" ? config.discoveryUrl : typeof config.issuer === "string" ? `${config.issuer.replace(/\/$/, "")}/.well-known/openid-configuration` : null;
142
252
  if (!discoveryUrl) throw new Error("Enterprise OIDC requires an issuer or discoveryUrl.");
253
+ const oidcFetch = createEnterpriseOidcFetch(config, config.issuer);
143
254
  return await Fx.run(Fx.defer(() => Fx.from({
144
255
  ok: async () => {
145
- const response = await fetch(discoveryUrl);
256
+ const response = await oidcFetch(discoveryUrl);
146
257
  if (!response.ok) throw new Error(`Failed to discover OIDC configuration: ${response.status}`);
147
258
  const discovery = await response.json();
148
259
  if (typeof discovery.issuer !== "string" || typeof discovery.authorization_endpoint !== "string" || typeof discovery.token_endpoint !== "string" || typeof discovery.jwks_uri !== "string") throw new Error("OIDC discovery document is missing required fields.");
@@ -151,18 +262,33 @@ async function discoverOidcConfiguration(config) {
151
262
  err: (error) => error instanceof Error ? error : new Error(String(error))
152
263
  })).pipe(Fx.timeout(1e4), Fx.retry(Fx.retry.compose(Fx.retry.jittered(Fx.retry.exponential(200)), Fx.retry.recurs(2))), Fx.recover((error) => Fx.fail(error instanceof Error ? error : new Error(String(error))))));
153
264
  }
154
- function getOidcJwks(url) {
155
- let jwks = OIDC_JWKS_CACHE.get(url);
265
+ function createEnterpriseOidcFetch(config, discoveredIssuer) {
266
+ const runtimeOrigin = typeof config.discoveryUrl === "string" ? new URL(config.discoveryUrl).origin : void 0;
267
+ const externalHost = typeof config.issuer === "string" ? new URL(config.issuer).host : typeof discoveredIssuer === "string" ? new URL(discoveredIssuer).host : void 0;
268
+ return async (input, init) => {
269
+ const url = new URL(typeof input === "string" ? input : input.toString());
270
+ const rewrittenUrl = runtimeOrigin !== void 0 && url.origin !== runtimeOrigin ? new URL(`${runtimeOrigin}${url.pathname}${url.search}`) : url;
271
+ const headers = new Headers(init?.headers);
272
+ if (runtimeOrigin !== void 0 && externalHost !== void 0) headers.set("host", externalHost);
273
+ return await fetch(rewrittenUrl, {
274
+ ...init,
275
+ headers
276
+ });
277
+ };
278
+ }
279
+ function getOidcJwks(url, fetchImpl) {
280
+ const cacheKey = fetchImpl ? `${url}::custom` : url;
281
+ let jwks = OIDC_JWKS_CACHE.get(cacheKey);
156
282
  if (!jwks) {
157
- jwks = createRemoteJWKSet(new URL(url));
158
- OIDC_JWKS_CACHE.set(url, jwks);
283
+ jwks = fetchImpl ? createRemoteJWKSet(new URL(url), { [customFetch]: fetchImpl }) : createRemoteJWKSet(new URL(url));
284
+ OIDC_JWKS_CACHE.set(cacheKey, jwks);
159
285
  }
160
286
  return jwks;
161
287
  }
162
288
  function userInfoProfileFx(opts) {
163
289
  return Fx.from({
164
290
  ok: async () => {
165
- const response = await fetch(opts.endpoint, { headers: { Authorization: `Bearer ${opts.accessToken}` } });
291
+ const response = await (opts.fetchImpl ?? fetch)(opts.endpoint, { headers: { Authorization: `Bearer ${opts.accessToken}` } });
166
292
  if (!response.ok) throw new Error(`OIDC userinfo request failed: ${response.status}`);
167
293
  return await response.json();
168
294
  },
@@ -185,6 +311,7 @@ function userInfoProfileFx(opts) {
185
311
  return Fx.fail(/* @__PURE__ */ new Error("OIDC userinfo subject does not match ID token subject."));
186
312
  }));
187
313
  }
314
+ /** @internal */
188
315
  async function createEnterpriseOidcProvider(config, redirectUri) {
189
316
  const discovery = await discoverOidcConfiguration(config);
190
317
  const expectedIssuer = String(config.issuer ?? discovery.issuer).replace(/\/$/, "");
@@ -202,6 +329,7 @@ async function createEnterpriseOidcProvider(config, redirectUri) {
202
329
  const jwksUri = String(config.jwksUri ?? discovery.jwks_uri);
203
330
  const supportedIdTokenSigningAlgs = Array.isArray(discovery.id_token_signing_alg_values_supported) ? discovery.id_token_signing_alg_values_supported.filter((value) => typeof value === "string") : [];
204
331
  const userinfoEndpoint = discovery.userinfo_endpoint ?? void 0;
332
+ const oidcFetch = createEnterpriseOidcFetch(config, discovery.issuer);
205
333
  const scopes = Array.isArray(config.scopes) ? config.scopes.filter((value) => typeof value === "string") : [
206
334
  "openid",
207
335
  "profile",
@@ -215,7 +343,7 @@ async function createEnterpriseOidcProvider(config, redirectUri) {
215
343
  return candidates;
216
344
  };
217
345
  const expectedIssuers = strictIssuer ? [expectedIssuer] : Array.from(new Set([...getIssuerCandidates(expectedIssuer), ...getIssuerCandidates(discoveredIssuer)]));
218
- const jwks = getOidcJwks(jwksUri);
346
+ const jwks = getOidcJwks(jwksUri, oidcFetch);
219
347
  let verifiedClaims = null;
220
348
  let verifiedProfile = null;
221
349
  const normalizeProfile = (claims) => ({
@@ -249,7 +377,7 @@ async function createEnterpriseOidcProvider(config, redirectUri) {
249
377
  });
250
378
  if (typeof config.clientSecret === "string") body.set("client_secret", config.clientSecret);
251
379
  if (codeVerifier) body.set("code_verifier", codeVerifier);
252
- const response = await fetch(tokenEndpoint, {
380
+ const response = await oidcFetch(tokenEndpoint, {
253
381
  method: "POST",
254
382
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
255
383
  body
@@ -318,7 +446,8 @@ async function createEnterpriseOidcProvider(config, redirectUri) {
318
446
  endpoint: userinfoEndpoint,
319
447
  accessToken: tokens.accessToken(),
320
448
  verifiedClaims,
321
- verifiedProfile
449
+ verifiedProfile,
450
+ fetchImpl: oidcFetch
322
451
  }));
323
452
  if (userInfoProfile !== null) return userInfoProfile;
324
453
  }
@@ -327,15 +456,17 @@ async function createEnterpriseOidcProvider(config, redirectUri) {
327
456
  }
328
457
  };
329
458
  }
330
- function createSyntheticOAuthMaterializedConfig(providerId) {
459
+ /** @internal */
460
+ function createSyntheticOAuthMaterializedConfig(providerId, options) {
331
461
  return {
332
462
  id: providerId,
333
463
  type: "oauth",
334
464
  provider: null,
335
465
  scopes: [],
336
- accountLinking: "verifiedEmail"
466
+ accountLinking: options?.accountLinking ?? "verifiedEmail"
337
467
  };
338
468
  }
469
+ /** @internal */
339
470
  function parseSamlIdpMetadata(metadata) {
340
471
  const entityMeta = IdentityProvider({ metadata }).entityMeta;
341
472
  const normalizeService = (value) => {
@@ -360,6 +491,7 @@ function parseSamlIdpMetadata(metadata) {
360
491
  wantsSignedAuthnRequests: entityMeta.isWantAuthnRequestsSigned()
361
492
  };
362
493
  }
494
+ /** @internal */
363
495
  function createServiceProviderMetadata(opts) {
364
496
  const binding = Constants.namespace.binding;
365
497
  return ServiceProvider({
@@ -384,6 +516,7 @@ function createServiceProviderMetadata(opts) {
384
516
  }] : void 0
385
517
  }).getMetadata();
386
518
  }
519
+ /** @internal */
387
520
  function createEnterpriseSamlMetadataXml(opts) {
388
521
  return createServiceProviderMetadata(getSamlServiceProviderOptions({
389
522
  rootUrl: opts.rootUrl,
@@ -391,6 +524,7 @@ function createEnterpriseSamlMetadataXml(opts) {
391
524
  config: opts.config
392
525
  }));
393
526
  }
527
+ /** @internal */
394
528
  function getSamlServiceProviderOptions(opts) {
395
529
  const saml = getSamlConfig(opts.config);
396
530
  const sp = asRecord(saml.sp) ?? {};
@@ -412,6 +546,7 @@ function getSamlServiceProviderOptions(opts) {
412
546
  encPrivateKeyPass: sp.encPrivateKeyPass
413
547
  };
414
548
  }
549
+ /** @internal */
415
550
  function createSamlServiceProvider(opts) {
416
551
  const binding = Constants.namespace.binding;
417
552
  return ServiceProvider({
@@ -437,6 +572,7 @@ function createSamlServiceProvider(opts) {
437
572
  }] : void 0
438
573
  });
439
574
  }
575
+ /** @internal */
440
576
  function createEnterpriseSamlRuntime(opts) {
441
577
  const saml = getSamlConfig(opts.config);
442
578
  const spOptions = getSamlServiceProviderOptions({
@@ -457,6 +593,7 @@ function createEnterpriseSamlRuntime(opts) {
457
593
  })
458
594
  };
459
595
  }
596
+ /** @internal */
460
597
  function createEnterpriseSamlSignInRequest(opts) {
461
598
  const runtime = createEnterpriseSamlRuntime({
462
599
  rootUrl: opts.rootUrl,
@@ -487,6 +624,7 @@ function createEnterpriseSamlSignInRequest(opts) {
487
624
  } : void 0
488
625
  };
489
626
  }
627
+ /** @internal */
490
628
  async function parseEnterpriseSamlLoginResponse(opts) {
491
629
  ensureSamlifyValidator();
492
630
  const httpRequest = await readEnterpriseSamlHttpRequest(opts.request);
@@ -527,9 +665,11 @@ function warnDeprecatedSamlAlgorithms(parsed) {
527
665
  if (digestAlg && DEPRECATED_SAML_ALGORITHMS.has(digestAlg)) console.warn(`[convex-auth] SAML response uses deprecated digest algorithm: ${digestAlg}. Consider upgrading your IdP to use SHA-256 or stronger.`);
528
666
  } catch {}
529
667
  }
668
+ /** @internal */
530
669
  function validateEnterpriseSamlLoginRelayState(opts) {
531
670
  if (opts.relayState.source.kind !== opts.source.kind || opts.relayState.source.id !== opts.source.id || opts.relayState.requestId !== opts.inResponseTo) throw new Error("SAML RelayState did not match the pending login request.");
532
671
  }
672
+ /** @internal */
533
673
  async function parseEnterpriseSamlLogoutMessage(opts) {
534
674
  ensureSamlifyValidator();
535
675
  const httpRequest = await readEnterpriseSamlHttpRequest(opts.request);
@@ -549,22 +689,23 @@ async function parseEnterpriseSamlLogoutMessage(opts) {
549
689
  parsedRequest
550
690
  };
551
691
  }
692
+ /** @internal */
552
693
  async function createEnterpriseOidcRuntime(opts) {
553
- const oidc = getOidcConfig(opts.config);
554
694
  const providerId = enterpriseOidcProviderId(opts.enterpriseId);
555
695
  const urls = getEnterpriseOidcUrls({
556
696
  rootUrl: opts.rootUrl,
557
697
  enterpriseId: opts.enterpriseId
558
698
  });
559
- const { provider, oauthConfig } = await createEnterpriseOidcProvider(oidc, urls.callbackUrl);
699
+ const { provider, oauthConfig } = await createEnterpriseOidcProvider(opts.oidc, urls.callbackUrl);
560
700
  return {
561
- oidc,
701
+ oidc: opts.oidc,
562
702
  providerId,
563
703
  provider,
564
704
  oauthConfig,
565
705
  ...urls
566
706
  };
567
707
  }
708
+ /** @internal */
568
709
  function profileFromSamlExtract(extract, mapping) {
569
710
  const attributes = typeof extract?.attributes === "object" && extract.attributes !== null ? extract.attributes : {};
570
711
  const resolveFirst = (...keys) => {
@@ -593,9 +734,10 @@ function profileFromSamlExtract(extract, mapping) {
593
734
  samlSessionIndex: extract?.sessionIndex?.SessionIndex
594
735
  };
595
736
  }
737
+ /** @internal */
596
738
  function parseScimPath(pathname) {
597
- const [api, auth, enterprise, enterpriseId, protocol, version, ...rest] = pathname.split("/").filter(Boolean);
598
- if (api !== "api" || auth !== "auth" || enterprise !== "enterprise" || !enterpriseId || enterpriseId === "setup" || protocol !== "scim" || version !== "v2") return {
739
+ const [api, auth, sso, enterpriseId, protocol, version, ...rest] = pathname.split("/").filter(Boolean);
740
+ if (api !== "api" || auth !== "auth" || sso !== "sso" || !enterpriseId || enterpriseId === "setup" || protocol !== "scim" || version !== "v2") return {
599
741
  enterpriseId: "",
600
742
  resource: "",
601
743
  resourceId: void 0
@@ -606,6 +748,7 @@ function parseScimPath(pathname) {
606
748
  resourceId: rest[1]
607
749
  };
608
750
  }
751
+ /** @internal */
609
752
  function parseScimListRequest(url) {
610
753
  const startIndex = Math.max(1, Number(url.searchParams.get("startIndex") ?? "1"));
611
754
  const count = Math.min(100, Math.max(1, Number(url.searchParams.get("count") ?? "100")));
@@ -623,6 +766,7 @@ function parseScimListRequest(url) {
623
766
  })() : void 0
624
767
  };
625
768
  }
769
+ /** @internal */
626
770
  function scimJson(data, status = 200, headers) {
627
771
  const responseHeaders = new Headers({ "Content-Type": "application/scim+json" });
628
772
  if (headers) new Headers(headers).forEach((value, key) => {
@@ -633,6 +777,7 @@ function scimJson(data, status = 200, headers) {
633
777
  headers: responseHeaders
634
778
  });
635
779
  }
780
+ /** @internal */
636
781
  function scimError(status, scimType, detail) {
637
782
  return scimJson({
638
783
  schemas: ["urn:ietf:params:scim:api:messages:2.0:Error"],
@@ -641,6 +786,7 @@ function scimError(status, scimType, detail) {
641
786
  detail
642
787
  }, status);
643
788
  }
789
+ /** @internal */
644
790
  function serializeScimUser(args) {
645
791
  return {
646
792
  schemas: [SCIM_USER_SCHEMA_ID],
@@ -664,6 +810,7 @@ function serializeScimUser(args) {
664
810
  displayName: args.user.name
665
811
  };
666
812
  }
813
+ /** @internal */
667
814
  function serializeScimGroup(args) {
668
815
  return {
669
816
  schemas: [SCIM_GROUP_SCHEMA_ID],
@@ -679,5 +826,5 @@ function serializeScimGroup(args) {
679
826
  }
680
827
 
681
828
  //#endregion
682
- export { ENTERPRISE_OIDC_PROVIDER_PREFIX, ENTERPRISE_SAML_PROVIDER_PREFIX, SCIM_GROUP_SCHEMA_ID, SCIM_USER_SCHEMA_ID, createEnterpriseOidcProvider, createEnterpriseOidcRuntime, createEnterpriseSamlMetadataXml, createEnterpriseSamlRuntime, createEnterpriseSamlSignInRequest, createSamlPostBindingResponse, createSamlServiceProvider, createServiceProviderMetadata, createSyntheticOAuthMaterializedConfig, decodeEnterpriseSamlRelayStateOrThrow, decodeRelayState, encodeEnterpriseSamlRelayState, enterpriseOidcProviderId, enterpriseSamlProviderId, getEnterpriseOidcUrls, getEnterpriseSamlUrls, getOidcConfig, getSamlConfig, getSamlServiceProviderOptions, isEnterpriseProviderId, isEnterpriseSamlSourceActive, normalizeDomain, parseEnterpriseSamlLoginResponse, parseEnterpriseSamlLogoutMessage, parseSamlIdpMetadata, parseScimListRequest, parseScimPath, profileFromSamlExtract, readEnterpriseSamlHttpRequest, readRequestBody, scimError, scimJson, serializeScimGroup, serializeScimUser, upsertProtocolConfig, validateEnterpriseSamlLoginRelayState };
829
+ export { DEFAULT_ENTERPRISE_POLICY, ENTERPRISE_OIDC_PROVIDER_PREFIX, ENTERPRISE_SAML_PROVIDER_PREFIX, SCIM_GROUP_SCHEMA_ID, SCIM_USER_SCHEMA_ID, createEnterpriseOidcProvider, createEnterpriseOidcRuntime, createEnterpriseSamlMetadataXml, createEnterpriseSamlRuntime, createEnterpriseSamlSignInRequest, createSamlPostBindingResponse, createSamlServiceProvider, createServiceProviderMetadata, createSyntheticOAuthMaterializedConfig, decodeEnterpriseSamlRelayStateOrThrow, decodeRelayState, encodeEnterpriseSamlRelayState, enterpriseOidcProviderId, enterpriseSamlProviderId, getEnterpriseOidcUrls, getEnterpriseSamlUrls, getOidcConfig, getPublicOidcConfig, getSamlConfig, getSamlServiceProviderOptions, isEnterpriseProviderId, isEnterpriseSamlSourceActive, normalizeDomain, normalizeEnterprisePolicy, parseEnterpriseSamlLoginResponse, parseEnterpriseSamlLogoutMessage, parseSamlIdpMetadata, parseScimListRequest, parseScimPath, patchEnterprisePolicy, profileFromSamlExtract, readEnterpriseSamlHttpRequest, readRequestBody, scimError, scimJson, serializeScimGroup, serializeScimUser, upsertProtocolConfig, validateEnterpriseSamlLoginRelayState, withOidcSecretState };
683
830
  //# sourceMappingURL=sso.js.map