Expose roleId on the Better Auth session user

This commit is contained in:
NeilClack
2026-09-10 14:59:28 -05:00
parent 9de0e2e25a
commit 0cb4b2148a
3 changed files with 43 additions and 3 deletions
+3 -3
View File
@@ -1,11 +1,11 @@
import type { Session, User } from 'better-auth'; import type { auth } from '$lib/auth';
import type { ApiKeyRecord } from '$lib/server/api-key'; import type { ApiKeyRecord } from '$lib/server/api-key';
declare global { declare global {
namespace App { namespace App {
interface Locals { interface Locals {
session: Session | null; session: typeof auth.$Infer.Session.session | null;
user: User | null; user: typeof auth.$Infer.Session.user | null;
apiKey?: ApiKeyRecord; apiKey?: ApiKeyRecord;
} }
} }
+12
View File
@@ -27,6 +27,18 @@ export const auth = betterAuth({
database: prismaAdapter(prisma, { database: prismaAdapter(prisma, {
provider: 'postgresql' provider: 'postgresql'
}), }),
user: {
// Expose our custom role column on the session user so role checks can
// read `locals.user.roleId` without a database round-trip.
additionalFields: {
roleId: {
type: 'number',
required: false,
defaultValue: 4,
input: false
}
}
},
emailVerification: { emailVerification: {
sendOnSignUp: true, sendOnSignUp: true,
sendVerificationEmail: async ({ user, token }) => { sendVerificationEmail: async ({ user, token }) => {
+28
View File
@@ -0,0 +1,28 @@
/**
* Role hierarchy. Lower ids are more privileged:
* SUPER = 1, ADMIN = 2, STAFF = 3, USER = 4
*
* `roleId` is exposed on the Better Auth session user (see `auth.ts`
* `user.additionalFields`), so these helpers never need a database call.
*/
export const SUPER = 1;
export const ADMIN = 2;
export const STAFF = 3;
export const USER = 4;
/** The current user's role id, defaulting to the least privileged role. */
export function roleId(locals: App.Locals): number {
return locals.user?.roleId ?? USER;
}
export function isSuper(locals: App.Locals): boolean {
return roleId(locals) <= SUPER;
}
export function isAdmin(locals: App.Locals): boolean {
return roleId(locals) <= ADMIN;
}
export function isStaff(locals: App.Locals): boolean {
return roleId(locals) <= STAFF;
}