@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,7 +11,6 @@
|
|
|
11
11
|
* `@oslojs/crypto` for signature verification.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { GenericId } from "convex/values";
|
|
15
14
|
import {
|
|
16
15
|
parseAttestationObject,
|
|
17
16
|
parseClientDataJSON,
|
|
@@ -22,9 +21,7 @@ import {
|
|
|
22
21
|
coseAlgorithmRS256,
|
|
23
22
|
COSEKeyType,
|
|
24
23
|
} from "@oslojs/webauthn";
|
|
25
|
-
import type { AuthenticatorData } from "@oslojs/webauthn";
|
|
26
24
|
import {
|
|
27
|
-
ECDSAPublicKey,
|
|
28
25
|
p256,
|
|
29
26
|
verifyECDSASignature,
|
|
30
27
|
decodeSEC1PublicKey,
|
|
@@ -44,10 +41,22 @@ import {
|
|
|
44
41
|
PasskeyProviderConfig,
|
|
45
42
|
GenericActionCtxWithAuthConfig,
|
|
46
43
|
} from "../types.js";
|
|
47
|
-
import {
|
|
44
|
+
import {
|
|
45
|
+
AuthDataModel,
|
|
46
|
+
SessionInfo,
|
|
47
|
+
queryUserById,
|
|
48
|
+
queryUserByVerifiedEmail,
|
|
49
|
+
queryPasskeysByUserId,
|
|
50
|
+
queryPasskeyByCredentialId,
|
|
51
|
+
queryVerifierById,
|
|
52
|
+
mutatePasskeyInsert,
|
|
53
|
+
mutatePasskeyUpdateCounter,
|
|
54
|
+
mutateVerifierDelete,
|
|
55
|
+
} from "./types.js";
|
|
48
56
|
import { callSignIn, callVerifier } from "./mutations/index.js";
|
|
49
|
-
import { callVerifierSignature } from "./mutations/
|
|
57
|
+
import { callVerifierSignature } from "./mutations/signature.js";
|
|
50
58
|
import { authDb } from "./db.js";
|
|
59
|
+
import { throwAuthError } from "../errors.js";
|
|
51
60
|
|
|
52
61
|
|
|
53
62
|
type EnrichedActionCtx = GenericActionCtxWithAuthConfig<AuthDataModel>;
|
|
@@ -64,7 +73,8 @@ function resolveRpOptions(provider: PasskeyProviderConfig) {
|
|
|
64
73
|
// because the RP ID wouldn't match the page origin.
|
|
65
74
|
const siteUrl = process.env.SITE_URL;
|
|
66
75
|
if (!siteUrl && !provider.options.rpId) {
|
|
67
|
-
|
|
76
|
+
throwAuthError(
|
|
77
|
+
"PASSKEY_MISSING_CONFIG",
|
|
68
78
|
"Passkey provider requires SITE_URL env var (your frontend URL) " +
|
|
69
79
|
"or explicit rpId / origin in the provider config. " +
|
|
70
80
|
"CONVEX_SITE_URL cannot be used because WebAuthn RP ID must match the frontend domain.",
|
|
@@ -124,10 +134,7 @@ async function handleRegisterOptions(
|
|
|
124
134
|
// Passkey registration requires an authenticated user
|
|
125
135
|
const identity = await ctx.auth.getUserIdentity();
|
|
126
136
|
if (identity === null) {
|
|
127
|
-
|
|
128
|
-
"Passkey registration requires an authenticated user. " +
|
|
129
|
-
"Sign in first, then add a passkey to your account.",
|
|
130
|
-
);
|
|
137
|
+
throwAuthError("PASSKEY_AUTH_REQUIRED");
|
|
131
138
|
}
|
|
132
139
|
const [userId] = identity.subject.split("|");
|
|
133
140
|
|
|
@@ -143,25 +150,16 @@ async function handleRegisterOptions(
|
|
|
143
150
|
});
|
|
144
151
|
|
|
145
152
|
// Get the user's profile for credential metadata
|
|
146
|
-
const user = await ctx
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
);
|
|
150
|
-
const userName = params.userName ?? (user as any)?.email ?? "user";
|
|
151
|
-
const userDisplayName = params.userDisplayName ?? (user as any)?.name ?? userName;
|
|
153
|
+
const user = await queryUserById(ctx, userId!);
|
|
154
|
+
const userName = params.userName ?? user?.email ?? "user";
|
|
155
|
+
const userDisplayName = params.userDisplayName ?? user?.name ?? userName;
|
|
152
156
|
|
|
153
157
|
// Collect existing credentials to prevent re-registration
|
|
154
|
-
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
);
|
|
159
|
-
if (existing) {
|
|
160
|
-
excludeCredentials = (existing as any[]).map((pk: any) => ({
|
|
161
|
-
id: pk.credentialId,
|
|
162
|
-
transports: pk.transports,
|
|
163
|
-
}));
|
|
164
|
-
}
|
|
158
|
+
const existing = await queryPasskeysByUserId(ctx, userId!);
|
|
159
|
+
const excludeCredentials = existing.map((pk) => ({
|
|
160
|
+
id: pk.credentialId,
|
|
161
|
+
transports: pk.transports,
|
|
162
|
+
}));
|
|
165
163
|
|
|
166
164
|
// User handle is derived from the Convex userId
|
|
167
165
|
const userHandle = encodeBase64urlNoPadding(
|
|
@@ -215,17 +213,14 @@ async function handleRegisterVerify(
|
|
|
215
213
|
// Passkey registration requires an authenticated user
|
|
216
214
|
const identity = await ctx.auth.getUserIdentity();
|
|
217
215
|
if (identity === null) {
|
|
218
|
-
|
|
219
|
-
"Passkey registration requires an authenticated user. " +
|
|
220
|
-
"Sign in first, then add a passkey to your account.",
|
|
221
|
-
);
|
|
216
|
+
throwAuthError("PASSKEY_AUTH_REQUIRED");
|
|
222
217
|
}
|
|
223
218
|
const [userId] = identity.subject.split("|");
|
|
224
219
|
|
|
225
220
|
const rp = resolveRpOptions(provider);
|
|
226
221
|
|
|
227
222
|
if (!verifierValue) {
|
|
228
|
-
|
|
223
|
+
throwAuthError("PASSKEY_MISSING_VERIFIER");
|
|
229
224
|
}
|
|
230
225
|
|
|
231
226
|
// Decode client data
|
|
@@ -234,13 +229,14 @@ async function handleRegisterVerify(
|
|
|
234
229
|
|
|
235
230
|
// Verify client data type is "webauthn.create"
|
|
236
231
|
if (clientData.type !== ClientDataType.Create) {
|
|
237
|
-
|
|
232
|
+
throwAuthError("PASSKEY_INVALID_CLIENT_DATA", "Invalid client data type: expected webauthn.create");
|
|
238
233
|
}
|
|
239
234
|
|
|
240
235
|
// Verify origin
|
|
241
236
|
const allowedOrigins = Array.isArray(rp.origin) ? rp.origin : [rp.origin];
|
|
242
237
|
if (!allowedOrigins.includes(clientData.origin)) {
|
|
243
|
-
|
|
238
|
+
throwAuthError(
|
|
239
|
+
"PASSKEY_INVALID_ORIGIN",
|
|
244
240
|
`Invalid origin: ${clientData.origin}, expected one of: ${allowedOrigins.join(", ")}`,
|
|
245
241
|
);
|
|
246
242
|
}
|
|
@@ -249,19 +245,13 @@ async function handleRegisterVerify(
|
|
|
249
245
|
const challengeHash = encodeBase64urlNoPadding(
|
|
250
246
|
new Uint8Array(sha256(clientData.challenge)),
|
|
251
247
|
);
|
|
252
|
-
const verifierDoc = await ctx
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
);
|
|
256
|
-
if (!verifierDoc || (verifierDoc as any).signature !== challengeHash) {
|
|
257
|
-
throw new Error("Invalid or expired challenge");
|
|
248
|
+
const verifierDoc = await queryVerifierById(ctx, verifierValue);
|
|
249
|
+
if (!verifierDoc || verifierDoc.signature !== challengeHash) {
|
|
250
|
+
throwAuthError("PASSKEY_INVALID_CHALLENGE");
|
|
258
251
|
}
|
|
259
252
|
|
|
260
253
|
// Clean up the verifier
|
|
261
|
-
await ctx
|
|
262
|
-
ctx.auth.config.component.public.verifierDelete,
|
|
263
|
-
{ verifierId: verifierValue },
|
|
264
|
-
);
|
|
254
|
+
await mutateVerifierDelete(ctx, verifierValue);
|
|
265
255
|
|
|
266
256
|
// Parse attestation object
|
|
267
257
|
const attestationObjectBytes = decodeBase64urlIgnorePadding(params.attestationObject);
|
|
@@ -270,21 +260,21 @@ async function handleRegisterVerify(
|
|
|
270
260
|
|
|
271
261
|
// Verify RP ID hash
|
|
272
262
|
if (!authenticatorData.verifyRelyingPartyIdHash(rp.rpId)) {
|
|
273
|
-
|
|
263
|
+
throwAuthError("PASSKEY_RP_MISMATCH");
|
|
274
264
|
}
|
|
275
265
|
|
|
276
266
|
// Verify user presence and verification flags
|
|
277
267
|
if (!authenticatorData.userPresent) {
|
|
278
|
-
|
|
268
|
+
throwAuthError("PASSKEY_USER_PRESENCE");
|
|
279
269
|
}
|
|
280
270
|
if (rp.userVerification === "required" && !authenticatorData.userVerified) {
|
|
281
|
-
|
|
271
|
+
throwAuthError("PASSKEY_USER_VERIFICATION");
|
|
282
272
|
}
|
|
283
273
|
|
|
284
274
|
// Extract credential
|
|
285
275
|
const credential = authenticatorData.credential;
|
|
286
276
|
if (!credential) {
|
|
287
|
-
|
|
277
|
+
throwAuthError("PASSKEY_NO_CREDENTIAL");
|
|
288
278
|
}
|
|
289
279
|
|
|
290
280
|
const credentialId = encodeBase64urlNoPadding(credential.id);
|
|
@@ -320,7 +310,7 @@ async function handleRegisterVerify(
|
|
|
320
310
|
const rsaPubKey = new RSAPublicKey(rsa.n, rsa.e);
|
|
321
311
|
publicKeyBytes = rsaPubKey.encodePKCS1();
|
|
322
312
|
} else {
|
|
323
|
-
|
|
313
|
+
throwAuthError("PASSKEY_UNSUPPORTED_ALGORITHM", `Unsupported algorithm: ${algorithm}`);
|
|
324
314
|
}
|
|
325
315
|
|
|
326
316
|
const deviceType = params.deviceType ?? "single-device";
|
|
@@ -337,24 +327,21 @@ async function handleRegisterVerify(
|
|
|
337
327
|
});
|
|
338
328
|
|
|
339
329
|
// Store the passkey credential
|
|
340
|
-
await ctx
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
createdAt: Date.now(),
|
|
356
|
-
},
|
|
357
|
-
);
|
|
330
|
+
await mutatePasskeyInsert(ctx, {
|
|
331
|
+
userId: userId!,
|
|
332
|
+
credentialId,
|
|
333
|
+
publicKey: publicKeyBytes.buffer.slice(
|
|
334
|
+
publicKeyBytes.byteOffset,
|
|
335
|
+
publicKeyBytes.byteOffset + publicKeyBytes.byteLength,
|
|
336
|
+
),
|
|
337
|
+
algorithm,
|
|
338
|
+
counter: authenticatorData.signatureCounter,
|
|
339
|
+
transports: params.transports,
|
|
340
|
+
deviceType,
|
|
341
|
+
backedUp,
|
|
342
|
+
name: params.passkeyName,
|
|
343
|
+
createdAt: Date.now(),
|
|
344
|
+
});
|
|
358
345
|
|
|
359
346
|
// Return tokens for the existing session
|
|
360
347
|
const signInResult = await callSignIn(ctx, {
|
|
@@ -399,17 +386,11 @@ async function handleAuthOptions(
|
|
|
399
386
|
let allowCredentials: Array<{ type: string; id: string; transports?: string[] }> | undefined;
|
|
400
387
|
if (params.email) {
|
|
401
388
|
// Look up user by email, then find their passkeys
|
|
402
|
-
const user = await ctx.
|
|
403
|
-
ctx.auth.config.component.public.userFindByVerifiedEmail,
|
|
404
|
-
{ email: params.email },
|
|
405
|
-
);
|
|
389
|
+
const user = await queryUserByVerifiedEmail(ctx, params.email);
|
|
406
390
|
if (user) {
|
|
407
|
-
const passkeys = await ctx.
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
);
|
|
411
|
-
if (passkeys && (passkeys as any[]).length > 0) {
|
|
412
|
-
allowCredentials = (passkeys as any[]).map((pk: any) => ({
|
|
391
|
+
const passkeys = await queryPasskeysByUserId(ctx, user._id);
|
|
392
|
+
if (passkeys.length > 0) {
|
|
393
|
+
allowCredentials = passkeys.map((pk) => ({
|
|
413
394
|
type: "public-key",
|
|
414
395
|
id: pk.credentialId,
|
|
415
396
|
transports: pk.transports,
|
|
@@ -447,7 +428,7 @@ async function handleAuthVerify(
|
|
|
447
428
|
const rp = resolveRpOptions(provider);
|
|
448
429
|
|
|
449
430
|
if (!verifierValue) {
|
|
450
|
-
|
|
431
|
+
throwAuthError("PASSKEY_MISSING_VERIFIER");
|
|
451
432
|
}
|
|
452
433
|
|
|
453
434
|
// Decode client data
|
|
@@ -456,13 +437,14 @@ async function handleAuthVerify(
|
|
|
456
437
|
|
|
457
438
|
// Verify client data type is "webauthn.get"
|
|
458
439
|
if (clientData.type !== ClientDataType.Get) {
|
|
459
|
-
|
|
440
|
+
throwAuthError("PASSKEY_INVALID_CLIENT_DATA", "Invalid client data type: expected webauthn.get");
|
|
460
441
|
}
|
|
461
442
|
|
|
462
443
|
// Verify origin
|
|
463
444
|
const allowedOrigins = Array.isArray(rp.origin) ? rp.origin : [rp.origin];
|
|
464
445
|
if (!allowedOrigins.includes(clientData.origin)) {
|
|
465
|
-
|
|
446
|
+
throwAuthError(
|
|
447
|
+
"PASSKEY_INVALID_ORIGIN",
|
|
466
448
|
`Invalid origin: ${clientData.origin}, expected one of: ${allowedOrigins.join(", ")}`,
|
|
467
449
|
);
|
|
468
450
|
}
|
|
@@ -471,34 +453,24 @@ async function handleAuthVerify(
|
|
|
471
453
|
const challengeHash = encodeBase64urlNoPadding(
|
|
472
454
|
new Uint8Array(sha256(clientData.challenge)),
|
|
473
455
|
);
|
|
474
|
-
const verifierDoc = await ctx
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
);
|
|
478
|
-
if (!verifierDoc || (verifierDoc as any).signature !== challengeHash) {
|
|
479
|
-
throw new Error("Invalid or expired challenge");
|
|
456
|
+
const verifierDoc = await queryVerifierById(ctx, verifierValue);
|
|
457
|
+
if (!verifierDoc || verifierDoc.signature !== challengeHash) {
|
|
458
|
+
throwAuthError("PASSKEY_INVALID_CHALLENGE");
|
|
480
459
|
}
|
|
481
460
|
|
|
482
461
|
// Clean up the verifier
|
|
483
|
-
await ctx
|
|
484
|
-
ctx.auth.config.component.public.verifierDelete,
|
|
485
|
-
{ verifierId: verifierValue },
|
|
486
|
-
);
|
|
462
|
+
await mutateVerifierDelete(ctx, verifierValue);
|
|
487
463
|
|
|
488
464
|
// Look up the credential
|
|
489
465
|
const credentialId = params.credentialId;
|
|
490
466
|
if (!credentialId) {
|
|
491
|
-
|
|
467
|
+
throwAuthError("PASSKEY_UNKNOWN_CREDENTIAL", "Missing credential ID");
|
|
492
468
|
}
|
|
493
469
|
|
|
494
|
-
const
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
);
|
|
498
|
-
if (!passkeyDoc) {
|
|
499
|
-
throw new Error("Unknown credential");
|
|
470
|
+
const passkey = await queryPasskeyByCredentialId(ctx, credentialId);
|
|
471
|
+
if (!passkey) {
|
|
472
|
+
throwAuthError("PASSKEY_UNKNOWN_CREDENTIAL", "Unknown credential");
|
|
500
473
|
}
|
|
501
|
-
const passkey = passkeyDoc as any;
|
|
502
474
|
|
|
503
475
|
// Parse authenticator data
|
|
504
476
|
const authenticatorDataBytes = decodeBase64urlIgnorePadding(params.authenticatorData);
|
|
@@ -506,15 +478,15 @@ async function handleAuthVerify(
|
|
|
506
478
|
|
|
507
479
|
// Verify RP ID hash
|
|
508
480
|
if (!authenticatorData.verifyRelyingPartyIdHash(rp.rpId)) {
|
|
509
|
-
|
|
481
|
+
throwAuthError("PASSKEY_RP_MISMATCH");
|
|
510
482
|
}
|
|
511
483
|
|
|
512
484
|
// Verify user presence
|
|
513
485
|
if (!authenticatorData.userPresent) {
|
|
514
|
-
|
|
486
|
+
throwAuthError("PASSKEY_USER_PRESENCE");
|
|
515
487
|
}
|
|
516
488
|
if (rp.userVerification === "required" && !authenticatorData.userVerified) {
|
|
517
|
-
|
|
489
|
+
throwAuthError("PASSKEY_USER_VERIFICATION");
|
|
518
490
|
}
|
|
519
491
|
|
|
520
492
|
// Verify signature
|
|
@@ -538,7 +510,7 @@ async function handleAuthVerify(
|
|
|
538
510
|
ecdsaSignature,
|
|
539
511
|
);
|
|
540
512
|
if (!valid) {
|
|
541
|
-
|
|
513
|
+
throwAuthError("PASSKEY_INVALID_SIGNATURE");
|
|
542
514
|
}
|
|
543
515
|
} else if (passkey.algorithm === coseAlgorithmRS256) {
|
|
544
516
|
// RSA PKCS#1 v1.5 with SHA-256 verification
|
|
@@ -552,10 +524,10 @@ async function handleAuthVerify(
|
|
|
552
524
|
signature,
|
|
553
525
|
);
|
|
554
526
|
if (!valid) {
|
|
555
|
-
|
|
527
|
+
throwAuthError("PASSKEY_INVALID_SIGNATURE");
|
|
556
528
|
}
|
|
557
529
|
} else {
|
|
558
|
-
|
|
530
|
+
throwAuthError("PASSKEY_UNSUPPORTED_ALGORITHM", `Unsupported algorithm: ${passkey.algorithm}`);
|
|
559
531
|
}
|
|
560
532
|
|
|
561
533
|
// Verify counter (clone detection)
|
|
@@ -565,19 +537,15 @@ async function handleAuthVerify(
|
|
|
565
537
|
authenticatorData.signatureCounter !== 0 &&
|
|
566
538
|
authenticatorData.signatureCounter <= passkey.counter
|
|
567
539
|
) {
|
|
568
|
-
|
|
569
|
-
"Authenticator counter did not increase — possible credential cloning detected",
|
|
570
|
-
);
|
|
540
|
+
throwAuthError("PASSKEY_COUNTER_ERROR");
|
|
571
541
|
}
|
|
572
542
|
|
|
573
543
|
// Update counter and last used timestamp
|
|
574
|
-
await
|
|
575
|
-
ctx
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
lastUsedAt: Date.now(),
|
|
580
|
-
},
|
|
544
|
+
await mutatePasskeyUpdateCounter(
|
|
545
|
+
ctx,
|
|
546
|
+
passkey._id,
|
|
547
|
+
authenticatorData.signatureCounter,
|
|
548
|
+
Date.now(),
|
|
581
549
|
);
|
|
582
550
|
|
|
583
551
|
// Sign in the user
|
|
@@ -611,7 +579,8 @@ export async function handlePasskey(
|
|
|
611
579
|
> {
|
|
612
580
|
const flow = args.params?.flow;
|
|
613
581
|
if (!flow) {
|
|
614
|
-
|
|
582
|
+
throwAuthError(
|
|
583
|
+
"PASSKEY_MISSING_FLOW",
|
|
615
584
|
"Missing `flow` parameter. Expected one of: register-options, register-verify, auth-options, auth-verify",
|
|
616
585
|
);
|
|
617
586
|
}
|
|
@@ -626,7 +595,8 @@ export async function handlePasskey(
|
|
|
626
595
|
case "auth-verify":
|
|
627
596
|
return handleAuthVerify(ctx, provider, args.params ?? {}, args.verifier);
|
|
628
597
|
default:
|
|
629
|
-
|
|
598
|
+
throwAuthError(
|
|
599
|
+
"PASSKEY_UNKNOWN_FLOW",
|
|
630
600
|
`Unknown passkey flow: ${flow}. Expected one of: register-options, register-verify, auth-options, auth-verify`,
|
|
631
601
|
);
|
|
632
602
|
}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { AuthProviderMaterializedConfig } from "../types.js";
|
|
2
2
|
import { ConvexAuthMaterializedConfig } from "../types.js";
|
|
3
|
+
import { throwAuthError } from "../errors.js";
|
|
3
4
|
|
|
4
5
|
export async function hash(provider: any, secret: string) {
|
|
5
6
|
if (provider.type !== "credentials") {
|
|
6
|
-
|
|
7
|
+
throwAuthError("INVALID_CREDENTIALS_PROVIDER", `Provider ${provider.id} is not a credentials provider`, { provider: provider.id });
|
|
7
8
|
}
|
|
8
9
|
const hashSecretFn = provider.crypto?.hashSecret;
|
|
9
10
|
if (hashSecretFn === undefined) {
|
|
10
|
-
|
|
11
|
-
`Provider ${provider.id} does not have a \`crypto.hashSecret\` function`,
|
|
12
|
-
);
|
|
11
|
+
throwAuthError("MISSING_CRYPTO_FUNCTION", `Provider ${provider.id} does not have a \`crypto.hashSecret\` function`, { provider: provider.id });
|
|
13
12
|
}
|
|
14
13
|
return await hashSecretFn(secret);
|
|
15
14
|
}
|
|
@@ -20,13 +19,11 @@ export async function verify(
|
|
|
20
19
|
hash: string,
|
|
21
20
|
) {
|
|
22
21
|
if (provider.type !== "credentials") {
|
|
23
|
-
|
|
22
|
+
throwAuthError("INVALID_CREDENTIALS_PROVIDER", `Provider ${provider.id} is not a credentials provider`, { provider: provider.id });
|
|
24
23
|
}
|
|
25
24
|
const verifySecretFn = provider.crypto?.verifySecret;
|
|
26
25
|
if (verifySecretFn === undefined) {
|
|
27
|
-
|
|
28
|
-
`Provider ${provider.id} does not have a \`crypto.verifySecret\` function`,
|
|
29
|
-
);
|
|
26
|
+
throwAuthError("MISSING_CRYPTO_FUNCTION", `Provider ${provider.id} does not have a \`crypto.verifySecret\` function`, { provider: provider.id });
|
|
30
27
|
}
|
|
31
28
|
return await verifySecretFn(secret, hash);
|
|
32
29
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ConvexAuthMaterializedConfig } from "../types.js";
|
|
2
2
|
import { requireEnv } from "../utils.js";
|
|
3
|
+
import { throwAuthError } from "../errors.js";
|
|
3
4
|
|
|
4
5
|
export async function redirectAbsoluteUrl(
|
|
5
6
|
config: ConvexAuthMaterializedConfig,
|
|
@@ -7,9 +8,7 @@ export async function redirectAbsoluteUrl(
|
|
|
7
8
|
) {
|
|
8
9
|
if (params.redirectTo !== undefined) {
|
|
9
10
|
if (typeof params.redirectTo !== "string") {
|
|
10
|
-
|
|
11
|
-
`Expected \`redirectTo\` to be a string, got ${params.redirectTo as any}`,
|
|
12
|
-
);
|
|
11
|
+
throwAuthError("INVALID_REDIRECT", `Expected \`redirectTo\` to be a string, got ${params.redirectTo as any}`);
|
|
13
12
|
}
|
|
14
13
|
const redirectCallback =
|
|
15
14
|
config.callbacks?.redirect ?? defaultRedirectCallback;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { GenericId } from "convex/values";
|
|
2
2
|
import { ConvexAuthConfig } from "../types.js";
|
|
3
|
+
import { throwAuthError } from "../errors.js";
|
|
3
4
|
import { Doc, MutationCtx } from "./types.js";
|
|
4
5
|
import {
|
|
5
6
|
LOG_LEVELS,
|
|
@@ -47,7 +48,7 @@ export const parseRefreshToken = (
|
|
|
47
48
|
} => {
|
|
48
49
|
const [refreshTokenId, sessionId] = refreshToken.split(REFRESH_TOKEN_DIVIDER);
|
|
49
50
|
if (!refreshTokenId || !sessionId) {
|
|
50
|
-
|
|
51
|
+
throwAuthError("INVALID_REFRESH_TOKEN", `Can't parse refresh token: ${maybeRedact(refreshToken)}`);
|
|
51
52
|
}
|
|
52
53
|
return {
|
|
53
54
|
refreshTokenId: refreshTokenId as GenericId<"token">,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
createRefreshToken,
|
|
15
15
|
formatRefreshToken,
|
|
16
16
|
deleteAllRefreshTokens,
|
|
17
|
-
} from "./
|
|
17
|
+
} from "./refresh.js";
|
|
18
18
|
import { authDb } from "./db.js";
|
|
19
19
|
|
|
20
20
|
const DEFAULT_SESSION_TOTAL_DURATION_MS = 1000 * 60 * 60 * 24 * 30; // 30 days
|
|
@@ -4,9 +4,7 @@ import {
|
|
|
4
4
|
ConvexCredentialsConfig,
|
|
5
5
|
EmailConfig,
|
|
6
6
|
GenericActionCtxWithAuthConfig,
|
|
7
|
-
PasskeyProviderConfig,
|
|
8
7
|
PhoneConfig,
|
|
9
|
-
TotpProviderConfig,
|
|
10
8
|
} from "../types.js";
|
|
11
9
|
import {
|
|
12
10
|
AuthDataModel,
|
|
@@ -28,6 +26,7 @@ import { OAuth2Config, OIDCConfig } from "@auth/core/providers/oauth.js";
|
|
|
28
26
|
import { generateRandomString } from "./utils.js";
|
|
29
27
|
import { handlePasskey } from "./passkey.js";
|
|
30
28
|
import { handleTotp, checkTotpRequired } from "./totp.js";
|
|
29
|
+
import { throwAuthError } from "../errors.js";
|
|
31
30
|
|
|
32
31
|
const DEFAULT_EMAIL_VERIFICATION_CODE_DURATION_S = 60 * 60 * 24; // 24 hours
|
|
33
32
|
|
|
@@ -63,9 +62,12 @@ export async function signInImpl(
|
|
|
63
62
|
| { kind: "totpSetup"; uri: string; secret: string; verifier: string; totpId: string }
|
|
64
63
|
> {
|
|
65
64
|
if (provider === null && args.refreshToken) {
|
|
66
|
-
const tokens
|
|
65
|
+
const tokens = await callRefreshSession(ctx, {
|
|
67
66
|
refreshToken: args.refreshToken,
|
|
68
|
-
})
|
|
67
|
+
});
|
|
68
|
+
if (tokens === null) {
|
|
69
|
+
return { kind: "signedIn", signedIn: null };
|
|
70
|
+
}
|
|
69
71
|
return { kind: "refreshTokens", signedIn: { tokens } };
|
|
70
72
|
}
|
|
71
73
|
if (provider === null && args.params?.code !== undefined) {
|
|
@@ -82,9 +84,7 @@ export async function signInImpl(
|
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
if (provider === null) {
|
|
85
|
-
|
|
86
|
-
"Cannot sign in: Missing `provider`, `params.code` or `refreshToken`",
|
|
87
|
-
);
|
|
87
|
+
throwAuthError("SIGN_IN_MISSING_PARAMS");
|
|
88
88
|
}
|
|
89
89
|
if (provider.type === "email" || provider.type === "phone") {
|
|
90
90
|
return handleEmailAndPhoneProvider(ctx, provider, args, options);
|
|
@@ -102,7 +102,8 @@ export async function signInImpl(
|
|
|
102
102
|
return handleTotp(ctx, provider, args);
|
|
103
103
|
}
|
|
104
104
|
const _typecheck: never = provider;
|
|
105
|
-
|
|
105
|
+
throwAuthError(
|
|
106
|
+
"UNSUPPORTED_PROVIDER_TYPE",
|
|
106
107
|
`Provider type ${(provider as any).type} is not supported yet`,
|
|
107
108
|
);
|
|
108
109
|
}
|
|
@@ -130,7 +131,7 @@ async function handleEmailAndPhoneProvider(
|
|
|
130
131
|
allowExtraProviders: options.allowExtraProviders,
|
|
131
132
|
});
|
|
132
133
|
if (result === null) {
|
|
133
|
-
|
|
134
|
+
throwAuthError("INVALID_VERIFICATION_CODE");
|
|
134
135
|
}
|
|
135
136
|
return {
|
|
136
137
|
kind: "signedIn",
|
|
@@ -206,7 +207,7 @@ async function handleCredentials(
|
|
|
206
207
|
const hasTotpEnrolled = await checkTotpRequired(ctx, result.userId);
|
|
207
208
|
if (hasTotpEnrolled) {
|
|
208
209
|
// Create session but withhold tokens — TOTP verification needed
|
|
209
|
-
|
|
210
|
+
await callSignIn(ctx, {
|
|
210
211
|
userId: result.userId,
|
|
211
212
|
sessionId: result.sessionId,
|
|
212
213
|
generateTokens: false,
|
|
@@ -271,7 +272,8 @@ async function handleOAuthProvider(
|
|
|
271
272
|
redirect.searchParams.set("code", verifier);
|
|
272
273
|
if (args.params?.redirectTo !== undefined) {
|
|
273
274
|
if (typeof args.params.redirectTo !== "string") {
|
|
274
|
-
|
|
275
|
+
throwAuthError(
|
|
276
|
+
"INVALID_REDIRECT",
|
|
275
277
|
`Expected \`redirectTo\` to be a string, got ${args.params.redirectTo}`,
|
|
276
278
|
);
|
|
277
279
|
}
|