add leading and trailing slash sanitization for params (#8276)
* add leading and trailing slash sanitization for params * chore: fix lint * refactor: use shared trimSlashes util --------- Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com> Co-authored-by: Nate Moore <nate@astro.build>
This commit is contained in:
parent
84427f33c1
commit
d3a6f9f836
3 changed files with 75 additions and 1 deletions
5
.changeset/chilled-hornets-press.md
Normal file
5
.changeset/chilled-hornets-press.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Sanitize route params for leading and trailing slashes
|
|
@ -1,5 +1,6 @@
|
|||
import type { GetStaticPathsItem, Params, RouteData } from '../../@types/astro';
|
||||
import { validateGetStaticPathsParameter } from './validation.js';
|
||||
import { trimSlashes } from '../path.js';
|
||||
|
||||
/**
|
||||
* given an array of params like `['x', 'y', 'z']` for
|
||||
|
@ -32,7 +33,9 @@ export function stringifyParams(params: GetStaticPathsItem['params'], route: Rou
|
|||
const validatedParams = Object.entries(params).reduce((acc, next) => {
|
||||
validateGetStaticPathsParameter(next, route.component);
|
||||
const [key, value] = next;
|
||||
acc[key] = value?.toString();
|
||||
if (value !== undefined) {
|
||||
acc[key] = typeof value === 'string' ? trimSlashes(value) : value.toString()
|
||||
}
|
||||
return acc;
|
||||
}, {} as Params);
|
||||
|
||||
|
|
66
packages/astro/test/units/routing/route-sanitization.test.js
Normal file
66
packages/astro/test/units/routing/route-sanitization.test.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
import {
|
||||
createBasicSettings,
|
||||
createFs,
|
||||
createRequestAndResponse,
|
||||
defaultLogger,
|
||||
} from '../test-utils.js';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { expect } from 'chai';
|
||||
import { createContainer } from '../../../dist/core/dev/container.js';
|
||||
import * as cheerio from 'cheerio';
|
||||
import testAdapter from '../../test-adapter.js';
|
||||
|
||||
const root = new URL('../../fixtures/alias/', import.meta.url);
|
||||
const fileSystem = {
|
||||
'/src/pages/[...testSlashTrim].astro': `
|
||||
---
|
||||
export function getStaticPaths() {
|
||||
return [
|
||||
{
|
||||
params: {
|
||||
testSlashTrim: "/a-route-param-with-leading-trailing-slash/",
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
---
|
||||
<p>Success!</p>
|
||||
`,
|
||||
};
|
||||
|
||||
describe('Route sanitization', () => {
|
||||
let container;
|
||||
let settings;
|
||||
|
||||
before(async () => {
|
||||
const fs = createFs(fileSystem, root);
|
||||
settings = await createBasicSettings({
|
||||
root: fileURLToPath(root),
|
||||
trailingSlash: 'never',
|
||||
output: 'hybrid',
|
||||
adapter: testAdapter(),
|
||||
});
|
||||
container = await createContainer({
|
||||
fs,
|
||||
settings,
|
||||
logger: defaultLogger,
|
||||
});
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await container.close();
|
||||
});
|
||||
|
||||
describe('Request', () => {
|
||||
it('should correctly match a route param with a trailing slash', async () => {
|
||||
const { req, res, text } = createRequestAndResponse({
|
||||
method: 'GET',
|
||||
url: '/a-route-param-with-leading-trailing-slash',
|
||||
});
|
||||
container.handle(req, res);
|
||||
const html = await text();
|
||||
const $ = cheerio.load(html);
|
||||
expect($('p').text()).to.equal('Success!');
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue