Allow staff access to admin UI with scoped permissions

This commit is contained in:
Esdras Renan 2025-10-13 16:30:52 -03:00
parent d6956cd99d
commit cf31158a9e
11 changed files with 155 additions and 52 deletions

View file

@ -5,9 +5,9 @@ import { Prisma } from "@prisma/client"
import { ConvexHttpClient } from "convex/browser"
import { api } from "@/convex/_generated/api"
import { assertAdminSession } from "@/lib/auth-server"
import { assertStaffSession } from "@/lib/auth-server"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { ROLE_OPTIONS, type RoleOption } from "@/lib/authz"
import { ROLE_OPTIONS, type RoleOption, isAdmin } from "@/lib/authz"
import { env } from "@/lib/env"
import { prisma } from "@/lib/prisma"
import { computeInviteStatus, normalizeInvite, type InviteWithEvents, type NormalizedInvite } from "@/server/invite-utils"
@ -91,7 +91,7 @@ function buildInvitePayload(invite: InviteWithEvents, now: Date) {
}
export async function GET() {
const session = await assertAdminSession()
const session = await assertStaffSession()
if (!session) {
return NextResponse.json({ error: "Não autorizado" }, { status: 401 })
}
@ -127,7 +127,7 @@ type CreateInvitePayload = {
}
export async function POST(request: Request) {
const session = await assertAdminSession()
const session = await assertStaffSession()
if (!session) {
return NextResponse.json({ error: "Não autorizado" }, { status: 401 })
}
@ -144,6 +144,10 @@ export async function POST(request: Request) {
const name = typeof body.name === "string" ? body.name.trim() : undefined
const role = normalizeRole(body.role)
const isSessionAdmin = isAdmin(session.user.role)
if (!isSessionAdmin && !["manager", "collaborator"].includes(role)) {
return NextResponse.json({ error: "Agentes só podem convidar gestores ou colaboradores" }, { status: 403 })
}
const tenantId = typeof body.tenantId === "string" && body.tenantId.trim() ? body.tenantId.trim() : session.user.tenantId || DEFAULT_TENANT_ID
const expiresInDays = Number.isFinite(body.expiresInDays) ? Math.max(1, Number(body.expiresInDays)) : DEFAULT_EXPIRATION_DAYS