@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.
- package/README.md +10 -11
- 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/index.js +2 -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 +41 -41
- package/dist/component/server/auth.d.ts +127 -130
- package/dist/component/server/auth.d.ts.map +1 -1
- package/dist/component/server/auth.js +100 -64
- package/dist/component/server/auth.js.map +1 -1
- package/dist/component/server/context.js +53 -0
- package/dist/component/server/context.js.map +1 -0
- package/dist/component/server/core.js +113 -250
- 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 +59 -16
- 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.d.ts +85 -0
- package/dist/component/server/http.d.ts.map +1 -0
- package/dist/component/server/http.js +85 -22
- 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 +5 -5
- package/dist/component/server/runtime.js +156 -113
- 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 +127 -130
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +100 -64
- package/dist/server/auth.js.map +1 -1
- package/dist/server/context.d.ts +1 -0
- package/dist/server/context.js +53 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/core.d.ts +74 -195
- package/dist/server/core.d.ts.map +1 -1
- package/dist/server/core.js +113 -250
- 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 +59 -16
- 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 +81 -3
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +84 -21
- 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 +3 -2
- package/dist/server/index.js +2 -2
- package/dist/server/limits.js +21 -30
- package/dist/server/limits.js.map +1 -1
- package/dist/server/mounts.d.ts +25 -63
- package/dist/server/mounts.d.ts.map +1 -1
- package/dist/server/mounts.js +46 -107
- 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/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 +11 -11
- package/dist/server/runtime.js +155 -112
- 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 +9 -3
- 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 +240 -182
- package/src/server/context.ts +90 -0
- package/src/server/core.ts +195 -286
- 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 +289 -30
- package/src/server/identity.ts +5 -5
- package/src/server/index.ts +9 -3
- package/src/server/limits.ts +53 -80
- package/src/server/mounts.ts +56 -80
- 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 +340 -302
- 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
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { getSessionUserId } from "./context.js";
|
|
2
|
+
import { materializeProvider } from "./config.js";
|
|
1
3
|
import { TOKEN_SUB_CLAIM_DIVIDER, generateRandomString, sha256 } from "./utils.js";
|
|
2
4
|
import { buildScopeChecker, checkKeyRateLimit, generateApiKey, hashApiKey } from "./keys.js";
|
|
3
|
-
import { materializeProvider } from "./config.js";
|
|
4
5
|
import { signInImpl } from "./signin.js";
|
|
6
|
+
import { Cv } from "@robelest/fx/convex";
|
|
5
7
|
|
|
6
8
|
//#region src/server/core.ts
|
|
7
9
|
/**
|
|
@@ -26,14 +28,12 @@ function createCoreDomains(deps) {
|
|
|
26
28
|
const normalizeRoleIds = (roleIds) => {
|
|
27
29
|
const normalized = Array.from(new Set(roleIds ?? []));
|
|
28
30
|
const invalid = normalized.filter((id) => getRoleDefinition(id) === null);
|
|
29
|
-
if (invalid.length > 0)
|
|
30
|
-
|
|
31
|
+
if (invalid.length > 0) throw Cv.error({
|
|
32
|
+
code: "INVALID_ROLE_IDS",
|
|
33
|
+
message: "One or more role IDs are invalid.",
|
|
31
34
|
invalidRoleIds: invalid
|
|
32
|
-
};
|
|
33
|
-
return
|
|
34
|
-
ok: true,
|
|
35
|
-
roleIds: normalized
|
|
36
|
-
};
|
|
35
|
+
});
|
|
36
|
+
return normalized;
|
|
37
37
|
};
|
|
38
38
|
const listAllKeysByUser = async (ctx, userId) => {
|
|
39
39
|
const items = [];
|
|
@@ -81,23 +81,6 @@ function createCoreDomains(deps) {
|
|
|
81
81
|
return ctx[AUTH_CACHE];
|
|
82
82
|
}
|
|
83
83
|
const user = {
|
|
84
|
-
id: async (ctx, request) => {
|
|
85
|
-
const identity = await ctx.auth.getUserIdentity();
|
|
86
|
-
if (identity !== null) {
|
|
87
|
-
const [userId] = identity.subject.split(TOKEN_SUB_CLAIM_DIVIDER);
|
|
88
|
-
return userId;
|
|
89
|
-
}
|
|
90
|
-
if (request !== void 0 && "runMutation" in ctx && ctx.runMutation) {
|
|
91
|
-
const authHeader = request.headers.get("Authorization");
|
|
92
|
-
if (authHeader?.startsWith("Bearer sk_")) {
|
|
93
|
-
const rawKey = authHeader.slice(7);
|
|
94
|
-
const result = await getAuth().key.verify(ctx, rawKey);
|
|
95
|
-
if (result.ok) return result.userId;
|
|
96
|
-
return null;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return null;
|
|
100
|
-
},
|
|
101
84
|
get: async (ctx, userId) => {
|
|
102
85
|
const c = cache(ctx);
|
|
103
86
|
if (c.users.has(userId)) return c.users.get(userId);
|
|
@@ -109,7 +92,7 @@ function createCoreDomains(deps) {
|
|
|
109
92
|
return await ctx.runQuery(config.component.public.userList, opts);
|
|
110
93
|
},
|
|
111
94
|
viewer: async (ctx) => {
|
|
112
|
-
const userId = await
|
|
95
|
+
const userId = await getSessionUserId(ctx);
|
|
113
96
|
if (userId === null) return null;
|
|
114
97
|
return await user.get(ctx, userId);
|
|
115
98
|
},
|
|
@@ -118,10 +101,7 @@ function createCoreDomains(deps) {
|
|
|
118
101
|
userId,
|
|
119
102
|
data
|
|
120
103
|
});
|
|
121
|
-
return {
|
|
122
|
-
ok: true,
|
|
123
|
-
userId
|
|
124
|
-
};
|
|
104
|
+
return { userId };
|
|
125
105
|
},
|
|
126
106
|
setActiveGroup: async (ctx, opts) => {
|
|
127
107
|
const doc = await user.get(ctx, opts.userId);
|
|
@@ -130,7 +110,6 @@ function createCoreDomains(deps) {
|
|
|
130
110
|
const { lastActiveGroup: _omit, ...rest } = existingExtend;
|
|
131
111
|
await user.update(ctx, opts.userId, { extend: rest });
|
|
132
112
|
return {
|
|
133
|
-
ok: true,
|
|
134
113
|
userId: opts.userId,
|
|
135
114
|
groupId: null
|
|
136
115
|
};
|
|
@@ -140,7 +119,6 @@ function createCoreDomains(deps) {
|
|
|
140
119
|
lastActiveGroup: opts.groupId
|
|
141
120
|
} });
|
|
142
121
|
return {
|
|
143
|
-
ok: true,
|
|
144
122
|
userId: opts.userId,
|
|
145
123
|
groupId: opts.groupId
|
|
146
124
|
};
|
|
@@ -164,10 +142,10 @@ function createCoreDomains(deps) {
|
|
|
164
142
|
ctx.runQuery(config.component.public.totpListByUserId, { userId })
|
|
165
143
|
]);
|
|
166
144
|
const totalLinked = sessions.length + accounts.length + keys.length + members.length + passkeys.length + totps.length;
|
|
167
|
-
if (!cascade && totalLinked > 0)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
};
|
|
145
|
+
if (!cascade && totalLinked > 0) throw Cv.error({
|
|
146
|
+
code: "INVALID_PARAMETERS",
|
|
147
|
+
message: "The provided parameters are invalid."
|
|
148
|
+
});
|
|
171
149
|
const deletions = [];
|
|
172
150
|
for (const s of sessions) deletions.push(ctx.runMutation(config.component.public.sessionDelete, { sessionId: s._id }));
|
|
173
151
|
for (const a of accounts) deletions.push(ctx.runMutation(config.component.public.accountDelete, { accountId: a._id }));
|
|
@@ -177,10 +155,7 @@ function createCoreDomains(deps) {
|
|
|
177
155
|
for (const t of totps) deletions.push(ctx.runMutation(config.component.public.totpDelete, { totpId: t._id }));
|
|
178
156
|
await Promise.all(deletions);
|
|
179
157
|
await ctx.runMutation(config.component.public.userDelete, { userId });
|
|
180
|
-
return {
|
|
181
|
-
ok: true,
|
|
182
|
-
userId
|
|
183
|
-
};
|
|
158
|
+
return { userId };
|
|
184
159
|
}
|
|
185
160
|
};
|
|
186
161
|
const session = {
|
|
@@ -193,7 +168,6 @@ function createCoreDomains(deps) {
|
|
|
193
168
|
invalidate: async (ctx, args) => {
|
|
194
169
|
await callInvalidateSessions(ctx, args);
|
|
195
170
|
return {
|
|
196
|
-
ok: true,
|
|
197
171
|
userId: args.userId,
|
|
198
172
|
except: args.except ?? []
|
|
199
173
|
};
|
|
@@ -207,10 +181,7 @@ function createCoreDomains(deps) {
|
|
|
207
181
|
};
|
|
208
182
|
const account = {
|
|
209
183
|
create: async (ctx, args) => {
|
|
210
|
-
return {
|
|
211
|
-
ok: true,
|
|
212
|
-
...await callCreateAccountFromCredentials(ctx, args)
|
|
213
|
-
};
|
|
184
|
+
return { ...await callCreateAccountFromCredentials(ctx, args) };
|
|
214
185
|
},
|
|
215
186
|
get: async (ctx, args) => {
|
|
216
187
|
const result = await callRetrieveAccountWithCredentials(ctx, args);
|
|
@@ -219,26 +190,20 @@ function createCoreDomains(deps) {
|
|
|
219
190
|
},
|
|
220
191
|
update: async (ctx, args) => {
|
|
221
192
|
await callModifyAccount(ctx, args);
|
|
222
|
-
return {
|
|
223
|
-
ok: true,
|
|
224
|
-
accountId: args.account.id
|
|
225
|
-
};
|
|
193
|
+
return { accountId: args.account.id };
|
|
226
194
|
},
|
|
227
195
|
delete: async (ctx, accountId) => {
|
|
228
196
|
const doc = await ctx.runQuery(config.component.public.accountGetById, { accountId });
|
|
229
|
-
if (doc === null)
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
};
|
|
233
|
-
if ((await ctx.runQuery(config.component.public.accountListByUser, { userId: doc.userId })).length <= 1)
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
};
|
|
197
|
+
if (doc === null) throw Cv.error({
|
|
198
|
+
code: "ACCOUNT_NOT_FOUND",
|
|
199
|
+
message: "Account not found."
|
|
200
|
+
});
|
|
201
|
+
if ((await ctx.runQuery(config.component.public.accountListByUser, { userId: doc.userId })).length <= 1) throw Cv.error({
|
|
202
|
+
code: "INVALID_PARAMETERS",
|
|
203
|
+
message: "The provided parameters are invalid."
|
|
204
|
+
});
|
|
237
205
|
await ctx.runMutation(config.component.public.accountDelete, { accountId });
|
|
238
|
-
return {
|
|
239
|
-
ok: true,
|
|
240
|
-
accountId
|
|
241
|
-
};
|
|
206
|
+
return { accountId };
|
|
242
207
|
},
|
|
243
208
|
listPasskeys: async (ctx, opts) => {
|
|
244
209
|
return await ctx.runQuery(config.component.public.passkeyListByUserId, opts);
|
|
@@ -248,27 +213,18 @@ function createCoreDomains(deps) {
|
|
|
248
213
|
passkeyId,
|
|
249
214
|
data: { name }
|
|
250
215
|
});
|
|
251
|
-
return {
|
|
252
|
-
ok: true,
|
|
253
|
-
passkeyId
|
|
254
|
-
};
|
|
216
|
+
return { passkeyId };
|
|
255
217
|
},
|
|
256
218
|
deletePasskey: async (ctx, passkeyId) => {
|
|
257
219
|
await ctx.runMutation(config.component.public.passkeyDelete, { passkeyId });
|
|
258
|
-
return {
|
|
259
|
-
ok: true,
|
|
260
|
-
passkeyId
|
|
261
|
-
};
|
|
220
|
+
return { passkeyId };
|
|
262
221
|
},
|
|
263
222
|
listTotps: async (ctx, opts) => {
|
|
264
223
|
return await ctx.runQuery(config.component.public.totpListByUserId, opts);
|
|
265
224
|
},
|
|
266
225
|
deleteTotp: async (ctx, totpId) => {
|
|
267
226
|
await ctx.runMutation(config.component.public.totpDelete, { totpId });
|
|
268
|
-
return {
|
|
269
|
-
ok: true,
|
|
270
|
-
totpId
|
|
271
|
-
};
|
|
227
|
+
return { totpId };
|
|
272
228
|
}
|
|
273
229
|
};
|
|
274
230
|
const provider = { signIn: async (ctx, providerConfig, args) => {
|
|
@@ -283,10 +239,7 @@ function createCoreDomains(deps) {
|
|
|
283
239
|
} };
|
|
284
240
|
const group = {
|
|
285
241
|
create: async (ctx, data) => {
|
|
286
|
-
return {
|
|
287
|
-
ok: true,
|
|
288
|
-
groupId: await ctx.runMutation(config.component.public.groupCreate, data)
|
|
289
|
-
};
|
|
242
|
+
return { groupId: await ctx.runMutation(config.component.public.groupCreate, data) };
|
|
290
243
|
},
|
|
291
244
|
get: async (ctx, groupId) => {
|
|
292
245
|
const c = cache(ctx);
|
|
@@ -309,17 +262,11 @@ function createCoreDomains(deps) {
|
|
|
309
262
|
groupId,
|
|
310
263
|
data
|
|
311
264
|
});
|
|
312
|
-
return {
|
|
313
|
-
ok: true,
|
|
314
|
-
groupId
|
|
315
|
-
};
|
|
265
|
+
return { groupId };
|
|
316
266
|
},
|
|
317
267
|
delete: async (ctx, groupId) => {
|
|
318
268
|
await ctx.runMutation(config.component.public.groupDelete, { groupId });
|
|
319
|
-
return {
|
|
320
|
-
ok: true,
|
|
321
|
-
groupId
|
|
322
|
-
};
|
|
269
|
+
return { groupId };
|
|
323
270
|
},
|
|
324
271
|
ancestors: async (ctx, opts) => {
|
|
325
272
|
const maxDepth = Math.max(0, Math.floor(opts.maxDepth ?? 32));
|
|
@@ -362,19 +309,11 @@ function createCoreDomains(deps) {
|
|
|
362
309
|
};
|
|
363
310
|
const member = {
|
|
364
311
|
create: async (ctx, data) => {
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
};
|
|
371
|
-
return {
|
|
372
|
-
ok: true,
|
|
373
|
-
memberId: await ctx.runMutation(config.component.public.memberAdd, {
|
|
374
|
-
...data,
|
|
375
|
-
roleIds: normalized.roleIds
|
|
376
|
-
})
|
|
377
|
-
};
|
|
312
|
+
const roleIds = normalizeRoleIds(data.roleIds);
|
|
313
|
+
return { memberId: await ctx.runMutation(config.component.public.memberAdd, {
|
|
314
|
+
...data,
|
|
315
|
+
roleIds
|
|
316
|
+
}) };
|
|
378
317
|
},
|
|
379
318
|
get: async (ctx, memberId) => {
|
|
380
319
|
return await ctx.runQuery(config.component.public.memberGet, { memberId });
|
|
@@ -390,137 +329,84 @@ function createCoreDomains(deps) {
|
|
|
390
329
|
},
|
|
391
330
|
delete: async (ctx, memberId) => {
|
|
392
331
|
await ctx.runMutation(config.component.public.memberRemove, { memberId });
|
|
393
|
-
return {
|
|
394
|
-
ok: true,
|
|
395
|
-
memberId
|
|
396
|
-
};
|
|
332
|
+
return { memberId };
|
|
397
333
|
},
|
|
398
334
|
update: async (ctx, memberId, data) => {
|
|
399
335
|
const nextData = { ...data };
|
|
400
|
-
if ("roleIds" in nextData)
|
|
401
|
-
const normalized = normalizeRoleIds(Array.isArray(nextData.roleIds) ? nextData.roleIds : void 0);
|
|
402
|
-
if (!normalized.ok) return {
|
|
403
|
-
ok: false,
|
|
404
|
-
code: "INVALID_ROLE_IDS",
|
|
405
|
-
invalidRoleIds: normalized.invalidRoleIds
|
|
406
|
-
};
|
|
407
|
-
nextData.roleIds = normalized.roleIds;
|
|
408
|
-
}
|
|
336
|
+
if ("roleIds" in nextData) nextData.roleIds = normalizeRoleIds(Array.isArray(nextData.roleIds) ? nextData.roleIds : void 0);
|
|
409
337
|
await ctx.runMutation(config.component.public.memberUpdate, {
|
|
410
338
|
memberId,
|
|
411
339
|
data: nextData
|
|
412
340
|
});
|
|
413
|
-
return {
|
|
414
|
-
ok: true,
|
|
415
|
-
memberId
|
|
416
|
-
};
|
|
341
|
+
return { memberId };
|
|
417
342
|
},
|
|
418
|
-
|
|
419
|
-
const normalized = normalizeRoleIds(opts.roleIds);
|
|
420
|
-
if (!normalized.ok) return {
|
|
421
|
-
ok: false,
|
|
422
|
-
membership: null,
|
|
423
|
-
matchedGroupId: null,
|
|
424
|
-
roleIds: [],
|
|
425
|
-
grants: [],
|
|
426
|
-
missingGrants: Array.from(new Set(opts.grants ?? [])),
|
|
427
|
-
depth: null,
|
|
428
|
-
isDirect: false,
|
|
429
|
-
isInherited: false,
|
|
430
|
-
traversedGroupIds: [],
|
|
431
|
-
code: "INVALID_ROLE_IDS",
|
|
432
|
-
invalidRoleIds: normalized.invalidRoleIds
|
|
433
|
-
};
|
|
434
|
-
const requestedRoleIds = normalized.roleIds;
|
|
435
|
-
const roleFilter = requestedRoleIds.length > 0 ? new Set(requestedRoleIds) : null;
|
|
436
|
-
const requiredGrants = Array.from(new Set(opts.grants ?? []));
|
|
343
|
+
inspect: async (ctx, opts) => {
|
|
437
344
|
const useAncestry = opts.ancestry === true;
|
|
438
345
|
let membership = null;
|
|
439
|
-
let matchedGroupId = null;
|
|
440
|
-
let depth = null;
|
|
441
|
-
let isDirect = false;
|
|
442
|
-
let isInherited = false;
|
|
443
|
-
let traversedGroupIds = [];
|
|
444
346
|
if (useAncestry) {
|
|
445
347
|
const maxDepth = Math.max(0, Math.floor(opts.maxDepth ?? 32));
|
|
446
|
-
|
|
348
|
+
membership = (await ctx.runQuery(config.component.public.memberResolve, {
|
|
447
349
|
userId: opts.userId,
|
|
448
350
|
groupId: opts.groupId,
|
|
449
351
|
maxDepth,
|
|
450
352
|
ancestry: true
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
isInherited = result.isInherited;
|
|
457
|
-
traversedGroupIds = result.traversedGroupIds ?? [];
|
|
458
|
-
} else {
|
|
459
|
-
const doc = await ctx.runQuery(config.component.public.memberGetByGroupAndUser, {
|
|
460
|
-
userId: opts.userId,
|
|
461
|
-
groupId: opts.groupId
|
|
462
|
-
});
|
|
463
|
-
membership = doc;
|
|
464
|
-
matchedGroupId = doc ? opts.groupId : null;
|
|
465
|
-
depth = doc ? 0 : null;
|
|
466
|
-
isDirect = doc !== null;
|
|
467
|
-
}
|
|
353
|
+
})).membership;
|
|
354
|
+
} else membership = await ctx.runQuery(config.component.public.memberGetByGroupAndUser, {
|
|
355
|
+
userId: opts.userId,
|
|
356
|
+
groupId: opts.groupId
|
|
357
|
+
});
|
|
468
358
|
if (membership === null) return {
|
|
469
|
-
ok: false,
|
|
470
359
|
membership: null,
|
|
471
|
-
matchedGroupId: null,
|
|
472
360
|
roleIds: [],
|
|
473
|
-
grants: []
|
|
474
|
-
missingGrants: requiredGrants,
|
|
475
|
-
depth: null,
|
|
476
|
-
isDirect: false,
|
|
477
|
-
isInherited: false,
|
|
478
|
-
traversedGroupIds
|
|
361
|
+
grants: []
|
|
479
362
|
};
|
|
480
363
|
const membershipRoleIds = membership.roleIds ?? [];
|
|
481
364
|
const membershipGrants = resolveGrantedPermissions(membershipRoleIds);
|
|
482
|
-
if (roleFilter !== null && !membershipRoleIds.some((roleId) => roleFilter.has(roleId))) return {
|
|
483
|
-
ok: false,
|
|
484
|
-
membership: null,
|
|
485
|
-
matchedGroupId: null,
|
|
486
|
-
roleIds: [],
|
|
487
|
-
grants: [],
|
|
488
|
-
missingGrants: requiredGrants,
|
|
489
|
-
depth: null,
|
|
490
|
-
isDirect: false,
|
|
491
|
-
isInherited: false,
|
|
492
|
-
traversedGroupIds
|
|
493
|
-
};
|
|
494
|
-
const missingGrants = requiredGrants.filter((grant) => !membershipGrants.includes(grant));
|
|
495
365
|
return {
|
|
496
|
-
ok: missingGrants.length === 0,
|
|
497
366
|
membership,
|
|
498
|
-
matchedGroupId,
|
|
499
367
|
roleIds: membershipRoleIds,
|
|
500
|
-
grants: membershipGrants
|
|
501
|
-
missingGrants,
|
|
502
|
-
depth,
|
|
503
|
-
isDirect,
|
|
504
|
-
isInherited,
|
|
505
|
-
traversedGroupIds
|
|
368
|
+
grants: membershipGrants
|
|
506
369
|
};
|
|
370
|
+
},
|
|
371
|
+
require: async (ctx, opts) => {
|
|
372
|
+
const validatedRoleIds = normalizeRoleIds(opts.roleIds);
|
|
373
|
+
const requiredGrants = Array.from(new Set(opts.grants ?? []));
|
|
374
|
+
const roleFilter = validatedRoleIds.length > 0 ? new Set(validatedRoleIds) : null;
|
|
375
|
+
const result = await member.inspect(ctx, {
|
|
376
|
+
userId: opts.userId,
|
|
377
|
+
groupId: opts.groupId,
|
|
378
|
+
ancestry: opts.ancestry,
|
|
379
|
+
maxDepth: opts.maxDepth
|
|
380
|
+
});
|
|
381
|
+
if (result.membership === null) throw Cv.error({
|
|
382
|
+
code: "NOT_A_MEMBER",
|
|
383
|
+
message: "User is not a member of this group.",
|
|
384
|
+
groupId: opts.groupId
|
|
385
|
+
});
|
|
386
|
+
if (roleFilter !== null && !result.roleIds.some((roleId) => roleFilter.has(roleId))) throw Cv.error({
|
|
387
|
+
code: "NOT_A_MEMBER",
|
|
388
|
+
message: "User is not a member of this group.",
|
|
389
|
+
groupId: opts.groupId
|
|
390
|
+
});
|
|
391
|
+
const missingGrants = requiredGrants.filter((grant) => !result.grants.includes(grant));
|
|
392
|
+
if (missingGrants.length > 0) throw Cv.error({
|
|
393
|
+
code: "MISSING_GRANTS",
|
|
394
|
+
message: "User is missing required grants.",
|
|
395
|
+
groupId: opts.groupId,
|
|
396
|
+
missingGrants
|
|
397
|
+
});
|
|
398
|
+
return result;
|
|
507
399
|
}
|
|
508
400
|
};
|
|
509
401
|
const invite = {
|
|
510
402
|
create: async (ctx, data) => {
|
|
511
|
-
const
|
|
512
|
-
if (!normalized.ok) return {
|
|
513
|
-
ok: false,
|
|
514
|
-
code: "INVALID_ROLE_IDS",
|
|
515
|
-
invalidRoleIds: normalized.invalidRoleIds
|
|
516
|
-
};
|
|
403
|
+
const roleIds = normalizeRoleIds(data.roleIds);
|
|
517
404
|
const token = generateRandomString(inviteTokenLength, inviteTokenAlphabet);
|
|
518
405
|
const tokenHash = await sha256(token);
|
|
519
406
|
return {
|
|
520
|
-
ok: true,
|
|
521
407
|
inviteId: await ctx.runMutation(config.component.public.inviteCreate, {
|
|
522
408
|
...data,
|
|
523
|
-
roleIds
|
|
409
|
+
roleIds,
|
|
524
410
|
tokenHash,
|
|
525
411
|
status: "pending"
|
|
526
412
|
}),
|
|
@@ -537,13 +423,10 @@ function createCoreDomains(deps) {
|
|
|
537
423
|
},
|
|
538
424
|
accept: async (ctx, args) => {
|
|
539
425
|
const tokenHash = await sha256(args.token);
|
|
540
|
-
return {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
acceptedByUserId: args.acceptedByUserId
|
|
545
|
-
})
|
|
546
|
-
};
|
|
426
|
+
return { ...await ctx.runMutation(config.component.public.inviteAcceptByToken, {
|
|
427
|
+
tokenHash,
|
|
428
|
+
acceptedByUserId: args.acceptedByUserId
|
|
429
|
+
}) };
|
|
547
430
|
}
|
|
548
431
|
},
|
|
549
432
|
list: async (ctx, opts) => {
|
|
@@ -561,24 +444,19 @@ function createCoreDomains(deps) {
|
|
|
561
444
|
...acceptedByUserId ? { acceptedByUserId } : {}
|
|
562
445
|
});
|
|
563
446
|
return {
|
|
564
|
-
ok: true,
|
|
565
447
|
inviteId,
|
|
566
448
|
acceptedByUserId: acceptedByUserId ?? null
|
|
567
449
|
};
|
|
568
450
|
},
|
|
569
451
|
revoke: async (ctx, inviteId) => {
|
|
570
452
|
await ctx.runMutation(config.component.public.inviteRevoke, { inviteId });
|
|
571
|
-
return {
|
|
572
|
-
ok: true,
|
|
573
|
-
inviteId
|
|
574
|
-
};
|
|
453
|
+
return { inviteId };
|
|
575
454
|
}
|
|
576
455
|
};
|
|
577
456
|
const key = {
|
|
578
457
|
create: async (ctx, opts) => {
|
|
579
458
|
const { raw, hashedKey, displayPrefix } = await generateApiKey("sk_");
|
|
580
459
|
return {
|
|
581
|
-
ok: true,
|
|
582
460
|
keyId: await ctx.runMutation(config.component.public.keyInsert, {
|
|
583
461
|
userId: opts.userId,
|
|
584
462
|
prefix: displayPrefix,
|
|
@@ -595,26 +473,26 @@ function createCoreDomains(deps) {
|
|
|
595
473
|
verify: async (ctx, rawKey) => {
|
|
596
474
|
const hashedKey = await hashApiKey(rawKey);
|
|
597
475
|
const doc = await ctx.runQuery(config.component.public.keyGetByHashedKey, { hashedKey });
|
|
598
|
-
if (!doc)
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
};
|
|
476
|
+
if (!doc) throw Cv.error({
|
|
477
|
+
code: "INVALID_API_KEY",
|
|
478
|
+
message: "Invalid API key."
|
|
479
|
+
});
|
|
602
480
|
const k = doc;
|
|
603
|
-
if (k.revoked)
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
};
|
|
607
|
-
if (k.expiresAt && k.expiresAt < Date.now())
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
};
|
|
481
|
+
if (k.revoked) throw Cv.error({
|
|
482
|
+
code: "API_KEY_REVOKED",
|
|
483
|
+
message: "This API key has been revoked."
|
|
484
|
+
});
|
|
485
|
+
if (k.expiresAt && k.expiresAt < Date.now()) throw Cv.error({
|
|
486
|
+
code: "API_KEY_EXPIRED",
|
|
487
|
+
message: "This API key has expired."
|
|
488
|
+
});
|
|
611
489
|
const patchData = { lastUsedAt: Date.now() };
|
|
612
490
|
if (k.rateLimit) {
|
|
613
491
|
const { limited, newState } = checkKeyRateLimit(k.rateLimit, k.rateLimitState ?? void 0);
|
|
614
|
-
if (limited)
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
};
|
|
492
|
+
if (limited) throw Cv.error({
|
|
493
|
+
code: "API_KEY_RATE_LIMITED",
|
|
494
|
+
message: "API key rate limit exceeded. Please try again later."
|
|
495
|
+
});
|
|
618
496
|
patchData.rateLimitState = newState;
|
|
619
497
|
}
|
|
620
498
|
await ctx.runMutation(config.component.public.keyPatch, {
|
|
@@ -622,7 +500,6 @@ function createCoreDomains(deps) {
|
|
|
622
500
|
data: patchData
|
|
623
501
|
});
|
|
624
502
|
return {
|
|
625
|
-
ok: true,
|
|
626
503
|
userId: k.userId,
|
|
627
504
|
keyId: k._id,
|
|
628
505
|
scopes: buildScopeChecker(k.scopes)
|
|
@@ -638,50 +515,36 @@ function createCoreDomains(deps) {
|
|
|
638
515
|
});
|
|
639
516
|
},
|
|
640
517
|
get: async (ctx, keyId) => {
|
|
641
|
-
|
|
642
|
-
if (!doc) return { ok: false };
|
|
643
|
-
return {
|
|
644
|
-
ok: true,
|
|
645
|
-
key: doc
|
|
646
|
-
};
|
|
518
|
+
return await ctx.runQuery(config.component.public.keyGetById, { keyId }) ?? null;
|
|
647
519
|
},
|
|
648
520
|
update: async (ctx, keyId, data) => {
|
|
649
521
|
await ctx.runMutation(config.component.public.keyPatch, {
|
|
650
522
|
keyId,
|
|
651
523
|
data
|
|
652
524
|
});
|
|
653
|
-
return {
|
|
654
|
-
ok: true,
|
|
655
|
-
keyId
|
|
656
|
-
};
|
|
525
|
+
return { keyId };
|
|
657
526
|
},
|
|
658
527
|
revoke: async (ctx, keyId) => {
|
|
659
528
|
await ctx.runMutation(config.component.public.keyPatch, {
|
|
660
529
|
keyId,
|
|
661
530
|
data: { revoked: true }
|
|
662
531
|
});
|
|
663
|
-
return {
|
|
664
|
-
ok: true,
|
|
665
|
-
keyId
|
|
666
|
-
};
|
|
532
|
+
return { keyId };
|
|
667
533
|
},
|
|
668
534
|
delete: async (ctx, keyId) => {
|
|
669
535
|
await ctx.runMutation(config.component.public.keyDelete, { keyId });
|
|
670
|
-
return {
|
|
671
|
-
ok: true,
|
|
672
|
-
keyId
|
|
673
|
-
};
|
|
536
|
+
return { keyId };
|
|
674
537
|
},
|
|
675
538
|
rotate: async (ctx, keyId, opts) => {
|
|
676
539
|
const existing = await ctx.runQuery(config.component.public.keyGetById, { keyId });
|
|
677
|
-
if (!existing)
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
};
|
|
681
|
-
if (existing.revoked === true)
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
};
|
|
540
|
+
if (!existing) throw Cv.error({
|
|
541
|
+
code: "INVALID_PARAMETERS",
|
|
542
|
+
message: "The provided parameters are invalid."
|
|
543
|
+
});
|
|
544
|
+
if (existing.revoked === true) throw Cv.error({
|
|
545
|
+
code: "API_KEY_REVOKED",
|
|
546
|
+
message: "This API key has been revoked."
|
|
547
|
+
});
|
|
685
548
|
await ctx.runMutation(config.component.public.keyPatch, {
|
|
686
549
|
keyId,
|
|
687
550
|
data: { revoked: true }
|