jwtSecret = $_ENV['JWT_SECRET'] ?? 'default-secret-fallback'; // Use um fallback seguro em dev } public function __invoke(ServerRequestInterface $request, callable $next) { // 1. Extrai o token do header Authorization $authHeader = $request->getHeaderLine('Authorization'); if (empty($authHeader) || !preg_match('/Bearer\s+(.*)/', $authHeader, $matches)) { return ResponseLib::sendFail("Unauthorized: Missing or invalid Authorization header", [], "E_VALIDATE")->withStatus(401); } $token = $matches[1]; try { // 2. Decodifica e valida o JWT $decoded = JWT::decode($token, new Key($this->jwtSecret, 'HS256')); // Use HS256 ou algoritmo desejado // 3. Extrai claims (assuma que o JWT tem 'sub' como user_id e 'username') $userId = $decoded->sub ?? null; $apiUser = $decoded->username ?? null; if (empty($userId) || empty($apiUser)) { return ResponseLib::sendFail("Unauthorized: Invalid JWT claims", [], "E_VALIDATE")->withStatus(401); } // 4. Verifica se o usuário existe e está ativo no banco (similar ao HMAC) $dbFile = $_ENV['DB_FILE'] ?? 'bridge.db'; $dbPath = __DIR__ . '/../' . $dbFile; $pdo = new \PDO("sqlite:" . $dbPath); $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(\PDO::ATTR_TIMEOUT, 5000); $stmt = $pdo->prepare("SELECT user_id FROM user WHERE user_id = :user_id AND user_name = :user_name AND user_flag = 'a'"); $stmt->execute(['user_id' => $userId, 'user_name' => $apiUser]); $user = $stmt->fetch(\PDO::FETCH_ASSOC); $stmt->closeCursor(); if (!$user) { return ResponseLib::sendFail("Unauthorized: Invalid or inactive user", [], "E_VALIDATE")->withStatus(401); } // 5. Tudo certo, adiciona atributos ao request (compatível com HMAC) $request = $request ->withAttribute('api_user', $apiUser) ->withAttribute('api_user_id', $userId); return $next($request); } catch (\Exception $e) { // Captura erros de JWT (ex: expirado, inválido) return ResponseLib::sendFail("Unauthorized: " . $e->getMessage(), [], "E_VALIDATE")->withStatus(401); } } }