diff --git a/apps/api/src/middleware/rbac.ts b/apps/api/src/middleware/rbac.ts index d5e764e..1fab0cc 100644 --- a/apps/api/src/middleware/rbac.ts +++ b/apps/api/src/middleware/rbac.ts @@ -1,5 +1,5 @@ import type { MiddlewareHandler } from "hono"; -import { eq, getDb, staff } from "@groombook/db"; +import { and, eq, getDb, isNull, staff } from "@groombook/db"; export type StaffRole = "groomer" | "receptionist" | "manager"; export type StaffRow = typeof staff.$inferSelect; @@ -89,6 +89,25 @@ export const resolveStaffMiddleware: MiddlewareHandler = async ( .from(staff) .where(eq(staff.oidcSub, jwt.sub)); if (!fallbackRow) { + // Auto-link: staff record exists with matching email but no userId — link it now + if (jwt.email) { + const [linkedStaff] = await db + .select() + .from(staff) + .where(and(eq(staff.email, jwt.email), isNull(staff.userId))); + if (linkedStaff) { + await db + .update(staff) + .set({ userId: jwt.sub }) + .where(eq(staff.id, linkedStaff.id)); + console.log( + `[rbac] Auto-linked staff ${linkedStaff.id} to Better-Auth user ${jwt.sub} via email ${jwt.email}` + ); + c.set("staff", linkedStaff); + await next(); + return; + } + } return c.json( { error: "Forbidden: no staff record found for authenticated user" }, 403 diff --git a/packages/db/src/index.ts b/packages/db/src/index.ts index 9cd8c01..8b3b01f 100644 --- a/packages/db/src/index.ts +++ b/packages/db/src/index.ts @@ -4,7 +4,7 @@ import * as schema from "./schema.js"; export * from "./schema.js"; export { encryptSecret, decryptSecret } from "./crypto.js"; -export { and, asc, desc, eq, exists, gte, gt, ilike, inArray, lt, lte, ne, or, sql } from "drizzle-orm"; +export { and, asc, desc, eq, exists, gte, gt, ilike, inArray, isNull, lt, lte, ne, or, sql } from "drizzle-orm"; let _db: ReturnType | null = null;