@robelest/convex-auth 0.0.4-preview.21 → 0.0.4-preview.23

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 (310) hide show
  1. package/dist/authorization/index.d.ts +1 -1
  2. package/dist/authorization/index.js +1 -1
  3. package/dist/authorization/index.js.map +1 -1
  4. package/dist/client/index.d.ts +1 -2
  5. package/dist/client/index.d.ts.map +1 -1
  6. package/dist/client/index.js +36 -39
  7. package/dist/client/index.js.map +1 -1
  8. package/dist/component/client/index.d.ts +1 -2
  9. package/dist/component/convex.config.d.ts +2 -2
  10. package/dist/component/convex.config.d.ts.map +1 -1
  11. package/dist/component/model.d.ts +5 -5
  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 +39 -39
  53. package/dist/component/server/auth.d.ts +95 -52
  54. package/dist/component/server/auth.d.ts.map +1 -1
  55. package/dist/component/server/auth.js +63 -43
  56. package/dist/component/server/auth.js.map +1 -1
  57. package/dist/component/server/core.js +116 -235
  58. package/dist/component/server/core.js.map +1 -1
  59. package/dist/component/server/crypto.js +25 -7
  60. package/dist/component/server/crypto.js.map +1 -1
  61. package/dist/component/server/device.js +58 -15
  62. package/dist/component/server/device.js.map +1 -1
  63. package/dist/component/server/enterprise/domain.js +148 -59
  64. package/dist/component/server/enterprise/domain.js.map +1 -1
  65. package/dist/component/server/enterprise/http.js +36 -15
  66. package/dist/component/server/enterprise/http.js.map +1 -1
  67. package/dist/component/server/enterprise/oidc.js +1 -1
  68. package/dist/component/server/http.js +26 -21
  69. package/dist/component/server/http.js.map +1 -1
  70. package/dist/component/server/identity.js +5 -2
  71. package/dist/component/server/identity.js.map +1 -1
  72. package/dist/component/server/limits.js +21 -30
  73. package/dist/component/server/limits.js.map +1 -1
  74. package/dist/component/server/mutations/account.js +12 -10
  75. package/dist/component/server/mutations/account.js.map +1 -1
  76. package/dist/component/server/mutations/code.js +5 -2
  77. package/dist/component/server/mutations/code.js.map +1 -1
  78. package/dist/component/server/mutations/invalidate.js +1 -1
  79. package/dist/component/server/mutations/invalidate.js.map +1 -1
  80. package/dist/component/server/mutations/oauth.js +10 -4
  81. package/dist/component/server/mutations/oauth.js.map +1 -1
  82. package/dist/component/server/mutations/refresh.js +2 -2
  83. package/dist/component/server/mutations/refresh.js.map +1 -1
  84. package/dist/component/server/mutations/register.js +46 -42
  85. package/dist/component/server/mutations/register.js.map +1 -1
  86. package/dist/component/server/mutations/retrieve.js +21 -25
  87. package/dist/component/server/mutations/retrieve.js.map +1 -1
  88. package/dist/component/server/mutations/signature.js +10 -4
  89. package/dist/component/server/mutations/signature.js.map +1 -1
  90. package/dist/component/server/mutations/signout.js.map +1 -1
  91. package/dist/component/server/mutations/store.js +9 -24
  92. package/dist/component/server/mutations/store.js.map +1 -1
  93. package/dist/component/server/mutations/verifier.js.map +1 -1
  94. package/dist/component/server/mutations/verify.js +1 -1
  95. package/dist/component/server/mutations/verify.js.map +1 -1
  96. package/dist/component/server/oauth.js +53 -16
  97. package/dist/component/server/oauth.js.map +1 -1
  98. package/dist/component/server/passkey.js +115 -31
  99. package/dist/component/server/passkey.js.map +1 -1
  100. package/dist/component/server/redirects.js +9 -3
  101. package/dist/component/server/redirects.js.map +1 -1
  102. package/dist/component/server/refresh.js +10 -7
  103. package/dist/component/server/refresh.js.map +1 -1
  104. package/dist/component/server/runtime.d.ts +3 -3
  105. package/dist/component/server/runtime.d.ts.map +1 -1
  106. package/dist/component/server/runtime.js +62 -20
  107. package/dist/component/server/runtime.js.map +1 -1
  108. package/dist/component/server/signin.js +34 -10
  109. package/dist/component/server/signin.js.map +1 -1
  110. package/dist/component/server/totp.js +79 -19
  111. package/dist/component/server/totp.js.map +1 -1
  112. package/dist/component/server/types.d.ts +12 -20
  113. package/dist/component/server/types.d.ts.map +1 -1
  114. package/dist/component/server/types.js.map +1 -1
  115. package/dist/component/server/users.js +6 -3
  116. package/dist/component/server/users.js.map +1 -1
  117. package/dist/component/server/utils.js +10 -4
  118. package/dist/component/server/utils.js.map +1 -1
  119. package/dist/core/types.d.ts +14 -22
  120. package/dist/core/types.d.ts.map +1 -1
  121. package/dist/factors/device.js +8 -9
  122. package/dist/factors/device.js.map +1 -1
  123. package/dist/factors/passkey.js +18 -21
  124. package/dist/factors/passkey.js.map +1 -1
  125. package/dist/providers/password.js +66 -81
  126. package/dist/providers/password.js.map +1 -1
  127. package/dist/runtime/invite.js +2 -8
  128. package/dist/runtime/invite.js.map +1 -1
  129. package/dist/server/auth.d.ts +95 -52
  130. package/dist/server/auth.d.ts.map +1 -1
  131. package/dist/server/auth.js +63 -43
  132. package/dist/server/auth.js.map +1 -1
  133. package/dist/server/core.d.ts +71 -159
  134. package/dist/server/core.d.ts.map +1 -1
  135. package/dist/server/core.js +116 -235
  136. package/dist/server/core.js.map +1 -1
  137. package/dist/server/crypto.d.ts.map +1 -1
  138. package/dist/server/crypto.js +25 -7
  139. package/dist/server/crypto.js.map +1 -1
  140. package/dist/server/device.js +58 -15
  141. package/dist/server/device.js.map +1 -1
  142. package/dist/server/enterprise/domain.d.ts +0 -8
  143. package/dist/server/enterprise/domain.d.ts.map +1 -1
  144. package/dist/server/enterprise/domain.js +148 -59
  145. package/dist/server/enterprise/domain.js.map +1 -1
  146. package/dist/server/enterprise/http.d.ts.map +1 -1
  147. package/dist/server/enterprise/http.js +35 -14
  148. package/dist/server/enterprise/http.js.map +1 -1
  149. package/dist/server/http.d.ts +2 -2
  150. package/dist/server/http.d.ts.map +1 -1
  151. package/dist/server/http.js +25 -20
  152. package/dist/server/http.js.map +1 -1
  153. package/dist/server/identity.js +5 -2
  154. package/dist/server/identity.js.map +1 -1
  155. package/dist/server/index.d.ts +2 -2
  156. package/dist/server/limits.js +21 -30
  157. package/dist/server/limits.js.map +1 -1
  158. package/dist/server/mounts.d.ts +26 -64
  159. package/dist/server/mounts.d.ts.map +1 -1
  160. package/dist/server/mounts.js +45 -106
  161. package/dist/server/mounts.js.map +1 -1
  162. package/dist/server/mutations/account.d.ts +8 -9
  163. package/dist/server/mutations/account.d.ts.map +1 -1
  164. package/dist/server/mutations/account.js +11 -9
  165. package/dist/server/mutations/account.js.map +1 -1
  166. package/dist/server/mutations/code.d.ts +13 -13
  167. package/dist/server/mutations/code.d.ts.map +1 -1
  168. package/dist/server/mutations/code.js +5 -2
  169. package/dist/server/mutations/code.js.map +1 -1
  170. package/dist/server/mutations/invalidate.d.ts +4 -4
  171. package/dist/server/mutations/invalidate.d.ts.map +1 -1
  172. package/dist/server/mutations/invalidate.js.map +1 -1
  173. package/dist/server/mutations/oauth.d.ts +12 -10
  174. package/dist/server/mutations/oauth.d.ts.map +1 -1
  175. package/dist/server/mutations/oauth.js +9 -3
  176. package/dist/server/mutations/oauth.js.map +1 -1
  177. package/dist/server/mutations/refresh.d.ts +3 -3
  178. package/dist/server/mutations/refresh.d.ts.map +1 -1
  179. package/dist/server/mutations/refresh.js +1 -1
  180. package/dist/server/mutations/refresh.js.map +1 -1
  181. package/dist/server/mutations/register.d.ts +11 -11
  182. package/dist/server/mutations/register.d.ts.map +1 -1
  183. package/dist/server/mutations/register.js +45 -41
  184. package/dist/server/mutations/register.js.map +1 -1
  185. package/dist/server/mutations/retrieve.d.ts +6 -6
  186. package/dist/server/mutations/retrieve.d.ts.map +1 -1
  187. package/dist/server/mutations/retrieve.js +20 -24
  188. package/dist/server/mutations/retrieve.js.map +1 -1
  189. package/dist/server/mutations/signature.d.ts +6 -7
  190. package/dist/server/mutations/signature.d.ts.map +1 -1
  191. package/dist/server/mutations/signature.js +9 -3
  192. package/dist/server/mutations/signature.js.map +1 -1
  193. package/dist/server/mutations/signin.d.ts +5 -5
  194. package/dist/server/mutations/signin.d.ts.map +1 -1
  195. package/dist/server/mutations/signout.js.map +1 -1
  196. package/dist/server/mutations/store.d.ts +97 -97
  197. package/dist/server/mutations/store.d.ts.map +1 -1
  198. package/dist/server/mutations/store.js +8 -23
  199. package/dist/server/mutations/store.js.map +1 -1
  200. package/dist/server/mutations/verifier.js.map +1 -1
  201. package/dist/server/mutations/verify.d.ts +10 -10
  202. package/dist/server/mutations/verify.d.ts.map +1 -1
  203. package/dist/server/mutations/verify.js.map +1 -1
  204. package/dist/server/oauth.js +53 -16
  205. package/dist/server/oauth.js.map +1 -1
  206. package/dist/server/passkey.d.ts +2 -2
  207. package/dist/server/passkey.d.ts.map +1 -1
  208. package/dist/server/passkey.js +114 -30
  209. package/dist/server/passkey.js.map +1 -1
  210. package/dist/server/redirects.js +9 -3
  211. package/dist/server/redirects.js.map +1 -1
  212. package/dist/server/refresh.js +10 -7
  213. package/dist/server/refresh.js.map +1 -1
  214. package/dist/server/runtime.d.ts +14 -14
  215. package/dist/server/runtime.d.ts.map +1 -1
  216. package/dist/server/runtime.js +61 -19
  217. package/dist/server/runtime.js.map +1 -1
  218. package/dist/server/signin.js +34 -10
  219. package/dist/server/signin.js.map +1 -1
  220. package/dist/server/ssr.d.ts.map +1 -1
  221. package/dist/server/ssr.js +175 -184
  222. package/dist/server/ssr.js.map +1 -1
  223. package/dist/server/totp.js +78 -18
  224. package/dist/server/totp.js.map +1 -1
  225. package/dist/server/types.d.ts +13 -21
  226. package/dist/server/types.d.ts.map +1 -1
  227. package/dist/server/types.js.map +1 -1
  228. package/dist/server/users.js +6 -3
  229. package/dist/server/users.js.map +1 -1
  230. package/dist/server/utils.js +10 -4
  231. package/dist/server/utils.js.map +1 -1
  232. package/package.json +2 -6
  233. package/src/authorization/index.ts +1 -1
  234. package/src/cli/index.ts +1 -1
  235. package/src/client/core/types.ts +14 -14
  236. package/src/client/factors/device.ts +10 -12
  237. package/src/client/factors/passkey.ts +23 -26
  238. package/src/client/index.ts +54 -64
  239. package/src/client/runtime/invite.ts +5 -7
  240. package/src/component/index.ts +1 -0
  241. package/src/component/public/enterprise/audit.ts +6 -1
  242. package/src/component/public/enterprise/core.ts +1 -0
  243. package/src/component/public/enterprise/domains.ts +5 -1
  244. package/src/component/public/enterprise/scim.ts +1 -0
  245. package/src/component/public/enterprise/secrets.ts +1 -0
  246. package/src/component/public/enterprise/webhooks.ts +1 -0
  247. package/src/component/public/factors/devices.ts +1 -0
  248. package/src/component/public/factors/passkeys.ts +1 -0
  249. package/src/component/public/factors/totp.ts +1 -0
  250. package/src/component/public/groups/core.ts +1 -1
  251. package/src/component/public/groups/invites.ts +7 -1
  252. package/src/component/public/groups/members.ts +1 -0
  253. package/src/component/public/identity/accounts.ts +1 -0
  254. package/src/component/public/identity/codes.ts +1 -0
  255. package/src/component/public/identity/sessions.ts +1 -0
  256. package/src/component/public/identity/tokens.ts +1 -0
  257. package/src/component/public/identity/users.ts +1 -0
  258. package/src/component/public/identity/verifiers.ts +1 -0
  259. package/src/component/public/security/keys.ts +1 -0
  260. package/src/component/public/security/limits.ts +1 -0
  261. package/src/providers/password.ts +89 -110
  262. package/src/server/auth.ts +177 -111
  263. package/src/server/core.ts +197 -233
  264. package/src/server/crypto.ts +31 -29
  265. package/src/server/device.ts +65 -32
  266. package/src/server/enterprise/domain.ts +158 -170
  267. package/src/server/enterprise/http.ts +46 -39
  268. package/src/server/http.ts +36 -30
  269. package/src/server/identity.ts +5 -5
  270. package/src/server/index.ts +2 -0
  271. package/src/server/limits.ts +53 -80
  272. package/src/server/mounts.ts +47 -74
  273. package/src/server/mutations/account.ts +22 -36
  274. package/src/server/mutations/code.ts +6 -6
  275. package/src/server/mutations/invalidate.ts +1 -1
  276. package/src/server/mutations/oauth.ts +14 -8
  277. package/src/server/mutations/refresh.ts +5 -4
  278. package/src/server/mutations/register.ts +87 -132
  279. package/src/server/mutations/retrieve.ts +44 -44
  280. package/src/server/mutations/signature.ts +13 -6
  281. package/src/server/mutations/signout.ts +1 -1
  282. package/src/server/mutations/store.ts +16 -31
  283. package/src/server/mutations/verifier.ts +1 -1
  284. package/src/server/mutations/verify.ts +3 -5
  285. package/src/server/oauth.ts +60 -69
  286. package/src/server/passkey.ts +567 -517
  287. package/src/server/redirects.ts +10 -6
  288. package/src/server/refresh.ts +14 -18
  289. package/src/server/runtime.ts +70 -55
  290. package/src/server/signin.ts +44 -37
  291. package/src/server/ssr.ts +390 -407
  292. package/src/server/totp.ts +85 -35
  293. package/src/server/types.ts +19 -22
  294. package/src/server/users.ts +7 -6
  295. package/src/server/utils.ts +10 -12
  296. package/dist/component/server/authError.js +0 -34
  297. package/dist/component/server/authError.js.map +0 -1
  298. package/dist/component/server/errors.d.ts +0 -1
  299. package/dist/component/server/errors.js +0 -137
  300. package/dist/component/server/errors.js.map +0 -1
  301. package/dist/server/authError.d.ts +0 -46
  302. package/dist/server/authError.d.ts.map +0 -1
  303. package/dist/server/authError.js +0 -34
  304. package/dist/server/authError.js.map +0 -1
  305. package/dist/server/errors.d.ts +0 -177
  306. package/dist/server/errors.d.ts.map +0 -1
  307. package/dist/server/errors.js +0 -212
  308. package/dist/server/errors.js.map +0 -1
  309. package/src/server/authError.ts +0 -44
  310. package/src/server/errors.ts +0 -290
package/src/server/ssr.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Fx } from "@robelest/fx";
1
2
  import { ConvexHttpClient } from "convex/browser";
2
3
  import { makeFunctionReference } from "convex/server";
3
4
  import { ConvexError } from "convex/values";
@@ -9,7 +10,6 @@ import type {
9
10
  SignInActionResult,
10
11
  SignOutAction,
11
12
  } from "./runtime";
12
- import { Fx } from "@robelest/fx";
13
13
  import { isLocalHost } from "./utils";
14
14
 
15
15
  const signInActionRef: SignInAction = makeFunctionReference("auth:signIn");
@@ -598,60 +598,158 @@ export function server(options: ServerOptions) {
598
598
  return Fx.run(
599
599
  Fx.match(actionDispatch, actionDispatch.action, {
600
600
  sessionStart: (_) =>
601
- Fx.from({
602
- ok: async () => {
603
- const refreshDispatch =
604
- args.refreshToken === undefined
605
- ? { kind: "passthrough" as const }
606
- : currentCookies.refreshToken === null
607
- ? { kind: "refreshRequestedWithoutCookie" as const }
608
- : {
609
- kind: "hydrateRefreshFromCookie" as const,
610
- refreshToken: currentCookies.refreshToken,
611
- };
601
+ Fx.promise(async () => {
602
+ const refreshDispatch =
603
+ args.refreshToken === undefined
604
+ ? { kind: "passthrough" as const }
605
+ : currentCookies.refreshToken === null
606
+ ? { kind: "refreshRequestedWithoutCookie" as const }
607
+ : {
608
+ kind: "hydrateRefreshFromCookie" as const,
609
+ refreshToken: currentCookies.refreshToken,
610
+ };
612
611
 
613
- const refreshResponse = await Fx.run(
614
- Fx.match(refreshDispatch, refreshDispatch.kind, {
615
- passthrough: async () => null,
616
- hydrateRefreshFromCookie: async ({ refreshToken }) => {
617
- args.refreshToken = refreshToken;
618
- return null;
619
- },
620
- refreshRequestedWithoutCookie: async () => {
621
- const currentToken = currentCookies.token;
622
- const decodedToken =
623
- currentToken === null
624
- ? null
625
- : await Fx.run(
626
- Fx.attempt(
627
- async () =>
628
- jwtDecode<DecodedToken>(currentToken),
629
- (decoded) => decoded,
630
- () => null,
631
- ),
612
+ const refreshResponse = await Fx.run(
613
+ Fx.match(refreshDispatch, refreshDispatch.kind, {
614
+ passthrough: async () => null,
615
+ hydrateRefreshFromCookie: async ({ refreshToken }) => {
616
+ args.refreshToken = refreshToken;
617
+ return null;
618
+ },
619
+ refreshRequestedWithoutCookie: async () => {
620
+ const currentToken = currentCookies.token;
621
+ const decodedToken =
622
+ currentToken === null
623
+ ? null
624
+ : await Fx.run(
625
+ Fx.attempt(
626
+ async () => jwtDecode<DecodedToken>(currentToken),
627
+ (decoded) => decoded,
628
+ () => null,
629
+ ),
630
+ );
631
+ const tokenDispatch =
632
+ currentToken !== null &&
633
+ decodedToken?.exp !== undefined &&
634
+ decodedToken.iss !== undefined &&
635
+ acceptedIssuers.has(normalizeIssuer(decodedToken.iss)) &&
636
+ decodedToken.exp * 1000 > Date.now()
637
+ ? {
638
+ kind: "validToken" as const,
639
+ token: currentToken,
640
+ }
641
+ : { kind: "missingToken" as const };
642
+ return await Fx.run(
643
+ Fx.match(tokenDispatch, tokenDispatch.kind, {
644
+ validToken: ({ token }) =>
645
+ new Response(
646
+ JSON.stringify({
647
+ tokens: {
648
+ token,
649
+ refreshToken: "dummy",
650
+ },
651
+ }),
652
+ {
653
+ status: 200,
654
+ headers: {
655
+ "Content-Type": "application/json",
656
+ },
657
+ },
658
+ ),
659
+ missingToken: () =>
660
+ new Response(JSON.stringify({ tokens: null }), {
661
+ status: 200,
662
+ headers: {
663
+ "Content-Type": "application/json",
664
+ },
665
+ }),
666
+ }),
667
+ );
668
+ },
669
+ }),
670
+ );
671
+ const refreshDecision =
672
+ refreshResponse !== null
673
+ ? {
674
+ kind: "shortCircuit" as const,
675
+ response: refreshResponse,
676
+ }
677
+ : { kind: "continue" as const };
678
+ const maybeShortCircuitResponse = await Fx.run(
679
+ Fx.match(refreshDecision, refreshDecision.kind, {
680
+ shortCircuit: ({ response }) => response,
681
+ continue: () => null,
682
+ }),
683
+ );
684
+ if (maybeShortCircuitResponse !== null) {
685
+ return maybeShortCircuitResponse;
686
+ }
687
+
688
+ const client = new ConvexHttpClient(convexUrl);
689
+ const authDispatch =
690
+ args.refreshToken === undefined &&
691
+ args.params?.code === undefined &&
692
+ currentCookies.token !== null
693
+ ? {
694
+ kind: "attachAuth" as const,
695
+ token: currentCookies.token,
696
+ }
697
+ : { kind: "skipAuth" as const };
698
+ await Fx.run(
699
+ Fx.match(authDispatch, authDispatch.kind, {
700
+ attachAuth: ({ token }) => {
701
+ client.setAuth(token);
702
+ },
703
+ skipAuth: () => undefined,
704
+ }),
705
+ );
706
+ return Fx.run(
707
+ Fx.from({
708
+ ok: () => client.action(signInActionRef, args),
709
+ err: (error) => error,
710
+ }).pipe(
711
+ Fx.fold({
712
+ ok: (result: SignInActionResult) =>
713
+ Fx.run(
714
+ Fx.match(result, result.kind, {
715
+ redirect: (redirectResult) => {
716
+ const response = new Response(
717
+ JSON.stringify({
718
+ kind: "redirect",
719
+ redirect: redirectResult.redirect,
720
+ verifier: redirectResult.verifier,
721
+ }),
722
+ {
723
+ status: 200,
724
+ headers: {
725
+ "Content-Type": "application/json",
726
+ },
727
+ },
632
728
  );
633
- const tokenDispatch =
634
- currentToken !== null &&
635
- decodedToken?.exp !== undefined &&
636
- decodedToken.iss !== undefined &&
637
- acceptedIssuers.has(
638
- normalizeIssuer(decodedToken.iss),
639
- ) &&
640
- decodedToken.exp * 1000 > Date.now()
641
- ? {
642
- kind: "validToken" as const,
643
- token: currentToken,
729
+ for (const value of serializeAuthCookies(
730
+ {
731
+ ...currentCookies,
732
+ verifier: redirectResult.verifier,
733
+ },
734
+ host,
735
+ cookieConfig,
736
+ cookieNamespace,
737
+ )) {
738
+ response.headers.append("Set-Cookie", value);
644
739
  }
645
- : { kind: "missingToken" as const };
646
- return await Fx.run(
647
- Fx.match(tokenDispatch, tokenDispatch.kind, {
648
- validToken: ({ token }) =>
649
- new Response(
740
+ return Fx.succeed(response);
741
+ },
742
+ signedIn: (signedInResult) => {
743
+ const response = new Response(
650
744
  JSON.stringify({
651
- tokens: {
652
- token,
653
- refreshToken: "dummy",
654
- },
745
+ kind: "signedIn",
746
+ tokens:
747
+ signedInResult.tokens === null
748
+ ? null
749
+ : {
750
+ token: signedInResult.tokens.token,
751
+ refreshToken: "dummy",
752
+ },
655
753
  }),
656
754
  {
657
755
  status: 200,
@@ -659,380 +757,265 @@ export function server(options: ServerOptions) {
659
757
  "Content-Type": "application/json",
660
758
  },
661
759
  },
662
- ),
663
- missingToken: () =>
664
- new Response(JSON.stringify({ tokens: null }), {
665
- status: 200,
666
- headers: {
667
- "Content-Type": "application/json",
760
+ );
761
+ for (const value of serializeAuthCookies(
762
+ {
763
+ token: signedInResult.tokens?.token ?? null,
764
+ refreshToken:
765
+ signedInResult.tokens?.refreshToken ?? null,
766
+ verifier: null,
668
767
  },
669
- }),
670
- }),
671
- );
672
- },
673
- }),
674
- );
675
- const refreshDecision =
676
- refreshResponse !== null
677
- ? {
678
- kind: "shortCircuit" as const,
679
- response: refreshResponse,
680
- }
681
- : { kind: "continue" as const };
682
- const maybeShortCircuitResponse = await Fx.run(
683
- Fx.match(refreshDecision, refreshDecision.kind, {
684
- shortCircuit: ({ response }) => response,
685
- continue: () => null,
686
- }),
687
- );
688
- if (maybeShortCircuitResponse !== null) {
689
- return maybeShortCircuitResponse;
690
- }
691
-
692
- const client = new ConvexHttpClient(convexUrl);
693
- const authDispatch =
694
- args.refreshToken === undefined &&
695
- args.params?.code === undefined &&
696
- currentCookies.token !== null
697
- ? {
698
- kind: "attachAuth" as const,
699
- token: currentCookies.token,
700
- }
701
- : { kind: "skipAuth" as const };
702
- await Fx.run(
703
- Fx.match(authDispatch, authDispatch.kind, {
704
- attachAuth: ({ token }) => {
705
- client.setAuth(token);
706
- },
707
- skipAuth: () => undefined,
708
- }),
709
- );
710
- return Fx.run(
711
- Fx.from({
712
- ok: () => client.action(signInActionRef, args),
713
- err: (error) => error,
714
- }).pipe(
715
- Fx.fold({
716
- ok: (result: SignInActionResult) =>
717
- Fx.run(
718
- Fx.match(result, result.kind, {
719
- redirect: (redirectResult) => {
720
- const response = new Response(
721
- JSON.stringify({
722
- kind: "redirect",
723
- redirect: redirectResult.redirect,
724
- verifier: redirectResult.verifier,
725
- }),
768
+ host,
769
+ cookieConfig,
770
+ cookieNamespace,
771
+ )) {
772
+ response.headers.append("Set-Cookie", value);
773
+ }
774
+ return Fx.succeed(response);
775
+ },
776
+ started: (startedResult) =>
777
+ Fx.succeed(
778
+ new Response(JSON.stringify(startedResult), {
779
+ status: 200,
780
+ headers: {
781
+ "Content-Type": "application/json",
782
+ },
783
+ }),
784
+ ),
785
+ passkeyOptions: (passkeyOptionsResult) =>
786
+ Fx.succeed(
787
+ new Response(
788
+ JSON.stringify(passkeyOptionsResult),
726
789
  {
727
790
  status: 200,
728
791
  headers: {
729
792
  "Content-Type": "application/json",
730
793
  },
731
794
  },
732
- );
733
- for (const value of serializeAuthCookies(
734
- {
735
- ...currentCookies,
736
- verifier: redirectResult.verifier,
795
+ ),
796
+ ),
797
+ totpRequired: (totpRequiredResult) =>
798
+ Fx.succeed(
799
+ new Response(JSON.stringify(totpRequiredResult), {
800
+ status: 200,
801
+ headers: {
802
+ "Content-Type": "application/json",
737
803
  },
738
- host,
739
- cookieConfig,
740
- cookieNamespace,
741
- )) {
742
- response.headers.append("Set-Cookie", value);
743
- }
744
- return Fx.succeed(response);
745
- },
746
- signedIn: (signedInResult) => {
747
- const response = new Response(
748
- JSON.stringify({
749
- kind: "signedIn",
750
- tokens:
751
- signedInResult.tokens === null
752
- ? null
753
- : {
754
- token: signedInResult.tokens.token,
755
- refreshToken: "dummy",
756
- },
757
- }),
758
- {
759
- status: 200,
760
- headers: {
761
- "Content-Type": "application/json",
762
- },
804
+ }),
805
+ ),
806
+ totpSetup: (totpSetupResult) =>
807
+ Fx.succeed(
808
+ new Response(JSON.stringify(totpSetupResult), {
809
+ status: 200,
810
+ headers: {
811
+ "Content-Type": "application/json",
763
812
  },
764
- );
765
- for (const value of serializeAuthCookies(
766
- {
767
- token: signedInResult.tokens?.token ?? null,
768
- refreshToken:
769
- signedInResult.tokens?.refreshToken ?? null,
770
- verifier: null,
813
+ }),
814
+ ),
815
+ deviceCode: (deviceCodeResult) =>
816
+ Fx.succeed(
817
+ new Response(JSON.stringify(deviceCodeResult), {
818
+ status: 200,
819
+ headers: {
820
+ "Content-Type": "application/json",
771
821
  },
772
- host,
773
- cookieConfig,
774
- cookieNamespace,
775
- )) {
776
- response.headers.append("Set-Cookie", value);
777
- }
778
- return Fx.succeed(response);
779
- },
780
- started: (startedResult) =>
781
- Fx.succeed(
782
- new Response(JSON.stringify(startedResult), {
783
- status: 200,
784
- headers: {
785
- "Content-Type": "application/json",
786
- },
787
- }),
788
- ),
789
- passkeyOptions: (passkeyOptionsResult) =>
790
- Fx.succeed(
791
- new Response(
792
- JSON.stringify(passkeyOptionsResult),
793
- {
794
- status: 200,
795
- headers: {
796
- "Content-Type": "application/json",
797
- },
798
- },
799
- ),
800
- ),
801
- totpRequired: (totpRequiredResult) =>
802
- Fx.succeed(
803
- new Response(
804
- JSON.stringify(totpRequiredResult),
805
- {
806
- status: 200,
807
- headers: {
808
- "Content-Type": "application/json",
809
- },
810
- },
811
- ),
812
- ),
813
- totpSetup: (totpSetupResult) =>
814
- Fx.succeed(
815
- new Response(JSON.stringify(totpSetupResult), {
816
- status: 200,
817
- headers: {
818
- "Content-Type": "application/json",
819
- },
820
- }),
821
- ),
822
- deviceCode: (deviceCodeResult) =>
823
- Fx.succeed(
824
- new Response(JSON.stringify(deviceCodeResult), {
825
- status: 200,
826
- headers: {
827
- "Content-Type": "application/json",
828
- },
829
- }),
830
- ),
831
- }),
832
- ),
833
- err: (error: unknown) => {
834
- const errorBody =
835
- error instanceof ConvexError &&
836
- typeof error.data === "object" &&
837
- error.data !== null &&
838
- "code" in error.data
839
- ? {
840
- error:
841
- (error.data as { message?: string })
842
- .message ?? String(error),
843
- authError: error.data,
844
- }
845
- : {
846
- error:
847
- error instanceof Error
848
- ? error.message
849
- : String(error),
850
- };
851
- const response = new Response(
852
- JSON.stringify(errorBody),
853
- {
854
- status: 400,
855
- headers: {
856
- "Content-Type": "application/json",
857
- },
858
- },
859
- );
860
- const clearSession =
861
- args.refreshToken !== undefined &&
862
- error instanceof ConvexError &&
863
- typeof error.data === "object" &&
864
- error.data !== null &&
865
- (error.data as Record<string, unknown>).code ===
866
- "INVALID_REFRESH_TOKEN";
867
- for (const value of serializeAuthCookies(
868
- {
869
- token: clearSession ? null : currentCookies.token,
870
- refreshToken: clearSession
871
- ? null
872
- : currentCookies.refreshToken,
873
- verifier: null,
874
- },
875
- host,
876
- cookieConfig,
877
- cookieNamespace,
878
- )) {
879
- response.headers.append("Set-Cookie", value);
880
- }
881
- return response;
882
- },
883
- }),
884
- ),
885
- );
886
- },
887
- err: (e) => e as never,
888
- }),
889
- sessionStop: (_) =>
890
- Fx.from({
891
- ok: async () => {
892
- await Fx.run(
893
- Fx.from({
894
- ok: () =>
895
- (() => {
896
- const client = new ConvexHttpClient(convexUrl);
897
- if (currentCookies.token !== null) {
898
- client.setAuth(currentCookies.token);
899
- }
900
- return client.action(signOutActionRef);
901
- })(),
902
- err: (error) => error,
903
- }).pipe(
904
- Fx.recover((error: unknown) => {
905
- console.error(
906
- "[convex-auth/server] proxy sign-out failed",
907
- error,
908
- );
909
- const fallbackDispatch =
910
- currentCookies.refreshToken !== null
822
+ }),
823
+ ),
824
+ }),
825
+ ),
826
+ err: (error: unknown) => {
827
+ const errorBody =
828
+ error instanceof ConvexError &&
829
+ typeof error.data === "object" &&
830
+ error.data !== null &&
831
+ "code" in error.data
911
832
  ? {
912
- kind: "attemptFallback" as const,
913
- refreshToken: currentCookies.refreshToken,
833
+ error:
834
+ (error.data as { message?: string }).message ??
835
+ String(error),
836
+ authError: error.data,
914
837
  }
915
- : { kind: "skipFallback" as const };
916
- return Fx.match(fallbackDispatch, fallbackDispatch.kind, {
917
- attemptFallback: ({ refreshToken }) =>
918
- Fx.from({
919
- ok: async () => {
920
- const refreshClient = new ConvexHttpClient(
921
- convexUrl,
922
- );
923
- const refreshed = (await refreshClient.action(
924
- signInActionRef,
925
- {
926
- refreshToken,
927
- },
928
- )) as SignInActionResult;
929
- const refreshedTokens = await Fx.run(
930
- Fx.match(refreshed, refreshed.kind, {
931
- signedIn: (signedInResult) =>
932
- Fx.succeed(signedInResult.tokens),
933
- redirect: () =>
934
- Fx.fatal(
935
- new Error(
936
- "Invalid `auth:signIn` result for sign-out fallback refresh",
937
- ),
838
+ : {
839
+ error:
840
+ error instanceof Error
841
+ ? error.message
842
+ : String(error),
843
+ };
844
+ const response = new Response(JSON.stringify(errorBody), {
845
+ status: 400,
846
+ headers: {
847
+ "Content-Type": "application/json",
848
+ },
849
+ });
850
+ const clearSession =
851
+ args.refreshToken !== undefined &&
852
+ error instanceof ConvexError &&
853
+ typeof error.data === "object" &&
854
+ error.data !== null &&
855
+ (error.data as Record<string, unknown>).code ===
856
+ "INVALID_REFRESH_TOKEN";
857
+ for (const value of serializeAuthCookies(
858
+ {
859
+ token: clearSession ? null : currentCookies.token,
860
+ refreshToken: clearSession
861
+ ? null
862
+ : currentCookies.refreshToken,
863
+ verifier: null,
864
+ },
865
+ host,
866
+ cookieConfig,
867
+ cookieNamespace,
868
+ )) {
869
+ response.headers.append("Set-Cookie", value);
870
+ }
871
+ return response;
872
+ },
873
+ }),
874
+ ),
875
+ );
876
+ }),
877
+ sessionStop: (_) =>
878
+ Fx.promise(async () => {
879
+ await Fx.run(
880
+ Fx.from({
881
+ ok: () =>
882
+ (() => {
883
+ const client = new ConvexHttpClient(convexUrl);
884
+ if (currentCookies.token !== null) {
885
+ client.setAuth(currentCookies.token);
886
+ }
887
+ return client.action(signOutActionRef);
888
+ })(),
889
+ err: (error) => error,
890
+ }).pipe(
891
+ Fx.recover((error: unknown) => {
892
+ console.error(
893
+ "[convex-auth/server] proxy sign-out failed",
894
+ error,
895
+ );
896
+ const fallbackDispatch =
897
+ currentCookies.refreshToken !== null
898
+ ? {
899
+ kind: "attemptFallback" as const,
900
+ refreshToken: currentCookies.refreshToken,
901
+ }
902
+ : { kind: "skipFallback" as const };
903
+ return Fx.match(fallbackDispatch, fallbackDispatch.kind, {
904
+ attemptFallback: ({ refreshToken }) =>
905
+ Fx.from({
906
+ ok: async () => {
907
+ const refreshClient = new ConvexHttpClient(
908
+ convexUrl,
909
+ );
910
+ const refreshed = (await refreshClient.action(
911
+ signInActionRef,
912
+ {
913
+ refreshToken,
914
+ },
915
+ )) as SignInActionResult;
916
+ const refreshedTokens = await Fx.run(
917
+ Fx.match(refreshed, refreshed.kind, {
918
+ signedIn: (signedInResult) =>
919
+ Fx.succeed(signedInResult.tokens),
920
+ redirect: () =>
921
+ Fx.fatal(
922
+ new Error(
923
+ "Invalid `auth:signIn` result for sign-out fallback refresh",
938
924
  ),
939
- started: () =>
940
- Fx.fatal(
941
- new Error(
942
- "Invalid `auth:signIn` result for sign-out fallback refresh",
943
- ),
925
+ ),
926
+ started: () =>
927
+ Fx.fatal(
928
+ new Error(
929
+ "Invalid `auth:signIn` result for sign-out fallback refresh",
944
930
  ),
945
- passkeyOptions: () =>
946
- Fx.fatal(
947
- new Error(
948
- "Invalid `auth:signIn` result for sign-out fallback refresh",
949
- ),
931
+ ),
932
+ passkeyOptions: () =>
933
+ Fx.fatal(
934
+ new Error(
935
+ "Invalid `auth:signIn` result for sign-out fallback refresh",
950
936
  ),
951
- totpRequired: () =>
952
- Fx.fatal(
953
- new Error(
954
- "Invalid `auth:signIn` result for sign-out fallback refresh",
955
- ),
937
+ ),
938
+ totpRequired: () =>
939
+ Fx.fatal(
940
+ new Error(
941
+ "Invalid `auth:signIn` result for sign-out fallback refresh",
956
942
  ),
957
- totpSetup: () =>
958
- Fx.fatal(
959
- new Error(
960
- "Invalid `auth:signIn` result for sign-out fallback refresh",
961
- ),
943
+ ),
944
+ totpSetup: () =>
945
+ Fx.fatal(
946
+ new Error(
947
+ "Invalid `auth:signIn` result for sign-out fallback refresh",
962
948
  ),
963
- deviceCode: () =>
964
- Fx.fatal(
965
- new Error(
966
- "Invalid `auth:signIn` result for sign-out fallback refresh",
967
- ),
949
+ ),
950
+ deviceCode: () =>
951
+ Fx.fatal(
952
+ new Error(
953
+ "Invalid `auth:signIn` result for sign-out fallback refresh",
968
954
  ),
969
- }),
970
- );
971
- const fallbackSignOutDispatch =
972
- refreshedTokens !== null
973
- ? {
974
- kind: "signOutWithRefreshed" as const,
975
- token: refreshedTokens.token,
976
- }
977
- : { kind: "skipRefreshedSignOut" as const };
978
- await Fx.run(
979
- Fx.match(
980
- fallbackSignOutDispatch,
981
- fallbackSignOutDispatch.kind,
982
- {
983
- signOutWithRefreshed: ({ token }) =>
984
- Fx.from({
985
- ok: async () => {
986
- const client = new ConvexHttpClient(
987
- convexUrl,
988
- );
989
- client.setAuth(token);
990
- await client.action(signOutActionRef);
991
- },
992
- err: (error) => error,
993
- }),
994
- skipRefreshedSignOut: () => Fx.succeed(undefined),
995
- },
996
- ),
997
- );
998
- },
999
- err: (fallbackError) => fallbackError,
1000
- }).pipe(
1001
- Fx.recover((fallbackError: unknown) => {
1002
- console.error(
1003
- "[convex-auth/server] proxy sign-out fallback failed",
1004
- fallbackError,
1005
- );
1006
- return Fx.succeed(undefined);
1007
- }),
1008
- ),
1009
- skipFallback: () => Fx.succeed(undefined),
1010
- });
1011
- }),
1012
- Fx.map(() => undefined),
1013
- ),
1014
- );
1015
- const response = new Response(JSON.stringify(null), {
1016
- status: 200,
1017
- headers: {
1018
- "Content-Type": "application/json",
1019
- },
1020
- });
1021
- for (const value of serializeAuthCookies(
1022
- {
1023
- token: null,
1024
- refreshToken: null,
1025
- verifier: null,
1026
- },
1027
- host,
1028
- cookieConfig,
1029
- cookieNamespace,
1030
- )) {
1031
- response.headers.append("Set-Cookie", value);
1032
- }
1033
- return response;
1034
- },
1035
- err: (e) => e as never,
955
+ ),
956
+ }),
957
+ );
958
+ const fallbackSignOutDispatch =
959
+ refreshedTokens !== null
960
+ ? {
961
+ kind: "signOutWithRefreshed" as const,
962
+ token: refreshedTokens.token,
963
+ }
964
+ : { kind: "skipRefreshedSignOut" as const };
965
+ await Fx.run(
966
+ Fx.match(
967
+ fallbackSignOutDispatch,
968
+ fallbackSignOutDispatch.kind,
969
+ {
970
+ signOutWithRefreshed: ({ token }) =>
971
+ Fx.promise(async () => {
972
+ const client = new ConvexHttpClient(
973
+ convexUrl,
974
+ );
975
+ client.setAuth(token);
976
+ await client.action(signOutActionRef);
977
+ }),
978
+ skipRefreshedSignOut: () =>
979
+ Fx.succeed(undefined),
980
+ },
981
+ ),
982
+ );
983
+ },
984
+ err: (error) => error,
985
+ }).pipe(
986
+ Fx.recover((fallbackError: unknown) => {
987
+ console.error(
988
+ "[convex-auth/server] proxy sign-out fallback failed",
989
+ fallbackError,
990
+ );
991
+ return Fx.succeed(undefined);
992
+ }),
993
+ ),
994
+ skipFallback: () => Fx.succeed(undefined),
995
+ });
996
+ }),
997
+ Fx.map(() => undefined),
998
+ ),
999
+ );
1000
+ const response = new Response(JSON.stringify(null), {
1001
+ status: 200,
1002
+ headers: {
1003
+ "Content-Type": "application/json",
1004
+ },
1005
+ });
1006
+ for (const value of serializeAuthCookies(
1007
+ {
1008
+ token: null,
1009
+ refreshToken: null,
1010
+ verifier: null,
1011
+ },
1012
+ host,
1013
+ cookieConfig,
1014
+ cookieNamespace,
1015
+ )) {
1016
+ response.headers.append("Set-Cookie", value);
1017
+ }
1018
+ return response;
1036
1019
  }),
1037
1020
  }),
1038
1021
  );