rgz
rgz•5mo ago

Customizing default Schema after OAuth login

I'm trying to use the default schema and just update it with a few items: I updated my schema with a new users table and added two fields at the end:
...authTables,
users: defineTable({
email: v.optional(v.string()),
emailVerificationTime: v.optional(v.float64()),
image: v.optional(v.string()),
isAnonymous: v.optional(v.boolean()),
name: v.optional(v.string()),
phone: v.optional(v.string()),
phoneVerificationTime: v.optional(v.float64()),
isOnboardingComplete: v.optional(v.boolean()),
orgIds: v.optional(v.array(v.object({
id: v.id("organization"),
role: v.union(v.literal("org:admin"), v.literal("org:member"))
}))),
})
.index("by_email", ["email"])
.index("by_phone", ["phone"]),
...authTables,
users: defineTable({
email: v.optional(v.string()),
emailVerificationTime: v.optional(v.float64()),
image: v.optional(v.string()),
isAnonymous: v.optional(v.boolean()),
name: v.optional(v.string()),
phone: v.optional(v.string()),
phoneVerificationTime: v.optional(v.float64()),
isOnboardingComplete: v.optional(v.boolean()),
orgIds: v.optional(v.array(v.object({
id: v.id("organization"),
role: v.union(v.literal("org:admin"), v.literal("org:member"))
}))),
})
.index("by_email", ["email"])
.index("by_phone", ["phone"]),
In the auth I used the createOrUpdateUser callback in auth.ts to create the user:
export const { auth, signIn, signOut, store } = convexAuth({
providers: [
GitHub,
Google,
ResendOTP,
Password,
Password({ id: "password-with-reset", reset: ResendOTPPasswordReset }),
Password({
id: "password-code",
reset: ResendOTPPasswordReset,
verify: ResendOTP,
}),
Password({ id: "password-link", verify: Resend }),
],
callbacks: {
async createOrUpdateUser(ctx, args) {
if (args.existingUserId) {
return args.existingUserId;
}

return ctx.db.insert("users", {
email: args.profile.email,
emailVerified: args.profile.emailVerified,
name: args.profile.name,
phone: args.profile.phone,
phoneVerified: args.profile.phoneVerified,
isOnboardingComplete: false,
orgIds: [],
});
},
},
});
export const { auth, signIn, signOut, store } = convexAuth({
providers: [
GitHub,
Google,
ResendOTP,
Password,
Password({ id: "password-with-reset", reset: ResendOTPPasswordReset }),
Password({
id: "password-code",
reset: ResendOTPPasswordReset,
verify: ResendOTP,
}),
Password({ id: "password-link", verify: Resend }),
],
callbacks: {
async createOrUpdateUser(ctx, args) {
if (args.existingUserId) {
return args.existingUserId;
}

return ctx.db.insert("users", {
email: args.profile.email,
emailVerified: args.profile.emailVerified,
name: args.profile.name,
phone: args.profile.phone,
phoneVerified: args.profile.phoneVerified,
isOnboardingComplete: false,
orgIds: [],
});
},
},
});
3 Replies
rgz
rgzOP•5mo ago
After sign-in, the user is redirected to /onboarding where it seems identity isn't being passed: [CONVEX M(mutations/workspace/index:createWorkspace)] [LOG] 'IDENTITY' null middleware.ts
import {
convexAuthNextjsMiddleware,
createRouteMatcher,
isAuthenticatedNextjs,
nextjsMiddlewareRedirect,
} from "@convex-dev/auth/nextjs/server";

const isSignInPage = createRouteMatcher(["/signin"]);
const isProtectedRoute = createRouteMatcher(["/onboarding(.*)", "/workspace(.*)", "/dashboard(.*)", "/"]);

export default convexAuthNextjsMiddleware(async (request, options) => {
if (isSignInPage(request) && isAuthenticatedNextjs()) {
return nextjsMiddlewareRedirect(request, "/dashboard");
}

if (isProtectedRoute(request) && !isAuthenticatedNextjs()) {
return nextjsMiddlewareRedirect(request, "/signin");
}
});

export const config = {
matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"],
};
import {
convexAuthNextjsMiddleware,
createRouteMatcher,
isAuthenticatedNextjs,
nextjsMiddlewareRedirect,
} from "@convex-dev/auth/nextjs/server";

const isSignInPage = createRouteMatcher(["/signin"]);
const isProtectedRoute = createRouteMatcher(["/onboarding(.*)", "/workspace(.*)", "/dashboard(.*)", "/"]);

export default convexAuthNextjsMiddleware(async (request, options) => {
if (isSignInPage(request) && isAuthenticatedNextjs()) {
return nextjsMiddlewareRedirect(request, "/dashboard");
}

if (isProtectedRoute(request) && !isAuthenticatedNextjs()) {
return nextjsMiddlewareRedirect(request, "/signin");
}
});

export const config = {
matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"],
};
Maybe I've just been at it too long today, but I'm ready to pull my hair out 😛 Anyone have any ideas? The user, authAccounts, authRefreshTokens and authSessions are created - I just can't get the identity of the logged in user afterwards.
{
_creationTime: 1723671544463.509,
_id: "jx73hwv21cyfzmd35v9jk3jnzd6ytvpv",
email: "metzgr@gmail.com",
isOnboardingComplete: false,
name: "Bobby Alv",
orgIds: [],
}
{
_creationTime: 1723671544463.509,
_id: "jx73hwv21cyfzmd35v9jk3jnzd6ytvpv",
email: "metzgr@gmail.com",
isOnboardingComplete: false,
name: "Bobby Alv",
orgIds: [],
}
Kibru
Kibru•5mo ago
me too. I'm stuck with the exact same issue
Michal Srb
Michal Srb•5mo ago
Try this temporary workaround if it's related: https://discord.com/channels/1019350475847499849/1273347536941486130/1273424586196779130 to confirm it's the issue, check the sync websocket and see whether the Authenticate message is being sent (how to check the websocket: https://docs.convex.dev/auth/debug )
Debugging Authentication | Convex Developer Hub
You have followed one of our authentication guides but something is not working.