'failure', 'message' => 'Internal server configuration error.']); exit; } $authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; $token = null; if (preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) { $token = $matches[1]; } if (!$token) { http_response_code(401); echo json_encode(['status' => 'failure', 'message' => 'Authorization token required']); exit; } try { return JWT::decode($token, new Key($secretKey, 'HS256')); } catch (ExpiredException $e) { http_response_code(401); echo json_encode(['status' => 'failure', 'message' => 'Token expired']); exit; } catch (SignatureInvalidException $e) { http_response_code(401); echo json_encode(['status' => 'failure', 'message' => 'Invalid token signature']); exit; } catch (BeforeValidException $e) { http_response_code(401); echo json_encode(['status' => 'failure', 'message' => 'Token not yet valid']); exit; } catch (Exception $e) { http_response_code(401); echo json_encode(['status' => 'failure', 'message' => 'Invalid token']); exit; } // NOTE: signature/expiry only — does not replicate backend's // core/Auth/JwtService::authenticate() JTI-blacklist (revoked-token) // check or X-Device-FP verification. Flagged as a follow-up in the // plan; not blocking for this read-only endpoint. } // Flutter's CRUD().get() always issues an HTTP POST under the hood // (see siro_rider/lib/controller/functions/crud.dart _makeRequest/doPost) — // so every field this endpoint reads comes through $_POST, never $_GET. function filterRequest($requestname, $type = 'string') { if (isset($_POST[$requestname]) && $_POST[$requestname] !== '') { $value = trim($_POST[$requestname]); $value = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $value); if ($type === 'numeric') { return filter_var($value, FILTER_VALIDATE_FLOAT) !== false ? $value : null; } return $value; } return null; } function printFailure($message = "none") { echo json_encode(["status" => "failure", "message" => $message]); }