@robelest/convex-auth 0.0.4-preview.13 → 0.0.4-preview.16
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/README.md +140 -9
- package/dist/bin.cjs +5957 -5478
- package/dist/client/index.d.ts +3 -7
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +27 -26
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +14 -0
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +1672 -24
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/convex.config.d.ts +2 -2
- package/dist/component/convex.config.d.ts.map +1 -1
- package/dist/component/index.d.ts +1 -1
- package/dist/component/index.js +2 -2
- package/dist/component/model.d.ts +153 -0
- package/dist/component/model.d.ts.map +1 -0
- package/dist/component/model.js +343 -0
- package/dist/component/model.js.map +1 -0
- package/dist/component/providers/sso.d.ts +1 -1
- package/dist/component/public/enterprise.d.ts +54 -0
- package/dist/component/public/enterprise.d.ts.map +1 -0
- package/dist/component/public/enterprise.js +515 -0
- package/dist/component/public/enterprise.js.map +1 -0
- package/dist/component/public/factors.d.ts +52 -0
- package/dist/component/public/factors.d.ts.map +1 -0
- package/dist/component/public/factors.js +285 -0
- package/dist/component/public/factors.js.map +1 -0
- package/dist/component/public/groups.d.ts +116 -0
- package/dist/component/public/groups.d.ts.map +1 -0
- package/dist/component/public/groups.js +596 -0
- package/dist/component/public/groups.js.map +1 -0
- package/dist/component/public/identity.d.ts +93 -0
- package/dist/component/public/identity.d.ts.map +1 -0
- package/dist/component/public/identity.js +426 -0
- package/dist/component/public/identity.js.map +1 -0
- package/dist/component/public/keys.d.ts +41 -0
- package/dist/component/public/keys.d.ts.map +1 -0
- package/dist/component/public/keys.js +157 -0
- package/dist/component/public/keys.js.map +1 -0
- package/dist/component/public/shared.d.ts +26 -0
- package/dist/component/public/shared.d.ts.map +1 -0
- package/dist/component/public/shared.js +32 -0
- package/dist/component/public/shared.js.map +1 -0
- package/dist/component/public.d.ts +9 -321
- package/dist/component/public.d.ts.map +1 -1
- package/dist/component/public.js +6 -2145
- package/dist/component/schema.d.ts +406 -260
- package/dist/component/schema.js +37 -32
- package/dist/component/schema.js.map +1 -1
- package/dist/component/server/auth.d.ts +161 -15
- package/dist/component/server/auth.d.ts.map +1 -1
- package/dist/component/server/auth.js +100 -7
- package/dist/component/server/auth.js.map +1 -1
- package/dist/component/server/cookies.js +3 -0
- package/dist/component/server/cookies.js.map +1 -1
- package/dist/component/server/db.js +1 -0
- package/dist/component/server/db.js.map +1 -1
- package/dist/component/server/device.js +3 -1
- package/dist/component/server/device.js.map +1 -1
- package/dist/component/server/domains/core.js +629 -0
- package/dist/component/server/domains/core.js.map +1 -0
- package/dist/component/server/domains/sso.js +884 -0
- package/dist/component/server/domains/sso.js.map +1 -0
- package/dist/component/server/factory.d.ts +136 -0
- package/dist/component/server/factory.d.ts.map +1 -0
- package/dist/component/server/factory.js +1134 -0
- package/dist/component/server/factory.js.map +1 -0
- package/dist/component/server/fx.js +2 -1
- package/dist/component/server/fx.js.map +1 -1
- package/dist/component/server/http.js +287 -0
- package/dist/component/server/http.js.map +1 -0
- package/dist/component/server/identity.js +13 -0
- package/dist/component/server/identity.js.map +1 -0
- package/dist/component/server/keys.js +4 -0
- package/dist/component/server/keys.js.map +1 -1
- package/dist/component/server/mutations/account.js +1 -1
- package/dist/component/server/mutations/index.js +2 -2
- package/dist/component/server/mutations/index.js.map +1 -1
- package/dist/component/server/mutations/invalidate.js +1 -1
- package/dist/component/server/mutations/oauth.js +10 -7
- package/dist/component/server/mutations/oauth.js.map +1 -1
- package/dist/component/server/mutations/refresh.js +1 -1
- package/dist/component/server/mutations/register.js +1 -1
- package/dist/component/server/mutations/retrieve.js +1 -1
- package/dist/component/server/mutations/signature.js +1 -1
- package/dist/component/server/mutations/store.js +6 -3
- package/dist/component/server/mutations/store.js.map +1 -1
- package/dist/component/server/mutations/verify.js +1 -1
- package/dist/component/server/oauth.js +3 -0
- package/dist/component/server/oauth.js.map +1 -1
- package/dist/component/server/passkey.js +3 -2
- package/dist/component/server/passkey.js.map +1 -1
- package/dist/component/server/provider.js +2 -0
- package/dist/component/server/provider.js.map +1 -1
- package/dist/component/server/providers.js +10 -0
- package/dist/component/server/providers.js.map +1 -1
- package/dist/component/server/ratelimit.js +3 -0
- package/dist/component/server/ratelimit.js.map +1 -1
- package/dist/component/server/redirects.js +2 -0
- package/dist/component/server/redirects.js.map +1 -1
- package/dist/component/server/refresh.js +5 -0
- package/dist/component/server/refresh.js.map +1 -1
- package/dist/component/server/sessions.js +5 -0
- package/dist/component/server/sessions.js.map +1 -1
- package/dist/component/server/signin.js +2 -1
- package/dist/component/server/signin.js.map +1 -1
- package/dist/component/server/sso.js +166 -19
- package/dist/component/server/sso.js.map +1 -1
- package/dist/component/server/tokens.js +1 -0
- package/dist/component/server/tokens.js.map +1 -1
- package/dist/component/server/totp.js +4 -2
- package/dist/component/server/totp.js.map +1 -1
- package/dist/component/server/types.d.ts +106 -38
- 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 +1 -0
- package/dist/component/server/users.js.map +1 -1
- package/dist/component/server/utils.js +44 -2
- package/dist/component/server/utils.js.map +1 -1
- package/dist/providers/anonymous.d.ts +1 -1
- package/dist/providers/credentials.d.ts +1 -1
- package/dist/providers/password.d.ts +1 -1
- package/dist/providers/sso.d.ts +1 -1
- package/dist/providers/sso.js.map +1 -1
- package/dist/server/auth.d.ts +163 -17
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +100 -7
- package/dist/server/auth.js.map +1 -1
- package/dist/server/cookies.d.ts +1 -38
- package/dist/server/cookies.js +3 -0
- package/dist/server/cookies.js.map +1 -1
- package/dist/server/db.d.ts +1 -125
- package/dist/server/db.js +1 -0
- package/dist/server/db.js.map +1 -1
- package/dist/server/device.d.ts +1 -24
- package/dist/server/device.js +3 -1
- package/dist/server/device.js.map +1 -1
- package/dist/server/domains/core.d.ts +434 -0
- package/dist/server/domains/core.d.ts.map +1 -0
- package/dist/server/domains/core.js +629 -0
- package/dist/server/domains/core.js.map +1 -0
- package/dist/server/domains/sso.d.ts +409 -0
- package/dist/server/domains/sso.d.ts.map +1 -0
- package/dist/server/domains/sso.js +884 -0
- package/dist/server/domains/sso.js.map +1 -0
- package/dist/server/enterpriseValidators.d.ts +1 -0
- package/dist/server/enterpriseValidators.js +60 -0
- package/dist/server/enterpriseValidators.js.map +1 -0
- package/dist/server/factory.d.ts +136 -0
- package/dist/server/factory.d.ts.map +1 -0
- package/dist/server/factory.js +1134 -0
- package/dist/server/factory.js.map +1 -0
- package/dist/server/fx.d.ts +1 -16
- package/dist/server/fx.d.ts.map +1 -1
- package/dist/server/fx.js +1 -0
- package/dist/server/fx.js.map +1 -1
- package/dist/server/http.d.ts +59 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +287 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/identity.d.ts +1 -0
- package/dist/server/identity.js +13 -0
- package/dist/server/identity.js.map +1 -0
- package/dist/server/index.d.ts +468 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +530 -36
- package/dist/server/index.js.map +1 -1
- package/dist/server/keys.d.ts +1 -57
- package/dist/server/keys.js +4 -0
- package/dist/server/keys.js.map +1 -1
- package/dist/server/mutations/account.d.ts +7 -7
- package/dist/server/mutations/account.d.ts.map +1 -1
- package/dist/server/mutations/code.d.ts +13 -13
- package/dist/server/mutations/code.d.ts.map +1 -1
- package/dist/server/mutations/index.d.ts +107 -107
- package/dist/server/mutations/index.d.ts.map +1 -1
- package/dist/server/mutations/index.js +1 -1
- package/dist/server/mutations/index.js.map +1 -1
- package/dist/server/mutations/invalidate.d.ts +5 -5
- package/dist/server/mutations/invalidate.d.ts.map +1 -1
- package/dist/server/mutations/oauth.d.ts +10 -10
- package/dist/server/mutations/oauth.d.ts.map +1 -1
- package/dist/server/mutations/oauth.js +9 -6
- package/dist/server/mutations/oauth.js.map +1 -1
- package/dist/server/mutations/refresh.d.ts +4 -4
- package/dist/server/mutations/register.d.ts +12 -12
- package/dist/server/mutations/register.d.ts.map +1 -1
- package/dist/server/mutations/retrieve.d.ts +7 -7
- package/dist/server/mutations/signature.d.ts +5 -5
- package/dist/server/mutations/signin.d.ts +6 -6
- package/dist/server/mutations/signin.d.ts.map +1 -1
- package/dist/server/mutations/signout.d.ts +1 -1
- package/dist/server/mutations/store.d.ts +3 -2
- package/dist/server/mutations/store.d.ts.map +1 -1
- package/dist/server/mutations/store.js +6 -3
- package/dist/server/mutations/store.js.map +1 -1
- package/dist/server/mutations/verifier.d.ts +1 -1
- package/dist/server/mutations/verify.d.ts +11 -11
- package/dist/server/mutations/verify.d.ts.map +1 -1
- package/dist/server/oauth.d.ts +1 -59
- package/dist/server/oauth.js +3 -0
- package/dist/server/oauth.js.map +1 -1
- package/dist/server/passkey.d.ts.map +1 -1
- package/dist/server/passkey.js +3 -2
- package/dist/server/passkey.js.map +1 -1
- package/dist/server/provider.d.ts +1 -14
- package/dist/server/provider.d.ts.map +1 -1
- package/dist/server/provider.js +2 -0
- package/dist/server/provider.js.map +1 -1
- package/dist/server/providers.js +10 -0
- package/dist/server/providers.js.map +1 -1
- package/dist/server/ratelimit.d.ts +1 -22
- package/dist/server/ratelimit.js +3 -0
- package/dist/server/ratelimit.js.map +1 -1
- package/dist/server/redirects.d.ts +1 -10
- package/dist/server/redirects.js +2 -0
- package/dist/server/redirects.js.map +1 -1
- package/dist/server/refresh.d.ts +1 -37
- package/dist/server/refresh.js +5 -0
- package/dist/server/refresh.js.map +1 -1
- package/dist/server/sessions.d.ts +1 -28
- package/dist/server/sessions.js +5 -0
- package/dist/server/sessions.js.map +1 -1
- package/dist/server/signin.d.ts +1 -55
- package/dist/server/signin.js +2 -1
- package/dist/server/signin.js.map +1 -1
- package/dist/server/sso.d.ts +1 -348
- package/dist/server/sso.js +165 -18
- package/dist/server/sso.js.map +1 -1
- package/dist/server/templates.d.ts +1 -21
- package/dist/server/templates.js +1 -0
- package/dist/server/templates.js.map +1 -1
- package/dist/server/tokens.d.ts +1 -11
- package/dist/server/tokens.js +1 -0
- package/dist/server/tokens.js.map +1 -1
- package/dist/server/totp.d.ts +1 -23
- package/dist/server/totp.js +4 -2
- package/dist/server/totp.js.map +1 -1
- package/dist/server/types.d.ts +114 -77
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js.map +1 -1
- package/dist/server/users.d.ts +1 -31
- package/dist/server/users.js +1 -0
- package/dist/server/users.js.map +1 -1
- package/dist/server/utils.d.ts +1 -27
- package/dist/server/utils.js +44 -2
- package/dist/server/utils.js.map +1 -1
- package/dist/server/version.d.ts +1 -1
- package/dist/server/version.js +1 -1
- package/dist/server/version.js.map +1 -1
- package/package.json +4 -5
- package/src/cli/bin.ts +5 -0
- package/src/cli/index.ts +22 -9
- package/src/cli/keys.ts +3 -0
- package/src/client/index.ts +36 -37
- package/src/component/_generated/api.ts +14 -0
- package/src/component/_generated/component.ts +2106 -9
- package/src/component/index.ts +3 -1
- package/src/component/model.ts +441 -0
- package/src/component/public/enterprise.ts +753 -0
- package/src/component/public/factors.ts +332 -0
- package/src/component/public/groups.ts +932 -0
- package/src/component/public/identity.ts +566 -0
- package/src/component/public/keys.ts +209 -0
- package/src/component/public/shared.ts +119 -0
- package/src/component/public.ts +5 -2965
- package/src/component/schema.ts +68 -63
- package/src/providers/sso.ts +1 -1
- package/src/server/auth.ts +413 -18
- package/src/server/cookies.ts +3 -0
- package/src/server/db.ts +3 -0
- package/src/server/device.ts +3 -1
- package/src/server/domains/core.ts +1071 -0
- package/src/server/domains/sso.ts +1749 -0
- package/src/server/enterpriseValidators.ts +93 -0
- package/src/server/factory.ts +2181 -0
- package/src/server/fx.ts +1 -0
- package/src/server/http.ts +529 -0
- package/src/server/identity.ts +18 -0
- package/src/server/index.ts +806 -40
- package/src/server/keys.ts +4 -0
- package/src/server/mutations/index.ts +1 -1
- package/src/server/mutations/oauth.ts +36 -8
- package/src/server/mutations/store.ts +6 -3
- package/src/server/oauth.ts +6 -0
- package/src/server/passkey.ts +3 -2
- package/src/server/provider.ts +2 -0
- package/src/server/providers.ts +20 -0
- package/src/server/ratelimit.ts +3 -0
- package/src/server/redirects.ts +2 -0
- package/src/server/refresh.ts +5 -0
- package/src/server/sessions.ts +5 -0
- package/src/server/signin.ts +1 -0
- package/src/server/sso.ts +259 -17
- package/src/server/templates.ts +1 -0
- package/src/server/tokens.ts +1 -0
- package/src/server/totp.ts +4 -2
- package/src/server/types.ts +178 -83
- package/src/server/users.ts +1 -0
- package/src/server/utils.ts +71 -1
- package/src/server/version.ts +1 -1
- package/dist/component/public.js.map +0 -1
- package/dist/component/server/implementation.d.ts +0 -1264
- package/dist/component/server/implementation.d.ts.map +0 -1
- package/dist/component/server/implementation.js +0 -2365
- package/dist/component/server/implementation.js.map +0 -1
- package/dist/server/cookies.d.ts.map +0 -1
- package/dist/server/db.d.ts.map +0 -1
- package/dist/server/device.d.ts.map +0 -1
- package/dist/server/implementation.d.ts +0 -1264
- package/dist/server/implementation.d.ts.map +0 -1
- package/dist/server/implementation.js +0 -2365
- package/dist/server/implementation.js.map +0 -1
- package/dist/server/keys.d.ts.map +0 -1
- package/dist/server/oauth.d.ts.map +0 -1
- package/dist/server/ratelimit.d.ts.map +0 -1
- package/dist/server/redirects.d.ts.map +0 -1
- package/dist/server/refresh.d.ts.map +0 -1
- package/dist/server/sessions.d.ts.map +0 -1
- package/dist/server/signin.d.ts.map +0 -1
- package/dist/server/sso.d.ts.map +0 -1
- package/dist/server/templates.d.ts.map +0 -1
- package/dist/server/tokens.d.ts.map +0 -1
- package/dist/server/totp.d.ts.map +0 -1
- package/dist/server/users.d.ts.map +0 -1
- package/dist/server/utils.d.ts.map +0 -1
- package/src/server/implementation.ts +0 -5336
package/src/server/auth.ts
CHANGED
|
@@ -8,12 +8,16 @@ import type { UserIdentity } from "convex/server";
|
|
|
8
8
|
import type { GenericId } from "convex/values";
|
|
9
9
|
|
|
10
10
|
import type { AuthApiRefs } from "../client/index";
|
|
11
|
+
import { Auth as AuthFactory } from "./factory";
|
|
11
12
|
import { Fx } from "./fx";
|
|
12
13
|
import { AuthError } from "./fx";
|
|
13
|
-
import { Auth as AuthFactory } from "./implementation";
|
|
14
14
|
import type { Doc } from "./types";
|
|
15
15
|
import type {
|
|
16
|
+
AuthAuthorizationConfig,
|
|
17
|
+
AuthGrant,
|
|
16
18
|
AuthProviderConfig,
|
|
19
|
+
AuthRoleDefinition,
|
|
20
|
+
AuthRoleId,
|
|
17
21
|
ConvexAuthConfig,
|
|
18
22
|
HasDeviceProvider,
|
|
19
23
|
HasPasskeyProvider,
|
|
@@ -31,8 +35,105 @@ import type {
|
|
|
31
35
|
*/
|
|
32
36
|
export type AuthConfig = Omit<ConvexAuthConfig, "component">;
|
|
33
37
|
|
|
38
|
+
type MemberApiWithAuthorization<
|
|
39
|
+
TAuthorization extends AuthAuthorizationConfig | undefined,
|
|
40
|
+
> = Omit<
|
|
41
|
+
ReturnType<typeof AuthFactory>["auth"]["member"],
|
|
42
|
+
"create" | "list" | "update" | "inherit" | "require"
|
|
43
|
+
> & {
|
|
44
|
+
create: (
|
|
45
|
+
ctx: Parameters<
|
|
46
|
+
ReturnType<typeof AuthFactory>["auth"]["member"]["create"]
|
|
47
|
+
>[0],
|
|
48
|
+
data: {
|
|
49
|
+
groupId: string;
|
|
50
|
+
userId: string;
|
|
51
|
+
roleIds?: AuthRoleId<TAuthorization>[];
|
|
52
|
+
status?: string;
|
|
53
|
+
extend?: Record<string, unknown>;
|
|
54
|
+
},
|
|
55
|
+
) => Promise<{ ok: true; memberId: string }>;
|
|
56
|
+
list: (
|
|
57
|
+
ctx: Parameters<
|
|
58
|
+
ReturnType<typeof AuthFactory>["auth"]["member"]["list"]
|
|
59
|
+
>[0],
|
|
60
|
+
opts?: {
|
|
61
|
+
where?: {
|
|
62
|
+
groupId?: string;
|
|
63
|
+
userId?: string;
|
|
64
|
+
roleId?: AuthRoleId<TAuthorization>;
|
|
65
|
+
status?: string;
|
|
66
|
+
};
|
|
67
|
+
limit?: number;
|
|
68
|
+
cursor?: string | null;
|
|
69
|
+
orderBy?: "_creationTime" | "status";
|
|
70
|
+
order?: "asc" | "desc";
|
|
71
|
+
},
|
|
72
|
+
) => ReturnType<ReturnType<typeof AuthFactory>["auth"]["member"]["list"]>;
|
|
73
|
+
update: (
|
|
74
|
+
ctx: Parameters<
|
|
75
|
+
ReturnType<typeof AuthFactory>["auth"]["member"]["update"]
|
|
76
|
+
>[0],
|
|
77
|
+
memberId: string,
|
|
78
|
+
data: Record<string, unknown> & { roleIds?: AuthRoleId<TAuthorization>[] },
|
|
79
|
+
) => Promise<{ ok: true; memberId: string }>;
|
|
80
|
+
inherit: (
|
|
81
|
+
ctx: Parameters<
|
|
82
|
+
ReturnType<typeof AuthFactory>["auth"]["member"]["inherit"]
|
|
83
|
+
>[0],
|
|
84
|
+
opts: {
|
|
85
|
+
userId: string;
|
|
86
|
+
groupId: string;
|
|
87
|
+
roleIds?: AuthRoleId<TAuthorization>[];
|
|
88
|
+
grants?: AuthGrant<TAuthorization>[];
|
|
89
|
+
maxDepth?: number;
|
|
90
|
+
},
|
|
91
|
+
) => ReturnType<ReturnType<typeof AuthFactory>["auth"]["member"]["inherit"]>;
|
|
92
|
+
require: (
|
|
93
|
+
ctx: Parameters<
|
|
94
|
+
ReturnType<typeof AuthFactory>["auth"]["member"]["require"]
|
|
95
|
+
>[0],
|
|
96
|
+
opts: {
|
|
97
|
+
userId: string;
|
|
98
|
+
groupId: string;
|
|
99
|
+
roleIds?: AuthRoleId<TAuthorization>[];
|
|
100
|
+
grants?: AuthGrant<TAuthorization>[];
|
|
101
|
+
maxDepth?: number;
|
|
102
|
+
},
|
|
103
|
+
) => ReturnType<ReturnType<typeof AuthFactory>["auth"]["member"]["require"]>;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
type AccessApiWithAuthorization<
|
|
107
|
+
TAuthorization extends AuthAuthorizationConfig | undefined,
|
|
108
|
+
> = {
|
|
109
|
+
check: (
|
|
110
|
+
ctx: Parameters<
|
|
111
|
+
ReturnType<typeof AuthFactory>["auth"]["access"]["check"]
|
|
112
|
+
>[0],
|
|
113
|
+
opts: {
|
|
114
|
+
userId: string;
|
|
115
|
+
groupId: string;
|
|
116
|
+
grants: AuthGrant<TAuthorization>[];
|
|
117
|
+
maxDepth?: number;
|
|
118
|
+
},
|
|
119
|
+
) => ReturnType<ReturnType<typeof AuthFactory>["auth"]["access"]["check"]>;
|
|
120
|
+
require: (
|
|
121
|
+
ctx: Parameters<
|
|
122
|
+
ReturnType<typeof AuthFactory>["auth"]["access"]["require"]
|
|
123
|
+
>[0],
|
|
124
|
+
opts: {
|
|
125
|
+
userId: string;
|
|
126
|
+
groupId: string;
|
|
127
|
+
grants: AuthGrant<TAuthorization>[];
|
|
128
|
+
maxDepth?: number;
|
|
129
|
+
},
|
|
130
|
+
) => ReturnType<ReturnType<typeof AuthFactory>["auth"]["access"]["require"]>;
|
|
131
|
+
};
|
|
132
|
+
|
|
34
133
|
/** The base auth API surface, without conditional namespaces. */
|
|
35
|
-
export type AuthApiBase
|
|
134
|
+
export type AuthApiBase<
|
|
135
|
+
TAuthorization extends AuthAuthorizationConfig | undefined = undefined,
|
|
136
|
+
> = {
|
|
36
137
|
signIn: ReturnType<typeof AuthFactory>["signIn"];
|
|
37
138
|
signOut: ReturnType<typeof AuthFactory>["signOut"];
|
|
38
139
|
store: ReturnType<typeof AuthFactory>["store"];
|
|
@@ -41,24 +142,115 @@ export type AuthApiBase = {
|
|
|
41
142
|
provider: ReturnType<typeof AuthFactory>["auth"]["provider"];
|
|
42
143
|
account: ReturnType<typeof AuthFactory>["auth"]["account"];
|
|
43
144
|
group: ReturnType<typeof AuthFactory>["auth"]["group"];
|
|
44
|
-
member:
|
|
145
|
+
member: MemberApiWithAuthorization<TAuthorization>;
|
|
146
|
+
access: AccessApiWithAuthorization<TAuthorization>;
|
|
45
147
|
invite: ReturnType<typeof AuthFactory>["auth"]["invite"];
|
|
46
148
|
key: ReturnType<typeof AuthFactory>["auth"]["key"];
|
|
47
149
|
http: ReturnType<typeof AuthFactory>["auth"]["http"];
|
|
48
150
|
};
|
|
49
151
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
152
|
+
type InternalSsoApi = ReturnType<typeof AuthFactory>["auth"]["sso"];
|
|
153
|
+
|
|
154
|
+
type PublicSsoAdminApi = {
|
|
155
|
+
connection: InternalSsoApi["connection"] & {
|
|
156
|
+
domain: {
|
|
157
|
+
list: InternalSsoApi["domain"]["list"];
|
|
158
|
+
validate: InternalSsoApi["domain"]["validate"];
|
|
159
|
+
set: (
|
|
160
|
+
ctx: Parameters<InternalSsoApi["connection"]["create"]>[0],
|
|
161
|
+
enterpriseId: string,
|
|
162
|
+
domains: Array<{
|
|
163
|
+
domain: string;
|
|
164
|
+
isPrimary?: boolean;
|
|
165
|
+
}>,
|
|
166
|
+
) => Promise<{
|
|
167
|
+
ok: true;
|
|
168
|
+
enterpriseId: string;
|
|
169
|
+
domains: Array<{
|
|
170
|
+
domainId: string;
|
|
171
|
+
domain: string;
|
|
172
|
+
isPrimary: boolean;
|
|
173
|
+
verified: boolean;
|
|
174
|
+
verifiedAt: number | null;
|
|
175
|
+
}>;
|
|
176
|
+
}>;
|
|
177
|
+
verification: {
|
|
178
|
+
request: (
|
|
179
|
+
ctx: Parameters<InternalSsoApi["connection"]["create"]>[0],
|
|
180
|
+
args: { enterpriseId: string; domain: string },
|
|
181
|
+
) => Promise<{
|
|
182
|
+
ok: true;
|
|
183
|
+
enterpriseId: string;
|
|
184
|
+
domain: string;
|
|
185
|
+
requestedAt: number;
|
|
186
|
+
expiresAt: number;
|
|
187
|
+
challenge: {
|
|
188
|
+
recordType: "TXT";
|
|
189
|
+
recordName: string;
|
|
190
|
+
recordValue: string;
|
|
191
|
+
};
|
|
192
|
+
}>;
|
|
193
|
+
confirm: (
|
|
194
|
+
ctx: Parameters<InternalSsoApi["connection"]["create"]>[0],
|
|
195
|
+
args: { enterpriseId: string; domain: string },
|
|
196
|
+
) => Promise<{
|
|
197
|
+
ok: boolean;
|
|
198
|
+
enterpriseId: string;
|
|
199
|
+
domain: string;
|
|
200
|
+
verifiedAt?: number;
|
|
201
|
+
checks: Array<{ name: string; ok: boolean; message?: string }>;
|
|
202
|
+
}>;
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
};
|
|
206
|
+
oidc: Omit<InternalSsoApi["oidc"], "signIn">;
|
|
207
|
+
saml: Omit<InternalSsoApi["saml"], "metadata">;
|
|
208
|
+
policy: InternalSsoApi["policy"];
|
|
209
|
+
audit: {
|
|
210
|
+
list: InternalSsoApi["audit"]["list"];
|
|
211
|
+
};
|
|
212
|
+
webhook: {
|
|
213
|
+
endpoint: InternalSsoApi["webhook"]["endpoint"];
|
|
214
|
+
delivery: {
|
|
215
|
+
list: InternalSsoApi["webhook"]["delivery"]["list"];
|
|
216
|
+
};
|
|
217
|
+
};
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
type PublicSsoClientApi = {
|
|
221
|
+
signIn: InternalSsoApi["oidc"]["signIn"];
|
|
222
|
+
metadata: InternalSsoApi["saml"]["metadata"];
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
type PublicSsoApi = {
|
|
226
|
+
admin: PublicSsoAdminApi;
|
|
227
|
+
client: PublicSsoClientApi;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
type PublicScimApi = {
|
|
231
|
+
admin: Omit<InternalSsoApi["scim"], "getConfigByToken" | "identity">;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
/** Auth API with enterprise namespaces — present only when `new SSO()` is in providers. */
|
|
235
|
+
export type AuthApi<
|
|
236
|
+
TAuthorization extends AuthAuthorizationConfig | undefined = undefined,
|
|
237
|
+
> = AuthApiBase<TAuthorization> & {
|
|
238
|
+
sso: PublicSsoApi;
|
|
239
|
+
scim: PublicScimApi;
|
|
53
240
|
};
|
|
54
241
|
|
|
55
242
|
/**
|
|
56
243
|
* The return type of `createAuth`. Conditional namespaces:
|
|
57
|
-
* - `auth.sso` — only when `new SSO()` is in providers
|
|
244
|
+
* - `auth.sso` and `auth.scim` — only when `new SSO()` is in providers
|
|
58
245
|
* - `auth.clientApi` — typed API refs for the client SDK with capabilities
|
|
59
246
|
*/
|
|
60
|
-
export type ConvexAuthResult<
|
|
61
|
-
|
|
247
|
+
export type ConvexAuthResult<
|
|
248
|
+
P extends AuthProviderConfig[],
|
|
249
|
+
TAuthorization extends AuthAuthorizationConfig | undefined = undefined,
|
|
250
|
+
> =
|
|
251
|
+
HasSSO<P> extends true
|
|
252
|
+
? AuthApi<TAuthorization>
|
|
253
|
+
: AuthApiBase<TAuthorization>;
|
|
62
254
|
|
|
63
255
|
/**
|
|
64
256
|
* Infer the typed `AuthApiRefs` for the client SDK from a `createAuth` call.
|
|
@@ -72,7 +264,7 @@ export type ConvexAuthResult<P extends AuthProviderConfig[]> =
|
|
|
72
264
|
* // Frontend
|
|
73
265
|
* import type { auth } from "../convex/auth";
|
|
74
266
|
* import type { InferClientApi } from "@robelest/convex-auth/component";
|
|
75
|
-
* const c = client<InferClientApi<typeof auth>>({ convex, api:
|
|
267
|
+
* const c = client<InferClientApi<typeof auth>>({ convex, api: api.auth });
|
|
76
268
|
* ```
|
|
77
269
|
*/
|
|
78
270
|
export type InferClientApi<T> =
|
|
@@ -94,19 +286,182 @@ export type AuthLike = Pick<AuthApiBase, "user">;
|
|
|
94
286
|
/**
|
|
95
287
|
* Create an auth API object.
|
|
96
288
|
*
|
|
97
|
-
* When `new SSO()` is included in providers, `auth.sso`
|
|
98
|
-
* on the returned object. Without it,
|
|
99
|
-
* accessing
|
|
289
|
+
* When `new SSO()` is included in providers, `auth.sso` and `auth.scim`
|
|
290
|
+
* are available on the returned object. Without it, those namespaces are
|
|
291
|
+
* absent and accessing them is a TypeScript compile error.
|
|
100
292
|
*/
|
|
101
|
-
export function createAuth<
|
|
293
|
+
export function createAuth<
|
|
294
|
+
P extends AuthProviderConfig[],
|
|
295
|
+
TAuthorization extends AuthAuthorizationConfig | undefined = undefined,
|
|
296
|
+
>(
|
|
102
297
|
component: ConvexAuthConfig["component"],
|
|
103
|
-
config: Omit<AuthConfig, "providers"> & {
|
|
104
|
-
|
|
298
|
+
config: Omit<AuthConfig, "providers" | "authorization"> & {
|
|
299
|
+
providers: P;
|
|
300
|
+
authorization?: TAuthorization;
|
|
301
|
+
},
|
|
302
|
+
): ConvexAuthResult<P, TAuthorization> {
|
|
105
303
|
const authResult = AuthFactory({
|
|
106
304
|
...config,
|
|
107
305
|
component,
|
|
108
306
|
providers: [...config.providers],
|
|
109
307
|
});
|
|
308
|
+
const {
|
|
309
|
+
domain: domainApi,
|
|
310
|
+
scim: scimApi,
|
|
311
|
+
connection: connectionApi,
|
|
312
|
+
audit: auditApi,
|
|
313
|
+
webhook: webhookApi,
|
|
314
|
+
oidc: oidcApi,
|
|
315
|
+
saml: samlApi,
|
|
316
|
+
...restSso
|
|
317
|
+
} = authResult.auth.sso as InternalSsoApi;
|
|
318
|
+
|
|
319
|
+
type SetEnterpriseDomains = PublicSsoAdminApi["connection"]["domain"]["set"];
|
|
320
|
+
type EnterpriseDomainInput = Array<{
|
|
321
|
+
domain: string;
|
|
322
|
+
isPrimary?: boolean;
|
|
323
|
+
}>;
|
|
324
|
+
const setEnterpriseDomains: PublicSsoAdminApi["connection"]["domain"]["set"] =
|
|
325
|
+
async (
|
|
326
|
+
ctx: Parameters<SetEnterpriseDomains>[0],
|
|
327
|
+
enterpriseId: Parameters<SetEnterpriseDomains>[1],
|
|
328
|
+
domains: EnterpriseDomainInput,
|
|
329
|
+
) => {
|
|
330
|
+
const enterprise = await connectionApi.get(ctx, enterpriseId);
|
|
331
|
+
if (enterprise === null) {
|
|
332
|
+
throw new AuthError(
|
|
333
|
+
"INVALID_PARAMETERS",
|
|
334
|
+
"Enterprise not found.",
|
|
335
|
+
).toConvexError();
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const normalized = domains.map((entry: (typeof domains)[number]) => ({
|
|
339
|
+
...entry,
|
|
340
|
+
domain: entry.domain.trim().toLowerCase(),
|
|
341
|
+
}));
|
|
342
|
+
const deduped = new Map<string, (typeof normalized)[number]>();
|
|
343
|
+
for (const entry of normalized) {
|
|
344
|
+
if (entry.domain.length === 0) {
|
|
345
|
+
throw new AuthError(
|
|
346
|
+
"INVALID_PARAMETERS",
|
|
347
|
+
"Domain must not be empty.",
|
|
348
|
+
).toConvexError();
|
|
349
|
+
}
|
|
350
|
+
if (deduped.has(entry.domain)) {
|
|
351
|
+
throw new AuthError(
|
|
352
|
+
"INVALID_PARAMETERS",
|
|
353
|
+
`Duplicate domain: ${entry.domain}`,
|
|
354
|
+
).toConvexError();
|
|
355
|
+
}
|
|
356
|
+
deduped.set(entry.domain, entry);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const nextDomains = [...deduped.values()];
|
|
360
|
+
const primaryCount = nextDomains.filter(
|
|
361
|
+
(entry) => entry.isPrimary,
|
|
362
|
+
).length;
|
|
363
|
+
if (primaryCount > 1) {
|
|
364
|
+
throw new AuthError(
|
|
365
|
+
"INVALID_PARAMETERS",
|
|
366
|
+
"Only one primary domain may be set.",
|
|
367
|
+
).toConvexError();
|
|
368
|
+
}
|
|
369
|
+
if (nextDomains.length > 0 && primaryCount === 0) {
|
|
370
|
+
nextDomains[0] = { ...nextDomains[0], isPrimary: true };
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const currentDomains = await domainApi.list(ctx, enterpriseId);
|
|
374
|
+
const currentByDomain = new Map<string, (typeof currentDomains)[number]>(
|
|
375
|
+
currentDomains.map((entry: (typeof currentDomains)[number]) => [
|
|
376
|
+
entry.domain.toLowerCase(),
|
|
377
|
+
entry,
|
|
378
|
+
]),
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
for (const existing of currentDomains) {
|
|
382
|
+
if (!deduped.has(existing.domain.toLowerCase())) {
|
|
383
|
+
await domainApi.remove(ctx, existing._id);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
for (const nextDomain of nextDomains) {
|
|
388
|
+
const current = currentByDomain.get(nextDomain.domain);
|
|
389
|
+
if (current && current.isPrimary === Boolean(nextDomain.isPrimary)) {
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
if (current) {
|
|
393
|
+
await domainApi.remove(ctx, current._id);
|
|
394
|
+
}
|
|
395
|
+
const domainId = await domainApi.add(ctx, {
|
|
396
|
+
enterpriseId: enterprise._id,
|
|
397
|
+
groupId: enterprise.groupId,
|
|
398
|
+
domain: nextDomain.domain,
|
|
399
|
+
isPrimary: nextDomain.isPrimary,
|
|
400
|
+
});
|
|
401
|
+
if (current?.verifiedAt !== undefined) {
|
|
402
|
+
await (ctx as any).runMutation(
|
|
403
|
+
component.public.enterpriseDomainVerify,
|
|
404
|
+
{
|
|
405
|
+
domainId,
|
|
406
|
+
verifiedAt: current.verifiedAt,
|
|
407
|
+
},
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const updatedDomains = await domainApi.list(ctx, enterpriseId);
|
|
413
|
+
return {
|
|
414
|
+
ok: true as const,
|
|
415
|
+
enterpriseId,
|
|
416
|
+
domains: updatedDomains.map(
|
|
417
|
+
(domain: (typeof updatedDomains)[number]) => ({
|
|
418
|
+
domainId: domain._id,
|
|
419
|
+
domain: domain.domain,
|
|
420
|
+
isPrimary: domain.isPrimary,
|
|
421
|
+
verified: domain.verifiedAt !== undefined,
|
|
422
|
+
verifiedAt: domain.verifiedAt ?? null,
|
|
423
|
+
}),
|
|
424
|
+
),
|
|
425
|
+
};
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
const publicSso: PublicSsoApi = {
|
|
429
|
+
admin: {
|
|
430
|
+
...restSso,
|
|
431
|
+
oidc: {
|
|
432
|
+
...oidcApi,
|
|
433
|
+
},
|
|
434
|
+
saml: {
|
|
435
|
+
...samlApi,
|
|
436
|
+
},
|
|
437
|
+
connection: {
|
|
438
|
+
...connectionApi,
|
|
439
|
+
domain: {
|
|
440
|
+
list: domainApi.list,
|
|
441
|
+
validate: domainApi.validate,
|
|
442
|
+
set: setEnterpriseDomains,
|
|
443
|
+
verification: {
|
|
444
|
+
request: domainApi.verification.request,
|
|
445
|
+
confirm: domainApi.verification.confirm,
|
|
446
|
+
},
|
|
447
|
+
},
|
|
448
|
+
},
|
|
449
|
+
policy: restSso.policy,
|
|
450
|
+
audit: {
|
|
451
|
+
list: auditApi.list,
|
|
452
|
+
},
|
|
453
|
+
webhook: {
|
|
454
|
+
endpoint: webhookApi.endpoint,
|
|
455
|
+
delivery: {
|
|
456
|
+
list: webhookApi.delivery.list,
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
},
|
|
460
|
+
client: {
|
|
461
|
+
signIn: oidcApi.signIn,
|
|
462
|
+
metadata: samlApi.metadata,
|
|
463
|
+
},
|
|
464
|
+
};
|
|
110
465
|
|
|
111
466
|
return {
|
|
112
467
|
signIn: authResult.signIn,
|
|
@@ -118,11 +473,51 @@ export function createAuth<P extends AuthProviderConfig[]>(
|
|
|
118
473
|
account: authResult.auth.account,
|
|
119
474
|
group: authResult.auth.group,
|
|
120
475
|
member: authResult.auth.member,
|
|
476
|
+
access: authResult.auth.access,
|
|
121
477
|
invite: authResult.auth.invite,
|
|
122
478
|
key: authResult.auth.key,
|
|
123
|
-
sso:
|
|
479
|
+
sso: publicSso,
|
|
480
|
+
scim: {
|
|
481
|
+
admin: {
|
|
482
|
+
configure: scimApi.configure,
|
|
483
|
+
get: scimApi.get,
|
|
484
|
+
validate: scimApi.validate,
|
|
485
|
+
},
|
|
486
|
+
},
|
|
124
487
|
http: authResult.auth.http,
|
|
125
|
-
} as ConvexAuthResult<P>;
|
|
488
|
+
} as unknown as ConvexAuthResult<P, TAuthorization>;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export function defineRoles<
|
|
492
|
+
const TRoles extends Record<
|
|
493
|
+
string,
|
|
494
|
+
{ label?: string; grants: readonly string[] }
|
|
495
|
+
>,
|
|
496
|
+
>(
|
|
497
|
+
roles: TRoles,
|
|
498
|
+
): {
|
|
499
|
+
[K in keyof TRoles]: {
|
|
500
|
+
id: K & string;
|
|
501
|
+
label?: TRoles[K]["label"];
|
|
502
|
+
grants: Array<TRoles[K]["grants"][number] & string>;
|
|
503
|
+
};
|
|
504
|
+
} {
|
|
505
|
+
return Object.fromEntries(
|
|
506
|
+
Object.entries(roles).map(([id, role]) => [
|
|
507
|
+
id,
|
|
508
|
+
{
|
|
509
|
+
id,
|
|
510
|
+
...(role.label ? { label: role.label } : {}),
|
|
511
|
+
grants: [...role.grants],
|
|
512
|
+
},
|
|
513
|
+
]),
|
|
514
|
+
) as {
|
|
515
|
+
[K in keyof TRoles]: {
|
|
516
|
+
id: K & string;
|
|
517
|
+
label?: TRoles[K]["label"];
|
|
518
|
+
grants: Array<TRoles[K]["grants"][number] & string>;
|
|
519
|
+
};
|
|
520
|
+
};
|
|
126
521
|
}
|
|
127
522
|
|
|
128
523
|
// ============================================================================
|
package/src/server/cookies.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isLocalHost } from "./utils";
|
|
2
2
|
|
|
3
|
+
/** @internal */
|
|
3
4
|
export const SHARED_COOKIE_OPTIONS = {
|
|
4
5
|
httpOnly: true,
|
|
5
6
|
sameSite: "none" as const,
|
|
@@ -9,6 +10,7 @@ export const SHARED_COOKIE_OPTIONS = {
|
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
const REDIRECT_MAX_AGE = 60 * 15; // 15 minutes in seconds
|
|
13
|
+
/** @internal */
|
|
12
14
|
export function redirectToParamCookie(providerId: string, redirectTo: string) {
|
|
13
15
|
return {
|
|
14
16
|
name: redirectToParamCookieName(providerId),
|
|
@@ -17,6 +19,7 @@ export function redirectToParamCookie(providerId: string, redirectTo: string) {
|
|
|
17
19
|
};
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
/** @internal */
|
|
20
23
|
export function useRedirectToParam(
|
|
21
24
|
providerId: string,
|
|
22
25
|
cookies: Record<string, string | undefined>,
|
package/src/server/db.ts
CHANGED
|
@@ -56,10 +56,13 @@ type AuthComponentApiLike = {
|
|
|
56
56
|
};
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
+
/** @internal */
|
|
59
60
|
export type AuthDbConfig = { component: AuthComponentApiLike };
|
|
60
61
|
|
|
62
|
+
/** @internal */
|
|
61
63
|
export type AuthDb = ReturnType<typeof authDb>;
|
|
62
64
|
|
|
65
|
+
/** @internal */
|
|
63
66
|
export function authDb(ctx: CtxLike, config: AuthDbConfig) {
|
|
64
67
|
const component = config.component;
|
|
65
68
|
return {
|
package/src/server/device.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import { Fx } from "@robelest/fx";
|
|
14
14
|
|
|
15
15
|
import { AuthError } from "./fx";
|
|
16
|
+
import { userIdFromIdentitySubject } from "./identity";
|
|
16
17
|
import { callSignIn } from "./mutations/index";
|
|
17
18
|
import { DeviceProviderConfig, GenericActionCtxWithAuthConfig } from "./types";
|
|
18
19
|
import {
|
|
@@ -63,6 +64,7 @@ type DeviceResult =
|
|
|
63
64
|
}
|
|
64
65
|
| { kind: "signedIn"; signedIn: SessionInfo | null };
|
|
65
66
|
|
|
67
|
+
/** @internal */
|
|
66
68
|
export const handleDevice = (
|
|
67
69
|
ctx: EnrichedActionCtx,
|
|
68
70
|
provider: DeviceProviderConfig,
|
|
@@ -187,7 +189,7 @@ export const handleDevice = (
|
|
|
187
189
|
);
|
|
188
190
|
}
|
|
189
191
|
|
|
190
|
-
const userId = identity.subject
|
|
192
|
+
const userId = userIdFromIdentitySubject(identity.subject);
|
|
191
193
|
const doc = await queryDeviceByUserCode(ctx, params.userCode);
|
|
192
194
|
if (doc === null) {
|
|
193
195
|
throw new AuthError("DEVICE_INVALID_USER_CODE");
|