@robelest/convex-auth 0.0.4-preview.22 → 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 (306) 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/model.d.ts +9 -9
  10. package/dist/component/model.d.ts.map +1 -1
  11. package/dist/component/public/enterprise/audit.d.ts.map +1 -1
  12. package/dist/component/public/enterprise/audit.js.map +1 -1
  13. package/dist/component/public/enterprise/core.d.ts.map +1 -1
  14. package/dist/component/public/enterprise/core.js.map +1 -1
  15. package/dist/component/public/enterprise/domains.d.ts.map +1 -1
  16. package/dist/component/public/enterprise/domains.js.map +1 -1
  17. package/dist/component/public/enterprise/scim.d.ts.map +1 -1
  18. package/dist/component/public/enterprise/scim.js.map +1 -1
  19. package/dist/component/public/enterprise/secrets.d.ts.map +1 -1
  20. package/dist/component/public/enterprise/secrets.js.map +1 -1
  21. package/dist/component/public/enterprise/webhooks.d.ts.map +1 -1
  22. package/dist/component/public/enterprise/webhooks.js.map +1 -1
  23. package/dist/component/public/factors/devices.d.ts.map +1 -1
  24. package/dist/component/public/factors/devices.js.map +1 -1
  25. package/dist/component/public/factors/passkeys.d.ts.map +1 -1
  26. package/dist/component/public/factors/passkeys.js.map +1 -1
  27. package/dist/component/public/factors/totp.d.ts.map +1 -1
  28. package/dist/component/public/factors/totp.js.map +1 -1
  29. package/dist/component/public/groups/core.js.map +1 -1
  30. package/dist/component/public/groups/invites.d.ts.map +1 -1
  31. package/dist/component/public/groups/invites.js.map +1 -1
  32. package/dist/component/public/groups/members.d.ts.map +1 -1
  33. package/dist/component/public/groups/members.js.map +1 -1
  34. package/dist/component/public/identity/accounts.d.ts.map +1 -1
  35. package/dist/component/public/identity/accounts.js.map +1 -1
  36. package/dist/component/public/identity/codes.d.ts.map +1 -1
  37. package/dist/component/public/identity/codes.js.map +1 -1
  38. package/dist/component/public/identity/sessions.d.ts.map +1 -1
  39. package/dist/component/public/identity/sessions.js.map +1 -1
  40. package/dist/component/public/identity/tokens.d.ts.map +1 -1
  41. package/dist/component/public/identity/tokens.js.map +1 -1
  42. package/dist/component/public/identity/users.d.ts.map +1 -1
  43. package/dist/component/public/identity/users.js.map +1 -1
  44. package/dist/component/public/identity/verifiers.d.ts.map +1 -1
  45. package/dist/component/public/identity/verifiers.js.map +1 -1
  46. package/dist/component/public/security/keys.d.ts.map +1 -1
  47. package/dist/component/public/security/keys.js.map +1 -1
  48. package/dist/component/public/security/limits.d.ts.map +1 -1
  49. package/dist/component/public/security/limits.js.map +1 -1
  50. package/dist/component/schema.d.ts +42 -42
  51. package/dist/component/server/auth.d.ts +37 -40
  52. package/dist/component/server/auth.d.ts.map +1 -1
  53. package/dist/component/server/auth.js +57 -23
  54. package/dist/component/server/auth.js.map +1 -1
  55. package/dist/component/server/core.js +116 -235
  56. package/dist/component/server/core.js.map +1 -1
  57. package/dist/component/server/crypto.js +25 -7
  58. package/dist/component/server/crypto.js.map +1 -1
  59. package/dist/component/server/device.js +58 -15
  60. package/dist/component/server/device.js.map +1 -1
  61. package/dist/component/server/enterprise/domain.js +148 -59
  62. package/dist/component/server/enterprise/domain.js.map +1 -1
  63. package/dist/component/server/enterprise/http.js +36 -15
  64. package/dist/component/server/enterprise/http.js.map +1 -1
  65. package/dist/component/server/enterprise/oidc.js +1 -1
  66. package/dist/component/server/http.js +26 -21
  67. package/dist/component/server/http.js.map +1 -1
  68. package/dist/component/server/identity.js +5 -2
  69. package/dist/component/server/identity.js.map +1 -1
  70. package/dist/component/server/limits.js +21 -30
  71. package/dist/component/server/limits.js.map +1 -1
  72. package/dist/component/server/mutations/account.js +12 -10
  73. package/dist/component/server/mutations/account.js.map +1 -1
  74. package/dist/component/server/mutations/code.js +5 -2
  75. package/dist/component/server/mutations/code.js.map +1 -1
  76. package/dist/component/server/mutations/invalidate.js +1 -1
  77. package/dist/component/server/mutations/invalidate.js.map +1 -1
  78. package/dist/component/server/mutations/oauth.js +10 -4
  79. package/dist/component/server/mutations/oauth.js.map +1 -1
  80. package/dist/component/server/mutations/refresh.js +2 -2
  81. package/dist/component/server/mutations/refresh.js.map +1 -1
  82. package/dist/component/server/mutations/register.js +46 -42
  83. package/dist/component/server/mutations/register.js.map +1 -1
  84. package/dist/component/server/mutations/retrieve.js +21 -25
  85. package/dist/component/server/mutations/retrieve.js.map +1 -1
  86. package/dist/component/server/mutations/signature.js +10 -4
  87. package/dist/component/server/mutations/signature.js.map +1 -1
  88. package/dist/component/server/mutations/signout.js.map +1 -1
  89. package/dist/component/server/mutations/store.js +9 -24
  90. package/dist/component/server/mutations/store.js.map +1 -1
  91. package/dist/component/server/mutations/verifier.js.map +1 -1
  92. package/dist/component/server/mutations/verify.js +1 -1
  93. package/dist/component/server/mutations/verify.js.map +1 -1
  94. package/dist/component/server/oauth.js +53 -16
  95. package/dist/component/server/oauth.js.map +1 -1
  96. package/dist/component/server/passkey.js +115 -31
  97. package/dist/component/server/passkey.js.map +1 -1
  98. package/dist/component/server/redirects.js +9 -3
  99. package/dist/component/server/redirects.js.map +1 -1
  100. package/dist/component/server/refresh.js +10 -7
  101. package/dist/component/server/refresh.js.map +1 -1
  102. package/dist/component/server/runtime.d.ts +1 -1
  103. package/dist/component/server/runtime.d.ts.map +1 -1
  104. package/dist/component/server/runtime.js +62 -20
  105. package/dist/component/server/runtime.js.map +1 -1
  106. package/dist/component/server/signin.js +34 -10
  107. package/dist/component/server/signin.js.map +1 -1
  108. package/dist/component/server/totp.js +79 -19
  109. package/dist/component/server/totp.js.map +1 -1
  110. package/dist/component/server/types.d.ts +12 -20
  111. package/dist/component/server/types.d.ts.map +1 -1
  112. package/dist/component/server/types.js.map +1 -1
  113. package/dist/component/server/users.js +6 -3
  114. package/dist/component/server/users.js.map +1 -1
  115. package/dist/component/server/utils.js +10 -4
  116. package/dist/component/server/utils.js.map +1 -1
  117. package/dist/core/types.d.ts +14 -22
  118. package/dist/core/types.d.ts.map +1 -1
  119. package/dist/factors/device.js +8 -9
  120. package/dist/factors/device.js.map +1 -1
  121. package/dist/factors/passkey.js +18 -21
  122. package/dist/factors/passkey.js.map +1 -1
  123. package/dist/providers/password.js +66 -81
  124. package/dist/providers/password.js.map +1 -1
  125. package/dist/runtime/invite.js +2 -8
  126. package/dist/runtime/invite.js.map +1 -1
  127. package/dist/server/auth.d.ts +37 -40
  128. package/dist/server/auth.d.ts.map +1 -1
  129. package/dist/server/auth.js +57 -23
  130. package/dist/server/auth.js.map +1 -1
  131. package/dist/server/core.d.ts +71 -159
  132. package/dist/server/core.d.ts.map +1 -1
  133. package/dist/server/core.js +116 -235
  134. package/dist/server/core.js.map +1 -1
  135. package/dist/server/crypto.d.ts.map +1 -1
  136. package/dist/server/crypto.js +25 -7
  137. package/dist/server/crypto.js.map +1 -1
  138. package/dist/server/device.js +58 -15
  139. package/dist/server/device.js.map +1 -1
  140. package/dist/server/enterprise/domain.d.ts +0 -8
  141. package/dist/server/enterprise/domain.d.ts.map +1 -1
  142. package/dist/server/enterprise/domain.js +148 -59
  143. package/dist/server/enterprise/domain.js.map +1 -1
  144. package/dist/server/enterprise/http.d.ts.map +1 -1
  145. package/dist/server/enterprise/http.js +35 -14
  146. package/dist/server/enterprise/http.js.map +1 -1
  147. package/dist/server/http.d.ts +2 -2
  148. package/dist/server/http.d.ts.map +1 -1
  149. package/dist/server/http.js +25 -20
  150. package/dist/server/http.js.map +1 -1
  151. package/dist/server/identity.js +5 -2
  152. package/dist/server/identity.js.map +1 -1
  153. package/dist/server/index.d.ts +2 -2
  154. package/dist/server/limits.js +21 -30
  155. package/dist/server/limits.js.map +1 -1
  156. package/dist/server/mounts.d.ts +24 -62
  157. package/dist/server/mounts.d.ts.map +1 -1
  158. package/dist/server/mounts.js +45 -106
  159. package/dist/server/mounts.js.map +1 -1
  160. package/dist/server/mutations/account.d.ts +8 -9
  161. package/dist/server/mutations/account.d.ts.map +1 -1
  162. package/dist/server/mutations/account.js +11 -9
  163. package/dist/server/mutations/account.js.map +1 -1
  164. package/dist/server/mutations/code.d.ts +12 -12
  165. package/dist/server/mutations/code.d.ts.map +1 -1
  166. package/dist/server/mutations/code.js +5 -2
  167. package/dist/server/mutations/code.js.map +1 -1
  168. package/dist/server/mutations/invalidate.d.ts +4 -4
  169. package/dist/server/mutations/invalidate.d.ts.map +1 -1
  170. package/dist/server/mutations/invalidate.js.map +1 -1
  171. package/dist/server/mutations/oauth.d.ts +14 -12
  172. package/dist/server/mutations/oauth.d.ts.map +1 -1
  173. package/dist/server/mutations/oauth.js +9 -3
  174. package/dist/server/mutations/oauth.js.map +1 -1
  175. package/dist/server/mutations/refresh.d.ts +3 -3
  176. package/dist/server/mutations/refresh.d.ts.map +1 -1
  177. package/dist/server/mutations/refresh.js +1 -1
  178. package/dist/server/mutations/refresh.js.map +1 -1
  179. package/dist/server/mutations/register.d.ts +11 -11
  180. package/dist/server/mutations/register.d.ts.map +1 -1
  181. package/dist/server/mutations/register.js +45 -41
  182. package/dist/server/mutations/register.js.map +1 -1
  183. package/dist/server/mutations/retrieve.d.ts +6 -6
  184. package/dist/server/mutations/retrieve.d.ts.map +1 -1
  185. package/dist/server/mutations/retrieve.js +20 -24
  186. package/dist/server/mutations/retrieve.js.map +1 -1
  187. package/dist/server/mutations/signature.d.ts +6 -7
  188. package/dist/server/mutations/signature.d.ts.map +1 -1
  189. package/dist/server/mutations/signature.js +9 -3
  190. package/dist/server/mutations/signature.js.map +1 -1
  191. package/dist/server/mutations/signin.d.ts +5 -5
  192. package/dist/server/mutations/signin.d.ts.map +1 -1
  193. package/dist/server/mutations/signout.js.map +1 -1
  194. package/dist/server/mutations/store.d.ts +83 -83
  195. package/dist/server/mutations/store.js +8 -23
  196. package/dist/server/mutations/store.js.map +1 -1
  197. package/dist/server/mutations/verifier.js.map +1 -1
  198. package/dist/server/mutations/verify.d.ts +7 -7
  199. package/dist/server/mutations/verify.d.ts.map +1 -1
  200. package/dist/server/mutations/verify.js.map +1 -1
  201. package/dist/server/oauth.js +53 -16
  202. package/dist/server/oauth.js.map +1 -1
  203. package/dist/server/passkey.d.ts +2 -2
  204. package/dist/server/passkey.d.ts.map +1 -1
  205. package/dist/server/passkey.js +114 -30
  206. package/dist/server/passkey.js.map +1 -1
  207. package/dist/server/redirects.js +9 -3
  208. package/dist/server/redirects.js.map +1 -1
  209. package/dist/server/refresh.js +10 -7
  210. package/dist/server/refresh.js.map +1 -1
  211. package/dist/server/runtime.d.ts +7 -7
  212. package/dist/server/runtime.d.ts.map +1 -1
  213. package/dist/server/runtime.js +61 -19
  214. package/dist/server/runtime.js.map +1 -1
  215. package/dist/server/signin.js +34 -10
  216. package/dist/server/signin.js.map +1 -1
  217. package/dist/server/ssr.d.ts.map +1 -1
  218. package/dist/server/ssr.js +175 -184
  219. package/dist/server/ssr.js.map +1 -1
  220. package/dist/server/totp.js +78 -18
  221. package/dist/server/totp.js.map +1 -1
  222. package/dist/server/types.d.ts +13 -21
  223. package/dist/server/types.d.ts.map +1 -1
  224. package/dist/server/types.js.map +1 -1
  225. package/dist/server/users.js +6 -3
  226. package/dist/server/users.js.map +1 -1
  227. package/dist/server/utils.js +10 -4
  228. package/dist/server/utils.js.map +1 -1
  229. package/package.json +1 -5
  230. package/src/authorization/index.ts +1 -1
  231. package/src/client/core/types.ts +14 -14
  232. package/src/client/factors/device.ts +10 -12
  233. package/src/client/factors/passkey.ts +23 -26
  234. package/src/client/index.ts +54 -64
  235. package/src/client/runtime/invite.ts +5 -7
  236. package/src/component/index.ts +1 -1
  237. package/src/component/public/enterprise/audit.ts +6 -1
  238. package/src/component/public/enterprise/core.ts +1 -0
  239. package/src/component/public/enterprise/domains.ts +5 -1
  240. package/src/component/public/enterprise/scim.ts +1 -0
  241. package/src/component/public/enterprise/secrets.ts +1 -0
  242. package/src/component/public/enterprise/webhooks.ts +1 -0
  243. package/src/component/public/factors/devices.ts +1 -0
  244. package/src/component/public/factors/passkeys.ts +1 -0
  245. package/src/component/public/factors/totp.ts +1 -0
  246. package/src/component/public/groups/core.ts +1 -1
  247. package/src/component/public/groups/invites.ts +7 -1
  248. package/src/component/public/groups/members.ts +1 -0
  249. package/src/component/public/identity/accounts.ts +1 -0
  250. package/src/component/public/identity/codes.ts +1 -0
  251. package/src/component/public/identity/sessions.ts +1 -0
  252. package/src/component/public/identity/tokens.ts +1 -0
  253. package/src/component/public/identity/users.ts +1 -0
  254. package/src/component/public/identity/verifiers.ts +1 -0
  255. package/src/component/public/security/keys.ts +1 -0
  256. package/src/component/public/security/limits.ts +1 -0
  257. package/src/providers/password.ts +89 -110
  258. package/src/server/auth.ts +92 -70
  259. package/src/server/core.ts +197 -233
  260. package/src/server/crypto.ts +31 -29
  261. package/src/server/device.ts +65 -32
  262. package/src/server/enterprise/domain.ts +158 -170
  263. package/src/server/enterprise/http.ts +46 -39
  264. package/src/server/http.ts +36 -30
  265. package/src/server/identity.ts +5 -5
  266. package/src/server/index.ts +1 -1
  267. package/src/server/limits.ts +53 -80
  268. package/src/server/mounts.ts +47 -74
  269. package/src/server/mutations/account.ts +22 -36
  270. package/src/server/mutations/code.ts +6 -6
  271. package/src/server/mutations/invalidate.ts +1 -1
  272. package/src/server/mutations/oauth.ts +14 -8
  273. package/src/server/mutations/refresh.ts +5 -4
  274. package/src/server/mutations/register.ts +87 -132
  275. package/src/server/mutations/retrieve.ts +44 -44
  276. package/src/server/mutations/signature.ts +13 -6
  277. package/src/server/mutations/signout.ts +1 -1
  278. package/src/server/mutations/store.ts +16 -31
  279. package/src/server/mutations/verifier.ts +1 -1
  280. package/src/server/mutations/verify.ts +3 -5
  281. package/src/server/oauth.ts +60 -69
  282. package/src/server/passkey.ts +567 -517
  283. package/src/server/redirects.ts +10 -6
  284. package/src/server/refresh.ts +14 -18
  285. package/src/server/runtime.ts +70 -55
  286. package/src/server/signin.ts +44 -37
  287. package/src/server/ssr.ts +390 -407
  288. package/src/server/totp.ts +85 -35
  289. package/src/server/types.ts +19 -22
  290. package/src/server/users.ts +7 -6
  291. package/src/server/utils.ts +10 -12
  292. package/dist/component/server/authError.js +0 -34
  293. package/dist/component/server/authError.js.map +0 -1
  294. package/dist/component/server/errors.d.ts +0 -1
  295. package/dist/component/server/errors.js +0 -137
  296. package/dist/component/server/errors.js.map +0 -1
  297. package/dist/server/authError.d.ts +0 -46
  298. package/dist/server/authError.d.ts.map +0 -1
  299. package/dist/server/authError.js +0 -34
  300. package/dist/server/authError.js.map +0 -1
  301. package/dist/server/errors.d.ts +0 -177
  302. package/dist/server/errors.d.ts.map +0 -1
  303. package/dist/server/errors.js +0 -212
  304. package/dist/server/errors.js.map +0 -1
  305. package/src/server/authError.ts +0 -44
  306. package/src/server/errors.ts +0 -290
@@ -4,12 +4,12 @@
4
4
  * @module
5
5
  */
6
6
 
7
+ import { Cv } from "@robelest/fx/convex";
7
8
  import type { UserIdentity } from "convex/server";
8
9
  import type { GenericId } from "convex/values";
9
10
 
10
11
  import type { AuthApiRefs } from "../client/index";
11
12
  import { Auth as AuthFactory } from "./runtime";
12
- import { AuthError } from "./authError";
13
13
  import type { Doc } from "./types";
14
14
  import type {
15
15
  AuthAuthorizationConfig,
@@ -41,7 +41,7 @@ type MemberApiWithAuthorization<
41
41
  TAuthorization extends AuthAuthorizationConfig | undefined,
42
42
  > = Omit<
43
43
  ReturnType<typeof AuthFactory>["auth"]["member"],
44
- "create" | "list" | "update" | "resolve"
44
+ "create" | "list" | "update" | "inspect" | "require"
45
45
  > & {
46
46
  create: (
47
47
  ctx: Parameters<
@@ -54,7 +54,7 @@ type MemberApiWithAuthorization<
54
54
  status?: string;
55
55
  extend?: Record<string, unknown>;
56
56
  },
57
- ) => Promise<{ ok: true; memberId: string }>;
57
+ ) => Promise<{ memberId: string }>;
58
58
  list: (
59
59
  ctx: Parameters<
60
60
  ReturnType<typeof AuthFactory>["auth"]["member"]["list"]
@@ -78,10 +78,21 @@ type MemberApiWithAuthorization<
78
78
  >[0],
79
79
  memberId: string,
80
80
  data: Record<string, unknown> & { roleIds?: AuthRoleId<TAuthorization>[] },
81
- ) => Promise<{ ok: true; memberId: string }>;
82
- resolve: (
81
+ ) => Promise<{ memberId: string }>;
82
+ inspect: (
83
83
  ctx: Parameters<
84
- ReturnType<typeof AuthFactory>["auth"]["member"]["resolve"]
84
+ ReturnType<typeof AuthFactory>["auth"]["member"]["inspect"]
85
+ >[0],
86
+ opts: {
87
+ userId: string;
88
+ groupId: string;
89
+ ancestry?: boolean;
90
+ maxDepth?: number;
91
+ },
92
+ ) => ReturnType<ReturnType<typeof AuthFactory>["auth"]["member"]["inspect"]>;
93
+ require: (
94
+ ctx: Parameters<
95
+ ReturnType<typeof AuthFactory>["auth"]["member"]["require"]
85
96
  >[0],
86
97
  opts: {
87
98
  userId: string;
@@ -91,10 +102,9 @@ type MemberApiWithAuthorization<
91
102
  grants?: AuthGrant<TAuthorization>[];
92
103
  maxDepth?: number;
93
104
  },
94
- ) => ReturnType<ReturnType<typeof AuthFactory>["auth"]["member"]["resolve"]>;
105
+ ) => ReturnType<ReturnType<typeof AuthFactory>["auth"]["member"]["require"]>;
95
106
  };
96
107
 
97
-
98
108
  /**
99
109
  * The base auth API surface returned by {@link createAuth}.
100
110
  *
@@ -126,30 +136,29 @@ export type AuthApiBase<
126
136
  key: ReturnType<typeof AuthFactory>["auth"]["key"];
127
137
  http: ReturnType<typeof AuthFactory>["auth"]["http"];
128
138
  /**
129
- * Resolve the current user's auth context. Framework-agnostic — use
139
+ * Resolve the current request's auth context. Framework-agnostic — use
130
140
  * this in fluent-convex middleware, custom wrappers, or anywhere you
131
- * need the resolved `{ userId, user, groupId, role, grants }` object.
141
+ * need the current `{ userId, user, groupId, role, grants }` object.
132
142
  *
133
- * Returns `null` when unauthenticated. Does not throw.
143
+ * Throws a structured `ConvexError` when unauthenticated.
134
144
  *
135
145
  * @param ctx - Convex query, mutation, or action context.
136
- * @returns The resolved auth context, or `null`.
146
+ * @returns The current auth context.
137
147
  *
138
148
  * @example fluent-convex middleware
139
149
  * ```ts
140
150
  * const withAuth = convex.createMiddleware(async (ctx, next) => {
141
- * return next({ ...ctx, auth: await auth.resolve(ctx) });
151
+ * return next({ ...ctx, auth: await auth.context(ctx) });
142
152
  * });
143
153
  * ```
144
154
  *
145
155
  * @example Direct usage in a handler
146
156
  * ```ts
147
- * const resolved = await auth.resolve(ctx);
148
- * if (!resolved) return { ok: false, code: "NOT_SIGNED_IN" };
149
- * const { userId, grants } = resolved;
157
+ * const authContext = await auth.context(ctx);
158
+ * const { userId, grants } = authContext;
150
159
  * ```
151
160
  */
152
- resolve: (ctx: any) => Promise<AuthResolvedContext | null>;
161
+ context: (ctx: any) => Promise<AuthContext>;
153
162
  /**
154
163
  * Context enrichment for convex-helpers `customQuery` / `customMutation` /
155
164
  * `customAction`.
@@ -158,9 +167,9 @@ export type AuthApiBase<
158
167
  * and grants, then attaches them to `ctx.auth`. Returns a `Customization`
159
168
  * object compatible with convex-helpers' custom function builders.
160
169
  *
161
- * `ctx.auth` is `{ userId, user, groupId, role, grants }` when
162
- * authenticated, `null` when unauthenticated. No throwing your
163
- * handler decides how to respond.
170
+ * `ctx.auth` is the current request auth context.
171
+ * By default this throws when unauthenticated so handlers can assume
172
+ * `ctx.auth.userId` and `ctx.auth.user` exist.
164
173
  *
165
174
  * @returns A convex-helpers `Customization` object.
166
175
  *
@@ -182,7 +191,6 @@ export type AuthApiBase<
182
191
  * export const list = authQuery({
183
192
  * args: { workspaceId: v.string() },
184
193
  * handler: async (ctx, args) => {
185
- * if (!ctx.auth) return [];
186
194
  * const { userId, groupId, grants } = ctx.auth;
187
195
  * // business logic
188
196
  * },
@@ -192,26 +200,27 @@ export type AuthApiBase<
192
200
  ctx: () => {
193
201
  args: Record<string, never>;
194
202
  input: (ctx: any) => Promise<{
195
- ctx: { auth: AuthResolvedContext | null };
203
+ ctx: { auth: AuthContext };
196
204
  args: Record<string, never>;
197
205
  }>;
198
206
  };
199
207
  };
200
208
 
201
209
  /**
202
- * Resolved auth context injected into `ctx.auth` by `auth.ctx()` and
203
- * {@link AuthCtx}. Also the expected return shape for custom
204
- * {@link AuthCtxConfig.authResolve | authResolve} hooks.
210
+ * Current request auth context injected into `ctx.auth` by `auth.ctx()` and
211
+ * {@link AuthCtx}. This is the authenticated auth shape returned by
212
+ * {@link createAuth().context}. Optional context builders may still surface
213
+ * nullable fields when `optional: true` is used.
205
214
  *
206
- * - `null` when unauthenticated.
207
215
  * - `groupId` is `null` when the user has no active group set.
208
- * - `role` / `grants` are `null` / `[]` when no active group or no membership.
216
+ * - `role` is `null` when no active group or no membership is resolved.
217
+ * - `grants` is `[]` when no active group or no membership is resolved.
209
218
  *
210
219
  * @example
211
220
  * ```ts
212
- * import type { AuthResolvedContext } from "@robelest/convex-auth/server";
221
+ * import type { AuthContext } from "@robelest/convex-auth/server";
213
222
  *
214
- * const mockAuth: AuthResolvedContext = {
223
+ * const mockAuth: AuthContext = {
215
224
  * userId: "user123" as Id<"User">,
216
225
  * user: { _id: "user123", email: "test@example.com" },
217
226
  * groupId: "group456",
@@ -220,7 +229,7 @@ export type AuthApiBase<
220
229
  * };
221
230
  * ```
222
231
  */
223
- export type AuthResolvedContext = {
232
+ export type AuthContext = {
224
233
  /** The authenticated user's document ID. */
225
234
  userId: GenericId<"User">;
226
235
  /** The authenticated user's full document. */
@@ -237,7 +246,7 @@ type AuthCtxBase = {
237
246
  getUserIdentity: () => Promise<UserIdentity | null>;
238
247
  };
239
248
 
240
- type RequiredAuthCtxState = AuthCtxBase & AuthResolvedContext;
249
+ type RequiredAuthCtxState = AuthCtxBase & AuthContext;
241
250
 
242
251
  type OptionalAuthCtxState = AuthCtxBase & {
243
252
  userId: GenericId<"User"> | null;
@@ -262,7 +271,6 @@ type PublicSsoAdminApi = {
262
271
  isPrimary?: boolean;
263
272
  }>,
264
273
  ) => Promise<{
265
- ok: true;
266
274
  enterpriseId: string;
267
275
  domains: Array<{
268
276
  domainId: string;
@@ -277,7 +285,6 @@ type PublicSsoAdminApi = {
277
285
  ctx: Parameters<InternalSsoApi["connection"]["create"]>[0],
278
286
  args: { enterpriseId: string; domain: string },
279
287
  ) => Promise<{
280
- ok: true;
281
288
  enterpriseId: string;
282
289
  domain: string;
283
290
  requestedAt: number;
@@ -292,7 +299,6 @@ type PublicSsoAdminApi = {
292
299
  ctx: Parameters<InternalSsoApi["connection"]["create"]>[0],
293
300
  args: { enterpriseId: string; domain: string },
294
301
  ) => Promise<{
295
- ok: boolean;
296
302
  enterpriseId: string;
297
303
  domain: string;
298
304
  verifiedAt?: number;
@@ -446,9 +452,12 @@ export type AuthLike = Pick<AuthApiBase, "user" | "member">;
446
452
  * 1. `user.id(ctx)` → userId or null (exit early)
447
453
  * 2. `user.get(ctx, userId)` → user doc (cached per-execution)
448
454
  * 3. `user.getActiveGroup(ctx, { userId })` → groupId or null
449
- * 4. If groupId → `member.resolve(ctx, { userId, groupId })` → role + grants
455
+ * 4. If groupId → `member.inspect(ctx, { userId, groupId })` → role + grants
450
456
  */
451
- async function resolveAuthContext(auth: AuthLike, ctx: any) {
457
+ async function getAuthContext(
458
+ auth: AuthLike,
459
+ ctx: any,
460
+ ): Promise<AuthContext | null> {
452
461
  const userId = await auth.user.id(ctx);
453
462
  if (!userId) return null;
454
463
  const user = await auth.user.get(ctx, userId);
@@ -456,7 +465,7 @@ async function resolveAuthContext(auth: AuthLike, ctx: any) {
456
465
  let role: string | null = null;
457
466
  let grants: string[] = [];
458
467
  if (groupId) {
459
- const resolved = await auth.member.resolve(ctx, { userId, groupId });
468
+ const resolved = await auth.member.inspect(ctx, { userId, groupId });
460
469
  if (resolved.membership) {
461
470
  role = resolved.roleIds[0] ?? null;
462
471
  grants = resolved.grants;
@@ -504,10 +513,10 @@ export function createAuth<
504
513
  ) => {
505
514
  const enterprise = await connectionApi.get(ctx, enterpriseId);
506
515
  if (enterprise === null) {
507
- throw new AuthError(
508
- "INVALID_PARAMETERS",
509
- "Enterprise not found.",
510
- ).toConvexError();
516
+ throw Cv.error({
517
+ code: "INVALID_PARAMETERS",
518
+ message: "Enterprise not found.",
519
+ });
511
520
  }
512
521
 
513
522
  const normalized = domains.map((entry: (typeof domains)[number]) => ({
@@ -517,16 +526,16 @@ export function createAuth<
517
526
  const deduped = new Map<string, (typeof normalized)[number]>();
518
527
  for (const entry of normalized) {
519
528
  if (entry.domain.length === 0) {
520
- throw new AuthError(
521
- "INVALID_PARAMETERS",
522
- "Domain must not be empty.",
523
- ).toConvexError();
529
+ throw Cv.error({
530
+ code: "INVALID_PARAMETERS",
531
+ message: "Domain must not be empty.",
532
+ });
524
533
  }
525
534
  if (deduped.has(entry.domain)) {
526
- throw new AuthError(
527
- "INVALID_PARAMETERS",
528
- `Duplicate domain: ${entry.domain}`,
529
- ).toConvexError();
535
+ throw Cv.error({
536
+ code: "INVALID_PARAMETERS",
537
+ message: `Duplicate domain: ${entry.domain}`,
538
+ });
530
539
  }
531
540
  deduped.set(entry.domain, entry);
532
541
  }
@@ -536,10 +545,10 @@ export function createAuth<
536
545
  (entry) => entry.isPrimary,
537
546
  ).length;
538
547
  if (primaryCount > 1) {
539
- throw new AuthError(
540
- "INVALID_PARAMETERS",
541
- "Only one primary domain may be set.",
542
- ).toConvexError();
548
+ throw Cv.error({
549
+ code: "INVALID_PARAMETERS",
550
+ message: "Only one primary domain may be set.",
551
+ });
543
552
  }
544
553
  if (nextDomains.length > 0 && primaryCount === 0) {
545
554
  nextDomains[0] = { ...nextDomains[0], isPrimary: true };
@@ -586,7 +595,6 @@ export function createAuth<
586
595
 
587
596
  const updatedDomains = await domainApi.list(ctx, enterpriseId);
588
597
  return {
589
- ok: true as const,
590
598
  enterpriseId,
591
599
  domains: updatedDomains.map(
592
600
  (domain: (typeof updatedDomains)[number]) => ({
@@ -660,12 +668,27 @@ export function createAuth<
660
668
  },
661
669
  http: authResult.auth.http,
662
670
 
663
- resolve: (ctx: any) => resolveAuthContext(authResult.auth, ctx),
671
+ context: async (ctx: any) => {
672
+ const authContext = await getAuthContext(authResult.auth, ctx);
673
+ if (authContext === null) {
674
+ throw Cv.error({
675
+ code: "NOT_SIGNED_IN",
676
+ message: "Authentication required.",
677
+ });
678
+ }
679
+ return authContext;
680
+ },
664
681
 
665
682
  ctx: () => ({
666
683
  args: {},
667
684
  input: async (ctx: any) => {
668
- const authCtx = await resolveAuthContext(authResult.auth, ctx);
685
+ const authCtx = await getAuthContext(authResult.auth, ctx);
686
+ if (authCtx === null) {
687
+ throw Cv.error({
688
+ code: "NOT_SIGNED_IN",
689
+ message: "Authentication required.",
690
+ });
691
+ }
669
692
  return { ctx: { auth: authCtx }, args: {} };
670
693
  },
671
694
  }),
@@ -694,14 +717,14 @@ export type AuthCtxConfig<
694
717
  resolve?: (
695
718
  ctx: any,
696
719
  user: UserDoc,
697
- auth: AuthResolvedContext,
720
+ auth: AuthContext,
698
721
  ) => Promise<TResolve> | TResolve;
699
722
  /**
700
723
  * Override or wrap the base auth resolution used by {@link AuthCtx}.
701
724
  *
702
725
  * Return `undefined` to fall back to the built-in resolver,
703
726
  * `null` for an explicit unauthenticated state, or an
704
- * {@link AuthResolvedContext} object to provide a pre-resolved auth state.
727
+ * {@link AuthContext} object to provide a pre-resolved auth state.
705
728
  * This is useful for tests, proxy auth, impersonation flows, or any
706
729
  * environment that needs to inject auth without depending on the standard
707
730
  * Convex auth tables.
@@ -722,12 +745,8 @@ export type AuthCtxConfig<
722
745
  */
723
746
  authResolve?: (
724
747
  ctx: any,
725
- fallback: () => Promise<AuthResolvedContext | null>,
726
- ) =>
727
- | Promise<AuthResolvedContext | null | undefined>
728
- | AuthResolvedContext
729
- | null
730
- | undefined;
748
+ fallback: () => Promise<AuthContext | null>,
749
+ ) => Promise<AuthContext | null | undefined> | AuthContext | null | undefined;
731
750
  };
732
751
 
733
752
  /**
@@ -774,11 +793,8 @@ export function AuthCtx<
774
793
  /**
775
794
  * Create a context enrichment for `customQuery` / `customMutation` — required auth (default).
776
795
  *
777
- * When `optional` is omitted or `false`, the inferred type is the authenticated
778
- * auth shape. At runtime this helper still resolves instead of throwing, so if
779
- * no user is signed in the returned `ctx.auth.userId` / `ctx.auth.user` are
780
- * `null`, `ctx.auth.groupId` / `ctx.auth.role` are `null`, and
781
- * `ctx.auth.grants` is `[]`.
796
+ * When `optional` is omitted or `false`, unauthenticated requests throw a
797
+ * structured `ConvexError` before your handler runs.
782
798
  *
783
799
  * @param auth - The auth API object returned by {@link createAuth}.
784
800
  * @param config - Optional configuration with a `resolve` callback
@@ -820,7 +836,7 @@ export function AuthCtx(auth: AuthLike, config?: AuthCtxConfig<any>) {
820
836
  input: async (ctx: any, _args: any, _extra?: any) => {
821
837
  const nativeAuth = ctx.auth;
822
838
  const getUserIdentity = nativeAuth.getUserIdentity.bind(nativeAuth);
823
- const fallback = () => resolveAuthContext(auth, ctx);
839
+ const fallback = () => getAuthContext(auth, ctx);
824
840
 
825
841
  const authOverride = config?.authResolve
826
842
  ? await config.authResolve(ctx, fallback)
@@ -829,6 +845,12 @@ export function AuthCtx(auth: AuthLike, config?: AuthCtxConfig<any>) {
829
845
  authOverride === undefined ? await fallback() : authOverride;
830
846
 
831
847
  if (resolved === null) {
848
+ if (config?.optional !== true) {
849
+ throw Cv.error({
850
+ code: "NOT_SIGNED_IN",
851
+ message: "Authentication required.",
852
+ });
853
+ }
832
854
  return {
833
855
  ctx: {
834
856
  auth: {