Skip to content

Commit dbfd004

Browse files
committed
Fix asQueryParams URL encoding issues for GET requests
When the field or other type of data has html entities in them (i.e. ampersands), since the data is not encoded for GET requests the JSORM url will be incidentally broken. For obvious reasons, POST requests shouldn't have this issue. encodeURIComponent encodes a lot of useful characters that doesn't actually need to be encoded for the brower, so we are only encoding the tokens that are likely to cause issues.
1 parent 7b94098 commit dbfd004

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

src/util/parameterize.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
const encodeTokens = ['&', '?', '#']
2+
const encodeTokensMatch = new RegExp(`[\\${encodeTokens.join('\\')}]`)
3+
const encodeTokenMapping = encodeTokens.map(token => {
4+
return [new RegExp(`\\${token}`, 'g'), encodeURIComponent(token)]
5+
})
6+
7+
const encodeParameter = (value: string): string => {
8+
let newValue: string = `${value}`
9+
if (newValue.match(encodeTokensMatch)) {
10+
encodeTokenMapping.forEach(mapping => newValue = newValue.replace.apply(newValue, mapping))
11+
}
12+
return newValue
13+
}
14+
115
const parameterize = (obj: any, prefix?: string): string => {
216
let str = []
317

@@ -12,12 +26,12 @@ const parameterize = (obj: any, prefix?: string): string => {
1226

1327
if (Array.isArray(value)) {
1428
if (value.length > 0) {
15-
str.push(`${key}=${value.join(",")}`)
29+
str.push(`${key}=${value.map(encodeParameter).join(",")}`)
1630
}
1731
} else if (typeof value === "object") {
1832
str.push(parameterize(value, key))
1933
} else {
20-
str.push(`${key}=${value}`)
34+
str.push(`${key}=${encodeParameter(value)}`)
2135
}
2236
}
2337
}

test/integration/finders.test.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,28 @@ describe("Model finders", () => {
332332
expect(data[0]).to.be.instanceof(Person)
333333
})
334334
})
335-
})
335+
336+
describe("when value is has special tokens", () => {
337+
beforeEach(() => {
338+
fetchMock.reset()
339+
fetchMock.get(
340+
"http://example.com/api/v1/people?filter[id]=2&filter[a]={{Penn %26 Teller %235%3F}}",
341+
{
342+
data: [{ id: "2", type: "people" }]
343+
}
344+
)
345+
})
346+
347+
it("still queries correctly", async () => {
348+
const { data } = await Person.where({ id: 2 })
349+
.where({ a: "{{Penn & Teller #5?}}" })
350+
.all()
351+
352+
expect(data.length).to.eq(1)
353+
expect(data[0]).to.be.instanceof(Person)
354+
expect(data[0]).to.have.property("id", "2")
355+
})
356+
}) })
336357

337358
describe("#stats", () => {
338359
beforeEach(() => {

0 commit comments

Comments
 (0)