BA
Better Auth•2w ago
KHRM

Setting Admin Roll With Hook

hooks: {
before: createAuthMiddleware(async (ctx) => {
if (ctx.path === "/sign-up/email") {
const email = ctx.body.email.trim().toLowerCase();

const ADMIN_EMAILS = process.env.ADMIN_EMAILS?.split(";") ?? [];
if (ADMIN_EMAILS.includes(email)) {
ctx.body.role = UserRole.ADMIN;
} else {
ctx.body.role = UserRole.USER;
}

console.log(ctx.body);
}

console.log("ctx.path", ctx.path);
}),
},
hooks: {
before: createAuthMiddleware(async (ctx) => {
if (ctx.path === "/sign-up/email") {
const email = ctx.body.email.trim().toLowerCase();

const ADMIN_EMAILS = process.env.ADMIN_EMAILS?.split(";") ?? [];
if (ADMIN_EMAILS.includes(email)) {
ctx.body.role = UserRole.ADMIN;
} else {
ctx.body.role = UserRole.USER;
}

console.log(ctx.body);
}

console.log("ctx.path", ctx.path);
}),
},
here is my hook in my auth config i checked that ctx.body.role = 'ADMIN' throughout this hook but when the user is created in my database their role is 'USER' I assume this comes from my @default(USER) on my prisma schema but why is this occuring if the role is set to user via the before hook? originally I had this logic in databaseHooks but I moved it to hooks so that I can use the required: true flag on the [user][additional fields] /* for now ill move logic back to databaseHooks */
7 Replies
KHRM
KHRMOP•2w ago
update i thought i found my mistake by not returning a context, as so
hooks: {
before: createAuthMiddleware(async (ctx) => {
if (ctx.path === "/sign-up/email") {
const email = ctx.body.email.trim().toLowerCase();
let role: UserRole = UserRole.USER;

const ADMIN_EMAILS = process.env.ADMIN_EMAILS?.split(";") ?? [];
if (ADMIN_EMAILS.includes(email)) {
role = UserRole.ADMIN;
}

return {
context: {
...ctx,
body: {
...ctx.body,
name: email.split("@")[0],
role,
},
},
};
}
}),
},
hooks: {
before: createAuthMiddleware(async (ctx) => {
if (ctx.path === "/sign-up/email") {
const email = ctx.body.email.trim().toLowerCase();
let role: UserRole = UserRole.USER;

const ADMIN_EMAILS = process.env.ADMIN_EMAILS?.split(";") ?? [];
if (ADMIN_EMAILS.includes(email)) {
role = UserRole.ADMIN;
}

return {
context: {
...ctx,
body: {
...ctx.body,
name: email.split("@")[0],
role,
},
},
};
}
}),
},
but ALAS the name gets changed but the role is still "USER" 😦 bump
Ping
Ping•7d ago
Are you sure your logic is correct and that if statement does return true for role to be admin?
KHRM
KHRMOP•7d ago
Pretty sure I did console logging throughout the hook I can try again since I moved the logic for role to database hooks I added the name just to show a 1-1 parallel and the name does get changed
Ping
Ping•7d ago
Might be easier to test if you can hardcode role in the return to just be ADMIN and see if that works.
KHRM
KHRMOP•7d ago
no dice
hooks: {
before: createAuthMiddleware(async (ctx) => {
if (ctx.path === "/sign-up/email") {
console.log({
body: {
...ctx.body,
name: "mitochondria is the powerhouse of the cell",
role: "admin",
},
});

return {
context: {
...ctx,
body: {
...ctx.body,
name: "mitochondria is the powerhouse of the cell",
role: "admin",
},
},
};
}
}),
},
hooks: {
before: createAuthMiddleware(async (ctx) => {
if (ctx.path === "/sign-up/email") {
console.log({
body: {
...ctx.body,
name: "mitochondria is the powerhouse of the cell",
role: "admin",
},
});

return {
context: {
...ctx,
body: {
...ctx.body,
name: "mitochondria is the powerhouse of the cell",
role: "admin",
},
},
};
}
}),
},
No description
KHRM
KHRMOP•7d ago
No description
KHRM
KHRMOP•7d ago
this is how sign up is being called originally for reference although i assume this happens before the hook
"use server";

import { auth, type ErrorTypes } from "@/lib/auth";
import { APIError } from "better-auth/api";

type ActionState =
| { success: true; error: null }
| { success: false; error: string };

export async function signUpAction(body: {
name: string;
email: string;
password: string;
}): Promise<ActionState> {
try {
await auth.api.signUpEmail({
body: {
...body,
callbackURL: "/auth/sign-in",
},
});

return { success: true, error: null };
} catch (err) {
...
}
}
"use server";

import { auth, type ErrorTypes } from "@/lib/auth";
import { APIError } from "better-auth/api";

type ActionState =
| { success: true; error: null }
| { success: false; error: string };

export async function signUpAction(body: {
name: string;
email: string;
password: string;
}): Promise<ActionState> {
try {
await auth.api.signUpEmail({
body: {
...body,
callbackURL: "/auth/sign-in",
},
});

return { success: true, error: null };
} catch (err) {
...
}
}

Did you find this page helpful?