Rejecting signin for unknown users when using magic link authorization (e.g. Resend)
I am using the Resend magic link w/ Convex Auth, which works fine, but I would like to prevent account creation for users that are not already registered in the database.
I looked a bit into how Auth.js handles this. They provide a pre-signIn callback that you can use to reject signin attempts. However, this callback isn't exposed via Convex Auth.
12 Replies
Does https://labs.convex.dev/auth/api_reference/server#callbackscreateorupdateuser potentially meet your needs here? Where you can throw if there's no existing user? (I haven't actually tried this, but just going off of the docs + scan of the code)
server - Convex Auth
Authentication library for your Convex backend
Hey @sshader , I appreciate the reply!
If I specify that callback it will require me to inline the rest of the createOrUpdateUser logic (https://github.com/get-convex/convex-auth/blob/10b7c9aee93053c3be0869396887030cda19b410/src/server/implementation/users.ts#L44) as well, which I'd prefer to avoid taking in.
GitHub
convex-auth/src/server/implementation/users.ts at 10b7c9aee93053c3b...
Library for built-in auth. Contribute to get-convex/convex-auth development by creating an account on GitHub.
Yeah makes sense. So you really want something that is triggered before
createOrUpdateUser
similar to Auth.js. Will look into exposing something like this / potentially exposing defaultCreateOrUpdateUser
to make it easier to customizeThanks, yes even that would help probably, though I’m not sure as I haven’t tried implementing that callback.
One thing I tried that almost worked but not quite - I implement a provider using ConvexCredentials (similar to the Password one), and in the authorize() method just threw an error if the user didn’t exist, and otherwise deferred to Resend. This felt like a fine solution but there were two issues:
1. Throwing from authorize does not bubble the error up to the client, it instead produces an ugly internal unhandled exception (but hey, it did prevent signin 😉
2. In order to handle the click through from the email I had to add Resend into the provider list, which felt unfortunate as it still exposes me from unauthorized signups.
For (1), you should be able to use
ConvexError
(https://docs.convex.dev/functions/error-handling/application-errors#throwing-application-errors).
Not sure how to best get around (2) -- curious if passing around an extra argument containing a secret only accessible in your Convex functions is possibleApplication Errors | Convex Developer Hub
If you have expected ways your functions might fail, you can either return
I did try that for #1
Oh interesting -- that sounds like a bug then!
It did feel like a bug 🙂
Did a quick re-test:
happy to submit a bug report somewhere if it would help
@Heath sure, feel free to file a bug report on the repo: https://github.com/get-convex/convex-auth
GitHub
GitHub - get-convex/convex-auth: Library for built-in auth
Library for built-in auth. Contribute to get-convex/convex-auth development by creating an account on GitHub.
GitHub
Exceptions thrown in ConvexCredentials.authorize() are unhandled · ...
Overview Exceptions (including ConvexError) are unhandled when thrown from a ConvexCredentials.authorize() method. Setup export const { auth, signIn, signOut, store } = convexAuth({ providers: [ Co...