Does this code have any flaws in terms of Better Auth best practices?

export const updateUserSF = actionClient.metadata({ permissions: { user: ["set-role"] } })
.inputSchema(z.strictObject({
id: z.string(),
personId: z.int().optional(),
role: z.enum(Roles).optional(),
})).action<typeof auth.$Infer.Session.user>(async ({ parsedInput: { id, personId, role } }) => {
const [user] = await db.select().from(usersTable).where(eq(usersTable.id, id)).limit(1);
if (!user) throw new CcActionError("User not found");
if (!user.emailVerified) throw new CcActionError("This user hasn't verified their email address yet");

if (role) {
await auth.api.setRole({ body: { userId: id, role }, headers: await headers() });
}

if (personId) {
return (await db.update(usersTable).set({ personId }).where(eq(usersTable.id, id)).returning()).at(0)!;
}

return (await db.select().from(usersTable).where(eq(usersTable.id, id)).limit(1)).at(0)!;
});
export const updateUserSF = actionClient.metadata({ permissions: { user: ["set-role"] } })
.inputSchema(z.strictObject({
id: z.string(),
personId: z.int().optional(),
role: z.enum(Roles).optional(),
})).action<typeof auth.$Infer.Session.user>(async ({ parsedInput: { id, personId, role } }) => {
const [user] = await db.select().from(usersTable).where(eq(usersTable.id, id)).limit(1);
if (!user) throw new CcActionError("User not found");
if (!user.emailVerified) throw new CcActionError("This user hasn't verified their email address yet");

if (role) {
await auth.api.setRole({ body: { userId: id, role }, headers: await headers() });
}

if (personId) {
return (await db.update(usersTable).set({ personId }).where(eq(usersTable.id, id)).returning()).at(0)!;
}

return (await db.select().from(usersTable).where(eq(usersTable.id, id)).limit(1)).at(0)!;
});
I'm using Next JS, Drizzle and next-safe-auth
1 Reply
Ping
Ping3mo ago
I assume anyone could in theory call that server function if they know the endpoint and pass any user id with a role they want for the user

Did you find this page helpful?