From 0883fb4529d5e2da405e04f2c3fcc05d9e0f6bd7 Mon Sep 17 00:00:00 2001 From: Srijan Tripathi <72181144+srijantrpth@users.noreply.github.com> Date: Mon, 16 Dec 2024 13:27:56 +0000 Subject: [PATCH] Improvised query headers handling and extend QueryOptions interface --- src/Utils/request/query.ts | 44 ++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/Utils/request/query.ts b/src/Utils/request/query.ts index 7ad9752a9e4..acba624021a 100644 --- a/src/Utils/request/query.ts +++ b/src/Utils/request/query.ts @@ -5,19 +5,43 @@ import { getResponseBody } from "@/Utils/request/request"; import { QueryOptions, Route } from "@/Utils/request/types"; import { makeHeaders, makeUrl } from "@/Utils/request/utils"; -declare module "@tanstack/react-query" { - interface Register { - defaultError: QueryError; - } +/** + * Extend the QueryOptions interface to include customHeaders + * @template TBody - The type of the request body + */ +export interface QueryOptionsWithHeaders extends QueryOptions { + customHeaders?: Record; + headers?: HeadersInit; } +// Function to sanitize custom headers +const sanitizeHeaders = (headers: Record) => { + const sanitized: Record = {}; + for (const [key, value] of Object.entries(headers)) { + // Ensure header names follow RFC 7230 and values are safe + if ( + /^[!#$%&'*+-.^_`|~0-9a-zA-Z]+$/.test(key) && + typeof value === "string" && // Changed 'string' to "string" + !value.includes("\n") && // Changed '\n' to "\n" + !value.includes("\r") + ) { + // Changed '\r' to "\r" + sanitized[key] = value; + } + } + return sanitized; +}; + async function queryRequest( { path, method, noAuth }: Route, - options?: QueryOptions, + options?: QueryOptionsWithHeaders, ): Promise { const url = `${careConfig.apiUrl}${makeUrl(path, options?.queryParams, options?.pathParams)}`; - const headers = makeHeaders(noAuth ?? false, options?.headers); + // Merge default headers with sanitized custom headers + const defaultHeaders = makeHeaders(noAuth ?? false); + const customHeaders = sanitizeHeaders(options?.customHeaders || {}); + const headers = { ...defaultHeaders, ...customHeaders }; // Merging headers manually const fetchOptions: RequestInit = { method, @@ -53,12 +77,14 @@ async function queryRequest( /** * Creates a TanStack Query compatible request function + * @template TData - The type of the response data + * @template TBody - The type of the request body */ export default function query( route: Route, - options?: QueryOptions, -) { - return ({ signal }: { signal: AbortSignal }) => { + options?: QueryOptionsWithHeaders, +): (params: { signal: AbortSignal }) => Promise { + return ({ signal }) => { return queryRequest(route, { ...options, signal }); }; }