UI: fix secret with % in path (#20430)
* Use encode/decode uri component instead of route-recognizer. Fixes #11616 * Remove route-recognizer explicit dependency * Add changelog
This commit is contained in:
parent
91481143af
commit
b743ada5ab
|
@ -0,0 +1,3 @@
|
|||
```release-note:bug
|
||||
ui: Fix secret render when path includes %. Resolves #11616.
|
||||
```
|
|
@ -3,14 +3,25 @@
|
|||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
||||
import RouteRecognizer from 'route-recognizer';
|
||||
|
||||
const {
|
||||
Normalizer: { normalizePath, encodePathSegment },
|
||||
} = RouteRecognizer;
|
||||
|
||||
export function encodePath(path) {
|
||||
return path ? path.split('/').map(encodePathSegment).join('/') : path;
|
||||
function encodePath(path) {
|
||||
return path
|
||||
? path
|
||||
.split('/')
|
||||
.map((segment) => encodeURIComponent(segment))
|
||||
.join('/')
|
||||
: path;
|
||||
}
|
||||
|
||||
export { normalizePath, encodePathSegment };
|
||||
function normalizePath(path) {
|
||||
// Unlike normalizePath from route-recognizer, this method assumes
|
||||
// we do not have percent-encoded data octets as defined in
|
||||
// https://datatracker.ietf.org/doc/html/rfc3986
|
||||
return path
|
||||
? path
|
||||
.split('/')
|
||||
.map((segment) => decodeURIComponent(segment))
|
||||
.join('/')
|
||||
: '';
|
||||
}
|
||||
|
||||
export { normalizePath, encodePath };
|
||||
|
|
|
@ -83,7 +83,7 @@ export default class KeyValueHeader extends Component {
|
|||
label: parts[index],
|
||||
text: this.stripTrailingSlash(parts[index]),
|
||||
path: path,
|
||||
model: ancestor,
|
||||
model: encodePath(ancestor),
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -187,7 +187,6 @@
|
|||
"pvutils": "^1.0.17",
|
||||
"qunit": "^2.19.1",
|
||||
"qunit-dom": "^2.0.0",
|
||||
"route-recognizer": "^0.3.4",
|
||||
"sass-svg-uri": "^1.0.0",
|
||||
"shell-quote": "^1.6.1",
|
||||
"string.prototype.endswith": "^0.2.0",
|
||||
|
|
|
@ -515,6 +515,37 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
|
|||
assert.strictEqual(currentURL(), `/vault/secrets/${enginePath}/show/${encodedSecretPath}?version=1`);
|
||||
});
|
||||
|
||||
test('UI handles secret with % in path correctly', async function (assert) {
|
||||
const enginePath = `kv-engine-${this.uid}`;
|
||||
const secretPath = 'per%cent/%fu ll';
|
||||
const [firstPath, secondPath] = secretPath.split('/');
|
||||
const commands = [`write sys/mounts/${enginePath} type=kv`, `write '${enginePath}/${secretPath}' 3=4`];
|
||||
await consoleComponent.runCommands(commands);
|
||||
await listPage.visitRoot({ backend: enginePath });
|
||||
assert.dom(`[data-test-secret-link="${firstPath}/"]`).exists('First section item exists');
|
||||
await click(`[data-test-secret-link="${firstPath}/"]`);
|
||||
|
||||
assert.strictEqual(
|
||||
currentURL(),
|
||||
`/vault/secrets/${enginePath}/list/${encodeURIComponent(firstPath)}/`,
|
||||
'First part of path is encoded in URL'
|
||||
);
|
||||
assert.dom(`[data-test-secret-link="${secretPath}"]`).exists('Link to secret exists');
|
||||
await click(`[data-test-secret-link="${secretPath}"]`);
|
||||
assert.strictEqual(
|
||||
currentURL(),
|
||||
`/vault/secrets/${enginePath}/show/${encodeURIComponent(firstPath)}/${encodeURIComponent(secondPath)}`,
|
||||
'secret path is encoded in URL'
|
||||
);
|
||||
assert.dom('h1').hasText(secretPath, 'Path renders correctly on show page');
|
||||
await click(`[data-test-secret-breadcrumb="${firstPath}"]`);
|
||||
assert.strictEqual(
|
||||
currentURL(),
|
||||
`/vault/secrets/${enginePath}/list/${encodeURIComponent(firstPath)}/`,
|
||||
'Breadcrumb link encodes correctly'
|
||||
);
|
||||
});
|
||||
|
||||
// the web cli does not handle a quote as part of a path, so we test it here via the UI
|
||||
test('creating a secret with a single or double quote works properly', async function (assert) {
|
||||
assert.expect(4);
|
||||
|
|
Loading…
Reference in New Issue