Spiced
Spiced13mo ago

Creating a auth role system with Convex

Hello everyone, is there a way to check if the user has a specific role when using convex auth?
3 Replies
oscklm
oscklm13mo ago
You would have to build your own role system, convex auth only which can definitely be done with convex, and a third party auth provider like clerk. Then is a very simple rough example of how one could approach it:
// schema.ts
users: defineTable({
name: v.string(),
roles: v.array(v.string()), // example ["CanEditPosts", "CanDeletePosts"]
tokenIdentifier: v.string(),
}).index("by_token", ["tokenIdentifier"]),
// schema.ts
users: defineTable({
name: v.string(),
roles: v.array(v.string()), // example ["CanEditPosts", "CanDeletePosts"]
tokenIdentifier: v.string(),
}).index("by_token", ["tokenIdentifier"]),
Then furthermore u could get the user in a query / mutation by using the ctx.auth.getUserIdentity() and then getting the user object from the identity.tokenIdentifier as also stated in the linked post below. Then checking the roles array and seeing if the role you require is present on the user, before allowing the user to proceed with any mutation or query. Look at this for inspiration on storing users in convex: https://docs.convex.dev/auth/database-auth This is just to give an idea of how it could be done. There are many ways to approach this. So google away and see how others have done it, and i can almost assure you that the same is possible with convex.
Storing Users in the Convex Database | Convex Developer Hub
You might want to have a centralized place that stores information about the
Spiced
SpicedOP13mo ago
@oscklm Hey, thank you for the very thourough explanation. can i just have a shema like so:
// schema.ts
users: defineTable({
tokenIdentifier: v.string(),
roles: v.array(v.string()), // example ["CanEditPosts", "CanDeletePosts"]
}).index("by_token", ["tokenIdentifier"]),
// schema.ts
users: defineTable({
tokenIdentifier: v.string(),
roles: v.array(v.string()), // example ["CanEditPosts", "CanDeletePosts"]
}).index("by_token", ["tokenIdentifier"]),
I'm already using clerk. Moreover, when im doing
const { isAuthenticated, isLoading } = useConvexAuth();
if (isLoading) {
return (
<div className="flex h-screen items-center justify-center">
<Spinner size={"xl"} />
</div>
);
}

if (!isAuthenticated) {
return redirect("/");
}
const { isAuthenticated, isLoading } = useConvexAuth();
if (isLoading) {
return (
<div className="flex h-screen items-center justify-center">
<Spinner size={"xl"} />
</div>
);
}

if (!isAuthenticated) {
return redirect("/");
}
Is there a way to build upon this? Thank you in advance!
oscklm
oscklm13mo ago
I unfortunately don’t have the time to explain or show exactly how to do it. But I would use the docs on auth with convex and the link that I sent. And then play around with it. Feel free to use this thread if you get stuck in something, and I can help with more specific issues. But you would have to try and set it up yourself. To point you in the right direction, you would have to limit any given action the user is trying to perform, within either a query or mutation and furthermore check for the required roles etc. before performing whatever the query or mutation does. Then throwing an error if the required roles is not met, which you could then use to show some feedback in the front end to the user if needed. Roughly speaking

Did you find this page helpful?