@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.
- package/dist/authorization/index.d.ts +1 -1
- package/dist/authorization/index.js +1 -1
- package/dist/authorization/index.js.map +1 -1
- package/dist/client/index.d.ts +1 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +36 -39
- package/dist/client/index.js.map +1 -1
- package/dist/component/client/index.d.ts +1 -2
- package/dist/component/model.d.ts +9 -9
- package/dist/component/model.d.ts.map +1 -1
- package/dist/component/public/enterprise/audit.d.ts.map +1 -1
- package/dist/component/public/enterprise/audit.js.map +1 -1
- package/dist/component/public/enterprise/core.d.ts.map +1 -1
- package/dist/component/public/enterprise/core.js.map +1 -1
- package/dist/component/public/enterprise/domains.d.ts.map +1 -1
- package/dist/component/public/enterprise/domains.js.map +1 -1
- package/dist/component/public/enterprise/scim.d.ts.map +1 -1
- package/dist/component/public/enterprise/scim.js.map +1 -1
- package/dist/component/public/enterprise/secrets.d.ts.map +1 -1
- package/dist/component/public/enterprise/secrets.js.map +1 -1
- package/dist/component/public/enterprise/webhooks.d.ts.map +1 -1
- package/dist/component/public/enterprise/webhooks.js.map +1 -1
- package/dist/component/public/factors/devices.d.ts.map +1 -1
- package/dist/component/public/factors/devices.js.map +1 -1
- package/dist/component/public/factors/passkeys.d.ts.map +1 -1
- package/dist/component/public/factors/passkeys.js.map +1 -1
- package/dist/component/public/factors/totp.d.ts.map +1 -1
- package/dist/component/public/factors/totp.js.map +1 -1
- package/dist/component/public/groups/core.js.map +1 -1
- package/dist/component/public/groups/invites.d.ts.map +1 -1
- package/dist/component/public/groups/invites.js.map +1 -1
- package/dist/component/public/groups/members.d.ts.map +1 -1
- package/dist/component/public/groups/members.js.map +1 -1
- package/dist/component/public/identity/accounts.d.ts.map +1 -1
- package/dist/component/public/identity/accounts.js.map +1 -1
- package/dist/component/public/identity/codes.d.ts.map +1 -1
- package/dist/component/public/identity/codes.js.map +1 -1
- package/dist/component/public/identity/sessions.d.ts.map +1 -1
- package/dist/component/public/identity/sessions.js.map +1 -1
- package/dist/component/public/identity/tokens.d.ts.map +1 -1
- package/dist/component/public/identity/tokens.js.map +1 -1
- package/dist/component/public/identity/users.d.ts.map +1 -1
- package/dist/component/public/identity/users.js.map +1 -1
- package/dist/component/public/identity/verifiers.d.ts.map +1 -1
- package/dist/component/public/identity/verifiers.js.map +1 -1
- package/dist/component/public/security/keys.d.ts.map +1 -1
- package/dist/component/public/security/keys.js.map +1 -1
- package/dist/component/public/security/limits.d.ts.map +1 -1
- package/dist/component/public/security/limits.js.map +1 -1
- package/dist/component/schema.d.ts +42 -42
- package/dist/component/server/auth.d.ts +37 -40
- package/dist/component/server/auth.d.ts.map +1 -1
- package/dist/component/server/auth.js +57 -23
- package/dist/component/server/auth.js.map +1 -1
- package/dist/component/server/core.js +116 -235
- package/dist/component/server/core.js.map +1 -1
- package/dist/component/server/crypto.js +25 -7
- package/dist/component/server/crypto.js.map +1 -1
- package/dist/component/server/device.js +58 -15
- package/dist/component/server/device.js.map +1 -1
- package/dist/component/server/enterprise/domain.js +148 -59
- package/dist/component/server/enterprise/domain.js.map +1 -1
- package/dist/component/server/enterprise/http.js +36 -15
- package/dist/component/server/enterprise/http.js.map +1 -1
- package/dist/component/server/enterprise/oidc.js +1 -1
- package/dist/component/server/http.js +26 -21
- package/dist/component/server/http.js.map +1 -1
- package/dist/component/server/identity.js +5 -2
- package/dist/component/server/identity.js.map +1 -1
- package/dist/component/server/limits.js +21 -30
- package/dist/component/server/limits.js.map +1 -1
- package/dist/component/server/mutations/account.js +12 -10
- package/dist/component/server/mutations/account.js.map +1 -1
- package/dist/component/server/mutations/code.js +5 -2
- package/dist/component/server/mutations/code.js.map +1 -1
- package/dist/component/server/mutations/invalidate.js +1 -1
- package/dist/component/server/mutations/invalidate.js.map +1 -1
- package/dist/component/server/mutations/oauth.js +10 -4
- package/dist/component/server/mutations/oauth.js.map +1 -1
- package/dist/component/server/mutations/refresh.js +2 -2
- package/dist/component/server/mutations/refresh.js.map +1 -1
- package/dist/component/server/mutations/register.js +46 -42
- package/dist/component/server/mutations/register.js.map +1 -1
- package/dist/component/server/mutations/retrieve.js +21 -25
- package/dist/component/server/mutations/retrieve.js.map +1 -1
- package/dist/component/server/mutations/signature.js +10 -4
- package/dist/component/server/mutations/signature.js.map +1 -1
- package/dist/component/server/mutations/signout.js.map +1 -1
- package/dist/component/server/mutations/store.js +9 -24
- package/dist/component/server/mutations/store.js.map +1 -1
- package/dist/component/server/mutations/verifier.js.map +1 -1
- package/dist/component/server/mutations/verify.js +1 -1
- package/dist/component/server/mutations/verify.js.map +1 -1
- package/dist/component/server/oauth.js +53 -16
- package/dist/component/server/oauth.js.map +1 -1
- package/dist/component/server/passkey.js +115 -31
- package/dist/component/server/passkey.js.map +1 -1
- package/dist/component/server/redirects.js +9 -3
- package/dist/component/server/redirects.js.map +1 -1
- package/dist/component/server/refresh.js +10 -7
- package/dist/component/server/refresh.js.map +1 -1
- package/dist/component/server/runtime.d.ts +1 -1
- package/dist/component/server/runtime.d.ts.map +1 -1
- package/dist/component/server/runtime.js +62 -20
- package/dist/component/server/runtime.js.map +1 -1
- package/dist/component/server/signin.js +34 -10
- package/dist/component/server/signin.js.map +1 -1
- package/dist/component/server/totp.js +79 -19
- package/dist/component/server/totp.js.map +1 -1
- package/dist/component/server/types.d.ts +12 -20
- package/dist/component/server/types.d.ts.map +1 -1
- package/dist/component/server/types.js.map +1 -1
- package/dist/component/server/users.js +6 -3
- package/dist/component/server/users.js.map +1 -1
- package/dist/component/server/utils.js +10 -4
- package/dist/component/server/utils.js.map +1 -1
- package/dist/core/types.d.ts +14 -22
- package/dist/core/types.d.ts.map +1 -1
- package/dist/factors/device.js +8 -9
- package/dist/factors/device.js.map +1 -1
- package/dist/factors/passkey.js +18 -21
- package/dist/factors/passkey.js.map +1 -1
- package/dist/providers/password.js +66 -81
- package/dist/providers/password.js.map +1 -1
- package/dist/runtime/invite.js +2 -8
- package/dist/runtime/invite.js.map +1 -1
- package/dist/server/auth.d.ts +37 -40
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +57 -23
- package/dist/server/auth.js.map +1 -1
- package/dist/server/core.d.ts +71 -159
- package/dist/server/core.d.ts.map +1 -1
- package/dist/server/core.js +116 -235
- package/dist/server/core.js.map +1 -1
- package/dist/server/crypto.d.ts.map +1 -1
- package/dist/server/crypto.js +25 -7
- package/dist/server/crypto.js.map +1 -1
- package/dist/server/device.js +58 -15
- package/dist/server/device.js.map +1 -1
- package/dist/server/enterprise/domain.d.ts +0 -8
- package/dist/server/enterprise/domain.d.ts.map +1 -1
- package/dist/server/enterprise/domain.js +148 -59
- package/dist/server/enterprise/domain.js.map +1 -1
- package/dist/server/enterprise/http.d.ts.map +1 -1
- package/dist/server/enterprise/http.js +35 -14
- package/dist/server/enterprise/http.js.map +1 -1
- package/dist/server/http.d.ts +2 -2
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +25 -20
- package/dist/server/http.js.map +1 -1
- package/dist/server/identity.js +5 -2
- package/dist/server/identity.js.map +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/server/limits.js +21 -30
- package/dist/server/limits.js.map +1 -1
- package/dist/server/mounts.d.ts +24 -62
- package/dist/server/mounts.d.ts.map +1 -1
- package/dist/server/mounts.js +45 -106
- package/dist/server/mounts.js.map +1 -1
- package/dist/server/mutations/account.d.ts +8 -9
- package/dist/server/mutations/account.d.ts.map +1 -1
- package/dist/server/mutations/account.js +11 -9
- package/dist/server/mutations/account.js.map +1 -1
- package/dist/server/mutations/code.d.ts +12 -12
- package/dist/server/mutations/code.d.ts.map +1 -1
- package/dist/server/mutations/code.js +5 -2
- package/dist/server/mutations/code.js.map +1 -1
- package/dist/server/mutations/invalidate.d.ts +4 -4
- package/dist/server/mutations/invalidate.d.ts.map +1 -1
- package/dist/server/mutations/invalidate.js.map +1 -1
- package/dist/server/mutations/oauth.d.ts +14 -12
- package/dist/server/mutations/oauth.d.ts.map +1 -1
- package/dist/server/mutations/oauth.js +9 -3
- package/dist/server/mutations/oauth.js.map +1 -1
- package/dist/server/mutations/refresh.d.ts +3 -3
- package/dist/server/mutations/refresh.d.ts.map +1 -1
- package/dist/server/mutations/refresh.js +1 -1
- package/dist/server/mutations/refresh.js.map +1 -1
- package/dist/server/mutations/register.d.ts +11 -11
- package/dist/server/mutations/register.d.ts.map +1 -1
- package/dist/server/mutations/register.js +45 -41
- package/dist/server/mutations/register.js.map +1 -1
- package/dist/server/mutations/retrieve.d.ts +6 -6
- package/dist/server/mutations/retrieve.d.ts.map +1 -1
- package/dist/server/mutations/retrieve.js +20 -24
- package/dist/server/mutations/retrieve.js.map +1 -1
- package/dist/server/mutations/signature.d.ts +6 -7
- package/dist/server/mutations/signature.d.ts.map +1 -1
- package/dist/server/mutations/signature.js +9 -3
- package/dist/server/mutations/signature.js.map +1 -1
- package/dist/server/mutations/signin.d.ts +5 -5
- package/dist/server/mutations/signin.d.ts.map +1 -1
- package/dist/server/mutations/signout.js.map +1 -1
- package/dist/server/mutations/store.d.ts +83 -83
- package/dist/server/mutations/store.js +8 -23
- package/dist/server/mutations/store.js.map +1 -1
- package/dist/server/mutations/verifier.js.map +1 -1
- package/dist/server/mutations/verify.d.ts +7 -7
- package/dist/server/mutations/verify.d.ts.map +1 -1
- package/dist/server/mutations/verify.js.map +1 -1
- package/dist/server/oauth.js +53 -16
- package/dist/server/oauth.js.map +1 -1
- package/dist/server/passkey.d.ts +2 -2
- package/dist/server/passkey.d.ts.map +1 -1
- package/dist/server/passkey.js +114 -30
- package/dist/server/passkey.js.map +1 -1
- package/dist/server/redirects.js +9 -3
- package/dist/server/redirects.js.map +1 -1
- package/dist/server/refresh.js +10 -7
- package/dist/server/refresh.js.map +1 -1
- package/dist/server/runtime.d.ts +7 -7
- package/dist/server/runtime.d.ts.map +1 -1
- package/dist/server/runtime.js +61 -19
- package/dist/server/runtime.js.map +1 -1
- package/dist/server/signin.js +34 -10
- package/dist/server/signin.js.map +1 -1
- package/dist/server/ssr.d.ts.map +1 -1
- package/dist/server/ssr.js +175 -184
- package/dist/server/ssr.js.map +1 -1
- package/dist/server/totp.js +78 -18
- package/dist/server/totp.js.map +1 -1
- package/dist/server/types.d.ts +13 -21
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js.map +1 -1
- package/dist/server/users.js +6 -3
- package/dist/server/users.js.map +1 -1
- package/dist/server/utils.js +10 -4
- package/dist/server/utils.js.map +1 -1
- package/package.json +1 -5
- package/src/authorization/index.ts +1 -1
- package/src/client/core/types.ts +14 -14
- package/src/client/factors/device.ts +10 -12
- package/src/client/factors/passkey.ts +23 -26
- package/src/client/index.ts +54 -64
- package/src/client/runtime/invite.ts +5 -7
- package/src/component/index.ts +1 -1
- package/src/component/public/enterprise/audit.ts +6 -1
- package/src/component/public/enterprise/core.ts +1 -0
- package/src/component/public/enterprise/domains.ts +5 -1
- package/src/component/public/enterprise/scim.ts +1 -0
- package/src/component/public/enterprise/secrets.ts +1 -0
- package/src/component/public/enterprise/webhooks.ts +1 -0
- package/src/component/public/factors/devices.ts +1 -0
- package/src/component/public/factors/passkeys.ts +1 -0
- package/src/component/public/factors/totp.ts +1 -0
- package/src/component/public/groups/core.ts +1 -1
- package/src/component/public/groups/invites.ts +7 -1
- package/src/component/public/groups/members.ts +1 -0
- package/src/component/public/identity/accounts.ts +1 -0
- package/src/component/public/identity/codes.ts +1 -0
- package/src/component/public/identity/sessions.ts +1 -0
- package/src/component/public/identity/tokens.ts +1 -0
- package/src/component/public/identity/users.ts +1 -0
- package/src/component/public/identity/verifiers.ts +1 -0
- package/src/component/public/security/keys.ts +1 -0
- package/src/component/public/security/limits.ts +1 -0
- package/src/providers/password.ts +89 -110
- package/src/server/auth.ts +92 -70
- package/src/server/core.ts +197 -233
- package/src/server/crypto.ts +31 -29
- package/src/server/device.ts +65 -32
- package/src/server/enterprise/domain.ts +158 -170
- package/src/server/enterprise/http.ts +46 -39
- package/src/server/http.ts +36 -30
- package/src/server/identity.ts +5 -5
- package/src/server/index.ts +1 -1
- package/src/server/limits.ts +53 -80
- package/src/server/mounts.ts +47 -74
- package/src/server/mutations/account.ts +22 -36
- package/src/server/mutations/code.ts +6 -6
- package/src/server/mutations/invalidate.ts +1 -1
- package/src/server/mutations/oauth.ts +14 -8
- package/src/server/mutations/refresh.ts +5 -4
- package/src/server/mutations/register.ts +87 -132
- package/src/server/mutations/retrieve.ts +44 -44
- package/src/server/mutations/signature.ts +13 -6
- package/src/server/mutations/signout.ts +1 -1
- package/src/server/mutations/store.ts +16 -31
- package/src/server/mutations/verifier.ts +1 -1
- package/src/server/mutations/verify.ts +3 -5
- package/src/server/oauth.ts +60 -69
- package/src/server/passkey.ts +567 -517
- package/src/server/redirects.ts +10 -6
- package/src/server/refresh.ts +14 -18
- package/src/server/runtime.ts +70 -55
- package/src/server/signin.ts +44 -37
- package/src/server/ssr.ts +390 -407
- package/src/server/totp.ts +85 -35
- package/src/server/types.ts +19 -22
- package/src/server/users.ts +7 -6
- package/src/server/utils.ts +10 -12
- package/dist/component/server/authError.js +0 -34
- package/dist/component/server/authError.js.map +0 -1
- package/dist/component/server/errors.d.ts +0 -1
- package/dist/component/server/errors.js +0 -137
- package/dist/component/server/errors.js.map +0 -1
- package/dist/server/authError.d.ts +0 -46
- package/dist/server/authError.d.ts.map +0 -1
- package/dist/server/authError.js +0 -34
- package/dist/server/authError.js.map +0 -1
- package/dist/server/errors.d.ts +0 -177
- package/dist/server/errors.d.ts.map +0 -1
- package/dist/server/errors.js +0 -212
- package/dist/server/errors.js.map +0 -1
- package/src/server/authError.ts +0 -44
- package/src/server/errors.ts +0 -290
package/src/server/auth.ts
CHANGED
|
@@ -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" | "
|
|
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<{
|
|
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<{
|
|
82
|
-
|
|
81
|
+
) => Promise<{ memberId: string }>;
|
|
82
|
+
inspect: (
|
|
83
83
|
ctx: Parameters<
|
|
84
|
-
ReturnType<typeof AuthFactory>["auth"]["member"]["
|
|
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"]["
|
|
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
|
|
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
|
|
141
|
+
* need the current `{ userId, user, groupId, role, grants }` object.
|
|
132
142
|
*
|
|
133
|
-
*
|
|
143
|
+
* Throws a structured `ConvexError` when unauthenticated.
|
|
134
144
|
*
|
|
135
145
|
* @param ctx - Convex query, mutation, or action context.
|
|
136
|
-
* @returns The
|
|
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.
|
|
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
|
|
148
|
-
*
|
|
149
|
-
* const { userId, grants } = resolved;
|
|
157
|
+
* const authContext = await auth.context(ctx);
|
|
158
|
+
* const { userId, grants } = authContext;
|
|
150
159
|
* ```
|
|
151
160
|
*/
|
|
152
|
-
|
|
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
|
|
162
|
-
*
|
|
163
|
-
*
|
|
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:
|
|
203
|
+
ctx: { auth: AuthContext };
|
|
196
204
|
args: Record<string, never>;
|
|
197
205
|
}>;
|
|
198
206
|
};
|
|
199
207
|
};
|
|
200
208
|
|
|
201
209
|
/**
|
|
202
|
-
*
|
|
203
|
-
* {@link AuthCtx}.
|
|
204
|
-
* {@link
|
|
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`
|
|
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 {
|
|
221
|
+
* import type { AuthContext } from "@robelest/convex-auth/server";
|
|
213
222
|
*
|
|
214
|
-
* const mockAuth:
|
|
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
|
|
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 &
|
|
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.
|
|
455
|
+
* 4. If groupId → `member.inspect(ctx, { userId, groupId })` → role + grants
|
|
450
456
|
*/
|
|
451
|
-
async function
|
|
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.
|
|
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
|
|
508
|
-
"INVALID_PARAMETERS",
|
|
509
|
-
"Enterprise not found.",
|
|
510
|
-
)
|
|
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
|
|
521
|
-
"INVALID_PARAMETERS",
|
|
522
|
-
"Domain must not be empty.",
|
|
523
|
-
)
|
|
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
|
|
527
|
-
"INVALID_PARAMETERS",
|
|
528
|
-
`Duplicate domain: ${entry.domain}`,
|
|
529
|
-
)
|
|
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
|
|
540
|
-
"INVALID_PARAMETERS",
|
|
541
|
-
"Only one primary domain may be set.",
|
|
542
|
-
)
|
|
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
|
-
|
|
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
|
|
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:
|
|
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
|
|
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<
|
|
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`,
|
|
778
|
-
*
|
|
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 = () =>
|
|
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: {
|