#Calling a mutation after the second stage of OTP auth.
8 messages · Page 1 of 1 (latest)
Hi @sonic onyx. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
Based on the knowledge sources, you can use the afterUserCreatedOrUpdated callback to trigger additional operations after a user is authenticated with OTP. This callback runs in a mutation context and allows you to perform additional database operations.
Here's how you can implement this:
import { convexAuth } from "@convex-dev/auth/server";
import { ResendOTP } from "./ResendOTP";
import { Password } from "@convex-dev/auth/providers/Password";
export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({
providers: [Password({ verify: ResendOTP })],
callbacks: {
async afterUserCreatedOrUpdated(ctx, { userId }) {
// Perform additional database operations here
await ctx.db.insert("someTable", { userId, data: "some data" });
// Or schedule an action to run immediately after this transaction completes
// if you need to perform side effects like API calls
ctx.scheduler.runAfter(0, internal.yourNamespace.yourAction, { userId });
},
},
});
It's important to note that this callback runs in a mutation context, so you cannot directly call actions from it. If you need to perform side effects like API calls, you should schedule an action to run after the transaction completes using ctx.scheduler.runAfter() as shown above.
The callback will be triggered after the OTP verification is successful and the user is created or updated in the database, all within the same authentication flow.
Auth Advanced Details
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@sonic onyx Kapa.ai is still learning and improving, please let me know how I did by reacting below.
But it needs to happen ONLY after the verification step, won’t afterusercreatedorupdated run during both steps @rancid sapphire ?
Let me check the knowledge base for you again. One moment! :books:
You're right to be concerned about when the callback runs. According to the documentation, the afterUserCreatedOrUpdated callback will only be triggered after the verification step is complete, not during both steps of the OTP flow.
From the API reference:
This callback is called during the sign-in process, after the user is created or updated, before account creation and token generation.
For OTP verification specifically, the callback will be called with args.type set to "verification" when it's triggered after an email or phone token verification:
args.type: "oauth" | "credentials" | "email" | "phone" | "verification"
Where "verification" indicates "this callback is called after an email or phone token verification" API Reference.
If you want to ensure your code only runs after the verification step, you can check the type parameter in your callback:
callbacks: {
async afterUserCreatedOrUpdated(ctx, args) {
// Only run after verification step
if (args.type === "verification") {
// Your code here
await ctx.db.insert("someTable", { userId: args.userId, data: "verified user" });
// Or schedule an action
ctx.scheduler.runAfter(0, internal.yourNamespace.yourAction, { userId: args.userId });
}
},
}
This way, your code will only execute after the verification step is complete, not during the initial OTP sending step.
Note that if you're using a custom createOrUpdateUser callback, the afterUserCreatedOrUpdated callback won't be called at all, as mentioned in the documentation: "This callback is only called if createOrUpdateUser is not specified."