['*'], // Permite todos os GETs 'POST' => [ 'api/login', 'api/logout', 'api/refresh', 'api/accounts/recalculate-all', // Recálculo de saldos (não modifica dados) 'api/accounts/*/recalculate', // Recálculo de conta específica 'api/categories/match', // Matching de categorias (leitura) 'api/cost-centers/match', // Matching de centros de custo (leitura) ], ]; /** * Handle an incoming request. * Bloqueia operações de escrita (POST/PUT/PATCH/DELETE) para usuário demo */ public function handle(Request $request, Closure $next): Response { $user = $request->user(); // Se não está logado ou não é demo, permite tudo if (!$user || !$user->is_demo) { return $next($request); } $method = $request->method(); $path = $request->path(); // GET sempre permitido para demo if ($method === 'GET') { return $next($request); } // Verifica se a rota está na whitelist if (isset($this->allowedRoutes[$method])) { foreach ($this->allowedRoutes[$method] as $allowedPath) { if ($allowedPath === '*' || $this->pathMatches($path, $allowedPath)) { return $next($request); } } } // Bloqueia a operação para usuário demo return response()->json([ 'success' => false, 'message' => 'Usuario DEMO: Esta acción no está permitida en modo demostración. Los datos no pueden ser modificados.', 'demo_mode' => true, ], 403); } /** * Verifica se o path corresponde ao padrão */ protected function pathMatches(string $path, string $pattern): bool { if ($pattern === '*') { return true; } $pattern = str_replace('*', '.*', $pattern); return (bool) preg_match('#^' . $pattern . '$#', $path); } }