Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
const isPublicRoute = createRouteMatcher(['/sign-in(.*)', '/sign-up(.*)', '/api/webhooks/clerk(.*)', '/api/cron(.*)'])

export default clerkMiddleware(async (auth, req) => {
if (!isPublicRoute(req)) await auth.protect()
// OTIMIZAÇÃO: Evitar processamento desnecessário para usuários já autenticados
// Apenas proteger rotas não públicas
if (!isPublicRoute(req)) {
await auth.protect()
}
})

export const config = {
Expand Down
31 changes: 2 additions & 29 deletions src/server/api/routers/user.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,9 @@
import type { Prisma, Enterprise } from "@prisma/client";
import { createTRPCRouter, protectedProcedure } from "../trpc"
import { createTRPCRouter, protectedProcedure, adminProcedure } from "../trpc"
import { z } from "zod"
import { type RolesConfig } from "@/types/role-config"
import { TRPCError } from "@trpc/server"

// Novo procedure para verificar permissões admin
const adminProcedure = protectedProcedure.use(async ({ ctx, next }) => {
const user = await ctx.db.user.findUnique({
where: { id: ctx.auth.userId },
select: { role_config: true }
});

const roleConfig = user?.role_config as RolesConfig | null;

// Verificar se tem permissão admin
const hasAdminAccess = !!roleConfig?.sudo ||
(Array.isArray(roleConfig?.admin_pages) && roleConfig?.admin_pages.includes("/admin"));

if (!hasAdminAccess) {
throw new TRPCError({
code: "FORBIDDEN",
message: "Acesso negado. Permissões administrativas necessárias.",
});
}

return next({
ctx: {
...ctx,
roleConfig
}
});
});

export const userRouter = createTRPCRouter({
me: protectedProcedure.query(async ({ ctx }) => {
Expand Down Expand Up @@ -145,7 +118,7 @@ export const userRouter = createTRPCRouter({
// Filtrar apenas usuários com permissões admin
return users.filter(user => {
const roleConfig = user.role_config as RolesConfig | null;
return !!roleConfig?.sudo || (Array.isArray(roleConfig?.admin_pages) && roleConfig.admin_pages.length > 0);
return !!roleConfig?.sudo || (Array.isArray(roleConfig?.admin_pages) && (roleConfig?.admin_pages?.length ?? 0) > 0);
});
}),

Expand Down
9 changes: 6 additions & 3 deletions src/server/api/trpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,12 @@ export const protectedProcedure = t.procedure.use(async ({ ctx, next }) => {
}

// Verificação adicional para usuários potencialmente problemáticos
// REMOVIDO: Query desnecessária que estava causando headers muito grandes
// O role_config completo não é necessário aqui - apenas verificamos se o usuário existe
try {
// Testar se conseguimos acessar o usuário no banco
const userExists = await ctx.db.user.findUnique({
where: { id: ctx.auth.userId },
select: { id: true, role_config: true }
select: { id: true } // Apenas verificar se existe, sem buscar role_config
});

if (!userExists) {
Expand All @@ -164,11 +165,13 @@ export const protectedProcedure = t.procedure.use(async ({ ctx, next }) => {
})

export const adminProcedure = protectedProcedure.use(async ({ ctx, next }) => {
// Buscar apenas os campos necessários para verificação de admin
// Evitar buscar arrays grandes como unlocked_forms, hidden_forms, etc.
const user = await ctx.db.user.findUnique({
where: { id: ctx.auth.userId },
select: {
id: true,
role_config: true,
role_config: true, // Mantém para compatibilidade, mas pode ser otimizado futuramente
}
})

Expand Down