diff --git a/.changeset/fast-jeans-explode.md b/.changeset/fast-jeans-explode.md new file mode 100644 index 000000000..db5db09a6 --- /dev/null +++ b/.changeset/fast-jeans-explode.md @@ -0,0 +1,5 @@ +--- +"sst": minor +--- + +handle keys in query string with escaped characters diff --git a/packages/sst/support/signing-function/helpers/queryStringToQueryParameterBag.ts b/packages/sst/support/signing-function/helpers/queryStringToQueryParameterBag.ts index a0f839364..b66faecba 100644 --- a/packages/sst/support/signing-function/helpers/queryStringToQueryParameterBag.ts +++ b/packages/sst/support/signing-function/helpers/queryStringToQueryParameterBag.ts @@ -3,31 +3,24 @@ import { QueryParameterBag } from "@aws-sdk/types"; export const queryStringToQueryParameterBag = ( queryString: string ): QueryParameterBag => { - const query: QueryParameterBag = {}; - - const kvPairs = queryString.split("&").filter((v) => v); - - for (const kvPair of kvPairs) { - const split = kvPair.split("=") as [string, string?]; - - const key = split[0]; - const value = split[1]; - - if (query[key] === undefined || query[key] === null) { - query[key] = value ? decodeURIComponent(value) : ""; - continue; - } - - if (value === undefined || value === "") { - continue; - } + if (!queryString) { + return {}; + } - if (Array.isArray(query[key])) { - (query[key] as string[]).push(decodeURIComponent(value)); - continue; + const query: QueryParameterBag = {}; + const searchParams = new URLSearchParams(queryString); + + for (const [key, value] of searchParams.entries()) { + const decodedKey = decodeURIComponent(key); + const decodedValue = decodeURIComponent(value); + + if (query[decodedKey] === undefined) { + query[decodedKey] = decodedValue; + } else if (Array.isArray(query[decodedKey])) { + (query[decodedKey] as string[]).push(decodedValue); + } else { + query[decodedKey] = [query[decodedKey] as string, decodedValue]; } - - query[key] = [query[key] as string, decodeURIComponent(value)]; } return query;