Heath
Heath4mo ago

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
sshader
sshader4mo ago
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
Heath
HeathOP4mo ago
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.
sshader
sshader4mo ago
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 customize
Heath
HeathOP4mo ago
Thanks, 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.
sshader
sshader4mo ago
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 possible
Application Errors | Convex Developer Hub
If you have expected ways your functions might fail, you can either return
Heath
HeathOP4mo ago
I did try that for #1
sshader
sshader4mo ago
Oh interesting -- that sounds like a bug then!
Heath
HeathOP4mo ago
It did feel like a bug 🙂
Heath
HeathOP4mo ago
Did a quick re-test:
export const { auth, signIn, signOut, store } = convexAuth({
providers: [
ConvexCredentials({
id: 'simple-auth',
authorize: async (params, ctx) => {
throw new ConvexError('Testing for @sshader')
export const { auth, signIn, signOut, store } = convexAuth({
providers: [
ConvexCredentials({
id: 'simple-auth',
authorize: async (params, ctx) => {
throw new ConvexError('Testing for @sshader')
No description
Heath
HeathOP4mo ago
happy to submit a bug report somewhere if it would help
jamwt
jamwt4mo ago
@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.
Heath
HeathOP4mo ago
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...

Did you find this page helpful?