Skip to content

Commit 2d7056b

Browse files
authored
[sc-160947] Switch to partial URL encoding. (#72)
1 parent 97130dd commit 2d7056b

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

src/__tests__/context-test.js

+5
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ describe('when determining canonical keys', () => {
7777
[{ kind: 'multi', user: { key: 'usertest' } }, 'user:usertest'],
7878
[{ kind: 'multi', user: { key: 'usertest' }, org: { key: 'orgtest' } }, 'org:orgtest:user:usertest'],
7979
[{ kind: 'multi', user: { key: 'user:test' }, org: { key: 'org:test' } }, 'org:org%3Atest:user:user%3Atest'],
80+
[{ kind: 'multi', user: { key: 'user%test' }, org: { key: 'org%test' } }, 'org:org%25test:user:user%25test'],
81+
[
82+
{ kind: 'multi', user: { key: 'user%:test' }, org: { key: 'org%:test' } },
83+
'org:org%25%3Atest:user:user%25%3Atest',
84+
],
8085
])('produces a canonical key for valid contexts', (context, canonicalKey) => {
8186
expect(getCanonicalKey(context)).toEqual(canonicalKey);
8287
});

src/context.js

+18-2
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,33 @@ function getContextKinds(context) {
5757
return [];
5858
}
5959

60+
/**
61+
* The partial URL encoding is needed because : is a valid character in context keys.
62+
*
63+
* Partial encoding is the replacement of all colon (:) characters with the URL
64+
* encoded equivalent (%3A) and all percent (%) characters with the URL encoded
65+
* equivalent (%25).
66+
* @param {string} key The key to encode.
67+
* @returns {string} Partially URL encoded key.
68+
*/
69+
function encodeKey(key) {
70+
if (key.includes('%') || key.includes(':')) {
71+
return key.replace(/%/g, '%25').replace(/:/g, '%3A');
72+
}
73+
return key;
74+
}
75+
6076
function getCanonicalKey(context) {
6177
if (context) {
6278
if ((context.kind === undefined || context.kind === null || context.kind === 'user') && context.key) {
6379
return context.key;
6480
} else if (context.kind !== 'multi' && context.key) {
65-
return `${context.kind}:${encodeURIComponent(context.key)}`;
81+
return `${context.kind}:${encodeKey(context.key)}`;
6682
} else if (context.kind === 'multi') {
6783
return Object.keys(context)
6884
.sort()
6985
.filter(key => key !== 'kind')
70-
.map(key => `${key}:${encodeURIComponent(context[key].key)}`)
86+
.map(key => `${key}:${encodeKey(context[key].key)}`)
7187
.join(':');
7288
}
7389
}

0 commit comments

Comments
 (0)