@robelest/convex-auth 0.0.3-preview → 0.0.3-preview.3
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/bin.cjs +15 -15
- package/dist/client/index.d.ts +40 -12
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +73 -12
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +2 -2
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/component.d.ts +1 -1
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/{portalBridge.d.ts → bridge.d.ts} +2 -2
- package/dist/component/bridge.d.ts.map +1 -0
- package/dist/component/{portalBridge.js → bridge.js} +2 -2
- package/dist/component/bridge.js.map +1 -0
- package/dist/component/index.d.ts +11 -4
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/index.js +8 -2
- package/dist/component/index.js.map +1 -1
- package/dist/component/public.d.ts +24 -17
- package/dist/component/public.d.ts.map +1 -1
- package/dist/component/public.js +23 -4
- package/dist/component/public.js.map +1 -1
- package/dist/component/schema.d.ts +11 -7
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +4 -1
- package/dist/component/schema.js.map +1 -1
- package/dist/providers/anonymous.d.ts +3 -0
- package/dist/providers/anonymous.d.ts.map +1 -1
- package/dist/providers/anonymous.js +3 -0
- package/dist/providers/anonymous.js.map +1 -1
- package/dist/providers/credentials.d.ts +3 -0
- package/dist/providers/credentials.d.ts.map +1 -1
- package/dist/providers/credentials.js +3 -0
- package/dist/providers/credentials.js.map +1 -1
- package/dist/providers/email.d.ts +3 -0
- package/dist/providers/email.d.ts.map +1 -1
- package/dist/providers/email.js +3 -0
- package/dist/providers/email.js.map +1 -1
- package/dist/providers/passkey.d.ts +7 -1
- package/dist/providers/passkey.d.ts.map +1 -1
- package/dist/providers/passkey.js +7 -1
- package/dist/providers/passkey.js.map +1 -1
- package/dist/providers/password.d.ts +3 -0
- package/dist/providers/password.d.ts.map +1 -1
- package/dist/providers/password.js +3 -0
- package/dist/providers/password.js.map +1 -1
- package/dist/providers/phone.d.ts +3 -0
- package/dist/providers/phone.d.ts.map +1 -1
- package/dist/providers/phone.js +3 -0
- package/dist/providers/phone.js.map +1 -1
- package/dist/providers/totp.d.ts +8 -0
- package/dist/providers/totp.d.ts.map +1 -1
- package/dist/providers/totp.js +8 -0
- package/dist/providers/totp.js.map +1 -1
- package/dist/server/{convex-auth.d.ts → auth.d.ts} +226 -36
- package/dist/server/auth.d.ts.map +1 -0
- package/dist/server/{convex-auth.js → auth.js} +287 -111
- package/dist/server/auth.js.map +1 -0
- package/dist/server/errors.d.ts +148 -0
- package/dist/server/errors.d.ts.map +1 -0
- package/dist/server/errors.js +179 -0
- package/dist/server/errors.js.map +1 -0
- package/dist/server/implementation/index.d.ts +170 -48
- package/dist/server/implementation/index.d.ts.map +1 -1
- package/dist/server/implementation/index.js +383 -167
- package/dist/server/implementation/index.js.map +1 -1
- package/dist/server/implementation/{apiKey.d.ts → keys.d.ts} +1 -1
- package/dist/server/implementation/keys.d.ts.map +1 -0
- package/dist/server/implementation/{apiKey.js → keys.js} +4 -5
- package/dist/server/implementation/keys.js.map +1 -0
- package/dist/server/implementation/mutations/{modifyAccount.d.ts → account.d.ts} +3 -3
- package/dist/server/implementation/mutations/account.d.ts.map +1 -0
- package/dist/server/implementation/mutations/{modifyAccount.js → account.js} +4 -3
- package/dist/server/implementation/mutations/account.js.map +1 -0
- package/dist/server/implementation/mutations/{createVerificationCode.d.ts → code.d.ts} +1 -1
- package/dist/server/implementation/mutations/code.d.ts.map +1 -0
- package/dist/server/implementation/mutations/{createVerificationCode.js → code.js} +2 -2
- package/dist/server/implementation/mutations/code.js.map +1 -0
- package/dist/server/implementation/mutations/index.d.ts +33 -33
- package/dist/server/implementation/mutations/index.d.ts.map +1 -1
- package/dist/server/implementation/mutations/index.js +22 -22
- package/dist/server/implementation/mutations/index.js.map +1 -1
- package/dist/server/implementation/mutations/{invalidateSessions.d.ts → invalidate.d.ts} +1 -1
- package/dist/server/implementation/mutations/invalidate.d.ts.map +1 -0
- package/dist/server/implementation/mutations/{invalidateSessions.js → invalidate.js} +2 -2
- package/dist/server/implementation/mutations/invalidate.js.map +1 -0
- package/dist/server/implementation/mutations/{userOAuth.d.ts → oauth.d.ts} +3 -3
- package/dist/server/implementation/mutations/oauth.d.ts.map +1 -0
- package/dist/server/implementation/mutations/{userOAuth.js → oauth.js} +4 -3
- package/dist/server/implementation/mutations/oauth.js.map +1 -0
- package/dist/server/implementation/mutations/{refreshSession.d.ts → refresh.d.ts} +1 -1
- package/dist/server/implementation/mutations/refresh.d.ts.map +1 -0
- package/dist/server/implementation/mutations/{refreshSession.js → refresh.js} +3 -3
- package/dist/server/implementation/mutations/refresh.js.map +1 -0
- package/dist/server/implementation/mutations/{createAccountFromCredentials.d.ts → register.d.ts} +4 -4
- package/dist/server/implementation/mutations/register.d.ts.map +1 -0
- package/dist/server/implementation/mutations/{createAccountFromCredentials.js → register.js} +4 -3
- package/dist/server/implementation/mutations/register.js.map +1 -0
- package/dist/server/implementation/mutations/{retrieveAccountWithCredentials.d.ts → retrieve.d.ts} +3 -3
- package/dist/server/implementation/mutations/retrieve.d.ts.map +1 -0
- package/dist/server/implementation/mutations/{retrieveAccountWithCredentials.js → retrieve.js} +3 -3
- package/dist/server/implementation/mutations/retrieve.js.map +1 -0
- package/dist/server/implementation/mutations/{verifierSignature.d.ts → signature.d.ts} +1 -1
- package/dist/server/implementation/mutations/signature.d.ts.map +1 -0
- package/dist/server/implementation/mutations/{verifierSignature.js → signature.js} +4 -3
- package/dist/server/implementation/mutations/signature.js.map +1 -0
- package/dist/server/implementation/mutations/{signIn.d.ts → signin.d.ts} +1 -1
- package/dist/server/implementation/mutations/{signIn.d.ts.map → signin.d.ts.map} +1 -1
- package/dist/server/implementation/mutations/{signIn.js → signin.js} +2 -2
- package/dist/server/implementation/mutations/{signIn.js.map → signin.js.map} +1 -1
- package/dist/server/implementation/mutations/{signOut.d.ts → signout.d.ts} +1 -1
- package/dist/server/implementation/mutations/{signOut.d.ts.map → signout.d.ts.map} +1 -1
- package/dist/server/implementation/mutations/{signOut.js → signout.js} +2 -2
- package/dist/server/implementation/mutations/{signOut.js.map → signout.js.map} +1 -1
- package/dist/server/implementation/mutations/{storeRef.d.ts → store.d.ts} +1 -1
- package/dist/server/implementation/mutations/store.d.ts.map +1 -0
- package/dist/server/implementation/mutations/{storeRef.js → store.js} +1 -1
- package/dist/server/implementation/mutations/store.js.map +1 -0
- package/dist/server/implementation/mutations/verifier.js +1 -1
- package/dist/server/implementation/mutations/verifier.js.map +1 -1
- package/dist/server/implementation/mutations/{verifyCodeAndSignIn.d.ts → verify.d.ts} +1 -1
- package/dist/server/implementation/mutations/verify.d.ts.map +1 -0
- package/dist/server/implementation/mutations/{verifyCodeAndSignIn.js → verify.js} +3 -3
- package/dist/server/implementation/mutations/verify.js.map +1 -0
- package/dist/server/implementation/passkey.d.ts.map +1 -1
- package/dist/server/implementation/passkey.js +47 -55
- package/dist/server/implementation/passkey.js.map +1 -1
- package/dist/server/implementation/provider.d.ts.map +1 -1
- package/dist/server/implementation/provider.js +5 -4
- package/dist/server/implementation/provider.js.map +1 -1
- package/dist/server/implementation/{rateLimit.d.ts → ratelimit.d.ts} +1 -1
- package/dist/server/implementation/{rateLimit.d.ts.map → ratelimit.d.ts.map} +1 -1
- package/dist/server/implementation/{rateLimit.js → ratelimit.js} +1 -1
- package/dist/server/implementation/{rateLimit.js.map → ratelimit.js.map} +1 -1
- package/dist/server/implementation/redirects.d.ts.map +1 -1
- package/dist/server/implementation/redirects.js +2 -1
- package/dist/server/implementation/redirects.js.map +1 -1
- package/dist/server/implementation/{refreshTokens.d.ts → refresh.d.ts} +1 -1
- package/dist/server/implementation/refresh.d.ts.map +1 -0
- package/dist/server/implementation/{refreshTokens.js → refresh.js} +3 -2
- package/dist/server/implementation/refresh.js.map +1 -0
- package/dist/server/implementation/sessions.js +1 -1
- package/dist/server/implementation/sessions.js.map +1 -1
- package/dist/server/implementation/{signIn.d.ts → signin.d.ts} +1 -1
- package/dist/server/implementation/{signIn.d.ts.map → signin.d.ts.map} +1 -1
- package/dist/server/implementation/{signIn.js → signin.js} +12 -8
- package/dist/server/implementation/signin.js.map +1 -0
- package/dist/server/implementation/totp.d.ts.map +1 -1
- package/dist/server/implementation/totp.js +29 -29
- package/dist/server/implementation/totp.js.map +1 -1
- package/dist/server/implementation/types.d.ts +131 -1
- package/dist/server/implementation/types.d.ts.map +1 -1
- package/dist/server/implementation/types.js +65 -1
- package/dist/server/implementation/types.js.map +1 -1
- package/dist/server/implementation/users.d.ts.map +1 -1
- package/dist/server/implementation/users.js +3 -2
- package/dist/server/implementation/users.js.map +1 -1
- package/dist/server/index.d.ts +131 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +117 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/oauth/{authorizationUrl.d.ts → authorization.d.ts} +1 -1
- package/dist/server/oauth/authorization.d.ts.map +1 -0
- package/dist/server/oauth/{authorizationUrl.js → authorization.js} +4 -3
- package/dist/server/oauth/authorization.js.map +1 -0
- package/dist/server/oauth/callback.d.ts.map +1 -1
- package/dist/server/oauth/callback.js +7 -6
- package/dist/server/oauth/callback.js.map +1 -1
- package/dist/server/oauth/checks.d.ts.map +1 -1
- package/dist/server/oauth/checks.js +2 -1
- package/dist/server/oauth/checks.js.map +1 -1
- package/dist/server/oauth/{convexAuth.d.ts → helpers.d.ts} +1 -1
- package/dist/server/oauth/helpers.d.ts.map +1 -0
- package/dist/server/oauth/{convexAuth.js → helpers.js} +6 -5
- package/dist/server/oauth/helpers.js.map +1 -0
- package/dist/server/oauth/lib/utils/{customFetch.d.ts → fetch.d.ts} +1 -1
- package/dist/server/oauth/lib/utils/fetch.d.ts.map +1 -0
- package/dist/server/oauth/lib/utils/{customFetch.js → fetch.js} +1 -1
- package/dist/server/oauth/lib/utils/fetch.js.map +1 -0
- package/dist/server/{provider_utils.d.ts → providers.d.ts} +1 -1
- package/dist/server/providers.d.ts.map +1 -0
- package/dist/server/{provider_utils.js → providers.js} +1 -1
- package/dist/server/providers.js.map +1 -0
- package/dist/server/{email-templates.d.ts → templates.d.ts} +8 -1
- package/dist/server/templates.d.ts.map +1 -0
- package/dist/server/{portal-email.js → templates.js} +74 -3
- package/dist/server/templates.js.map +1 -0
- package/dist/server/types.d.ts +88 -5
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/utils.d.ts.map +1 -1
- package/dist/server/utils.js +2 -1
- package/dist/server/utils.js.map +1 -1
- package/dist/server/version.d.ts +1 -1
- package/dist/server/version.d.ts.map +1 -1
- package/dist/server/version.js +1 -1
- package/dist/server/version.js.map +1 -1
- package/package.json +5 -1
- package/src/cli/index.ts +5 -5
- package/src/cli/{portal-link.ts → link.ts} +1 -1
- package/src/cli/utils.ts +1 -1
- package/src/client/index.ts +102 -17
- package/src/component/_generated/api.ts +2 -2
- package/src/component/_generated/component.ts +1 -1
- package/src/component/{portalBridge.ts → bridge.ts} +2 -2
- package/src/component/index.ts +10 -2
- package/src/component/public.ts +25 -4
- package/src/component/schema.ts +4 -1
- package/src/providers/anonymous.ts +3 -0
- package/src/providers/credentials.ts +3 -0
- package/src/providers/email.ts +3 -0
- package/src/providers/passkey.ts +8 -1
- package/src/providers/password.ts +3 -0
- package/src/providers/phone.ts +3 -0
- package/src/providers/totp.ts +9 -0
- package/src/server/auth.ts +969 -0
- package/src/server/errors.ts +275 -0
- package/src/server/implementation/index.ts +370 -88
- package/src/server/implementation/{apiKey.ts → keys.ts} +7 -6
- package/src/server/implementation/mutations/{modifyAccount.ts → account.ts} +3 -4
- package/src/server/implementation/mutations/{createVerificationCode.ts → code.ts} +1 -1
- package/src/server/implementation/mutations/index.ts +22 -22
- package/src/server/implementation/mutations/{invalidateSessions.ts → invalidate.ts} +1 -1
- package/src/server/implementation/mutations/{userOAuth.ts → oauth.ts} +3 -2
- package/src/server/implementation/mutations/{refreshSession.ts → refresh.ts} +2 -2
- package/src/server/implementation/mutations/{createAccountFromCredentials.ts → register.ts} +3 -2
- package/src/server/implementation/mutations/{retrieveAccountWithCredentials.ts → retrieve.ts} +2 -2
- package/src/server/implementation/mutations/{verifierSignature.ts → signature.ts} +3 -2
- package/src/server/implementation/mutations/{signIn.ts → signin.ts} +1 -1
- package/src/server/implementation/mutations/{signOut.ts → signout.ts} +1 -1
- package/src/server/implementation/mutations/verifier.ts +1 -1
- package/src/server/implementation/mutations/{verifyCodeAndSignIn.ts → verify.ts} +2 -2
- package/src/server/implementation/passkey.ts +86 -116
- package/src/server/implementation/provider.ts +5 -8
- package/src/server/implementation/redirects.ts +2 -3
- package/src/server/implementation/{refreshTokens.ts → refresh.ts} +2 -1
- package/src/server/implementation/sessions.ts +1 -1
- package/src/server/implementation/{signIn.ts → signin.ts} +13 -11
- package/src/server/implementation/totp.ts +60 -84
- package/src/server/implementation/types.ts +316 -1
- package/src/server/implementation/users.ts +4 -7
- package/src/server/index.ts +142 -3
- package/src/server/oauth/{authorizationUrl.ts → authorization.ts} +3 -2
- package/src/server/oauth/callback.ts +7 -6
- package/src/server/oauth/checks.ts +3 -1
- package/src/server/oauth/{convexAuth.ts → helpers.ts} +8 -5
- package/src/server/{portal-email.ts → templates.ts} +78 -2
- package/src/server/types.ts +133 -4
- package/src/server/utils.ts +3 -1
- package/src/server/version.ts +1 -1
- package/dist/component/portalBridge.d.ts.map +0 -1
- package/dist/component/portalBridge.js.map +0 -1
- package/dist/server/convex-auth.d.ts.map +0 -1
- package/dist/server/convex-auth.js.map +0 -1
- package/dist/server/convex_types.d.ts +0 -17
- package/dist/server/convex_types.d.ts.map +0 -1
- package/dist/server/convex_types.js +0 -2
- package/dist/server/convex_types.js.map +0 -1
- package/dist/server/email-templates.d.ts.map +0 -1
- package/dist/server/email-templates.js +0 -74
- package/dist/server/email-templates.js.map +0 -1
- package/dist/server/implementation/apiKey.d.ts.map +0 -1
- package/dist/server/implementation/apiKey.js.map +0 -1
- package/dist/server/implementation/mutations/createAccountFromCredentials.d.ts.map +0 -1
- package/dist/server/implementation/mutations/createAccountFromCredentials.js.map +0 -1
- package/dist/server/implementation/mutations/createVerificationCode.d.ts.map +0 -1
- package/dist/server/implementation/mutations/createVerificationCode.js.map +0 -1
- package/dist/server/implementation/mutations/invalidateSessions.d.ts.map +0 -1
- package/dist/server/implementation/mutations/invalidateSessions.js.map +0 -1
- package/dist/server/implementation/mutations/modifyAccount.d.ts.map +0 -1
- package/dist/server/implementation/mutations/modifyAccount.js.map +0 -1
- package/dist/server/implementation/mutations/refreshSession.d.ts.map +0 -1
- package/dist/server/implementation/mutations/refreshSession.js.map +0 -1
- package/dist/server/implementation/mutations/retrieveAccountWithCredentials.d.ts.map +0 -1
- package/dist/server/implementation/mutations/retrieveAccountWithCredentials.js.map +0 -1
- package/dist/server/implementation/mutations/storeRef.d.ts.map +0 -1
- package/dist/server/implementation/mutations/storeRef.js.map +0 -1
- package/dist/server/implementation/mutations/userOAuth.d.ts.map +0 -1
- package/dist/server/implementation/mutations/userOAuth.js.map +0 -1
- package/dist/server/implementation/mutations/verifierSignature.d.ts.map +0 -1
- package/dist/server/implementation/mutations/verifierSignature.js.map +0 -1
- package/dist/server/implementation/mutations/verifyCodeAndSignIn.d.ts.map +0 -1
- package/dist/server/implementation/mutations/verifyCodeAndSignIn.js.map +0 -1
- package/dist/server/implementation/refreshTokens.d.ts.map +0 -1
- package/dist/server/implementation/refreshTokens.js.map +0 -1
- package/dist/server/implementation/signIn.js.map +0 -1
- package/dist/server/oauth/authorizationUrl.d.ts.map +0 -1
- package/dist/server/oauth/authorizationUrl.js.map +0 -1
- package/dist/server/oauth/convexAuth.d.ts.map +0 -1
- package/dist/server/oauth/convexAuth.js.map +0 -1
- package/dist/server/oauth/lib/utils/customFetch.d.ts.map +0 -1
- package/dist/server/oauth/lib/utils/customFetch.js.map +0 -1
- package/dist/server/portal-email.d.ts +0 -19
- package/dist/server/portal-email.d.ts.map +0 -1
- package/dist/server/portal-email.js.map +0 -1
- package/dist/server/provider_utils.d.ts.map +0 -1
- package/dist/server/provider_utils.js.map +0 -1
- package/src/server/convex-auth.ts +0 -602
- package/src/server/convex_types.ts +0 -55
- package/src/server/email-templates.ts +0 -77
- /package/src/cli/{generateKeys.ts → keys.ts} +0 -0
- /package/src/cli/{portal-upload.ts → upload.ts} +0 -0
- /package/src/server/implementation/mutations/{storeRef.ts → store.ts} +0 -0
- /package/src/server/implementation/{rateLimit.ts → ratelimit.ts} +0 -0
- /package/src/server/oauth/lib/utils/{customFetch.ts → fetch.ts} +0 -0
- /package/src/server/{provider_utils.ts → providers.ts} +0 -0
|
@@ -11,9 +11,7 @@
|
|
|
11
11
|
* `@oslojs/encoding` for base-32 secret encoding.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { GenericId } from "convex/values";
|
|
15
14
|
import {
|
|
16
|
-
generateTOTP,
|
|
17
15
|
verifyTOTPWithGracePeriod,
|
|
18
16
|
createTOTPKeyURI,
|
|
19
17
|
} from "@oslojs/otp";
|
|
@@ -22,9 +20,21 @@ import {
|
|
|
22
20
|
TotpProviderConfig,
|
|
23
21
|
GenericActionCtxWithAuthConfig,
|
|
24
22
|
} from "../types.js";
|
|
25
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
AuthDataModel,
|
|
25
|
+
SessionInfo,
|
|
26
|
+
queryUserById,
|
|
27
|
+
queryTotpById,
|
|
28
|
+
queryTotpVerifiedByUserId,
|
|
29
|
+
queryVerifierById,
|
|
30
|
+
mutateTotpInsert,
|
|
31
|
+
mutateTotpMarkVerified,
|
|
32
|
+
mutateTotpUpdateLastUsed,
|
|
33
|
+
mutateVerifierDelete,
|
|
34
|
+
} from "./types.js";
|
|
26
35
|
import { callSignIn, callVerifier } from "./mutations/index.js";
|
|
27
|
-
import { callVerifierSignature } from "./mutations/
|
|
36
|
+
import { callVerifierSignature } from "./mutations/signature.js";
|
|
37
|
+
import { throwAuthError } from "../errors.js";
|
|
28
38
|
|
|
29
39
|
type EnrichedActionCtx = GenericActionCtxWithAuthConfig<AuthDataModel>;
|
|
30
40
|
|
|
@@ -53,10 +63,7 @@ async function handleSetup(
|
|
|
53
63
|
// TOTP enrollment requires an authenticated user
|
|
54
64
|
const identity = await ctx.auth.getUserIdentity();
|
|
55
65
|
if (identity === null) {
|
|
56
|
-
|
|
57
|
-
"TOTP enrollment requires an authenticated user. " +
|
|
58
|
-
"Sign in first, then add TOTP to your account.",
|
|
59
|
-
);
|
|
66
|
+
throwAuthError("TOTP_AUTH_REQUIRED");
|
|
60
67
|
}
|
|
61
68
|
const [userId] = identity.subject.split("|");
|
|
62
69
|
|
|
@@ -67,11 +74,8 @@ async function handleSetup(
|
|
|
67
74
|
// Resolve the account name for the otpauth:// URI
|
|
68
75
|
let accountName: string = params.accountName as string;
|
|
69
76
|
if (!accountName) {
|
|
70
|
-
const user = await ctx
|
|
71
|
-
|
|
72
|
-
{ userId: userId! },
|
|
73
|
-
);
|
|
74
|
-
accountName = (user as any)?.email ?? "user";
|
|
77
|
+
const user = await queryUserById(ctx, userId!);
|
|
78
|
+
accountName = user?.email ?? "user";
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
// Build the otpauth:// URI for QR code scanning
|
|
@@ -99,28 +103,25 @@ async function handleSetup(
|
|
|
99
103
|
});
|
|
100
104
|
|
|
101
105
|
// Insert an UNVERIFIED TOTP record in the DB
|
|
102
|
-
const totpId = await ctx
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
secret
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
createdAt: Date.now(),
|
|
115
|
-
},
|
|
116
|
-
);
|
|
106
|
+
const totpId = await mutateTotpInsert(ctx, {
|
|
107
|
+
userId: userId!,
|
|
108
|
+
secret: secret.buffer.slice(
|
|
109
|
+
secret.byteOffset,
|
|
110
|
+
secret.byteOffset + secret.byteLength,
|
|
111
|
+
),
|
|
112
|
+
digits: provider.options.digits,
|
|
113
|
+
period: provider.options.period,
|
|
114
|
+
verified: false,
|
|
115
|
+
name: params.name,
|
|
116
|
+
createdAt: Date.now(),
|
|
117
|
+
});
|
|
117
118
|
|
|
118
119
|
return {
|
|
119
120
|
kind: "totpSetup" as const,
|
|
120
121
|
uri,
|
|
121
122
|
secret: base32Secret,
|
|
122
123
|
verifier,
|
|
123
|
-
totpId
|
|
124
|
+
totpId,
|
|
124
125
|
};
|
|
125
126
|
}
|
|
126
127
|
|
|
@@ -143,37 +144,31 @@ async function handleConfirm(
|
|
|
143
144
|
// TOTP confirmation requires an authenticated user
|
|
144
145
|
const identity = await ctx.auth.getUserIdentity();
|
|
145
146
|
if (identity === null) {
|
|
146
|
-
|
|
147
|
-
"TOTP confirmation requires an authenticated user. " +
|
|
148
|
-
"Sign in first, then confirm your TOTP enrollment.",
|
|
149
|
-
);
|
|
147
|
+
throwAuthError("TOTP_AUTH_REQUIRED");
|
|
150
148
|
}
|
|
151
149
|
const [userId] = identity.subject.split("|");
|
|
152
150
|
|
|
153
151
|
if (!verifierValue) {
|
|
154
|
-
|
|
152
|
+
throwAuthError("TOTP_MISSING_VERIFIER");
|
|
155
153
|
}
|
|
156
154
|
if (!params.code) {
|
|
157
|
-
|
|
155
|
+
throwAuthError("TOTP_MISSING_CODE");
|
|
158
156
|
}
|
|
159
157
|
if (!params.totpId) {
|
|
160
|
-
|
|
158
|
+
throwAuthError("TOTP_MISSING_ID");
|
|
161
159
|
}
|
|
162
160
|
|
|
163
161
|
// Look up the TOTP record
|
|
164
|
-
const totpDoc = await ctx.
|
|
165
|
-
ctx.auth.config.component.public.totpGetById,
|
|
166
|
-
{ totpId: params.totpId },
|
|
167
|
-
);
|
|
162
|
+
const totpDoc = await queryTotpById(ctx, params.totpId);
|
|
168
163
|
if (!totpDoc) {
|
|
169
|
-
|
|
164
|
+
throwAuthError("TOTP_NOT_FOUND");
|
|
170
165
|
}
|
|
171
|
-
if (
|
|
172
|
-
|
|
166
|
+
if (totpDoc.verified) {
|
|
167
|
+
throwAuthError("TOTP_ALREADY_VERIFIED");
|
|
173
168
|
}
|
|
174
169
|
|
|
175
170
|
// Extract the secret from the TOTP record
|
|
176
|
-
const secret = new Uint8Array(
|
|
171
|
+
const secret = new Uint8Array(totpDoc.secret);
|
|
177
172
|
|
|
178
173
|
// Verify the code with a 30-second grace period
|
|
179
174
|
const valid = verifyTOTPWithGracePeriod(
|
|
@@ -184,20 +179,14 @@ async function handleConfirm(
|
|
|
184
179
|
30,
|
|
185
180
|
);
|
|
186
181
|
if (!valid) {
|
|
187
|
-
|
|
182
|
+
throwAuthError("TOTP_INVALID_CODE");
|
|
188
183
|
}
|
|
189
184
|
|
|
190
185
|
// Mark the enrollment as verified
|
|
191
|
-
await ctx.
|
|
192
|
-
ctx.auth.config.component.public.totpMarkVerified,
|
|
193
|
-
{ totpId: params.totpId as any, lastUsedAt: Date.now() },
|
|
194
|
-
);
|
|
186
|
+
await mutateTotpMarkVerified(ctx, params.totpId, Date.now());
|
|
195
187
|
|
|
196
188
|
// Clean up the verifier
|
|
197
|
-
await ctx
|
|
198
|
-
ctx.auth.config.component.public.verifierDelete,
|
|
199
|
-
{ verifierId: verifierValue },
|
|
200
|
-
);
|
|
189
|
+
await mutateVerifierDelete(ctx, verifierValue);
|
|
201
190
|
|
|
202
191
|
// Return tokens for the existing session
|
|
203
192
|
const signInResult = await callSignIn(ctx, {
|
|
@@ -225,60 +214,48 @@ async function handleVerify(
|
|
|
225
214
|
verifierValue: string | undefined,
|
|
226
215
|
): Promise<{ kind: "signedIn"; signedIn: SessionInfo | null }> {
|
|
227
216
|
if (!verifierValue) {
|
|
228
|
-
|
|
217
|
+
throwAuthError("TOTP_MISSING_VERIFIER");
|
|
229
218
|
}
|
|
230
219
|
if (!params.code) {
|
|
231
|
-
|
|
220
|
+
throwAuthError("TOTP_MISSING_CODE");
|
|
232
221
|
}
|
|
233
222
|
|
|
234
223
|
// Look up the verifier to retrieve the stored userId
|
|
235
|
-
const verifierDoc = await ctx
|
|
236
|
-
ctx.auth.config.component.public.verifierGetById,
|
|
237
|
-
{ verifierId: verifierValue },
|
|
238
|
-
);
|
|
224
|
+
const verifierDoc = await queryVerifierById(ctx, verifierValue);
|
|
239
225
|
if (!verifierDoc) {
|
|
240
|
-
|
|
226
|
+
throwAuthError("TOTP_INVALID_VERIFIER");
|
|
241
227
|
}
|
|
242
228
|
|
|
243
229
|
// Parse the signature to extract userId
|
|
244
|
-
const signatureData = JSON.parse(
|
|
230
|
+
const signatureData = JSON.parse(verifierDoc.signature!);
|
|
245
231
|
const userId = signatureData.userId as string;
|
|
246
232
|
|
|
247
233
|
// Look up the user's verified TOTP enrollment
|
|
248
|
-
const totpDoc = await ctx
|
|
249
|
-
ctx.auth.config.component.public.totpGetVerifiedByUserId,
|
|
250
|
-
{ userId: userId as any },
|
|
251
|
-
);
|
|
234
|
+
const totpDoc = await queryTotpVerifiedByUserId(ctx, userId);
|
|
252
235
|
if (!totpDoc) {
|
|
253
|
-
|
|
236
|
+
throwAuthError("TOTP_NO_ENROLLMENT");
|
|
254
237
|
}
|
|
255
238
|
|
|
256
239
|
// Extract the secret from the TOTP record
|
|
257
|
-
const secret = new Uint8Array(
|
|
240
|
+
const secret = new Uint8Array(totpDoc.secret);
|
|
258
241
|
|
|
259
242
|
// Verify the code with a 30-second grace period
|
|
260
243
|
const valid = verifyTOTPWithGracePeriod(
|
|
261
244
|
secret,
|
|
262
|
-
|
|
263
|
-
|
|
245
|
+
totpDoc.period,
|
|
246
|
+
totpDoc.digits,
|
|
264
247
|
params.code,
|
|
265
248
|
30,
|
|
266
249
|
);
|
|
267
250
|
if (!valid) {
|
|
268
|
-
|
|
251
|
+
throwAuthError("TOTP_INVALID_CODE");
|
|
269
252
|
}
|
|
270
253
|
|
|
271
254
|
// Update last used timestamp
|
|
272
|
-
await ctx.
|
|
273
|
-
ctx.auth.config.component.public.totpUpdateLastUsed,
|
|
274
|
-
{ totpId: (totpDoc as any)._id, lastUsedAt: Date.now() },
|
|
275
|
-
);
|
|
255
|
+
await mutateTotpUpdateLastUsed(ctx, totpDoc._id, Date.now());
|
|
276
256
|
|
|
277
257
|
// Clean up the verifier
|
|
278
|
-
await ctx
|
|
279
|
-
ctx.auth.config.component.public.verifierDelete,
|
|
280
|
-
{ verifierId: verifierValue },
|
|
281
|
-
);
|
|
258
|
+
await mutateVerifierDelete(ctx, verifierValue);
|
|
282
259
|
|
|
283
260
|
// Sign in the user with tokens
|
|
284
261
|
const signInResult = await callSignIn(ctx, {
|
|
@@ -317,7 +294,8 @@ export async function handleTotp(
|
|
|
317
294
|
> {
|
|
318
295
|
const flow = args.params?.flow;
|
|
319
296
|
if (!flow) {
|
|
320
|
-
|
|
297
|
+
throwAuthError(
|
|
298
|
+
"TOTP_MISSING_FLOW",
|
|
321
299
|
"Missing `flow` parameter. Expected one of: setup, confirm, verify",
|
|
322
300
|
);
|
|
323
301
|
}
|
|
@@ -340,7 +318,8 @@ export async function handleTotp(
|
|
|
340
318
|
args.verifier,
|
|
341
319
|
);
|
|
342
320
|
default:
|
|
343
|
-
|
|
321
|
+
throwAuthError(
|
|
322
|
+
"TOTP_UNKNOWN_FLOW",
|
|
344
323
|
`Unknown TOTP flow: ${flow}. Expected one of: setup, confirm, verify`,
|
|
345
324
|
);
|
|
346
325
|
}
|
|
@@ -358,9 +337,6 @@ export async function checkTotpRequired(
|
|
|
358
337
|
ctx: EnrichedActionCtx,
|
|
359
338
|
userId: string,
|
|
360
339
|
): Promise<boolean> {
|
|
361
|
-
const totpDoc = await ctx
|
|
362
|
-
ctx.auth.config.component.public.totpGetVerifiedByUserId,
|
|
363
|
-
{ userId: userId as any },
|
|
364
|
-
);
|
|
340
|
+
const totpDoc = await queryTotpVerifiedByUserId(ctx, userId);
|
|
365
341
|
return totpDoc !== null;
|
|
366
342
|
}
|
|
@@ -6,8 +6,9 @@ import {
|
|
|
6
6
|
TableNamesInDataModel,
|
|
7
7
|
} from "convex/server";
|
|
8
8
|
import { GenericId } from "convex/values";
|
|
9
|
-
import { GenericDoc } from "../
|
|
9
|
+
import { GenericDoc } from "../types.js";
|
|
10
10
|
import schema from "../../component/schema.js";
|
|
11
|
+
import { AuthComponentApi } from "../types.js";
|
|
11
12
|
|
|
12
13
|
/** Data model derived from the component schema. */
|
|
13
14
|
export type AuthDataModel = DataModelFromSchemaDefinition<typeof schema>;
|
|
@@ -43,3 +44,317 @@ export type SessionInfoWithTokens = {
|
|
|
43
44
|
sessionId: GenericId<"session">;
|
|
44
45
|
tokens: Tokens;
|
|
45
46
|
};
|
|
47
|
+
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Cross-component document shapes
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// These mirror the component schema tables. They exist so that server-side
|
|
52
|
+
// code can work with typed results from cross-component queries/mutations
|
|
53
|
+
// instead of casting to `any` at every field access.
|
|
54
|
+
|
|
55
|
+
export interface TotpDoc {
|
|
56
|
+
_id: string;
|
|
57
|
+
_creationTime: number;
|
|
58
|
+
userId: string;
|
|
59
|
+
secret: ArrayBuffer;
|
|
60
|
+
digits: number;
|
|
61
|
+
period: number;
|
|
62
|
+
verified: boolean;
|
|
63
|
+
name?: string;
|
|
64
|
+
createdAt: number;
|
|
65
|
+
lastUsedAt?: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface PasskeyDoc {
|
|
69
|
+
_id: string;
|
|
70
|
+
_creationTime: number;
|
|
71
|
+
userId: string;
|
|
72
|
+
credentialId: string;
|
|
73
|
+
publicKey: ArrayBuffer;
|
|
74
|
+
algorithm: number;
|
|
75
|
+
counter: number;
|
|
76
|
+
transports?: string[];
|
|
77
|
+
deviceType: string;
|
|
78
|
+
backedUp: boolean;
|
|
79
|
+
name?: string;
|
|
80
|
+
createdAt: number;
|
|
81
|
+
lastUsedAt?: number;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface VerifierDoc {
|
|
85
|
+
_id: string;
|
|
86
|
+
_creationTime: number;
|
|
87
|
+
signature?: string;
|
|
88
|
+
sessionId?: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface UserDoc {
|
|
92
|
+
_id: string;
|
|
93
|
+
_creationTime: number;
|
|
94
|
+
email?: string;
|
|
95
|
+
emailVerificationTime?: number;
|
|
96
|
+
phone?: string;
|
|
97
|
+
phoneVerificationTime?: number;
|
|
98
|
+
name?: string;
|
|
99
|
+
image?: string;
|
|
100
|
+
isAnonymous?: boolean;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface KeyDoc {
|
|
104
|
+
_id: string;
|
|
105
|
+
_creationTime: number;
|
|
106
|
+
userId: string;
|
|
107
|
+
prefix: string;
|
|
108
|
+
hashedKey: string;
|
|
109
|
+
name: string;
|
|
110
|
+
scopes: Array<{ resource: string; actions: string[] }>;
|
|
111
|
+
rateLimit?: { maxRequests: number; windowMs: number };
|
|
112
|
+
rateLimitState?: { attemptsLeft: number; lastAttemptTime: number };
|
|
113
|
+
expiresAt?: number;
|
|
114
|
+
lastUsedAt?: number;
|
|
115
|
+
createdAt: number;
|
|
116
|
+
revoked: boolean;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
// Cross-component wrapper context
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
// Structural type accepted by all wrappers below. Works for both action and
|
|
123
|
+
// mutation contexts — the only capabilities we need are runQuery / runMutation
|
|
124
|
+
// and access to the component API via `auth.config.component`.
|
|
125
|
+
|
|
126
|
+
/** @internal */
|
|
127
|
+
export type ComponentCallCtx = {
|
|
128
|
+
runQuery: GenericActionCtx<AuthDataModel>["runQuery"];
|
|
129
|
+
runMutation: GenericActionCtx<AuthDataModel>["runMutation"];
|
|
130
|
+
auth: { config: { component: AuthComponentApi } };
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// Typed wrappers for cross-component calls
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
// Each wrapper encapsulates the single `as any` cast at the component
|
|
137
|
+
// boundary so that callers get full type safety on both args and return
|
|
138
|
+
// values.
|
|
139
|
+
|
|
140
|
+
// -- User queries --
|
|
141
|
+
|
|
142
|
+
export async function queryUserById(
|
|
143
|
+
ctx: ComponentCallCtx,
|
|
144
|
+
userId: string,
|
|
145
|
+
): Promise<UserDoc | null> {
|
|
146
|
+
return (await ctx.runQuery(
|
|
147
|
+
ctx.auth.config.component.public.userGetById,
|
|
148
|
+
{ userId },
|
|
149
|
+
)) as UserDoc | null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export async function queryUserByVerifiedEmail(
|
|
153
|
+
ctx: ComponentCallCtx,
|
|
154
|
+
email: string,
|
|
155
|
+
): Promise<UserDoc | null> {
|
|
156
|
+
return (await ctx.runQuery(
|
|
157
|
+
ctx.auth.config.component.public.userFindByVerifiedEmail,
|
|
158
|
+
{ email },
|
|
159
|
+
)) as UserDoc | null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// -- Verifier queries / mutations --
|
|
163
|
+
|
|
164
|
+
export async function queryVerifierById(
|
|
165
|
+
ctx: ComponentCallCtx,
|
|
166
|
+
verifierId: string,
|
|
167
|
+
): Promise<VerifierDoc | null> {
|
|
168
|
+
return (await ctx.runQuery(
|
|
169
|
+
ctx.auth.config.component.public.verifierGetById,
|
|
170
|
+
{ verifierId },
|
|
171
|
+
)) as VerifierDoc | null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export async function mutateVerifierDelete(
|
|
175
|
+
ctx: ComponentCallCtx,
|
|
176
|
+
verifierId: string,
|
|
177
|
+
): Promise<void> {
|
|
178
|
+
await ctx.runMutation(
|
|
179
|
+
ctx.auth.config.component.public.verifierDelete,
|
|
180
|
+
{ verifierId },
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// -- TOTP queries / mutations --
|
|
185
|
+
|
|
186
|
+
export async function queryTotpById(
|
|
187
|
+
ctx: ComponentCallCtx,
|
|
188
|
+
totpId: string,
|
|
189
|
+
): Promise<TotpDoc | null> {
|
|
190
|
+
return (await ctx.runQuery(
|
|
191
|
+
ctx.auth.config.component.public.totpGetById,
|
|
192
|
+
{ totpId },
|
|
193
|
+
)) as TotpDoc | null;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export async function queryTotpVerifiedByUserId(
|
|
197
|
+
ctx: ComponentCallCtx,
|
|
198
|
+
userId: string,
|
|
199
|
+
): Promise<TotpDoc | null> {
|
|
200
|
+
return (await ctx.runQuery(
|
|
201
|
+
ctx.auth.config.component.public.totpGetVerifiedByUserId,
|
|
202
|
+
{ userId },
|
|
203
|
+
)) as TotpDoc | null;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export async function mutateTotpInsert(
|
|
207
|
+
ctx: ComponentCallCtx,
|
|
208
|
+
args: {
|
|
209
|
+
userId: string;
|
|
210
|
+
secret: ArrayBuffer;
|
|
211
|
+
digits: number;
|
|
212
|
+
period: number;
|
|
213
|
+
verified: boolean;
|
|
214
|
+
name?: string;
|
|
215
|
+
createdAt: number;
|
|
216
|
+
},
|
|
217
|
+
): Promise<string> {
|
|
218
|
+
return (await ctx.runMutation(
|
|
219
|
+
ctx.auth.config.component.public.totpInsert,
|
|
220
|
+
args,
|
|
221
|
+
)) as string;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export async function mutateTotpMarkVerified(
|
|
225
|
+
ctx: ComponentCallCtx,
|
|
226
|
+
totpId: string,
|
|
227
|
+
lastUsedAt: number,
|
|
228
|
+
): Promise<void> {
|
|
229
|
+
await ctx.runMutation(
|
|
230
|
+
ctx.auth.config.component.public.totpMarkVerified,
|
|
231
|
+
{ totpId, lastUsedAt },
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export async function mutateTotpUpdateLastUsed(
|
|
236
|
+
ctx: ComponentCallCtx,
|
|
237
|
+
totpId: string,
|
|
238
|
+
lastUsedAt: number,
|
|
239
|
+
): Promise<void> {
|
|
240
|
+
await ctx.runMutation(
|
|
241
|
+
ctx.auth.config.component.public.totpUpdateLastUsed,
|
|
242
|
+
{ totpId, lastUsedAt },
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// -- Passkey queries / mutations --
|
|
247
|
+
|
|
248
|
+
export async function queryPasskeysByUserId(
|
|
249
|
+
ctx: ComponentCallCtx,
|
|
250
|
+
userId: string,
|
|
251
|
+
): Promise<PasskeyDoc[]> {
|
|
252
|
+
return (await ctx.runQuery(
|
|
253
|
+
ctx.auth.config.component.public.passkeyListByUserId,
|
|
254
|
+
{ userId },
|
|
255
|
+
)) as PasskeyDoc[];
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export async function queryPasskeyByCredentialId(
|
|
259
|
+
ctx: ComponentCallCtx,
|
|
260
|
+
credentialId: string,
|
|
261
|
+
): Promise<PasskeyDoc | null> {
|
|
262
|
+
return (await ctx.runQuery(
|
|
263
|
+
ctx.auth.config.component.public.passkeyGetByCredentialId,
|
|
264
|
+
{ credentialId },
|
|
265
|
+
)) as PasskeyDoc | null;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export async function mutatePasskeyInsert(
|
|
269
|
+
ctx: ComponentCallCtx,
|
|
270
|
+
args: {
|
|
271
|
+
userId: string;
|
|
272
|
+
credentialId: string;
|
|
273
|
+
publicKey: ArrayBuffer | ArrayBufferLike;
|
|
274
|
+
algorithm: number;
|
|
275
|
+
counter: number;
|
|
276
|
+
transports?: string[];
|
|
277
|
+
deviceType: string;
|
|
278
|
+
backedUp: boolean;
|
|
279
|
+
name?: string;
|
|
280
|
+
createdAt: number;
|
|
281
|
+
},
|
|
282
|
+
): Promise<string> {
|
|
283
|
+
return (await ctx.runMutation(
|
|
284
|
+
ctx.auth.config.component.public.passkeyInsert,
|
|
285
|
+
args,
|
|
286
|
+
)) as string;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export async function mutatePasskeyUpdateCounter(
|
|
290
|
+
ctx: ComponentCallCtx,
|
|
291
|
+
passkeyId: string,
|
|
292
|
+
counter: number,
|
|
293
|
+
lastUsedAt: number,
|
|
294
|
+
): Promise<void> {
|
|
295
|
+
await ctx.runMutation(
|
|
296
|
+
ctx.auth.config.component.public.passkeyUpdateCounter,
|
|
297
|
+
{ passkeyId, counter, lastUsedAt },
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// -- Key queries / mutations --
|
|
302
|
+
|
|
303
|
+
export async function mutateKeyInsert(
|
|
304
|
+
ctx: ComponentCallCtx,
|
|
305
|
+
args: {
|
|
306
|
+
userId: string;
|
|
307
|
+
prefix: string;
|
|
308
|
+
hashedKey: string;
|
|
309
|
+
name: string;
|
|
310
|
+
scopes: Array<{ resource: string; actions: string[] }>;
|
|
311
|
+
rateLimit?: { maxRequests: number; windowMs: number };
|
|
312
|
+
expiresAt?: number;
|
|
313
|
+
},
|
|
314
|
+
): Promise<string> {
|
|
315
|
+
return (await ctx.runMutation(
|
|
316
|
+
ctx.auth.config.component.public.keyInsert,
|
|
317
|
+
args,
|
|
318
|
+
)) as string;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export async function queryKeysByUserId(
|
|
322
|
+
ctx: ComponentCallCtx,
|
|
323
|
+
userId: string,
|
|
324
|
+
): Promise<KeyDoc[]> {
|
|
325
|
+
return (await ctx.runQuery(
|
|
326
|
+
ctx.auth.config.component.public.keyListByUserId,
|
|
327
|
+
{ userId },
|
|
328
|
+
)) as KeyDoc[];
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export async function queryKeyById(
|
|
332
|
+
ctx: ComponentCallCtx,
|
|
333
|
+
keyId: string,
|
|
334
|
+
): Promise<KeyDoc | null> {
|
|
335
|
+
return (await ctx.runQuery(
|
|
336
|
+
ctx.auth.config.component.public.keyGetById,
|
|
337
|
+
{ keyId },
|
|
338
|
+
)) as KeyDoc | null;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export async function mutateKeyPatch(
|
|
342
|
+
ctx: ComponentCallCtx,
|
|
343
|
+
keyId: string,
|
|
344
|
+
data: Record<string, unknown>,
|
|
345
|
+
): Promise<void> {
|
|
346
|
+
await ctx.runMutation(
|
|
347
|
+
ctx.auth.config.component.public.keyPatch,
|
|
348
|
+
{ keyId, data },
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export async function mutateKeyDelete(
|
|
353
|
+
ctx: ComponentCallCtx,
|
|
354
|
+
keyId: string,
|
|
355
|
+
): Promise<void> {
|
|
356
|
+
await ctx.runMutation(
|
|
357
|
+
ctx.auth.config.component.public.keyDelete,
|
|
358
|
+
{ keyId },
|
|
359
|
+
);
|
|
360
|
+
}
|
|
@@ -3,6 +3,7 @@ import { Doc, MutationCtx } from "./types.js";
|
|
|
3
3
|
import { AuthProviderMaterializedConfig, ConvexAuthConfig } from "../types.js";
|
|
4
4
|
import { LOG_LEVELS, logWithLevel } from "./utils.js";
|
|
5
5
|
import { authDb } from "./db.js";
|
|
6
|
+
import { throwAuthError } from "../errors.js";
|
|
6
7
|
|
|
7
8
|
type CreateOrUpdateUserArgs = {
|
|
8
9
|
type: "oauth" | "credentials" | "email" | "phone" | "verification";
|
|
@@ -137,12 +138,10 @@ async function defaultCreateOrUpdateUser(
|
|
|
137
138
|
try {
|
|
138
139
|
await db.users.patch(userId, userData);
|
|
139
140
|
} catch (error) {
|
|
140
|
-
|
|
141
|
-
`Could not update user document with ID \`${userId}\`, ` +
|
|
141
|
+
throwAuthError("USER_UPDATE_FAILED", `Could not update user document with ID \`${userId}\`, ` +
|
|
142
142
|
`either the user has been deleted but their account has not, ` +
|
|
143
143
|
`or the profile data doesn't match the \`users\` table schema: ` +
|
|
144
|
-
`${(error as Error).message}
|
|
145
|
-
);
|
|
144
|
+
`${(error as Error).message}`);
|
|
146
145
|
}
|
|
147
146
|
} else {
|
|
148
147
|
userId = (await db.users.insert(userData)) as GenericId<"user">;
|
|
@@ -231,9 +230,7 @@ export async function getAccountOrThrow(
|
|
|
231
230
|
) {
|
|
232
231
|
const existingAccount = await authDb(ctx, config).accounts.getById(existingAccountId);
|
|
233
232
|
if (existingAccount === null) {
|
|
234
|
-
|
|
235
|
-
`Expected an account to exist for ID "${existingAccountId}"`,
|
|
236
|
-
);
|
|
233
|
+
throwAuthError("ACCOUNT_NOT_FOUND", `Expected an account to exist for ID "${existingAccountId}"`);
|
|
237
234
|
}
|
|
238
235
|
return existingAccount;
|
|
239
236
|
}
|