@robelest/convex-auth 0.0.4-preview.22 → 0.0.4-preview.24

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 (314) hide show
  1. package/README.md +10 -11
  2. package/dist/authorization/index.d.ts +1 -1
  3. package/dist/authorization/index.js +1 -1
  4. package/dist/authorization/index.js.map +1 -1
  5. package/dist/client/index.d.ts +1 -2
  6. package/dist/client/index.d.ts.map +1 -1
  7. package/dist/client/index.js +36 -39
  8. package/dist/client/index.js.map +1 -1
  9. package/dist/component/client/index.d.ts +1 -2
  10. package/dist/component/index.js +2 -2
  11. package/dist/component/model.d.ts +9 -9
  12. package/dist/component/model.d.ts.map +1 -1
  13. package/dist/component/public/enterprise/audit.d.ts.map +1 -1
  14. package/dist/component/public/enterprise/audit.js.map +1 -1
  15. package/dist/component/public/enterprise/core.d.ts.map +1 -1
  16. package/dist/component/public/enterprise/core.js.map +1 -1
  17. package/dist/component/public/enterprise/domains.d.ts.map +1 -1
  18. package/dist/component/public/enterprise/domains.js.map +1 -1
  19. package/dist/component/public/enterprise/scim.d.ts.map +1 -1
  20. package/dist/component/public/enterprise/scim.js.map +1 -1
  21. package/dist/component/public/enterprise/secrets.d.ts.map +1 -1
  22. package/dist/component/public/enterprise/secrets.js.map +1 -1
  23. package/dist/component/public/enterprise/webhooks.d.ts.map +1 -1
  24. package/dist/component/public/enterprise/webhooks.js.map +1 -1
  25. package/dist/component/public/factors/devices.d.ts.map +1 -1
  26. package/dist/component/public/factors/devices.js.map +1 -1
  27. package/dist/component/public/factors/passkeys.d.ts.map +1 -1
  28. package/dist/component/public/factors/passkeys.js.map +1 -1
  29. package/dist/component/public/factors/totp.d.ts.map +1 -1
  30. package/dist/component/public/factors/totp.js.map +1 -1
  31. package/dist/component/public/groups/core.js.map +1 -1
  32. package/dist/component/public/groups/invites.d.ts.map +1 -1
  33. package/dist/component/public/groups/invites.js.map +1 -1
  34. package/dist/component/public/groups/members.d.ts.map +1 -1
  35. package/dist/component/public/groups/members.js.map +1 -1
  36. package/dist/component/public/identity/accounts.d.ts.map +1 -1
  37. package/dist/component/public/identity/accounts.js.map +1 -1
  38. package/dist/component/public/identity/codes.d.ts.map +1 -1
  39. package/dist/component/public/identity/codes.js.map +1 -1
  40. package/dist/component/public/identity/sessions.d.ts.map +1 -1
  41. package/dist/component/public/identity/sessions.js.map +1 -1
  42. package/dist/component/public/identity/tokens.d.ts.map +1 -1
  43. package/dist/component/public/identity/tokens.js.map +1 -1
  44. package/dist/component/public/identity/users.d.ts.map +1 -1
  45. package/dist/component/public/identity/users.js.map +1 -1
  46. package/dist/component/public/identity/verifiers.d.ts.map +1 -1
  47. package/dist/component/public/identity/verifiers.js.map +1 -1
  48. package/dist/component/public/security/keys.d.ts.map +1 -1
  49. package/dist/component/public/security/keys.js.map +1 -1
  50. package/dist/component/public/security/limits.d.ts.map +1 -1
  51. package/dist/component/public/security/limits.js.map +1 -1
  52. package/dist/component/schema.d.ts +41 -41
  53. package/dist/component/server/auth.d.ts +127 -130
  54. package/dist/component/server/auth.d.ts.map +1 -1
  55. package/dist/component/server/auth.js +100 -64
  56. package/dist/component/server/auth.js.map +1 -1
  57. package/dist/component/server/context.js +53 -0
  58. package/dist/component/server/context.js.map +1 -0
  59. package/dist/component/server/core.js +113 -250
  60. package/dist/component/server/core.js.map +1 -1
  61. package/dist/component/server/crypto.js +25 -7
  62. package/dist/component/server/crypto.js.map +1 -1
  63. package/dist/component/server/device.js +59 -16
  64. package/dist/component/server/device.js.map +1 -1
  65. package/dist/component/server/enterprise/domain.js +148 -59
  66. package/dist/component/server/enterprise/domain.js.map +1 -1
  67. package/dist/component/server/enterprise/http.js +36 -15
  68. package/dist/component/server/enterprise/http.js.map +1 -1
  69. package/dist/component/server/enterprise/oidc.js +1 -1
  70. package/dist/component/server/http.d.ts +85 -0
  71. package/dist/component/server/http.d.ts.map +1 -0
  72. package/dist/component/server/http.js +85 -22
  73. package/dist/component/server/http.js.map +1 -1
  74. package/dist/component/server/identity.js +5 -2
  75. package/dist/component/server/identity.js.map +1 -1
  76. package/dist/component/server/limits.js +21 -30
  77. package/dist/component/server/limits.js.map +1 -1
  78. package/dist/component/server/mutations/account.js +12 -10
  79. package/dist/component/server/mutations/account.js.map +1 -1
  80. package/dist/component/server/mutations/code.js +5 -2
  81. package/dist/component/server/mutations/code.js.map +1 -1
  82. package/dist/component/server/mutations/invalidate.js +1 -1
  83. package/dist/component/server/mutations/invalidate.js.map +1 -1
  84. package/dist/component/server/mutations/oauth.js +10 -4
  85. package/dist/component/server/mutations/oauth.js.map +1 -1
  86. package/dist/component/server/mutations/refresh.js +2 -2
  87. package/dist/component/server/mutations/refresh.js.map +1 -1
  88. package/dist/component/server/mutations/register.js +46 -42
  89. package/dist/component/server/mutations/register.js.map +1 -1
  90. package/dist/component/server/mutations/retrieve.js +21 -25
  91. package/dist/component/server/mutations/retrieve.js.map +1 -1
  92. package/dist/component/server/mutations/signature.js +10 -4
  93. package/dist/component/server/mutations/signature.js.map +1 -1
  94. package/dist/component/server/mutations/signout.js.map +1 -1
  95. package/dist/component/server/mutations/store.js +9 -24
  96. package/dist/component/server/mutations/store.js.map +1 -1
  97. package/dist/component/server/mutations/verifier.js.map +1 -1
  98. package/dist/component/server/mutations/verify.js +1 -1
  99. package/dist/component/server/mutations/verify.js.map +1 -1
  100. package/dist/component/server/oauth.js +53 -16
  101. package/dist/component/server/oauth.js.map +1 -1
  102. package/dist/component/server/passkey.js +115 -31
  103. package/dist/component/server/passkey.js.map +1 -1
  104. package/dist/component/server/redirects.js +9 -3
  105. package/dist/component/server/redirects.js.map +1 -1
  106. package/dist/component/server/refresh.js +10 -7
  107. package/dist/component/server/refresh.js.map +1 -1
  108. package/dist/component/server/runtime.d.ts +5 -5
  109. package/dist/component/server/runtime.js +156 -113
  110. package/dist/component/server/runtime.js.map +1 -1
  111. package/dist/component/server/signin.js +34 -10
  112. package/dist/component/server/signin.js.map +1 -1
  113. package/dist/component/server/totp.js +79 -19
  114. package/dist/component/server/totp.js.map +1 -1
  115. package/dist/component/server/types.d.ts +12 -20
  116. package/dist/component/server/types.d.ts.map +1 -1
  117. package/dist/component/server/types.js.map +1 -1
  118. package/dist/component/server/users.js +6 -3
  119. package/dist/component/server/users.js.map +1 -1
  120. package/dist/component/server/utils.js +10 -4
  121. package/dist/component/server/utils.js.map +1 -1
  122. package/dist/core/types.d.ts +14 -22
  123. package/dist/core/types.d.ts.map +1 -1
  124. package/dist/factors/device.js +8 -9
  125. package/dist/factors/device.js.map +1 -1
  126. package/dist/factors/passkey.js +18 -21
  127. package/dist/factors/passkey.js.map +1 -1
  128. package/dist/providers/password.js +66 -81
  129. package/dist/providers/password.js.map +1 -1
  130. package/dist/runtime/invite.js +2 -8
  131. package/dist/runtime/invite.js.map +1 -1
  132. package/dist/server/auth.d.ts +127 -130
  133. package/dist/server/auth.d.ts.map +1 -1
  134. package/dist/server/auth.js +100 -64
  135. package/dist/server/auth.js.map +1 -1
  136. package/dist/server/context.d.ts +1 -0
  137. package/dist/server/context.js +53 -0
  138. package/dist/server/context.js.map +1 -0
  139. package/dist/server/core.d.ts +74 -195
  140. package/dist/server/core.d.ts.map +1 -1
  141. package/dist/server/core.js +113 -250
  142. package/dist/server/core.js.map +1 -1
  143. package/dist/server/crypto.d.ts.map +1 -1
  144. package/dist/server/crypto.js +25 -7
  145. package/dist/server/crypto.js.map +1 -1
  146. package/dist/server/device.js +59 -16
  147. package/dist/server/device.js.map +1 -1
  148. package/dist/server/enterprise/domain.d.ts +0 -8
  149. package/dist/server/enterprise/domain.d.ts.map +1 -1
  150. package/dist/server/enterprise/domain.js +148 -59
  151. package/dist/server/enterprise/domain.js.map +1 -1
  152. package/dist/server/enterprise/http.d.ts.map +1 -1
  153. package/dist/server/enterprise/http.js +35 -14
  154. package/dist/server/enterprise/http.js.map +1 -1
  155. package/dist/server/http.d.ts +81 -3
  156. package/dist/server/http.d.ts.map +1 -1
  157. package/dist/server/http.js +84 -21
  158. package/dist/server/http.js.map +1 -1
  159. package/dist/server/identity.js +5 -2
  160. package/dist/server/identity.js.map +1 -1
  161. package/dist/server/index.d.ts +3 -2
  162. package/dist/server/index.js +2 -2
  163. package/dist/server/limits.js +21 -30
  164. package/dist/server/limits.js.map +1 -1
  165. package/dist/server/mounts.d.ts +25 -63
  166. package/dist/server/mounts.d.ts.map +1 -1
  167. package/dist/server/mounts.js +46 -107
  168. package/dist/server/mounts.js.map +1 -1
  169. package/dist/server/mutations/account.d.ts +8 -9
  170. package/dist/server/mutations/account.d.ts.map +1 -1
  171. package/dist/server/mutations/account.js +11 -9
  172. package/dist/server/mutations/account.js.map +1 -1
  173. package/dist/server/mutations/code.d.ts +12 -12
  174. package/dist/server/mutations/code.d.ts.map +1 -1
  175. package/dist/server/mutations/code.js +5 -2
  176. package/dist/server/mutations/code.js.map +1 -1
  177. package/dist/server/mutations/invalidate.d.ts +4 -4
  178. package/dist/server/mutations/invalidate.d.ts.map +1 -1
  179. package/dist/server/mutations/invalidate.js.map +1 -1
  180. package/dist/server/mutations/oauth.d.ts +14 -12
  181. package/dist/server/mutations/oauth.d.ts.map +1 -1
  182. package/dist/server/mutations/oauth.js +9 -3
  183. package/dist/server/mutations/oauth.js.map +1 -1
  184. package/dist/server/mutations/refresh.d.ts +3 -3
  185. package/dist/server/mutations/refresh.d.ts.map +1 -1
  186. package/dist/server/mutations/refresh.js +1 -1
  187. package/dist/server/mutations/refresh.js.map +1 -1
  188. package/dist/server/mutations/register.d.ts +11 -11
  189. package/dist/server/mutations/register.d.ts.map +1 -1
  190. package/dist/server/mutations/register.js +45 -41
  191. package/dist/server/mutations/register.js.map +1 -1
  192. package/dist/server/mutations/retrieve.d.ts +6 -6
  193. package/dist/server/mutations/retrieve.d.ts.map +1 -1
  194. package/dist/server/mutations/retrieve.js +20 -24
  195. package/dist/server/mutations/retrieve.js.map +1 -1
  196. package/dist/server/mutations/signature.d.ts +6 -7
  197. package/dist/server/mutations/signature.d.ts.map +1 -1
  198. package/dist/server/mutations/signature.js +9 -3
  199. package/dist/server/mutations/signature.js.map +1 -1
  200. package/dist/server/mutations/signin.d.ts +5 -5
  201. package/dist/server/mutations/signout.js.map +1 -1
  202. package/dist/server/mutations/store.d.ts +83 -83
  203. package/dist/server/mutations/store.js +8 -23
  204. package/dist/server/mutations/store.js.map +1 -1
  205. package/dist/server/mutations/verifier.js.map +1 -1
  206. package/dist/server/mutations/verify.d.ts +7 -7
  207. package/dist/server/mutations/verify.d.ts.map +1 -1
  208. package/dist/server/mutations/verify.js.map +1 -1
  209. package/dist/server/oauth.js +53 -16
  210. package/dist/server/oauth.js.map +1 -1
  211. package/dist/server/passkey.d.ts +2 -2
  212. package/dist/server/passkey.d.ts.map +1 -1
  213. package/dist/server/passkey.js +114 -30
  214. package/dist/server/passkey.js.map +1 -1
  215. package/dist/server/redirects.js +9 -3
  216. package/dist/server/redirects.js.map +1 -1
  217. package/dist/server/refresh.js +10 -7
  218. package/dist/server/refresh.js.map +1 -1
  219. package/dist/server/runtime.d.ts +11 -11
  220. package/dist/server/runtime.js +155 -112
  221. package/dist/server/runtime.js.map +1 -1
  222. package/dist/server/signin.js +34 -10
  223. package/dist/server/signin.js.map +1 -1
  224. package/dist/server/ssr.d.ts.map +1 -1
  225. package/dist/server/ssr.js +175 -184
  226. package/dist/server/ssr.js.map +1 -1
  227. package/dist/server/totp.js +78 -18
  228. package/dist/server/totp.js.map +1 -1
  229. package/dist/server/types.d.ts +13 -21
  230. package/dist/server/types.d.ts.map +1 -1
  231. package/dist/server/types.js.map +1 -1
  232. package/dist/server/users.js +6 -3
  233. package/dist/server/users.js.map +1 -1
  234. package/dist/server/utils.js +10 -4
  235. package/dist/server/utils.js.map +1 -1
  236. package/package.json +1 -5
  237. package/src/authorization/index.ts +1 -1
  238. package/src/client/core/types.ts +14 -14
  239. package/src/client/factors/device.ts +10 -12
  240. package/src/client/factors/passkey.ts +23 -26
  241. package/src/client/index.ts +54 -64
  242. package/src/client/runtime/invite.ts +5 -7
  243. package/src/component/index.ts +9 -3
  244. package/src/component/public/enterprise/audit.ts +6 -1
  245. package/src/component/public/enterprise/core.ts +1 -0
  246. package/src/component/public/enterprise/domains.ts +5 -1
  247. package/src/component/public/enterprise/scim.ts +1 -0
  248. package/src/component/public/enterprise/secrets.ts +1 -0
  249. package/src/component/public/enterprise/webhooks.ts +1 -0
  250. package/src/component/public/factors/devices.ts +1 -0
  251. package/src/component/public/factors/passkeys.ts +1 -0
  252. package/src/component/public/factors/totp.ts +1 -0
  253. package/src/component/public/groups/core.ts +1 -1
  254. package/src/component/public/groups/invites.ts +7 -1
  255. package/src/component/public/groups/members.ts +1 -0
  256. package/src/component/public/identity/accounts.ts +1 -0
  257. package/src/component/public/identity/codes.ts +1 -0
  258. package/src/component/public/identity/sessions.ts +1 -0
  259. package/src/component/public/identity/tokens.ts +1 -0
  260. package/src/component/public/identity/users.ts +1 -0
  261. package/src/component/public/identity/verifiers.ts +1 -0
  262. package/src/component/public/security/keys.ts +1 -0
  263. package/src/component/public/security/limits.ts +1 -0
  264. package/src/providers/password.ts +89 -110
  265. package/src/server/auth.ts +240 -182
  266. package/src/server/context.ts +90 -0
  267. package/src/server/core.ts +195 -286
  268. package/src/server/crypto.ts +31 -29
  269. package/src/server/device.ts +65 -32
  270. package/src/server/enterprise/domain.ts +158 -170
  271. package/src/server/enterprise/http.ts +46 -39
  272. package/src/server/http.ts +289 -30
  273. package/src/server/identity.ts +5 -5
  274. package/src/server/index.ts +9 -3
  275. package/src/server/limits.ts +53 -80
  276. package/src/server/mounts.ts +56 -80
  277. package/src/server/mutations/account.ts +22 -36
  278. package/src/server/mutations/code.ts +6 -6
  279. package/src/server/mutations/invalidate.ts +1 -1
  280. package/src/server/mutations/oauth.ts +14 -8
  281. package/src/server/mutations/refresh.ts +5 -4
  282. package/src/server/mutations/register.ts +87 -132
  283. package/src/server/mutations/retrieve.ts +44 -44
  284. package/src/server/mutations/signature.ts +13 -6
  285. package/src/server/mutations/signout.ts +1 -1
  286. package/src/server/mutations/store.ts +16 -31
  287. package/src/server/mutations/verifier.ts +1 -1
  288. package/src/server/mutations/verify.ts +3 -5
  289. package/src/server/oauth.ts +60 -69
  290. package/src/server/passkey.ts +567 -517
  291. package/src/server/redirects.ts +10 -6
  292. package/src/server/refresh.ts +14 -18
  293. package/src/server/runtime.ts +340 -302
  294. package/src/server/signin.ts +44 -37
  295. package/src/server/ssr.ts +390 -407
  296. package/src/server/totp.ts +85 -35
  297. package/src/server/types.ts +19 -22
  298. package/src/server/users.ts +7 -6
  299. package/src/server/utils.ts +10 -12
  300. package/dist/component/server/authError.js +0 -34
  301. package/dist/component/server/authError.js.map +0 -1
  302. package/dist/component/server/errors.d.ts +0 -1
  303. package/dist/component/server/errors.js +0 -137
  304. package/dist/component/server/errors.js.map +0 -1
  305. package/dist/server/authError.d.ts +0 -46
  306. package/dist/server/authError.d.ts.map +0 -1
  307. package/dist/server/authError.js +0 -34
  308. package/dist/server/authError.js.map +0 -1
  309. package/dist/server/errors.d.ts +0 -177
  310. package/dist/server/errors.d.ts.map +0 -1
  311. package/dist/server/errors.js +0 -212
  312. package/dist/server/errors.js.map +0 -1
  313. package/src/server/authError.ts +0 -44
  314. package/src/server/errors.ts +0 -290
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","names":["result","parseCookies"],"sources":["../../src/server/http.ts"],"sourcesContent":["import {\n GenericActionCtx,\n GenericDataModel,\n HttpRouter,\n httpActionGeneric,\n} from \"convex/server\";\nimport { ConvexError } from \"convex/values\";\nimport { parse as parseCookies } from \"cookie\";\n\nimport { isAuthError } from \"./errors\";\nimport { Fx } from \"@robelest/fx\";\n\nimport { AuthError } from \"./authError\";\nimport type { CorsConfig, HttpKeyContext } from \"./types\";\nimport { logError } from \"./utils\";\n\nexport function createHttpAction(auth: {\n key: { verify: (ctx: GenericActionCtx<any>, rawKey: string) => Promise<any> };\n}) {\n return (\n handler: (\n ctx: GenericActionCtx<GenericDataModel> & HttpKeyContext,\n request: Request,\n ) => Promise<Response | Record<string, unknown>>,\n options?: {\n scope?: { resource: string; action: string };\n cors?: CorsConfig;\n },\n ) => {\n const corsConfig = options?.cors ?? {};\n const corsHeaders: Record<string, string> = {\n \"Access-Control-Allow-Origin\": corsConfig.origin ?? \"*\",\n \"Access-Control-Allow-Methods\":\n corsConfig.methods ?? \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n \"Access-Control-Allow-Headers\":\n corsConfig.headers ?? \"Content-Type,Authorization\",\n };\n\n return httpActionGeneric(async (genericCtx, request) => {\n return Fx.run(\n Fx.from({\n ok: async () => {\n const authHeader = request.headers.get(\"Authorization\");\n if (!authHeader?.startsWith(\"Bearer \")) {\n return new Response(\n JSON.stringify({\n error: \"Missing or malformed Authorization: Bearer header.\",\n code: \"MISSING_BEARER_TOKEN\",\n }),\n {\n status: 401,\n headers: {\n ...corsHeaders,\n \"Content-Type\": \"application/json\",\n },\n },\n );\n }\n const rawKey = authHeader.slice(7);\n\n const keyResult = await Fx.run(\n Fx.from({\n ok: () => auth.key.verify(genericCtx, rawKey),\n err: (error) => error,\n }).pipe(\n Fx.fold({\n ok: (result) => ({ ok: true, value: result }) as const,\n err: (error) => ({ ok: false, error }) as const,\n }),\n ),\n );\n\n if (!keyResult.ok) {\n if (isAuthError(keyResult.error)) {\n const { code, message } = keyResult.error.data as {\n code: string;\n message: string;\n };\n return new Response(JSON.stringify({ error: message, code }), {\n status: 403,\n headers: {\n ...corsHeaders,\n \"Content-Type\": \"application/json\",\n },\n });\n }\n throw keyResult.error;\n }\n\n if (\n options?.scope &&\n !keyResult.value.scopes.can(\n options.scope.resource,\n options.scope.action,\n )\n ) {\n return new Response(\n JSON.stringify({\n error: \"This API key does not have the required permissions.\",\n code: \"SCOPE_CHECK_FAILED\",\n }),\n {\n status: 403,\n headers: {\n ...corsHeaders,\n \"Content-Type\": \"application/json\",\n },\n },\n );\n }\n\n const enrichedCtx = Object.assign(genericCtx, {\n key: {\n userId: keyResult.value.userId,\n keyId: keyResult.value.keyId,\n scopes: keyResult.value.scopes,\n },\n });\n const result = await handler(enrichedCtx, request);\n\n if (result instanceof Response) {\n const headers = new Headers(result.headers);\n for (const [k, val] of Object.entries(corsHeaders)) {\n if (!headers.has(k)) headers.set(k, val);\n }\n return new Response(result.body, {\n status: result.status,\n statusText: result.statusText,\n headers,\n });\n }\n\n return new Response(JSON.stringify(result), {\n status: 200,\n headers: {\n ...corsHeaders,\n \"Content-Type\": \"application/json\",\n },\n });\n },\n err: (error) => error,\n }).pipe(\n Fx.recover((error) => {\n logError(error);\n return Fx.succeed(\n new Response(\n JSON.stringify({\n error: \"An unexpected error occurred.\",\n code: \"INTERNAL_ERROR\",\n }),\n {\n status: 500,\n headers: {\n ...corsHeaders,\n \"Content-Type\": \"application/json\",\n },\n },\n ),\n );\n }),\n ),\n );\n });\n };\n}\n\nexport function createHttpRoute(\n wrapAction: ReturnType<typeof createHttpAction>,\n) {\n return (\n http: { route: (config: any) => void },\n routeConfig: {\n path: string;\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n handler: (\n ctx: GenericActionCtx<GenericDataModel> & HttpKeyContext,\n request: Request,\n ) => Promise<Response | Record<string, unknown>>;\n scope?: { resource: string; action: string };\n cors?: CorsConfig;\n },\n ) => {\n const corsConfig = routeConfig.cors ?? {};\n const corsHeaders: Record<string, string> = {\n \"Access-Control-Allow-Origin\": corsConfig.origin ?? \"*\",\n \"Access-Control-Allow-Methods\":\n corsConfig.methods ?? \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n \"Access-Control-Allow-Headers\":\n corsConfig.headers ?? \"Content-Type,Authorization\",\n };\n\n http.route({\n path: routeConfig.path,\n method: \"OPTIONS\",\n handler: httpActionGeneric(async () => {\n return new Response(null, { status: 204, headers: corsHeaders });\n }),\n });\n\n http.route({\n path: routeConfig.path,\n method: routeConfig.method,\n handler: wrapAction(routeConfig.handler, {\n scope: routeConfig.scope,\n cors: routeConfig.cors,\n }),\n });\n };\n}\n\nexport function convertErrorsToResponse(\n errorStatusCode: number,\n action: (ctx: GenericActionCtx<any>, request: Request) => Promise<Response>,\n) {\n return async (ctx: GenericActionCtx<any>, request: Request) => {\n return Fx.run(\n Fx.from({\n ok: () => action(ctx, request),\n err: (error) => error,\n }).pipe(\n Fx.recover((error) => {\n if (isAuthError(error)) {\n return Fx.succeed(\n new Response(\n JSON.stringify({\n code: error.data.code,\n message: error.data.message,\n }),\n {\n status: errorStatusCode,\n headers: { \"Content-Type\": \"application/json\" },\n },\n ),\n );\n } else if (error instanceof ConvexError) {\n return Fx.succeed(\n new Response(null, {\n status: errorStatusCode,\n statusText:\n typeof error.data === \"string\" ? error.data : \"Error\",\n }),\n );\n } else {\n logError(error);\n return Fx.succeed(\n new Response(null, {\n status: 500,\n statusText: \"Internal Server Error\",\n }),\n );\n }\n }),\n ),\n );\n };\n}\n\nexport function getCookies(\n request: Request,\n): Record<string, string | undefined> {\n return parseCookies(request.headers.get(\"Cookie\") ?? \"\");\n}\n\nexport type SSORuntimeRoute = {\n pathname?: string;\n enterpriseId: string;\n protocol: \"oidc\" | \"saml\" | \"scim\";\n rest: string[];\n};\n\nfunction parseEnterpriseRuntimeRoute(\n pathname: string,\n routeBase: string,\n): SSORuntimeRoute | null {\n const runtimePrefix = `${routeBase}/`;\n const runtimeParts = pathname.startsWith(runtimePrefix)\n ? pathname.slice(runtimePrefix.length).split(\"/\").filter(Boolean)\n : [];\n const [runtimeEnterpriseId, protocol, ...rest] = runtimeParts;\n if (\n runtimeEnterpriseId === undefined ||\n (protocol !== \"oidc\" && protocol !== \"saml\" && protocol !== \"scim\") ||\n rest.length === 0\n ) {\n return null;\n }\n return {\n pathname,\n enterpriseId: runtimeEnterpriseId,\n protocol,\n rest,\n };\n}\n\nexport function addOpenIdRoutes(\n http: HttpRouter,\n deps: {\n getIssuer: () => string;\n getJwks: () => string;\n },\n) {\n const cacheControl =\n \"public, max-age=15, stale-while-revalidate=15, stale-if-error=86400\";\n\n http.route({\n path: \"/.well-known/openid-configuration\",\n method: \"GET\",\n handler: httpActionGeneric(async () => {\n const issuer = deps.getIssuer();\n return new Response(\n JSON.stringify({\n issuer,\n jwks_uri: `${issuer}/.well-known/jwks.json`,\n }),\n {\n status: 200,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": cacheControl,\n },\n },\n );\n }),\n });\n\n http.route({\n path: \"/.well-known/jwks.json\",\n method: \"GET\",\n handler: httpActionGeneric(async () => {\n return new Response(deps.getJwks(), {\n status: 200,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": cacheControl,\n },\n });\n }),\n });\n}\n\nexport function addAuthRoutes(\n http: HttpRouter,\n deps: {\n handleSignIn: (\n ctx: GenericActionCtx<any>,\n request: Request,\n ) => Promise<Response>;\n handleCallback: (\n ctx: GenericActionCtx<any>,\n request: Request,\n ) => Promise<Response>;\n },\n) {\n http.route({\n pathPrefix: \"/api/auth/signin/\",\n method: \"GET\",\n handler: httpActionGeneric(deps.handleSignIn),\n });\n\n const callbackHandler = httpActionGeneric(deps.handleCallback);\n\n http.route({\n pathPrefix: \"/api/auth/callback/\",\n method: \"GET\",\n handler: callbackHandler,\n });\n\n http.route({\n pathPrefix: \"/api/auth/callback/\",\n method: \"POST\",\n handler: callbackHandler,\n });\n}\n\nexport function addSSORoutes(\n http: HttpRouter,\n deps: {\n routeBase: string;\n convertErrorsToResponse: typeof convertErrorsToResponse;\n handleSamlMetadata: (\n ctx: GenericActionCtx<any>,\n request: Request,\n route: SSORuntimeRoute,\n ) => Promise<Response>;\n handleSamlSignIn: (\n ctx: GenericActionCtx<any>,\n request: Request,\n route: SSORuntimeRoute,\n ) => Promise<Response>;\n handleOidcSignIn: (\n ctx: GenericActionCtx<any>,\n request: Request,\n route: SSORuntimeRoute,\n ) => Promise<Response>;\n handleOidcCallback: (\n ctx: GenericActionCtx<any>,\n request: Request,\n route: SSORuntimeRoute,\n ) => Promise<Response>;\n handleSamlAcs: (\n ctx: GenericActionCtx<any>,\n request: Request,\n route: SSORuntimeRoute,\n ) => Promise<Response>;\n handleSamlSlo: (\n ctx: GenericActionCtx<any>,\n request: Request,\n route: SSORuntimeRoute,\n ) => Promise<Response>;\n handleScimRequest: (\n ctx: GenericActionCtx<any>,\n request: Request,\n ) => Promise<Response>;\n scimError: (status: number, scimType: string, detail: string) => Response;\n },\n) {\n const routePrefix = `${deps.routeBase}/`;\n\n http.route({\n pathPrefix: routePrefix,\n method: \"GET\",\n handler: httpActionGeneric(\n deps.convertErrorsToResponse(400, async (ctx, request) => {\n const route = parseEnterpriseRuntimeRoute(\n new URL(request.url).pathname,\n deps.routeBase,\n );\n if (!route) {\n throw new AuthError(\n \"INVALID_PARAMETERS\",\n \"Invalid enterprise runtime path.\",\n ).toConvexError();\n }\n if (route.protocol === \"saml\" && route.rest.length === 1) {\n if (route.rest[0] === \"metadata\") {\n return await deps.handleSamlMetadata(ctx, request, route);\n }\n if (route.rest[0] === \"signin\") {\n return await deps.handleSamlSignIn(ctx, request, route);\n }\n if (route.rest[0] === \"acs\") {\n return await deps.handleSamlAcs(ctx, request, route);\n }\n if (route.rest[0] === \"slo\") {\n return await deps.handleSamlSlo(ctx, request, route);\n }\n }\n if (route.protocol === \"oidc\" && route.rest.length === 1) {\n if (route.rest[0] === \"signin\") {\n return await deps.handleOidcSignIn(ctx, request, route);\n }\n if (route.rest[0] === \"callback\") {\n return await deps.handleOidcCallback(ctx, request, route);\n }\n }\n if (route.protocol === \"scim\" && route.rest[0] === \"v2\") {\n return await deps.handleScimRequest(ctx, request);\n }\n throw new AuthError(\n \"INVALID_PARAMETERS\",\n \"Invalid enterprise runtime path.\",\n ).toConvexError();\n }),\n ),\n });\n\n http.route({\n pathPrefix: routePrefix,\n method: \"POST\",\n handler: httpActionGeneric(\n deps.convertErrorsToResponse(400, async (ctx, request) => {\n const route = parseEnterpriseRuntimeRoute(\n new URL(request.url).pathname,\n deps.routeBase,\n );\n if (route?.protocol === \"saml\" && route.rest.length === 1) {\n if (route.rest[0] === \"acs\") {\n return await deps.handleSamlAcs(ctx, request, route);\n }\n if (route.rest[0] === \"slo\") {\n return await deps.handleSamlSlo(ctx, request, route);\n }\n }\n if (route?.protocol === \"scim\" && route.rest[0] === \"v2\") {\n return await deps.handleScimRequest(ctx, request);\n }\n throw new AuthError(\n \"INVALID_PARAMETERS\",\n \"Invalid enterprise runtime path.\",\n ).toConvexError();\n }),\n ),\n });\n\n http.route({\n pathPrefix: routePrefix,\n method: \"PUT\",\n handler: httpActionGeneric(\n deps.convertErrorsToResponse(400, async (ctx, request) => {\n const route = parseEnterpriseRuntimeRoute(\n new URL(request.url).pathname,\n deps.routeBase,\n );\n if (route?.protocol === \"scim\" && route.rest[0] === \"v2\") {\n return await deps.handleScimRequest(ctx, request);\n }\n throw new AuthError(\n \"INVALID_PARAMETERS\",\n \"Invalid enterprise runtime path.\",\n ).toConvexError();\n }),\n ),\n });\n\n for (const method of [\"PATCH\", \"DELETE\"] as const) {\n http.route({\n pathPrefix: routePrefix,\n method,\n handler: httpActionGeneric(async (ctx, request) => {\n const route = parseEnterpriseRuntimeRoute(\n new URL(request.url).pathname,\n deps.routeBase,\n );\n if (!route || route.protocol !== \"scim\" || route.rest[0] !== \"v2\") {\n return deps.scimError(404, \"notFound\", \"SCIM resource not found.\");\n }\n return await deps.handleScimRequest(ctx, request);\n }),\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"http.js","names":["result","parseCookies"],"sources":["../../src/server/http.ts"],"sourcesContent":["import { Fx } from \"@robelest/fx\";\nimport { Cv } from \"@robelest/fx/convex\";\nimport {\n GenericActionCtx,\n GenericDataModel,\n HttpRouter,\n httpActionGeneric,\n} from \"convex/server\";\nimport { ConvexError } from \"convex/values\";\nimport { parse as parseCookies } from \"cookie\";\n\nimport type {\n AuthContext,\n OptionalAuthContext,\n UserDoc,\n} from \"./auth\";\nimport {\n createUnauthenticatedAuthContext,\n getAuthContextForUser,\n getSessionUserId,\n} from \"./context\";\nimport type { CorsConfig, HttpKeyContext } from \"./types\";\nimport { logError } from \"./utils\";\n\ntype HttpContextAuthLike = {\n user: {\n get: (ctx: any, userId: string) => Promise<UserDoc>;\n getActiveGroup: (\n ctx: any,\n args: { userId: string },\n ) => Promise<string | null>;\n };\n member: {\n inspect: (\n ctx: any,\n args: { userId: string; groupId: string },\n ) => Promise<{\n membership: unknown;\n roleIds: string[];\n grants: string[];\n }>;\n };\n key: {\n verify: (ctx: GenericActionCtx<any>, rawKey: string) => Promise<{\n userId: string;\n keyId: string;\n scopes: HttpKeyContext[\"key\"][\"scopes\"];\n }>;\n };\n};\n\n/**\n * Auth context returned by `auth.http.context(ctx, request)`.\n *\n * This resolves raw HTTP authentication in two steps:\n * 1. session auth from `ctx.auth.getUserIdentity()`\n * 2. API key auth from `Authorization: Bearer sk_*`\n *\n * The `source` field tells you which authentication path succeeded.\n * When `source === \"key\"`, the verified API key metadata is available on\n * `key`.\n *\n * @example\n * ```ts\n * const authContext = await auth.http.context(ctx, request);\n * if (authContext.source === \"key\") {\n * console.log(authContext.key.keyId);\n * }\n * ```\n */\nexport type HttpAuthContext =\n | (AuthContext & {\n /** The request authenticated through a browser or session token. */\n source: \"session\";\n /** No API key was used for this request. */\n key: null;\n })\n | (AuthContext & {\n /** The request authenticated through an API key. */\n source: \"key\";\n /** Verified API key metadata for the request. */\n key: HttpKeyContext[\"key\"];\n });\n\n/**\n * Nullable HTTP auth context returned by\n * `auth.http.context(ctx, request, { optional: true })`.\n *\n * This preserves a stable auth-shaped object for raw `httpAction` handlers\n * that allow anonymous callers.\n */\nexport type OptionalHttpAuthContext =\n | (OptionalAuthContext & {\n /** No authentication source was resolved. */\n source: null;\n /** No API key metadata is available. */\n key: null;\n })\n | HttpAuthContext;\n\n/**\n * Configuration for {@link createAuth().http.context}.\n *\n * This mirrors {@link AuthContextConfig} for raw HTTP handlers and adds support\n * for enriching mixed session/API-key auth results.\n *\n * @typeParam TResolve - Extra fields returned from `resolve()` and merged into\n * the resolved HTTP auth context.\n *\n * @example\n * ```ts\n * const authContext = await auth.http.context(ctx, request, {\n * resolve: async (_ctx, user, authState) => ({\n * email: user.email,\n * isMachineRequest: authState.source === \"key\",\n * }),\n * });\n * ```\n */\nexport type HttpAuthContextConfig<\n TResolve extends Record<string, unknown> = Record<string, never>,\n> = {\n /**\n * Allow unauthenticated callers and return a null-shaped auth object instead\n * of throwing `NOT_SIGNED_IN`.\n */\n optional?: boolean;\n /**\n * Attach additional derived fields to the resolved HTTP auth context.\n *\n * This callback runs only when authentication succeeds.\n */\n resolve?: (\n ctx: GenericActionCtx<any>,\n user: UserDoc,\n auth: HttpAuthContext,\n ) => Promise<TResolve> | TResolve;\n /**\n * Override or wrap HTTP auth resolution.\n *\n * Return `undefined` to use the built-in session-or-key resolver, `null` for\n * an explicit unauthenticated state, or a fully resolved\n * {@link HttpAuthContext}.\n */\n authResolve?: (\n ctx: GenericActionCtx<any>,\n fallback: () => Promise<HttpAuthContext | null>,\n ) =>\n | Promise<HttpAuthContext | null | undefined>\n | HttpAuthContext\n | null\n | undefined;\n};\n\nfunction createNotSignedInError() {\n return Cv.error({\n code: \"NOT_SIGNED_IN\",\n message: \"Authentication required.\",\n });\n}\n\nasync function getHttpKeyContext(\n auth: HttpContextAuthLike,\n ctx: GenericActionCtx<any>,\n request: Request,\n): Promise<HttpAuthContext | null> {\n const authHeader = request.headers.get(\"Authorization\");\n if (!authHeader?.startsWith(\"Bearer sk_\")) {\n return null;\n }\n\n try {\n const verified = await auth.key.verify(ctx, authHeader.slice(7));\n const authContext = await getAuthContextForUser(auth, ctx, verified.userId);\n return {\n ...authContext,\n source: \"key\",\n key: {\n userId: verified.userId,\n keyId: verified.keyId,\n scopes: verified.scopes,\n },\n };\n } catch {\n return null;\n }\n}\n\nasync function resolveHttpAuthContext(\n auth: HttpContextAuthLike,\n ctx: GenericActionCtx<any>,\n request: Request,\n): Promise<HttpAuthContext | null> {\n const sessionUserId = await getSessionUserId(ctx);\n if (sessionUserId !== null) {\n const authContext = await getAuthContextForUser(auth, ctx, sessionUserId);\n return {\n ...authContext,\n source: \"session\",\n key: null,\n };\n }\n\n return await getHttpKeyContext(auth, ctx, request);\n}\n\n/**\n * @internal\n * Create the implementation behind `auth.http.context(...)`.\n */\nexport function createHttpContext(auth: HttpContextAuthLike): {\n <TResolve extends Record<string, unknown> = Record<string, never>>(\n ctx: GenericActionCtx<any>,\n request: Request,\n config: HttpAuthContextConfig<TResolve> & { optional: true },\n ): Promise<OptionalHttpAuthContext & TResolve>;\n <TResolve extends Record<string, unknown> = Record<string, never>>(\n ctx: GenericActionCtx<any>,\n request: Request,\n config?: HttpAuthContextConfig<TResolve>,\n ): Promise<HttpAuthContext & TResolve>;\n} {\n return (async (\n ctx: GenericActionCtx<any>,\n request: Request,\n config?: HttpAuthContextConfig<any>,\n ) => {\n const fallback = () => resolveHttpAuthContext(auth, ctx, request);\n const authOverride = config?.authResolve\n ? await config.authResolve(ctx, fallback)\n : undefined;\n const resolved =\n authOverride === undefined ? await fallback() : authOverride;\n\n if (resolved === null) {\n if (config?.optional !== true) {\n throw createNotSignedInError();\n }\n return {\n ...createUnauthenticatedAuthContext(),\n source: null,\n key: null,\n };\n }\n\n const extra = config?.resolve\n ? await config.resolve(ctx, resolved.user, resolved)\n : {};\n\n return {\n ...resolved,\n ...extra,\n };\n }) as {\n <TResolve extends Record<string, unknown> = Record<string, never>>(\n ctx: GenericActionCtx<any>,\n request: Request,\n config: HttpAuthContextConfig<TResolve> & { optional: true },\n ): Promise<OptionalHttpAuthContext & TResolve>;\n <TResolve extends Record<string, unknown> = Record<string, never>>(\n ctx: GenericActionCtx<any>,\n request: Request,\n config?: HttpAuthContextConfig<TResolve>,\n ): Promise<HttpAuthContext & TResolve>;\n };\n}\n\nexport function createHttpAction(auth: {\n key: { verify: (ctx: GenericActionCtx<any>, rawKey: string) => Promise<any> };\n}) {\n return (\n handler: (\n ctx: GenericActionCtx<GenericDataModel> & HttpKeyContext,\n request: Request,\n ) => Promise<Response | Record<string, unknown>>,\n options?: {\n scope?: { resource: string; action: string };\n cors?: CorsConfig;\n },\n ) => {\n const corsConfig = options?.cors ?? {};\n const corsHeaders: Record<string, string> = {\n \"Access-Control-Allow-Origin\": corsConfig.origin ?? \"*\",\n \"Access-Control-Allow-Methods\":\n corsConfig.methods ?? \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n \"Access-Control-Allow-Headers\":\n corsConfig.headers ?? \"Content-Type,Authorization\",\n };\n\n return httpActionGeneric(async (genericCtx, request) => {\n return Fx.run(\n Fx.from({\n ok: async () => {\n const authHeader = request.headers.get(\"Authorization\");\n if (!authHeader?.startsWith(\"Bearer \")) {\n return new Response(\n JSON.stringify({\n error: \"Missing or malformed Authorization: Bearer header.\",\n code: \"MISSING_BEARER_TOKEN\",\n }),\n {\n status: 401,\n headers: {\n ...corsHeaders,\n \"Content-Type\": \"application/json\",\n },\n },\n );\n }\n const rawKey = authHeader.slice(7);\n\n const keyResult = await Fx.run(\n Fx.attempt(\n () => auth.key.verify(genericCtx, rawKey),\n (result) => ({ ok: true, value: result }) as const,\n (error) => ({ ok: false, error }) as const,\n ),\n );\n\n if (!keyResult.ok) {\n if (\n keyResult.error instanceof ConvexError &&\n typeof keyResult.error.data === \"object\" &&\n keyResult.error.data !== null &&\n \"code\" in keyResult.error.data &&\n \"message\" in keyResult.error.data\n ) {\n const { code, message } = keyResult.error.data as {\n code: string;\n message: string;\n };\n return new Response(JSON.stringify({ error: message, code }), {\n status: 403,\n headers: {\n ...corsHeaders,\n \"Content-Type\": \"application/json\",\n },\n });\n }\n throw keyResult.error;\n }\n\n if (\n options?.scope &&\n !keyResult.value.scopes.can(\n options.scope.resource,\n options.scope.action,\n )\n ) {\n return new Response(\n JSON.stringify({\n error: \"This API key does not have the required permissions.\",\n code: \"SCOPE_CHECK_FAILED\",\n }),\n {\n status: 403,\n headers: {\n ...corsHeaders,\n \"Content-Type\": \"application/json\",\n },\n },\n );\n }\n\n const enrichedCtx = Object.assign(genericCtx, {\n key: {\n userId: keyResult.value.userId,\n keyId: keyResult.value.keyId,\n scopes: keyResult.value.scopes,\n },\n });\n const result = await handler(enrichedCtx, request);\n\n if (result instanceof Response) {\n const headers = new Headers(result.headers);\n for (const [k, val] of Object.entries(corsHeaders)) {\n if (!headers.has(k)) headers.set(k, val);\n }\n return new Response(result.body, {\n status: result.status,\n statusText: result.statusText,\n headers,\n });\n }\n\n return new Response(JSON.stringify(result), {\n status: 200,\n headers: {\n ...corsHeaders,\n \"Content-Type\": \"application/json\",\n },\n });\n },\n err: (error) => error,\n }).pipe(\n Fx.recover((error) => {\n logError(error);\n return Fx.succeed(\n new Response(\n JSON.stringify({\n error: \"An unexpected error occurred.\",\n code: \"INTERNAL_ERROR\",\n }),\n {\n status: 500,\n headers: {\n ...corsHeaders,\n \"Content-Type\": \"application/json\",\n },\n },\n ),\n );\n }),\n ),\n );\n });\n };\n}\n\nexport function createHttpRoute(\n wrapAction: ReturnType<typeof createHttpAction>,\n) {\n return (\n http: { route: (config: any) => void },\n routeConfig: {\n path: string;\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n handler: (\n ctx: GenericActionCtx<GenericDataModel> & HttpKeyContext,\n request: Request,\n ) => Promise<Response | Record<string, unknown>>;\n scope?: { resource: string; action: string };\n cors?: CorsConfig;\n },\n ) => {\n const corsConfig = routeConfig.cors ?? {};\n const corsHeaders: Record<string, string> = {\n \"Access-Control-Allow-Origin\": corsConfig.origin ?? \"*\",\n \"Access-Control-Allow-Methods\":\n corsConfig.methods ?? \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n \"Access-Control-Allow-Headers\":\n corsConfig.headers ?? \"Content-Type,Authorization\",\n };\n\n http.route({\n path: routeConfig.path,\n method: \"OPTIONS\",\n handler: httpActionGeneric(async () => {\n return new Response(null, { status: 204, headers: corsHeaders });\n }),\n });\n\n http.route({\n path: routeConfig.path,\n method: routeConfig.method,\n handler: wrapAction(routeConfig.handler, {\n scope: routeConfig.scope,\n cors: routeConfig.cors,\n }),\n });\n };\n}\n\nexport function convertErrorsToResponse(\n errorStatusCode: number,\n action: (ctx: GenericActionCtx<any>, request: Request) => Promise<Response>,\n) {\n return async (ctx: GenericActionCtx<any>, request: Request) => {\n return Fx.run(\n Fx.from({\n ok: () => action(ctx, request),\n err: (error) => error,\n }).pipe(\n Fx.recover((error) => {\n if (\n error instanceof ConvexError &&\n typeof error.data === \"object\" &&\n error.data !== null &&\n \"code\" in error.data &&\n \"message\" in error.data\n ) {\n return Fx.succeed(\n new Response(\n JSON.stringify({\n code: error.data.code,\n message: error.data.message,\n }),\n {\n status: errorStatusCode,\n headers: { \"Content-Type\": \"application/json\" },\n },\n ),\n );\n } else if (error instanceof ConvexError) {\n return Fx.succeed(\n new Response(null, {\n status: errorStatusCode,\n statusText:\n typeof error.data === \"string\" ? error.data : \"Error\",\n }),\n );\n } else {\n logError(error);\n return Fx.succeed(\n new Response(null, {\n status: 500,\n statusText: \"Internal Server Error\",\n }),\n );\n }\n }),\n ),\n );\n };\n}\n\nexport function getCookies(\n request: Request,\n): Record<string, string | undefined> {\n return parseCookies(request.headers.get(\"Cookie\") ?? \"\");\n}\n\nexport type SSORuntimeRoute = {\n pathname?: string;\n enterpriseId: string;\n protocol: \"oidc\" | \"saml\" | \"scim\";\n rest: string[];\n};\n\nfunction parseEnterpriseRuntimeRoute(\n pathname: string,\n routeBase: string,\n): SSORuntimeRoute | null {\n const runtimePrefix = `${routeBase}/`;\n const runtimeParts = pathname.startsWith(runtimePrefix)\n ? pathname.slice(runtimePrefix.length).split(\"/\").filter(Boolean)\n : [];\n const [runtimeEnterpriseId, protocol, ...rest] = runtimeParts;\n if (\n runtimeEnterpriseId === undefined ||\n (protocol !== \"oidc\" && protocol !== \"saml\" && protocol !== \"scim\") ||\n rest.length === 0\n ) {\n return null;\n }\n return {\n pathname,\n enterpriseId: runtimeEnterpriseId,\n protocol,\n rest,\n };\n}\n\nexport function addOpenIdRoutes(\n http: HttpRouter,\n deps: {\n getIssuer: () => string;\n getJwks: () => string;\n },\n) {\n const cacheControl =\n \"public, max-age=15, stale-while-revalidate=15, stale-if-error=86400\";\n\n http.route({\n path: \"/.well-known/openid-configuration\",\n method: \"GET\",\n handler: httpActionGeneric(async () => {\n const issuer = deps.getIssuer();\n return new Response(\n JSON.stringify({\n issuer,\n jwks_uri: `${issuer}/.well-known/jwks.json`,\n }),\n {\n status: 200,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": cacheControl,\n },\n },\n );\n }),\n });\n\n http.route({\n path: \"/.well-known/jwks.json\",\n method: \"GET\",\n handler: httpActionGeneric(async () => {\n return new Response(deps.getJwks(), {\n status: 200,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": cacheControl,\n },\n });\n }),\n });\n}\n\nexport function addAuthRoutes(\n http: HttpRouter,\n deps: {\n handleSignIn: (\n ctx: GenericActionCtx<any>,\n request: Request,\n ) => Promise<Response>;\n handleCallback: (\n ctx: GenericActionCtx<any>,\n request: Request,\n ) => Promise<Response>;\n },\n) {\n http.route({\n pathPrefix: \"/api/auth/signin/\",\n method: \"GET\",\n handler: httpActionGeneric(deps.handleSignIn),\n });\n\n const callbackHandler = httpActionGeneric(deps.handleCallback);\n\n http.route({\n pathPrefix: \"/api/auth/callback/\",\n method: \"GET\",\n handler: callbackHandler,\n });\n\n http.route({\n pathPrefix: \"/api/auth/callback/\",\n method: \"POST\",\n handler: callbackHandler,\n });\n}\n\nexport function addSSORoutes(\n http: HttpRouter,\n deps: {\n routeBase: string;\n convertErrorsToResponse: typeof convertErrorsToResponse;\n handleSamlMetadata: (\n ctx: GenericActionCtx<any>,\n request: Request,\n route: SSORuntimeRoute,\n ) => Promise<Response>;\n handleSamlSignIn: (\n ctx: GenericActionCtx<any>,\n request: Request,\n route: SSORuntimeRoute,\n ) => Promise<Response>;\n handleOidcSignIn: (\n ctx: GenericActionCtx<any>,\n request: Request,\n route: SSORuntimeRoute,\n ) => Promise<Response>;\n handleOidcCallback: (\n ctx: GenericActionCtx<any>,\n request: Request,\n route: SSORuntimeRoute,\n ) => Promise<Response>;\n handleSamlAcs: (\n ctx: GenericActionCtx<any>,\n request: Request,\n route: SSORuntimeRoute,\n ) => Promise<Response>;\n handleSamlSlo: (\n ctx: GenericActionCtx<any>,\n request: Request,\n route: SSORuntimeRoute,\n ) => Promise<Response>;\n handleScimRequest: (\n ctx: GenericActionCtx<any>,\n request: Request,\n ) => Promise<Response>;\n scimError: (status: number, scimType: string, detail: string) => Response;\n },\n) {\n const routePrefix = `${deps.routeBase}/`;\n\n http.route({\n pathPrefix: routePrefix,\n method: \"GET\",\n handler: httpActionGeneric(\n deps.convertErrorsToResponse(400, async (ctx, request) => {\n const route = parseEnterpriseRuntimeRoute(\n new URL(request.url).pathname,\n deps.routeBase,\n );\n if (!route) {\n throw Cv.error({\n code: \"INVALID_PARAMETERS\",\n message: \"Invalid enterprise runtime path.\",\n });\n }\n if (route.protocol === \"saml\" && route.rest.length === 1) {\n if (route.rest[0] === \"metadata\") {\n return await deps.handleSamlMetadata(ctx, request, route);\n }\n if (route.rest[0] === \"signin\") {\n return await deps.handleSamlSignIn(ctx, request, route);\n }\n if (route.rest[0] === \"acs\") {\n return await deps.handleSamlAcs(ctx, request, route);\n }\n if (route.rest[0] === \"slo\") {\n return await deps.handleSamlSlo(ctx, request, route);\n }\n }\n if (route.protocol === \"oidc\" && route.rest.length === 1) {\n if (route.rest[0] === \"signin\") {\n return await deps.handleOidcSignIn(ctx, request, route);\n }\n if (route.rest[0] === \"callback\") {\n return await deps.handleOidcCallback(ctx, request, route);\n }\n }\n if (route.protocol === \"scim\" && route.rest[0] === \"v2\") {\n return await deps.handleScimRequest(ctx, request);\n }\n throw Cv.error({\n code: \"INVALID_PARAMETERS\",\n message: \"Invalid enterprise runtime path.\",\n });\n }),\n ),\n });\n\n http.route({\n pathPrefix: routePrefix,\n method: \"POST\",\n handler: httpActionGeneric(\n deps.convertErrorsToResponse(400, async (ctx, request) => {\n const route = parseEnterpriseRuntimeRoute(\n new URL(request.url).pathname,\n deps.routeBase,\n );\n if (route?.protocol === \"saml\" && route.rest.length === 1) {\n if (route.rest[0] === \"acs\") {\n return await deps.handleSamlAcs(ctx, request, route);\n }\n if (route.rest[0] === \"slo\") {\n return await deps.handleSamlSlo(ctx, request, route);\n }\n }\n if (route?.protocol === \"scim\" && route.rest[0] === \"v2\") {\n return await deps.handleScimRequest(ctx, request);\n }\n throw Cv.error({\n code: \"INVALID_PARAMETERS\",\n message: \"Invalid enterprise runtime path.\",\n });\n }),\n ),\n });\n\n http.route({\n pathPrefix: routePrefix,\n method: \"PUT\",\n handler: httpActionGeneric(\n deps.convertErrorsToResponse(400, async (ctx, request) => {\n const route = parseEnterpriseRuntimeRoute(\n new URL(request.url).pathname,\n deps.routeBase,\n );\n if (route?.protocol === \"scim\" && route.rest[0] === \"v2\") {\n return await deps.handleScimRequest(ctx, request);\n }\n throw Cv.error({\n code: \"INVALID_PARAMETERS\",\n message: \"Invalid enterprise runtime path.\",\n });\n }),\n ),\n });\n\n for (const method of [\"PATCH\", \"DELETE\"] as const) {\n http.route({\n pathPrefix: routePrefix,\n method,\n handler: httpActionGeneric(async (ctx, request) => {\n const route = parseEnterpriseRuntimeRoute(\n new URL(request.url).pathname,\n deps.routeBase,\n );\n if (!route || route.protocol !== \"scim\" || route.rest[0] !== \"v2\") {\n return deps.scimError(404, \"notFound\", \"SCIM resource not found.\");\n }\n return await deps.handleScimRequest(ctx, request);\n }),\n });\n }\n}\n"],"mappings":"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"}
@@ -1,10 +1,13 @@
1
- import { AuthError } from "./authError.js";
1
+ import { Cv } from "@robelest/fx/convex";
2
2
 
3
3
  //#region src/server/identity.ts
4
4
  /** @internal */
5
5
  function userIdFromIdentitySubject(subject) {
6
6
  const [userId, ...rest] = subject.split("|");
7
- if (typeof userId !== "string" || userId.length === 0 || rest.length === 0 || rest.some((segment) => segment.length === 0)) throw new AuthError("INTERNAL_ERROR", "Authenticated identity subject is malformed.");
7
+ if (typeof userId !== "string" || userId.length === 0 || rest.length === 0 || rest.some((segment) => segment.length === 0)) throw Cv.error({
8
+ code: "INTERNAL_ERROR",
9
+ message: "Authenticated identity subject is malformed."
10
+ });
8
11
  return userId;
9
12
  }
10
13
 
@@ -1 +1 @@
1
- {"version":3,"file":"identity.js","names":[],"sources":["../../src/server/identity.ts"],"sourcesContent":["import { AuthError } from \"./authError\";\n\n/** @internal */\nexport function userIdFromIdentitySubject(subject: string): string {\n const [userId, ...rest] = subject.split(\"|\");\n if (\n typeof userId !== \"string\" ||\n userId.length === 0 ||\n rest.length === 0 ||\n rest.some((segment) => segment.length === 0)\n ) {\n throw new AuthError(\n \"INTERNAL_ERROR\",\n \"Authenticated identity subject is malformed.\",\n );\n }\n return userId;\n}\n"],"mappings":";;;;AAGA,SAAgB,0BAA0B,SAAyB;CACjE,MAAM,CAAC,QAAQ,GAAG,QAAQ,QAAQ,MAAM,IAAI;AAC5C,KACE,OAAO,WAAW,YAClB,OAAO,WAAW,KAClB,KAAK,WAAW,KAChB,KAAK,MAAM,YAAY,QAAQ,WAAW,EAAE,CAE5C,OAAM,IAAI,UACR,kBACA,+CACD;AAEH,QAAO"}
1
+ {"version":3,"file":"identity.js","names":[],"sources":["../../src/server/identity.ts"],"sourcesContent":["import { Cv } from \"@robelest/fx/convex\";\n\n/** @internal */\nexport function userIdFromIdentitySubject(subject: string): string {\n const [userId, ...rest] = subject.split(\"|\");\n if (\n typeof userId !== \"string\" ||\n userId.length === 0 ||\n rest.length === 0 ||\n rest.some((segment) => segment.length === 0)\n ) {\n throw Cv.error({\n code: \"INTERNAL_ERROR\",\n message: \"Authenticated identity subject is malformed.\",\n });\n }\n return userId;\n}\n"],"mappings":";;;;AAGA,SAAgB,0BAA0B,SAAyB;CACjE,MAAM,CAAC,QAAQ,GAAG,QAAQ,QAAQ,MAAM,IAAI;AAC5C,KACE,OAAO,WAAW,YAClB,OAAO,WAAW,KAClB,KAAK,WAAW,KAChB,KAAK,MAAM,YAAY,QAAQ,WAAW,EAAE,CAE5C,OAAM,GAAG,MAAM;EACb,MAAM;EACN,SAAS;EACV,CAAC;AAEJ,QAAO"}
@@ -1,4 +1,5 @@
1
- import { AuthApi, AuthApiBase, AuthConfig, AuthCtx, AuthCtxConfig, AuthResolvedContext, ConvexAuthResult, InferAuth, InferClientApi, UserDoc, createAuth } from "./auth.js";
1
+ import { AuthApi, AuthApiBase, AuthConfig, AuthContext, AuthContextConfig, ConvexAuthResult, InferAuth, InferClientApi, OptionalAuthContext, UserDoc, createAuth } from "./auth.js";
2
+ import { HttpAuthContext, HttpAuthContextConfig, OptionalHttpAuthContext } from "./http.js";
2
3
  import { EnterpriseAdminAuthorizationInput, EnterpriseAdminPermission, EnterpriseAuthorizer, EnterpriseMountOptions, enterprise, scim, sso } from "./mounts.js";
3
4
  import { AuthCookie, AuthCookieConfig, AuthCookies, RefreshResult, ServerOptions, authCookieNames, parseAuthCookies, serializeAuthCookies, server, shouldProxyAuthAction, structuredAuthCookies } from "./ssr.js";
4
- export { type AuthApi, type AuthApiBase, type AuthConfig, type AuthCookie, type AuthCookieConfig, type AuthCookies, AuthCtx, type AuthCtxConfig, type AuthResolvedContext, type ConvexAuthResult, type EnterpriseAdminAuthorizationInput, type EnterpriseAdminPermission, type EnterpriseAuthorizer, type EnterpriseMountOptions, type InferAuth, type InferClientApi, type RefreshResult, type ServerOptions, type UserDoc, authCookieNames, createAuth, enterprise, parseAuthCookies, scim, serializeAuthCookies, server, shouldProxyAuthAction, sso, structuredAuthCookies };
5
+ export { type AuthApi, type AuthApiBase, type AuthConfig, type AuthContext, type AuthContextConfig, type AuthCookie, type AuthCookieConfig, type AuthCookies, type ConvexAuthResult, type EnterpriseAdminAuthorizationInput, type EnterpriseAdminPermission, type EnterpriseAuthorizer, type EnterpriseMountOptions, type HttpAuthContext, type HttpAuthContextConfig, type InferAuth, type InferClientApi, type OptionalAuthContext, type OptionalHttpAuthContext, type RefreshResult, type ServerOptions, type UserDoc, authCookieNames, createAuth, enterprise, parseAuthCookies, scim, serializeAuthCookies, server, shouldProxyAuthAction, sso, structuredAuthCookies };
@@ -1,5 +1,5 @@
1
- import { AuthCtx, createAuth } from "./auth.js";
1
+ import { createAuth } from "./auth.js";
2
2
  import { enterprise, scim, sso } from "./mounts.js";
3
3
  import { authCookieNames, parseAuthCookies, serializeAuthCookies, server, shouldProxyAuthAction, structuredAuthCookies } from "./ssr.js";
4
4
 
5
- export { AuthCtx, authCookieNames, createAuth, enterprise, parseAuthCookies, scim, serializeAuthCookies, server, shouldProxyAuthAction, sso, structuredAuthCookies };
5
+ export { authCookieNames, createAuth, enterprise, parseAuthCookies, scim, serializeAuthCookies, server, shouldProxyAuthAction, sso, structuredAuthCookies };
@@ -1,5 +1,3 @@
1
- import { AuthError } from "./authError.js";
2
- import { errorMessage } from "./utils.js";
3
1
  import { authDb } from "./db.js";
4
2
  import { Fx } from "@robelest/fx";
5
3
 
@@ -16,45 +14,38 @@ const isSignInRateLimited = (ctx, identifier, config) => getRateLimitState(ctx,
16
14
  * If a record exists, decrement; otherwise create.
17
15
  */
18
16
  /** @internal */
19
- const recordFailedSignIn = (ctx, identifier, config) => getRateLimitState(ctx, identifier, config).pipe(Fx.chain((state) => state !== null ? Fx.from({
20
- ok: () => authDb(ctx, config).rateLimits.patch(state.limit._id, {
17
+ const recordFailedSignIn = (ctx, identifier, config) => Fx.gen(function* () {
18
+ const state = yield* getRateLimitState(ctx, identifier, config);
19
+ if (state !== null) yield* Fx.promise(() => authDb(ctx, config).rateLimits.patch(state.limit._id, {
21
20
  attemptsLeft: state.attemptsLeft - 1,
22
21
  lastAttemptTime: Date.now()
23
- }),
24
- err: (e) => new AuthError("INTERNAL_ERROR", `Failed to patch rate limit: ${errorMessage(e)}`)
25
- }) : Fx.from({
26
- ok: () => authDb(ctx, config).rateLimits.create({
22
+ }));
23
+ else yield* Fx.promise(() => authDb(ctx, config).rateLimits.create({
27
24
  identifier,
28
25
  attemptsLeft: (config.signIn?.maxFailedAttemptsPerHour ?? DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR) - 1,
29
26
  lastAttemptTime: Date.now()
30
- }),
31
- err: (e) => new AuthError("INTERNAL_ERROR", `Failed to create rate limit: ${errorMessage(e)}`)
32
- })), Fx.map(() => void 0));
27
+ }));
28
+ });
33
29
  /**
34
30
  * Reset the rate limit for the given identifier (e.g. after successful sign-in).
35
31
  */
36
32
  /** @internal */
37
- const resetSignInRateLimit = (ctx, identifier, config) => getRateLimitState(ctx, identifier, config).pipe(Fx.chain((state) => state !== null ? Fx.from({
38
- ok: () => authDb(ctx, config).rateLimits.delete(state.limit._id),
39
- err: (e) => new AuthError("INTERNAL_ERROR", `Failed to delete rate limit: ${errorMessage(e)}`)
40
- }) : Fx.unit));
41
- const getRateLimitState = (ctx, identifier, config) => {
33
+ const resetSignInRateLimit = (ctx, identifier, config) => Fx.gen(function* () {
34
+ const state = yield* getRateLimitState(ctx, identifier, config);
35
+ if (state !== null) yield* Fx.promise(() => authDb(ctx, config).rateLimits.delete(state.limit._id));
36
+ });
37
+ const getRateLimitState = (ctx, identifier, config) => Fx.gen(function* () {
42
38
  const now = Date.now();
43
39
  const maxAttemptsPerHour = config.signIn?.maxFailedAttemptsPerHour ?? DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR;
44
- return Fx.from({
45
- ok: () => authDb(ctx, config).rateLimits.get(identifier),
46
- err: (e) => new AuthError("INTERNAL_ERROR", `Failed to get rate limit: ${errorMessage(e)}`)
47
- }).pipe(Fx.map((raw) => {
48
- const limit = raw;
49
- if (limit === null) return null;
50
- const elapsed = now - limit.lastAttemptTime;
51
- const maxAttemptsPerMs = maxAttemptsPerHour / (3600 * 1e3);
52
- return {
53
- limit,
54
- attemptsLeft: Math.min(maxAttemptsPerHour, limit.attemptsLeft + elapsed * maxAttemptsPerMs)
55
- };
56
- }));
57
- };
40
+ const limit = yield* Fx.promise(() => authDb(ctx, config).rateLimits.get(identifier));
41
+ if (limit === null) return null;
42
+ const elapsed = now - limit.lastAttemptTime;
43
+ const maxAttemptsPerMs = maxAttemptsPerHour / (3600 * 1e3);
44
+ return {
45
+ limit,
46
+ attemptsLeft: Math.min(maxAttemptsPerHour, limit.attemptsLeft + elapsed * maxAttemptsPerMs)
47
+ };
48
+ });
58
49
 
59
50
  //#endregion
60
51
  export { isSignInRateLimited, recordFailedSignIn, resetSignInRateLimit };
@@ -1 +1 @@
1
- {"version":3,"file":"limits.js","names":[],"sources":["../../src/server/limits.ts"],"sourcesContent":["import { Fx } from \"@robelest/fx\";\n\nimport { authDb } from \"./db\";\nimport { AuthError } from \"./authError\";\nimport { Doc, MutationCtx } from \"./types\";\nimport { ConvexAuthConfig } from \"./types\";\nimport { errorMessage } from \"./utils\";\n\nconst DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR = 10;\n\n/**\n * Check whether the given identifier is currently rate-limited.\n */\n/** @internal */\nexport const isSignInRateLimited = (\n ctx: MutationCtx,\n identifier: string,\n config: ConvexAuthConfig,\n): Fx<boolean, AuthError> =>\n getRateLimitState(ctx, identifier, config).pipe(\n Fx.map((state) => state !== null && state.attemptsLeft < 1),\n );\n\n/**\n * Record a failed sign-in attempt for the given identifier.\n *\n * If a record exists, decrement; otherwise create.\n */\n/** @internal */\nexport const recordFailedSignIn = (\n ctx: MutationCtx,\n identifier: string,\n config: ConvexAuthConfig,\n): Fx<void, AuthError> =>\n getRateLimitState(ctx, identifier, config).pipe(\n Fx.chain((state) =>\n state !== null\n ? Fx.from({\n ok: () =>\n authDb(ctx, config).rateLimits.patch(state.limit._id, {\n attemptsLeft: state.attemptsLeft - 1,\n lastAttemptTime: Date.now(),\n }),\n err: (e) =>\n new AuthError(\n \"INTERNAL_ERROR\",\n `Failed to patch rate limit: ${errorMessage(e)}`,\n ),\n })\n : Fx.from({\n ok: () =>\n authDb(ctx, config).rateLimits.create({\n identifier,\n attemptsLeft:\n (config.signIn?.maxFailedAttemptsPerHour ??\n DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR) - 1,\n lastAttemptTime: Date.now(),\n }),\n err: (e) =>\n new AuthError(\n \"INTERNAL_ERROR\",\n `Failed to create rate limit: ${errorMessage(e)}`,\n ),\n }),\n ),\n Fx.map(() => undefined),\n );\n\n/**\n * Reset the rate limit for the given identifier (e.g. after successful sign-in).\n */\n/** @internal */\nexport const resetSignInRateLimit = (\n ctx: MutationCtx,\n identifier: string,\n config: ConvexAuthConfig,\n): Fx<void, AuthError> =>\n getRateLimitState(ctx, identifier, config).pipe(\n Fx.chain((state) =>\n state !== null\n ? Fx.from({\n ok: () => authDb(ctx, config).rateLimits.delete(state.limit._id),\n err: (e) =>\n new AuthError(\n \"INTERNAL_ERROR\",\n `Failed to delete rate limit: ${errorMessage(e)}`,\n ),\n })\n : Fx.unit,\n ),\n );\n\n// ---------------------------------------------------------------------------\n// Internal\n// ---------------------------------------------------------------------------\n\ntype RateLimitState = {\n limit: Doc<\"RateLimit\"> & { attemptsLeft: number; lastAttemptTime: number };\n attemptsLeft: number;\n} | null;\n\nconst getRateLimitState = (\n ctx: MutationCtx,\n identifier: string,\n config: ConvexAuthConfig,\n): Fx<RateLimitState, AuthError> => {\n const now = Date.now();\n const maxAttemptsPerHour =\n config.signIn?.maxFailedAttemptsPerHour ??\n DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR;\n\n return Fx.from({\n ok: () => authDb(ctx, config).rateLimits.get(identifier),\n err: (e) =>\n new AuthError(\n \"INTERNAL_ERROR\",\n `Failed to get rate limit: ${errorMessage(e)}`,\n ),\n }).pipe(\n Fx.map((raw) => {\n const limit = raw as\n | (Doc<\"RateLimit\"> & { attemptsLeft: number; lastAttemptTime: number })\n | null;\n if (limit === null) return null;\n const elapsed = now - limit.lastAttemptTime;\n const maxAttemptsPerMs = maxAttemptsPerHour / (60 * 60 * 1000);\n const attemptsLeft = Math.min(\n maxAttemptsPerHour,\n limit.attemptsLeft + elapsed * maxAttemptsPerMs,\n );\n return { limit, attemptsLeft };\n }),\n );\n};\n"],"mappings":";;;;;;AAQA,MAAM,wCAAwC;;;;;AAM9C,MAAa,uBACX,KACA,YACA,WAEA,kBAAkB,KAAK,YAAY,OAAO,CAAC,KACzC,GAAG,KAAK,UAAU,UAAU,QAAQ,MAAM,eAAe,EAAE,CAC5D;;;;;;;AAQH,MAAa,sBACX,KACA,YACA,WAEA,kBAAkB,KAAK,YAAY,OAAO,CAAC,KACzC,GAAG,OAAO,UACR,UAAU,OACN,GAAG,KAAK;CACN,UACE,OAAO,KAAK,OAAO,CAAC,WAAW,MAAM,MAAM,MAAM,KAAK;EACpD,cAAc,MAAM,eAAe;EACnC,iBAAiB,KAAK,KAAK;EAC5B,CAAC;CACJ,MAAM,MACJ,IAAI,UACF,kBACA,+BAA+B,aAAa,EAAE,GAC/C;CACJ,CAAC,GACF,GAAG,KAAK;CACN,UACE,OAAO,KAAK,OAAO,CAAC,WAAW,OAAO;EACpC;EACA,eACG,OAAO,QAAQ,4BACd,yCAAyC;EAC7C,iBAAiB,KAAK,KAAK;EAC5B,CAAC;CACJ,MAAM,MACJ,IAAI,UACF,kBACA,gCAAgC,aAAa,EAAE,GAChD;CACJ,CAAC,CACP,EACD,GAAG,UAAU,OAAU,CACxB;;;;;AAMH,MAAa,wBACX,KACA,YACA,WAEA,kBAAkB,KAAK,YAAY,OAAO,CAAC,KACzC,GAAG,OAAO,UACR,UAAU,OACN,GAAG,KAAK;CACN,UAAU,OAAO,KAAK,OAAO,CAAC,WAAW,OAAO,MAAM,MAAM,IAAI;CAChE,MAAM,MACJ,IAAI,UACF,kBACA,gCAAgC,aAAa,EAAE,GAChD;CACJ,CAAC,GACF,GAAG,KACR,CACF;AAWH,MAAM,qBACJ,KACA,YACA,WACkC;CAClC,MAAM,MAAM,KAAK,KAAK;CACtB,MAAM,qBACJ,OAAO,QAAQ,4BACf;AAEF,QAAO,GAAG,KAAK;EACb,UAAU,OAAO,KAAK,OAAO,CAAC,WAAW,IAAI,WAAW;EACxD,MAAM,MACJ,IAAI,UACF,kBACA,6BAA6B,aAAa,EAAE,GAC7C;EACJ,CAAC,CAAC,KACD,GAAG,KAAK,QAAQ;EACd,MAAM,QAAQ;AAGd,MAAI,UAAU,KAAM,QAAO;EAC3B,MAAM,UAAU,MAAM,MAAM;EAC5B,MAAM,mBAAmB,sBAAsB,OAAU;AAKzD,SAAO;GAAE;GAAO,cAJK,KAAK,IACxB,oBACA,MAAM,eAAe,UAAU,iBAChC;GAC6B;GAC9B,CACH"}
1
+ {"version":3,"file":"limits.js","names":[],"sources":["../../src/server/limits.ts"],"sourcesContent":["import { Fx } from \"@robelest/fx\";\nimport { ConvexError } from \"convex/values\";\n\nimport { authDb } from \"./db\";\nimport { Doc, MutationCtx } from \"./types\";\nimport { ConvexAuthConfig } from \"./types\";\n\nconst DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR = 10;\n\n/**\n * Check whether the given identifier is currently rate-limited.\n */\n/** @internal */\nexport const isSignInRateLimited = (\n ctx: MutationCtx,\n identifier: string,\n config: ConvexAuthConfig,\n): Fx<boolean, ConvexError<any>> =>\n getRateLimitState(ctx, identifier, config).pipe(\n Fx.map((state) => state !== null && state.attemptsLeft < 1),\n );\n\n/**\n * Record a failed sign-in attempt for the given identifier.\n *\n * If a record exists, decrement; otherwise create.\n */\n/** @internal */\nexport const recordFailedSignIn = (\n ctx: MutationCtx,\n identifier: string,\n config: ConvexAuthConfig,\n): Fx<void, ConvexError<any>> =>\n Fx.gen(function* () {\n const state = yield* getRateLimitState(ctx, identifier, config);\n if (state !== null) {\n yield* Fx.promise(() =>\n authDb(ctx, config).rateLimits.patch(state.limit._id, {\n attemptsLeft: state.attemptsLeft - 1,\n lastAttemptTime: Date.now(),\n }),\n );\n } else {\n yield* Fx.promise(() =>\n authDb(ctx, config).rateLimits.create({\n identifier,\n attemptsLeft:\n (config.signIn?.maxFailedAttemptsPerHour ??\n DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR) - 1,\n lastAttemptTime: Date.now(),\n }),\n );\n }\n });\n\n/**\n * Reset the rate limit for the given identifier (e.g. after successful sign-in).\n */\n/** @internal */\nexport const resetSignInRateLimit = (\n ctx: MutationCtx,\n identifier: string,\n config: ConvexAuthConfig,\n): Fx<void, ConvexError<any>> =>\n Fx.gen(function* () {\n const state = yield* getRateLimitState(ctx, identifier, config);\n if (state !== null) {\n yield* Fx.promise(() =>\n authDb(ctx, config).rateLimits.delete(state.limit._id),\n );\n }\n });\n\n// ---------------------------------------------------------------------------\n// Internal\n// ---------------------------------------------------------------------------\n\ntype RateLimitState = {\n limit: Doc<\"RateLimit\"> & { attemptsLeft: number; lastAttemptTime: number };\n attemptsLeft: number;\n} | null;\n\nconst getRateLimitState = (\n ctx: MutationCtx,\n identifier: string,\n config: ConvexAuthConfig,\n): Fx<RateLimitState, ConvexError<any>> =>\n Fx.gen(function* () {\n const now = Date.now();\n const maxAttemptsPerHour =\n config.signIn?.maxFailedAttemptsPerHour ??\n DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR;\n\n const limit = (yield* Fx.promise(() =>\n authDb(ctx, config).rateLimits.get(identifier),\n )) as\n | (Doc<\"RateLimit\"> & { attemptsLeft: number; lastAttemptTime: number })\n | null;\n if (limit === null) return null;\n const elapsed = now - limit.lastAttemptTime;\n const maxAttemptsPerMs = maxAttemptsPerHour / (60 * 60 * 1000);\n const attemptsLeft = Math.min(\n maxAttemptsPerHour,\n limit.attemptsLeft + elapsed * maxAttemptsPerMs,\n );\n return { limit, attemptsLeft };\n });\n"],"mappings":";;;;AAOA,MAAM,wCAAwC;;;;;AAM9C,MAAa,uBACX,KACA,YACA,WAEA,kBAAkB,KAAK,YAAY,OAAO,CAAC,KACzC,GAAG,KAAK,UAAU,UAAU,QAAQ,MAAM,eAAe,EAAE,CAC5D;;;;;;;AAQH,MAAa,sBACX,KACA,YACA,WAEA,GAAG,IAAI,aAAa;CAClB,MAAM,QAAQ,OAAO,kBAAkB,KAAK,YAAY,OAAO;AAC/D,KAAI,UAAU,KACZ,QAAO,GAAG,cACR,OAAO,KAAK,OAAO,CAAC,WAAW,MAAM,MAAM,MAAM,KAAK;EACpD,cAAc,MAAM,eAAe;EACnC,iBAAiB,KAAK,KAAK;EAC5B,CAAC,CACH;KAED,QAAO,GAAG,cACR,OAAO,KAAK,OAAO,CAAC,WAAW,OAAO;EACpC;EACA,eACG,OAAO,QAAQ,4BACd,yCAAyC;EAC7C,iBAAiB,KAAK,KAAK;EAC5B,CAAC,CACH;EAEH;;;;;AAMJ,MAAa,wBACX,KACA,YACA,WAEA,GAAG,IAAI,aAAa;CAClB,MAAM,QAAQ,OAAO,kBAAkB,KAAK,YAAY,OAAO;AAC/D,KAAI,UAAU,KACZ,QAAO,GAAG,cACR,OAAO,KAAK,OAAO,CAAC,WAAW,OAAO,MAAM,MAAM,IAAI,CACvD;EAEH;AAWJ,MAAM,qBACJ,KACA,YACA,WAEA,GAAG,IAAI,aAAa;CAClB,MAAM,MAAM,KAAK,KAAK;CACtB,MAAM,qBACJ,OAAO,QAAQ,4BACf;CAEF,MAAM,QAAS,OAAO,GAAG,cACvB,OAAO,KAAK,OAAO,CAAC,WAAW,IAAI,WAAW,CAC/C;AAGD,KAAI,UAAU,KAAM,QAAO;CAC3B,MAAM,UAAU,MAAM,MAAM;CAC5B,MAAM,mBAAmB,sBAAsB,OAAU;AAKzD,QAAO;EAAE;EAAO,cAJK,KAAK,IACxB,oBACA,MAAM,eAAe,UAAU,iBAChC;EAC6B;EAC9B"}
@@ -36,11 +36,11 @@ type EnterpriseAdminAuthorizationInput = {
36
36
  /**
37
37
  * App-defined authorization hook for mounted enterprise admin APIs.
38
38
  *
39
- * Return `void` (or resolve) to allow the operation, or `{ ok: false }` to deny it.
39
+ * Return `void` (or resolve) to allow the operation, or throw to deny it.
40
40
  *
41
41
  * @param ctx - Convex context with `ctx.auth` for identity checks.
42
42
  * @param input - The {@link EnterpriseAdminAuthorizationInput} describing who is doing what.
43
- * @returns `void` to allow, `{ ok: false }` to deny.
43
+ * @returns `void` to allow; throw to deny.
44
44
  *
45
45
  * @example
46
46
  * ```ts
@@ -48,16 +48,14 @@ type EnterpriseAdminAuthorizationInput = {
48
48
  *
49
49
  * const authorized: EnterpriseAuthorizer = async (ctx, input) => {
50
50
  * const identity = await ctx.auth.getUserIdentity();
51
- * if (!identity) return { ok: false };
51
+ * if (!identity) throw new Error("Forbidden");
52
52
  * // Allow all admin ops for the org owner
53
53
  * };
54
54
  * ```
55
55
  */
56
56
  type EnterpriseAuthorizer = (ctx: {
57
57
  auth: convex_server0.Auth;
58
- }, input: EnterpriseAdminAuthorizationInput) => Promise<void | {
59
- ok: false;
60
- }>;
58
+ }, input: EnterpriseAdminAuthorizationInput) => Promise<void>;
61
59
  type RoleRef<TRoleId extends string> = {
62
60
  id: TRoleId;
63
61
  };
@@ -126,14 +124,14 @@ type EnterpriseMountOptions<TRoleId extends string = string> = {
126
124
  * @see {@link scim}
127
125
  * @see {@link enterprise}
128
126
  */
129
- declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined = undefined>(auth: Pick<AuthApi<TAuthorization>, "group" | "member" | "sso" | "user">, options?: MountedEnterpriseOptions<AuthRoleId<TAuthorization>>): {
127
+ declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined = undefined>(auth: Pick<AuthApi<TAuthorization>, "context" | "group" | "member" | "sso">, options?: MountedEnterpriseOptions<AuthRoleId<TAuthorization>>): {
130
128
  admin: {
131
129
  connection: {
132
130
  create: convex_server0.RegisteredMutation<"public", {
131
+ groupId?: string | undefined;
133
132
  name?: string | undefined;
134
133
  slug?: string | undefined;
135
134
  status?: "draft" | "active" | "disabled" | undefined;
136
- groupId?: string | undefined;
137
135
  domain?: string | undefined;
138
136
  }, Promise<any>>;
139
137
  get: convex_server0.RegisteredQuery<"public", {
@@ -146,12 +144,12 @@ declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined
146
144
  domain: string;
147
145
  }, Promise<any>>;
148
146
  list: convex_server0.RegisteredQuery<"public", {
147
+ limit?: number | undefined;
149
148
  where?: {
149
+ groupId?: string | undefined;
150
150
  slug?: string | undefined;
151
151
  status?: "draft" | "active" | "disabled" | undefined;
152
- groupId?: string | undefined;
153
152
  } | undefined;
154
- limit?: number | undefined;
155
153
  cursor?: string | null | undefined;
156
154
  orderBy?: string | undefined;
157
155
  order?: "asc" | "desc" | undefined;
@@ -164,13 +162,7 @@ declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined
164
162
  status?: "draft" | "active" | "disabled" | undefined;
165
163
  };
166
164
  }, Promise<{
167
- ok: false;
168
- code: "NOT_SIGNED_IN" | "FORBIDDEN";
169
- enterpriseId?: undefined;
170
- } | {
171
- ok: true;
172
165
  enterpriseId: string;
173
- code?: undefined;
174
166
  }>>;
175
167
  delete: convex_server0.RegisteredMutation<"public", {
176
168
  enterpriseId: string;
@@ -194,12 +186,12 @@ declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined
194
186
  }, Promise<any>>;
195
187
  verification: {
196
188
  request: convex_server0.RegisteredMutation<"public", {
197
- enterpriseId: string;
198
189
  domain: string;
190
+ enterpriseId: string;
199
191
  }, Promise<any>>;
200
192
  confirm: convex_server0.RegisteredAction<"public", {
201
- enterpriseId: string;
202
193
  domain: string;
194
+ enterpriseId: string;
203
195
  }, Promise<any>>;
204
196
  };
205
197
  };
@@ -263,8 +255,8 @@ declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined
263
255
  patch: {
264
256
  identity?: {
265
257
  accountLinking?: {
266
- saml?: "verifiedEmail" | "none" | undefined;
267
258
  oidc?: "verifiedEmail" | "none" | undefined;
259
+ saml?: "verifiedEmail" | "none" | undefined;
268
260
  } | undefined;
269
261
  } | undefined;
270
262
  provisioning?: {
@@ -287,9 +279,9 @@ declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined
287
279
  };
288
280
  audit: {
289
281
  list: convex_server0.RegisteredQuery<"public", {
290
- enterpriseId?: string | undefined;
291
282
  groupId?: string | undefined;
292
283
  limit?: number | undefined;
284
+ enterpriseId?: string | undefined;
293
285
  }, Promise<any>>;
294
286
  };
295
287
  webhook: {
@@ -302,21 +294,11 @@ declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined
302
294
  endpoint: {
303
295
  create: convex_server0.RegisteredMutation<"public", {
304
296
  createdByUserId?: string | undefined;
305
- enterpriseId: string;
306
297
  secret: string;
298
+ enterpriseId: string;
307
299
  url: string;
308
300
  subscriptions: string[];
309
301
  }, Promise<{
310
- ok: false;
311
- code: "NOT_SIGNED_IN" | "FORBIDDEN";
312
- _id?: undefined;
313
- enterpriseId?: undefined;
314
- url?: undefined;
315
- subscriptions?: undefined;
316
- createdByUserId?: undefined;
317
- status?: undefined;
318
- failureCount?: undefined;
319
- } | {
320
302
  _id: any;
321
303
  enterpriseId: string;
322
304
  url: string;
@@ -324,8 +306,6 @@ declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined
324
306
  createdByUserId: string;
325
307
  status: string;
326
308
  failureCount: number;
327
- ok?: undefined;
328
- code?: undefined;
329
309
  }>>;
330
310
  list: convex_server0.RegisteredQuery<"public", {
331
311
  enterpriseId: string;
@@ -339,8 +319,8 @@ declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined
339
319
  client: {
340
320
  signIn: convex_server0.RegisteredQuery<"public", {
341
321
  email?: string | undefined;
342
- enterpriseId?: string | undefined;
343
322
  domain?: string | undefined;
323
+ enterpriseId?: string | undefined;
344
324
  redirectTo?: string | undefined;
345
325
  }, Promise<any>>;
346
326
  metadata: convex_server0.RegisteredQuery<"public", {
@@ -380,7 +360,7 @@ declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined
380
360
  * @see {@link sso}
381
361
  * @see {@link enterprise}
382
362
  */
383
- declare function scim<TAuthorization extends AuthAuthorizationConfig | undefined = undefined>(auth: Pick<AuthApi<TAuthorization>, "scim" | "sso" | "user">, options?: MountedEnterpriseOptions<AuthRoleId<TAuthorization>>): {
363
+ declare function scim<TAuthorization extends AuthAuthorizationConfig | undefined = undefined>(auth: Pick<AuthApi<TAuthorization>, "context" | "scim" | "sso">, options?: MountedEnterpriseOptions<AuthRoleId<TAuthorization>>): {
384
364
  admin: {
385
365
  configure: convex_server0.RegisteredMutation<"public", {
386
366
  status?: "draft" | "active" | "disabled" | undefined;
@@ -430,12 +410,12 @@ declare function scim<TAuthorization extends AuthAuthorizationConfig | undefined
430
410
  * @see {@link sso}
431
411
  * @see {@link scim}
432
412
  */
433
- declare function enterprise<TAuthorization extends AuthAuthorizationConfig | undefined = undefined>(auth: Pick<AuthApi<TAuthorization>, "group" | "member" | "scim" | "sso" | "user">, options: EnterpriseMountOptions<AuthRoleId<TAuthorization>>): {
413
+ declare function enterprise<TAuthorization extends AuthAuthorizationConfig | undefined = undefined>(auth: Pick<AuthApi<TAuthorization>, "context" | "group" | "member" | "scim" | "sso">, options: EnterpriseMountOptions<AuthRoleId<TAuthorization>>): {
434
414
  createConnection: convex_server0.RegisteredMutation<"public", {
415
+ groupId?: string | undefined;
435
416
  name?: string | undefined;
436
417
  slug?: string | undefined;
437
418
  status?: "draft" | "active" | "disabled" | undefined;
438
- groupId?: string | undefined;
439
419
  domain?: string | undefined;
440
420
  }, Promise<any>>;
441
421
  getConnection: convex_server0.RegisteredQuery<"public", {
@@ -448,12 +428,12 @@ declare function enterprise<TAuthorization extends AuthAuthorizationConfig | und
448
428
  domain: string;
449
429
  }, Promise<any>>;
450
430
  listConnections: convex_server0.RegisteredQuery<"public", {
431
+ limit?: number | undefined;
451
432
  where?: {
433
+ groupId?: string | undefined;
452
434
  slug?: string | undefined;
453
435
  status?: "draft" | "active" | "disabled" | undefined;
454
- groupId?: string | undefined;
455
436
  } | undefined;
456
- limit?: number | undefined;
457
437
  cursor?: string | null | undefined;
458
438
  orderBy?: string | undefined;
459
439
  order?: "asc" | "desc" | undefined;
@@ -466,13 +446,7 @@ declare function enterprise<TAuthorization extends AuthAuthorizationConfig | und
466
446
  status?: "draft" | "active" | "disabled" | undefined;
467
447
  };
468
448
  }, Promise<{
469
- ok: false;
470
- code: "NOT_SIGNED_IN" | "FORBIDDEN";
471
- enterpriseId?: undefined;
472
- } | {
473
- ok: true;
474
449
  enterpriseId: string;
475
- code?: undefined;
476
450
  }>>;
477
451
  deleteConnection: convex_server0.RegisteredMutation<"public", {
478
452
  enterpriseId: string;
@@ -494,12 +468,12 @@ declare function enterprise<TAuthorization extends AuthAuthorizationConfig | und
494
468
  }[];
495
469
  }, Promise<any>>;
496
470
  requestDomainVerification: convex_server0.RegisteredMutation<"public", {
497
- enterpriseId: string;
498
471
  domain: string;
472
+ enterpriseId: string;
499
473
  }, Promise<any>>;
500
474
  confirmDomainVerification: convex_server0.RegisteredAction<"public", {
501
- enterpriseId: string;
502
475
  domain: string;
476
+ enterpriseId: string;
503
477
  }, Promise<any>>;
504
478
  configureOidc: convex_server0.RegisteredMutation<"public", {
505
479
  scopes?: string[] | undefined;
@@ -555,8 +529,8 @@ declare function enterprise<TAuthorization extends AuthAuthorizationConfig | und
555
529
  patch: {
556
530
  identity?: {
557
531
  accountLinking?: {
558
- saml?: "verifiedEmail" | "none" | undefined;
559
532
  oidc?: "verifiedEmail" | "none" | undefined;
533
+ saml?: "verifiedEmail" | "none" | undefined;
560
534
  } | undefined;
561
535
  } | undefined;
562
536
  provisioning?: {
@@ -577,27 +551,17 @@ declare function enterprise<TAuthorization extends AuthAuthorizationConfig | und
577
551
  enterpriseId: string;
578
552
  }, Promise<any>>;
579
553
  listAudit: convex_server0.RegisteredQuery<"public", {
580
- enterpriseId?: string | undefined;
581
554
  groupId?: string | undefined;
582
555
  limit?: number | undefined;
556
+ enterpriseId?: string | undefined;
583
557
  }, Promise<any>>;
584
558
  createWebhookEndpoint: convex_server0.RegisteredMutation<"public", {
585
559
  createdByUserId?: string | undefined;
586
- enterpriseId: string;
587
560
  secret: string;
561
+ enterpriseId: string;
588
562
  url: string;
589
563
  subscriptions: string[];
590
564
  }, Promise<{
591
- ok: false;
592
- code: "NOT_SIGNED_IN" | "FORBIDDEN";
593
- _id?: undefined;
594
- enterpriseId?: undefined;
595
- url?: undefined;
596
- subscriptions?: undefined;
597
- createdByUserId?: undefined;
598
- status?: undefined;
599
- failureCount?: undefined;
600
- } | {
601
565
  _id: any;
602
566
  enterpriseId: string;
603
567
  url: string;
@@ -605,8 +569,6 @@ declare function enterprise<TAuthorization extends AuthAuthorizationConfig | und
605
569
  createdByUserId: string;
606
570
  status: string;
607
571
  failureCount: number;
608
- ok?: undefined;
609
- code?: undefined;
610
572
  }>>;
611
573
  listWebhookEndpoints: convex_server0.RegisteredQuery<"public", {
612
574
  enterpriseId: string;
@@ -631,8 +593,8 @@ declare function enterprise<TAuthorization extends AuthAuthorizationConfig | und
631
593
  }, Promise<any>>;
632
594
  signIn: convex_server0.RegisteredQuery<"public", {
633
595
  email?: string | undefined;
634
- enterpriseId?: string | undefined;
635
596
  domain?: string | undefined;
597
+ enterpriseId?: string | undefined;
636
598
  redirectTo?: string | undefined;
637
599
  }, Promise<any>>;
638
600
  metadata: convex_server0.RegisteredQuery<"public", {
@@ -1 +1 @@
1
- {"version":3,"file":"mounts.d.ts","names":[],"sources":["../../src/server/mounts.ts"],"mappings":";;;;;;;;AA+BA;;;;;AAiBA;;;;;;;;KAjBY,yBAAA;;;;AAkDZ;;;KAjCY,iCAAA;EAmCH,2DAjCP,MAAA,UAkCU;EAhCV,UAAA,EAAY,yBAAA,EA8BL;EA5BP,YAAA,WA4BA;EA1BA,OAAA,WA2BA;EAzBA,eAAA;AAAA;;;AA0BiC;;;;;;;;;AAEiB;;;;;;;;;KALxC,oBAAA,IACV,GAAA;EAAO,IAAA,EADuB,cAAA,CACO,IAAA;AAAA,GACrC,KAAA,EAAO,iCAAA,KACJ,OAAA;EAAiB,EAAA;AAAA;AAAA,KAEjB,OAAA;EAAoC,EAAA,EAAI,OAAA;AAAA;AAAA,KAExC,wBAAA;EACH,KAAA;IACE,UAAA,GAAa,oBAAA;IACb,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAA,CAAQ,OAAA;EAAA;AAAA;;;;;;;;;;;;;;;;;;;;AA6KpC;KArJY,sBAAA;EACV,KAAA;IACE,UAAA,EAAY,oBAAA;IACZ,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAA,CAAQ,OAAA;EAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkJpB,GAAA,wBACS,uBAAA,yBAAA,CAEvB,IAAA,EAAM,IAAA,CAAK,OAAA,CAAQ,cAAA,yCACnB,OAAA,GAAU,wBAAA,CAAyB,UAAA,CAAW,cAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8hBhC,IAAA,wBACS,uBAAA,yBAAA,CAEvB,IAAA,EAAM,IAAA,CAAK,OAAA,CAAQ,cAAA,6BACnB,OAAA,GAAU,wBAAA,CAAyB,UAAA,CAAW,cAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkFhC,UAAA,wBACS,uBAAA,yBAAA,CAEvB,IAAA,EAAM,IAAA,CACJ,OAAA,CAAQ,cAAA,kDAGV,OAAA,EAAS,sBAAA,CAAuB,UAAA,CAAW,cAAA"}
1
+ {"version":3,"file":"mounts.d.ts","names":[],"sources":["../../src/server/mounts.ts"],"mappings":";;;;;;;;AAgCA;;;;;AAiBA;;;;;;;;KAjBY,yBAAA;;;;AAkDZ;;;KAjCY,iCAAA;EAmCH,2DAjCP,MAAA,UAkCU;EAhCV,UAAA,EAAY,yBAAA,EA8BL;EA5BP,YAAA,WA4BA;EA1BA,OAAA,WA2BA;EAzBA,eAAA;AAAA;;AA0BiB;;;;;;;;;AAEiC;;;;;;;;;;KALxC,oBAAA,IACV,GAAA;EAAO,IAAA,EADuB,cAAA,CACO,IAAA;AAAA,GACrC,KAAA,EAAO,iCAAA,KACJ,OAAA;AAAA,KAEA,OAAA;EAAoC,EAAA,EAAI,OAAA;AAAA;AAAA,KAExC,wBAAA;EACH,KAAA;IACE,UAAA,GAAa,oBAAA;IACb,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAA,CAAQ,OAAA;EAAA;AAAA;;;;;;;;;;;;;;;;;;;;;KAwBxB,sBAAA;EACV,KAAA;IACE,UAAA,EAAY,oBAAA;IACZ,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAA,CAAQ,OAAA;EAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqJpB,GAAA,wBACS,uBAAA,yBAAA,CAEvB,IAAA,EAAM,IAAA,CACJ,OAAA,CAAQ,cAAA,4CAGV,OAAA,GAAU,wBAAA,CAAyB,UAAA,CAAW,cAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkgBhC,IAAA,wBACS,uBAAA,yBAAA,CAEvB,IAAA,EAAM,IAAA,CAAK,OAAA,CAAQ,cAAA,gCACnB,OAAA,GAAU,wBAAA,CAAyB,UAAA,CAAW,cAAA;;;;;;;;;;;;;;;;AAJhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmFgB,UAAA,wBACS,uBAAA,yBAAA,CAEvB,IAAA,EAAM,IAAA,CACJ,OAAA,CAAQ,cAAA,qDAGV,OAAA,EAAS,sBAAA,CAAuB,UAAA,CAAW,cAAA"}