@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
@@ -12,7 +12,7 @@ import { GenericId } from "convex/values";
12
12
  type AuthConfig = Omit<ConvexAuthConfig, "component">;
13
13
  /** Canonical user document type exposed by Convex Auth. */
14
14
  type UserDoc = Doc<"User">;
15
- type MemberApiWithAuthorization<TAuthorization extends AuthAuthorizationConfig | undefined> = Omit<ReturnType<typeof Auth>["auth"]["member"], "create" | "list" | "update" | "resolve"> & {
15
+ type MemberApiWithAuthorization<TAuthorization extends AuthAuthorizationConfig | undefined> = Omit<ReturnType<typeof Auth>["auth"]["member"], "create" | "list" | "update" | "inspect" | "require"> & {
16
16
  create: (ctx: Parameters<ReturnType<typeof Auth>["auth"]["member"]["create"]>[0], data: {
17
17
  groupId: string;
18
18
  userId: string;
@@ -20,7 +20,6 @@ type MemberApiWithAuthorization<TAuthorization extends AuthAuthorizationConfig |
20
20
  status?: string;
21
21
  extend?: Record<string, unknown>;
22
22
  }) => Promise<{
23
- ok: true;
24
23
  memberId: string;
25
24
  }>;
26
25
  list: (ctx: Parameters<ReturnType<typeof Auth>["auth"]["member"]["list"]>[0], opts?: {
@@ -38,17 +37,22 @@ type MemberApiWithAuthorization<TAuthorization extends AuthAuthorizationConfig |
38
37
  update: (ctx: Parameters<ReturnType<typeof Auth>["auth"]["member"]["update"]>[0], memberId: string, data: Record<string, unknown> & {
39
38
  roleIds?: AuthRoleId<TAuthorization>[];
40
39
  }) => Promise<{
41
- ok: true;
42
40
  memberId: string;
43
41
  }>;
44
- resolve: (ctx: Parameters<ReturnType<typeof Auth>["auth"]["member"]["resolve"]>[0], opts: {
42
+ inspect: (ctx: Parameters<ReturnType<typeof Auth>["auth"]["member"]["inspect"]>[0], opts: {
43
+ userId: string;
44
+ groupId: string;
45
+ ancestry?: boolean;
46
+ maxDepth?: number;
47
+ }) => ReturnType<ReturnType<typeof Auth>["auth"]["member"]["inspect"]>;
48
+ require: (ctx: Parameters<ReturnType<typeof Auth>["auth"]["member"]["require"]>[0], opts: {
45
49
  userId: string;
46
50
  groupId: string;
47
51
  ancestry?: boolean;
48
52
  roleIds?: AuthRoleId<TAuthorization>[];
49
53
  grants?: AuthGrant<TAuthorization>[];
50
54
  maxDepth?: number;
51
- }) => ReturnType<ReturnType<typeof Auth>["auth"]["member"]["resolve"]>;
55
+ }) => ReturnType<ReturnType<typeof Auth>["auth"]["member"]["require"]>;
52
56
  };
53
57
  /**
54
58
  * The base auth API surface returned by {@link createAuth}.
@@ -79,30 +83,40 @@ type AuthApiBase<TAuthorization extends AuthAuthorizationConfig | undefined = un
79
83
  key: ReturnType<typeof Auth>["auth"]["key"];
80
84
  http: ReturnType<typeof Auth>["auth"]["http"];
81
85
  /**
82
- * Resolve the current user's auth context. Framework-agnostic — use
86
+ * Resolve the current request's auth context. Framework-agnostic — use
83
87
  * this in fluent-convex middleware, custom wrappers, or anywhere you
84
- * need the resolved `{ userId, user, groupId, role, grants }` object.
88
+ * need the current `{ userId, user, groupId, role, grants }` object.
85
89
  *
86
- * Returns `null` when unauthenticated. Does not throw.
90
+ * Throws a structured `ConvexError` when unauthenticated by default.
91
+ * Pass `{ optional: true }` to get a null-shaped auth object instead.
87
92
  *
88
93
  * @param ctx - Convex query, mutation, or action context.
89
- * @returns The resolved auth context, or `null`.
94
+ * @param config - Optional auth resolution config. Supports `optional`,
95
+ * `resolve`, and `authResolve`.
96
+ * @returns The current auth context.
90
97
  *
91
98
  * @example fluent-convex middleware
92
99
  * ```ts
93
100
  * const withAuth = convex.createMiddleware(async (ctx, next) => {
94
- * return next({ ...ctx, auth: await auth.resolve(ctx) });
101
+ * return next({ ...ctx, auth: await auth.context(ctx) });
95
102
  * });
96
103
  * ```
97
104
  *
98
105
  * @example Direct usage in a handler
99
- * ```ts
100
- * const resolved = await auth.resolve(ctx);
101
- * if (!resolved) return { ok: false, code: "NOT_SIGNED_IN" };
102
- * const { userId, grants } = resolved;
103
- * ```
104
- */
105
- resolve: (ctx: any) => Promise<AuthResolvedContext | null>;
106
+ * ```ts
107
+ * const authContext = await auth.context(ctx);
108
+ * const { userId, grants } = authContext;
109
+ * ```
110
+ *
111
+ * @example Optional usage
112
+ * ```ts
113
+ * const authContext = await auth.context(ctx, { optional: true });
114
+ * if (authContext.userId === null) {
115
+ * return null;
116
+ * }
117
+ * ```
118
+ */
119
+ context: AuthContextResolver;
106
120
  /**
107
121
  * Context enrichment for convex-helpers `customQuery` / `customMutation` /
108
122
  * `customAction`.
@@ -111,9 +125,9 @@ type AuthApiBase<TAuthorization extends AuthAuthorizationConfig | undefined = un
111
125
  * and grants, then attaches them to `ctx.auth`. Returns a `Customization`
112
126
  * object compatible with convex-helpers' custom function builders.
113
127
  *
114
- * `ctx.auth` is `{ userId, user, groupId, role, grants }` when
115
- * authenticated, `null` when unauthenticated. No throwing your
116
- * handler decides how to respond.
128
+ * `ctx.auth` is the current request auth context.
129
+ * By default this throws when unauthenticated so handlers can assume
130
+ * `ctx.auth.userId` and `ctx.auth.user` exist.
117
131
  *
118
132
  * @returns A convex-helpers `Customization` object.
119
133
  *
@@ -135,37 +149,29 @@ type AuthApiBase<TAuthorization extends AuthAuthorizationConfig | undefined = un
135
149
  * export const list = authQuery({
136
150
  * args: { workspaceId: v.string() },
137
151
  * handler: async (ctx, args) => {
138
- * if (!ctx.auth) return [];
139
152
  * const { userId, groupId, grants } = ctx.auth;
140
153
  * // business logic
141
154
  * },
142
155
  * });
143
156
  * ```
144
157
  */
145
- ctx: () => {
146
- args: Record<string, never>;
147
- input: (ctx: any) => Promise<{
148
- ctx: {
149
- auth: AuthResolvedContext | null;
150
- };
151
- args: Record<string, never>;
152
- }>;
153
- };
158
+ ctx: AuthContextFactory;
154
159
  };
155
160
  /**
156
- * Resolved auth context injected into `ctx.auth` by `auth.ctx()` and
157
- * {@link AuthCtx}. Also the expected return shape for custom
158
- * {@link AuthCtxConfig.authResolve | authResolve} hooks.
161
+ * Current request auth context injected into `ctx.auth` by `auth.ctx()`. This
162
+ * is the authenticated auth shape returned by {@link createAuth().context}.
163
+ * Optional context builders may still surface nullable fields when
164
+ * `optional: true` is used.
159
165
  *
160
- * - `null` when unauthenticated.
161
166
  * - `groupId` is `null` when the user has no active group set.
162
- * - `role` / `grants` are `null` / `[]` when no active group or no membership.
167
+ * - `role` is `null` when no active group or no membership is resolved.
168
+ * - `grants` is `[]` when no active group or no membership is resolved.
163
169
  *
164
170
  * @example
165
171
  * ```ts
166
- * import type { AuthResolvedContext } from "@robelest/convex-auth/server";
172
+ * import type { AuthContext } from "@robelest/convex-auth/server";
167
173
  *
168
- * const mockAuth: AuthResolvedContext = {
174
+ * const mockAuth: AuthContext = {
169
175
  * userId: "user123" as Id<"User">,
170
176
  * user: { _id: "user123", email: "test@example.com" },
171
177
  * groupId: "group456",
@@ -174,23 +180,66 @@ type AuthApiBase<TAuthorization extends AuthAuthorizationConfig | undefined = un
174
180
  * };
175
181
  * ```
176
182
  */
177
- type AuthResolvedContext = {
183
+ type AuthContext = {
178
184
  /** The authenticated user's document ID. */userId: GenericId<"User">; /** The authenticated user's full document. */
179
185
  user: UserDoc; /** The user's active group ID, or `null` if none set. */
180
186
  groupId: string | null; /** The user's primary role in the active group, or `null`. */
181
187
  role: string | null; /** Resolved grant strings from the user's role definitions. */
182
188
  grants: string[];
183
189
  };
184
- type AuthCtxBase = {
190
+ /**
191
+ * Nullable auth context returned by `auth.context(ctx, { optional: true })`
192
+ * and injected by `auth.ctx({ optional: true })`.
193
+ *
194
+ * Use this when callers may be unauthenticated but you still want a stable
195
+ * auth-shaped object.
196
+ *
197
+ * - `userId` and `user` are `null` when unauthenticated.
198
+ * - `groupId` and `role` are `null` when no active group is resolved.
199
+ * - `grants` is `[]` when no membership is resolved.
200
+ *
201
+ * @example
202
+ * ```ts
203
+ * const authContext = await auth.context(ctx, { optional: true });
204
+ * if (authContext.userId === null) {
205
+ * return null;
206
+ * }
207
+ * ```
208
+ */
209
+ type OptionalAuthContext = {
210
+ /** The authenticated user's document ID, or `null` when unauthenticated. */userId: GenericId<"User"> | null; /** The authenticated user's full document, or `null` when unauthenticated. */
211
+ user: UserDoc | null; /** The user's active group ID, or `null` if none is set. */
212
+ groupId: string | null; /** The user's primary role in the active group, or `null`. */
213
+ role: string | null; /** Resolved grant strings for the active membership, or `[]`. */
214
+ grants: string[];
215
+ };
216
+ type AuthContextBase = {
185
217
  getUserIdentity: () => Promise<UserIdentity | null>;
186
218
  };
187
- type RequiredAuthCtxState = AuthCtxBase & AuthResolvedContext;
188
- type OptionalAuthCtxState = AuthCtxBase & {
189
- userId: GenericId<"User"> | null;
190
- user: UserDoc | null;
191
- groupId: string | null;
192
- role: string | null;
193
- grants: string[];
219
+ type RequiredAuthContextState = AuthContextBase & AuthContext;
220
+ type OptionalAuthContextState = AuthContextBase & OptionalAuthContext;
221
+ type ResolvedAuthContext<TResolve> = AuthContext & TResolve;
222
+ type ResolvedOptionalAuthContext<TResolve> = OptionalAuthContext & TResolve;
223
+ type AuthContextResolver = {
224
+ <TResolve extends Record<string, unknown> = Record<string, never>>(ctx: any, config: AuthContextConfig<TResolve> & {
225
+ optional: true;
226
+ }): Promise<ResolvedOptionalAuthContext<TResolve>>;
227
+ <TResolve extends Record<string, unknown> = Record<string, never>>(ctx: any, config?: AuthContextConfig<TResolve>): Promise<ResolvedAuthContext<TResolve>>;
228
+ };
229
+ type AuthContextCustomization<TAuth> = {
230
+ args: {};
231
+ input: (ctx: any, _args: any, _extra?: any) => Promise<{
232
+ ctx: {
233
+ auth: TAuth;
234
+ };
235
+ args: {};
236
+ }>;
237
+ };
238
+ type AuthContextFactory = {
239
+ <TResolve extends Record<string, unknown> = Record<string, never>>(config: AuthContextConfig<TResolve> & {
240
+ optional: true;
241
+ }): AuthContextCustomization<OptionalAuthContextState & TResolve>;
242
+ <TResolve extends Record<string, unknown> = Record<string, never>>(config?: AuthContextConfig<TResolve>): AuthContextCustomization<RequiredAuthContextState & TResolve>;
194
243
  };
195
244
  type InternalSsoApi = ReturnType<typeof Auth>["auth"]["sso"];
196
245
  type PublicSsoAdminApi = {
@@ -202,7 +251,6 @@ type PublicSsoAdminApi = {
202
251
  domain: string;
203
252
  isPrimary?: boolean;
204
253
  }>) => Promise<{
205
- ok: true;
206
254
  enterpriseId: string;
207
255
  domains: Array<{
208
256
  domainId: string;
@@ -217,7 +265,6 @@ type PublicSsoAdminApi = {
217
265
  enterpriseId: string;
218
266
  domain: string;
219
267
  }) => Promise<{
220
- ok: true;
221
268
  enterpriseId: string;
222
269
  domain: string;
223
270
  requestedAt: number;
@@ -232,7 +279,6 @@ type PublicSsoAdminApi = {
232
279
  enterpriseId: string;
233
280
  domain: string;
234
281
  }) => Promise<{
235
- ok: boolean;
236
282
  enterpriseId: string;
237
283
  domain: string;
238
284
  verifiedAt?: number;
@@ -309,35 +355,53 @@ declare function createAuth<P extends AuthProviderConfig[], TAuthorization exten
309
355
  authorization?: TAuthorization;
310
356
  }): ConvexAuthResult<P, TAuthorization>;
311
357
  /**
312
- * Configuration for {@link AuthCtx} context enrichment.
358
+ * Configuration for {@link createAuth().ctx} context enrichment.
359
+ *
360
+ * The same config shape is also used by {@link createAuth().context}.
313
361
  *
314
362
  * @typeParam TResolve - Extra fields returned from `resolve()` and merged into
315
363
  * the resulting `ctx.auth` object.
364
+ *
365
+ * @example
366
+ * ```ts
367
+ * const authContext = await auth.context(ctx, {
368
+ * resolve: async (_ctx, user, authState) => ({
369
+ * email: user.email,
370
+ * canWrite: authState.grants.includes("posts.write"),
371
+ * }),
372
+ * });
373
+ * ```
316
374
  */
317
- type AuthCtxConfig<TResolve extends Record<string, unknown> = Record<string, never>> = {
318
- /** Allow unauthenticated callers and return `userId: null` / `user: null`. */optional?: boolean;
375
+ type AuthContextConfig<TResolve extends Record<string, unknown> = Record<string, never>> = {
376
+ /**
377
+ * Allow unauthenticated callers and return a null-shaped auth object instead
378
+ * of throwing `NOT_SIGNED_IN`.
379
+ */
380
+ optional?: boolean;
319
381
  /**
320
382
  * Attach additional derived fields to the auth context after the base auth
321
383
  * context is resolved.
384
+ *
385
+ * This callback runs only when a user is authenticated.
322
386
  */
323
- resolve?: (ctx: any, user: UserDoc, auth: AuthResolvedContext) => Promise<TResolve> | TResolve;
387
+ resolve?: (ctx: any, user: UserDoc, auth: AuthContext) => Promise<TResolve> | TResolve;
324
388
  /**
325
- * Override or wrap the base auth resolution used by {@link AuthCtx}.
389
+ * Override or wrap the base auth resolution used by {@link createAuth().ctx}.
326
390
  *
327
391
  * Return `undefined` to fall back to the built-in resolver,
328
392
  * `null` for an explicit unauthenticated state, or an
329
- * {@link AuthResolvedContext} object to provide a pre-resolved auth state.
393
+ * {@link AuthContext} object to provide a pre-resolved auth state.
330
394
  * This is useful for tests, proxy auth, impersonation flows, or any
331
395
  * environment that needs to inject auth without depending on the standard
332
396
  * Convex auth tables.
333
397
  *
334
398
  * @param ctx - The Convex function context.
335
- * @param fallback - The built-in auth resolver used by {@link AuthCtx}.
399
+ * @param fallback - The built-in auth resolver used by {@link createAuth().ctx}.
336
400
  * @returns Resolved auth state, `null`, or `undefined` to use the fallback.
337
401
  *
338
402
  * @example
339
403
  * ```ts
340
- * const authCtx = AuthCtx(auth, {
404
+ * const authCtx = auth.ctx({
341
405
  * authResolve: async (ctx, fallback) => {
342
406
  * const injected = getInjectedAuth(ctx);
343
407
  * return injected ?? (await fallback());
@@ -345,91 +409,24 @@ type AuthCtxConfig<TResolve extends Record<string, unknown> = Record<string, nev
345
409
  * });
346
410
  * ```
347
411
  */
348
- authResolve?: (ctx: any, fallback: () => Promise<AuthResolvedContext | null>) => Promise<AuthResolvedContext | null | undefined> | AuthResolvedContext | null | undefined;
349
- };
350
- /**
351
- * Create a context enrichment for `customQuery` / `customMutation` — optional auth.
352
- *
353
- * When `optional: true` is set, unauthenticated requests are allowed.
354
- * The enriched `ctx.auth` will have `userId: null`, `user: null`,
355
- * `groupId: null`, `role: null`, and `grants: []` for unauthenticated callers.
356
- *
357
- * @param auth - The auth API object returned by {@link createAuth}.
358
- * @param config - Configuration with `optional: true` and an optional
359
- * `resolve` callback for attaching extra fields to the auth context.
360
- * @returns An object with `args` and `input` compatible with Convex
361
- * custom function builders.
362
- *
363
- * @example
364
- * ```ts
365
- * const authCtx = AuthCtx(auth, {
366
- * optional: true,
367
- * resolve: async (_ctx, user) => ({ plan: user?.extend?.plan ?? null }),
368
- * });
369
- * ```
370
- *
371
- * @see {@link createAuth}
372
- */
373
- declare function AuthCtx<TResolve extends Record<string, unknown> = Record<string, never>>(auth: AuthLike, config: AuthCtxConfig<TResolve> & {
374
- optional: true;
375
- }): {
376
- args: {};
377
- input: (ctx: any, _args: any, _extra?: any) => Promise<{
378
- ctx: {
379
- auth: OptionalAuthCtxState & TResolve;
380
- };
381
- args: {};
382
- }>;
383
- };
384
- /**
385
- * Create a context enrichment for `customQuery` / `customMutation` — required auth (default).
386
- *
387
- * When `optional` is omitted or `false`, the inferred type is the authenticated
388
- * auth shape. At runtime this helper still resolves instead of throwing, so if
389
- * no user is signed in the returned `ctx.auth.userId` / `ctx.auth.user` are
390
- * `null`, `ctx.auth.groupId` / `ctx.auth.role` are `null`, and
391
- * `ctx.auth.grants` is `[]`.
392
- *
393
- * @param auth - The auth API object returned by {@link createAuth}.
394
- * @param config - Optional configuration with a `resolve` callback
395
- * for attaching extra fields to the auth context.
396
- * @returns An object with `args` and `input` compatible with Convex
397
- * custom function builders.
398
- *
399
- * @example
400
- * ```ts
401
- * const authCtx = AuthCtx(auth, {
402
- * resolve: async (_ctx, user) => ({ email: user.email }),
403
- * });
404
- * ```
405
- *
406
- * @see {@link createAuth}
407
- */
408
- declare function AuthCtx<TResolve extends Record<string, unknown> = Record<string, never>>(auth: AuthLike, config?: AuthCtxConfig<TResolve>): {
409
- args: {};
410
- input: (ctx: any, _args: any, _extra?: any) => Promise<{
411
- ctx: {
412
- auth: RequiredAuthCtxState & TResolve;
413
- };
414
- args: {};
415
- }>;
412
+ authResolve?: (ctx: any, fallback: () => Promise<AuthContext | null>) => Promise<AuthContext | null | undefined> | AuthContext | null | undefined;
416
413
  };
417
414
  /**
418
- * Extract the resolved `auth` context type from an {@link AuthCtx} instance.
415
+ * Extract the resolved `auth` context type from an `auth.ctx()` customization.
419
416
  *
420
417
  * Use this to type function parameters or variables that receive the
421
- * enriched auth context produced by `AuthCtx`. The inferred type includes
418
+ * enriched auth context produced by `auth.ctx()`. The inferred type includes
422
419
  * `userId`, `user`, `groupId`, `role`, `grants`, `getUserIdentity`, and any
423
420
  * additional fields added by the `resolve` callback. This is the generic
424
421
  * utility for reusing the enriched auth shape without manually duplicating
425
422
  * conditional auth types.
426
423
  *
427
- * @typeParam T - An `AuthCtx` return value (must have an `input` method
424
+ * @typeParam T - An `auth.ctx()` return value (must have an `input` method
428
425
  * that returns `{ ctx: { auth: ... } }`).
429
426
  *
430
427
  * @example
431
428
  * ```ts
432
- * const authCtx = AuthCtx(auth, {
429
+ * const authCtx = auth.ctx({
433
430
  * resolve: async (ctx, user) => ({ orgId: user.orgId }),
434
431
  * });
435
432
  * type Auth = InferAuth<typeof authCtx>;
@@ -446,5 +443,5 @@ type InferAuth<T extends {
446
443
  }>;
447
444
  }> = Awaited<ReturnType<T["input"]>>["ctx"]["auth"];
448
445
  //#endregion
449
- export { AuthApi, AuthConfig, AuthCtx, AuthCtxConfig, AuthResolvedContext, InferAuth, UserDoc, createAuth };
446
+ export { AuthApi, AuthConfig, AuthContext, AuthContextConfig, InferAuth, OptionalAuthContext, UserDoc, createAuth };
450
447
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","names":[],"sources":["../../../src/server/auth.ts"],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","names":[],"sources":["../../../src/server/auth.ts"],"mappings":"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"}
@@ -1,8 +1,14 @@
1
- import { AuthError } from "./authError.js";
1
+ import { createUnauthenticatedAuthContext, getAuthContext } from "./context.js";
2
2
  import { Auth } from "./runtime.js";
3
+ import { Cv } from "@robelest/fx/convex";
3
4
 
4
5
  //#region src/server/auth.ts
5
6
  /**
7
+ * Auth configuration helpers for Convex Auth.
8
+ *
9
+ * @module
10
+ */
11
+ /**
6
12
  * Create an auth API object.
7
13
  *
8
14
  * When `new SSO()` is included in providers, `auth.sso` and `auth.scim`
@@ -26,41 +32,29 @@ import { Auth } from "./runtime.js";
26
32
  * });
27
33
  * ```
28
34
  *
29
- * @see {@link AuthCtx}
30
- */
31
- /**
32
- * Resolve auth context for the current user. Returns the enriched
33
- * `ctx.auth` object or `null` when unauthenticated.
34
- *
35
- * Resolution flow:
36
- * 1. `user.id(ctx)` → userId or null (exit early)
37
- * 2. `user.get(ctx, userId)` → user doc (cached per-execution)
38
- * 3. `user.getActiveGroup(ctx, { userId })` → groupId or null
39
- * 4. If groupId → `member.resolve(ctx, { userId, groupId })` → role + grants
35
+ * @see {@link AuthContextConfig}
40
36
  */
41
- async function resolveAuthContext(auth, ctx) {
42
- const userId = await auth.user.id(ctx);
43
- if (!userId) return null;
44
- const user = await auth.user.get(ctx, userId);
45
- const groupId = await auth.user.getActiveGroup(ctx, { userId });
46
- let role = null;
47
- let grants = [];
48
- if (groupId) {
49
- const resolved = await auth.member.resolve(ctx, {
50
- userId,
51
- groupId
52
- });
53
- if (resolved.membership) {
54
- role = resolved.roleIds[0] ?? null;
55
- grants = resolved.grants;
56
- }
37
+ async function resolveConfiguredAuthContext(auth, ctx, config) {
38
+ const fallback = () => getAuthContext(auth, ctx);
39
+ const authOverride = config?.authResolve ? await config.authResolve(ctx, fallback) : void 0;
40
+ return authOverride === void 0 ? await fallback() : authOverride;
41
+ }
42
+ function createNotSignedInError() {
43
+ return Cv.error({
44
+ code: "NOT_SIGNED_IN",
45
+ message: "Authentication required."
46
+ });
47
+ }
48
+ async function createPublicAuthContext(auth, ctx, config) {
49
+ const resolved = await resolveConfiguredAuthContext(auth, ctx, config);
50
+ if (resolved === null) {
51
+ if (config?.optional !== true) throw createNotSignedInError();
52
+ return createUnauthenticatedAuthContext();
57
53
  }
54
+ const extra = config?.resolve ? await config.resolve(ctx, resolved.user, resolved) : {};
58
55
  return {
59
- userId,
60
- user,
61
- groupId,
62
- role,
63
- grants
56
+ ...resolved,
57
+ ...extra
64
58
  };
65
59
  }
66
60
  function createAuth(component, config) {
@@ -72,20 +66,32 @@ function createAuth(component, config) {
72
66
  const { domain: domainApi, scim: scimApi, connection: connectionApi, audit: auditApi, webhook: webhookApi, oidc: oidcApi, saml: samlApi, ...restSso } = authResult.auth.sso;
73
67
  const setEnterpriseDomains = async (ctx, enterpriseId, domains) => {
74
68
  const enterprise = await connectionApi.get(ctx, enterpriseId);
75
- if (enterprise === null) throw new AuthError("INVALID_PARAMETERS", "Enterprise not found.").toConvexError();
69
+ if (enterprise === null) throw Cv.error({
70
+ code: "INVALID_PARAMETERS",
71
+ message: "Enterprise not found."
72
+ });
76
73
  const normalized = domains.map((entry) => ({
77
74
  ...entry,
78
75
  domain: entry.domain.trim().toLowerCase()
79
76
  }));
80
77
  const deduped = /* @__PURE__ */ new Map();
81
78
  for (const entry of normalized) {
82
- if (entry.domain.length === 0) throw new AuthError("INVALID_PARAMETERS", "Domain must not be empty.").toConvexError();
83
- if (deduped.has(entry.domain)) throw new AuthError("INVALID_PARAMETERS", `Duplicate domain: ${entry.domain}`).toConvexError();
79
+ if (entry.domain.length === 0) throw Cv.error({
80
+ code: "INVALID_PARAMETERS",
81
+ message: "Domain must not be empty."
82
+ });
83
+ if (deduped.has(entry.domain)) throw Cv.error({
84
+ code: "INVALID_PARAMETERS",
85
+ message: `Duplicate domain: ${entry.domain}`
86
+ });
84
87
  deduped.set(entry.domain, entry);
85
88
  }
86
89
  const nextDomains = [...deduped.values()];
87
90
  const primaryCount = nextDomains.filter((entry) => entry.isPrimary).length;
88
- if (primaryCount > 1) throw new AuthError("INVALID_PARAMETERS", "Only one primary domain may be set.").toConvexError();
91
+ if (primaryCount > 1) throw Cv.error({
92
+ code: "INVALID_PARAMETERS",
93
+ message: "Only one primary domain may be set."
94
+ });
89
95
  if (nextDomains.length > 0 && primaryCount === 0) nextDomains[0] = {
90
96
  ...nextDomains[0],
91
97
  isPrimary: true
@@ -109,7 +115,6 @@ function createAuth(component, config) {
109
115
  });
110
116
  }
111
117
  return {
112
- ok: true,
113
118
  enterpriseId,
114
119
  domains: (await domainApi.list(ctx, enterpriseId)).map((domain) => ({
115
120
  domainId: domain._id,
@@ -168,38 +173,69 @@ function createAuth(component, config) {
168
173
  validate: scimApi.validate
169
174
  } },
170
175
  http: authResult.auth.http,
171
- resolve: (ctx) => resolveAuthContext(authResult.auth, ctx),
172
- ctx: () => ({
173
- args: {},
174
- input: async (ctx) => {
175
- return {
176
- ctx: { auth: await resolveAuthContext(authResult.auth, ctx) },
177
- args: {}
178
- };
179
- }
180
- })
176
+ context: ((ctx, config$1) => createPublicAuthContext(authResult.auth, ctx, config$1)),
177
+ ctx: ((config$1) => createAuthContextCustomization(authResult.auth, config$1))
181
178
  };
182
179
  }
183
- function AuthCtx(auth, config) {
180
+ /**
181
+ * Create a context enrichment for `customQuery` / `customMutation` — optional auth.
182
+ *
183
+ * When `optional: true` is set, unauthenticated requests are allowed.
184
+ * The enriched `ctx.auth` will have `userId: null`, `user: null`,
185
+ * `groupId: null`, `role: null`, and `grants: []` for unauthenticated callers.
186
+ *
187
+ * @param config - Configuration with `optional: true` and an optional
188
+ * `resolve` callback for attaching extra fields to the auth context.
189
+ * @returns An object with `args` and `input` compatible with Convex
190
+ * custom function builders.
191
+ *
192
+ * @example
193
+ * ```ts
194
+ * const authCtx = auth.ctx({
195
+ * optional: true,
196
+ * resolve: async (_ctx, user) => ({ plan: user.extend?.plan ?? null }),
197
+ * });
198
+ * ```
199
+ *
200
+ * @see {@link createAuth}
201
+ */
202
+ /**
203
+ * Create a context enrichment for `customQuery` / `customMutation` — required auth (default).
204
+ *
205
+ * When `optional` is omitted or `false`, unauthenticated requests throw a
206
+ * structured `ConvexError` before your handler runs.
207
+ *
208
+ * @param config - Optional configuration with a `resolve` callback
209
+ * for attaching extra fields to the auth context.
210
+ * @returns An object with `args` and `input` compatible with Convex
211
+ * custom function builders.
212
+ *
213
+ * @example
214
+ * ```ts
215
+ * const authCtx = auth.ctx({
216
+ * resolve: async (_ctx, user) => ({ email: user.email }),
217
+ * });
218
+ * ```
219
+ *
220
+ * @see {@link createAuth}
221
+ */
222
+ function createAuthContextCustomization(auth, config) {
184
223
  return {
185
224
  args: {},
186
225
  input: async (ctx, _args, _extra) => {
187
226
  const nativeAuth = ctx.auth;
188
227
  const getUserIdentity = nativeAuth.getUserIdentity.bind(nativeAuth);
189
- const fallback = () => resolveAuthContext(auth, ctx);
190
- const authOverride = config?.authResolve ? await config.authResolve(ctx, fallback) : void 0;
191
- const resolved = authOverride === void 0 ? await fallback() : authOverride;
192
- if (resolved === null) return {
193
- ctx: { auth: {
194
- getUserIdentity,
195
- userId: null,
196
- user: null,
197
- groupId: null,
198
- role: null,
199
- grants: []
200
- } },
201
- args: {}
202
- };
228
+ const resolved = await resolveConfiguredAuthContext(auth, ctx, config);
229
+ if (resolved === null) {
230
+ if (config?.optional !== true) throw createNotSignedInError();
231
+ return {
232
+ ctx: { auth: {
233
+ getUserIdentity,
234
+ ...createUnauthenticatedAuthContext()
235
+ } },
236
+ args: {}
237
+ };
238
+ }
203
239
  const extra = config?.resolve ? await config.resolve(ctx, resolved.user, resolved) : {};
204
240
  return {
205
241
  ctx: { auth: {
@@ -214,5 +250,5 @@ function AuthCtx(auth, config) {
214
250
  }
215
251
 
216
252
  //#endregion
217
- export { AuthCtx, createAuth };
253
+ export { createAuth };
218
254
  //# sourceMappingURL=auth.js.map