mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-10 15:47:23 +02:00
fix(v2): reject routeBasePath: '' (#3377)
* routeBasePath: '' should be forbidden * routeBasePath: '' should be forbidden * commit * try to trigger cla bot
This commit is contained in:
parent
d8cfabb66a
commit
1eb6e13fb7
9 changed files with 33 additions and 24 deletions
|
@ -15,6 +15,7 @@
|
||||||
"@docusaurus/core": "^2.0.0-alpha.62",
|
"@docusaurus/core": "^2.0.0-alpha.62",
|
||||||
"@docusaurus/types": "^2.0.0-alpha.62",
|
"@docusaurus/types": "^2.0.0-alpha.62",
|
||||||
"@docusaurus/utils": "^2.0.0-alpha.62",
|
"@docusaurus/utils": "^2.0.0-alpha.62",
|
||||||
|
"@docusaurus/utils-validation": "^2.0.0-alpha.62",
|
||||||
"@hapi/joi": "^17.1.1",
|
"@hapi/joi": "^17.1.1",
|
||||||
"@types/hapi__joi": "^17.1.2",
|
"@types/hapi__joi": "^17.1.2",
|
||||||
"chalk": "^3.0.0",
|
"chalk": "^3.0.0",
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
import {PluginOptions, RedirectOption, UserPluginOptions} from './types';
|
import {PluginOptions, RedirectOption, UserPluginOptions} from './types';
|
||||||
import * as Joi from '@hapi/joi';
|
import * as Joi from '@hapi/joi';
|
||||||
import {PathnameValidator} from './redirectValidation';
|
import {PathnameSchema} from '@docusaurus/utils-validation';
|
||||||
import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';
|
import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';
|
||||||
|
|
||||||
export const DefaultPluginOptions: PluginOptions = {
|
export const DefaultPluginOptions: PluginOptions = {
|
||||||
|
@ -18,10 +18,10 @@ export const DefaultPluginOptions: PluginOptions = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const RedirectPluginOptionValidation = Joi.object<RedirectOption>({
|
const RedirectPluginOptionValidation = Joi.object<RedirectOption>({
|
||||||
to: PathnameValidator.required(),
|
to: PathnameSchema.required(),
|
||||||
from: Joi.alternatives().try(
|
from: Joi.alternatives().try(
|
||||||
PathnameValidator.required(),
|
PathnameSchema.required(),
|
||||||
Joi.array().items(PathnameValidator.required()),
|
Joi.array().items(PathnameSchema.required()),
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,24 +6,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as Joi from '@hapi/joi';
|
import * as Joi from '@hapi/joi';
|
||||||
import {isValidPathname} from '@docusaurus/utils';
|
|
||||||
import {RedirectMetadata} from './types';
|
import {RedirectMetadata} from './types';
|
||||||
|
import {PathnameSchema} from '@docusaurus/utils-validation';
|
||||||
export const PathnameValidator = Joi.string()
|
|
||||||
.custom((val) => {
|
|
||||||
if (!isValidPathname(val)) {
|
|
||||||
throw new Error();
|
|
||||||
} else {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.message(
|
|
||||||
'{{#label}} is not a valid pathname. Pathname should start with / and not contain any domain or query string',
|
|
||||||
);
|
|
||||||
|
|
||||||
const RedirectSchema = Joi.object<RedirectMetadata>({
|
const RedirectSchema = Joi.object<RedirectMetadata>({
|
||||||
from: PathnameValidator.required(),
|
from: PathnameSchema.required(),
|
||||||
to: PathnameValidator.required(),
|
to: PathnameSchema.required(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export function validateRedirect(redirect: RedirectMetadata): void {
|
export function validateRedirect(redirect: RedirectMetadata): void {
|
||||||
|
|
|
@ -22,7 +22,7 @@ test('should accept correctly defined user options', () => {
|
||||||
...DEFAULT_OPTIONS,
|
...DEFAULT_OPTIONS,
|
||||||
feedOptions: {type: 'rss', title: 'myTitle'},
|
feedOptions: {type: 'rss', title: 'myTitle'},
|
||||||
path: 'not_blog',
|
path: 'not_blog',
|
||||||
routeBasePath: '',
|
routeBasePath: 'myBlog',
|
||||||
postsPerPage: 5,
|
postsPerPage: 5,
|
||||||
include: ['api/*', 'docs/*'],
|
include: ['api/*', 'docs/*'],
|
||||||
};
|
};
|
||||||
|
@ -37,7 +37,7 @@ test('should accept correctly defined user options', () => {
|
||||||
test('should accept valid user options', async () => {
|
test('should accept valid user options', async () => {
|
||||||
const userOptions = {
|
const userOptions = {
|
||||||
...DEFAULT_OPTIONS,
|
...DEFAULT_OPTIONS,
|
||||||
routeBasePath: '',
|
routeBasePath: 'myBlog',
|
||||||
beforeDefaultRemarkPlugins: [],
|
beforeDefaultRemarkPlugins: [],
|
||||||
beforeDefaultRehypePlugins: [markdownPluginsFunctionStub],
|
beforeDefaultRehypePlugins: [markdownPluginsFunctionStub],
|
||||||
remarkPlugins: [[markdownPluginsFunctionStub, {option1: '42'}]],
|
remarkPlugins: [[markdownPluginsFunctionStub, {option1: '42'}]],
|
||||||
|
|
|
@ -35,7 +35,10 @@ export const DEFAULT_OPTIONS = {
|
||||||
|
|
||||||
export const PluginOptionSchema = Joi.object({
|
export const PluginOptionSchema = Joi.object({
|
||||||
path: Joi.string().default(DEFAULT_OPTIONS.path),
|
path: Joi.string().default(DEFAULT_OPTIONS.path),
|
||||||
routeBasePath: Joi.string().allow('').default(DEFAULT_OPTIONS.routeBasePath),
|
routeBasePath: Joi.string()
|
||||||
|
// '' not allowed, see https://github.com/facebook/docusaurus/issues/3374
|
||||||
|
// .allow('')
|
||||||
|
.default(DEFAULT_OPTIONS.routeBasePath),
|
||||||
include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
|
include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
|
||||||
postsPerPage: Joi.number()
|
postsPerPage: Joi.number()
|
||||||
.integer()
|
.integer()
|
||||||
|
|
|
@ -49,7 +49,10 @@ const VersionsOptionsSchema = Joi.object()
|
||||||
export const OptionsSchema = Joi.object({
|
export const OptionsSchema = Joi.object({
|
||||||
path: Joi.string().default(DEFAULT_OPTIONS.path),
|
path: Joi.string().default(DEFAULT_OPTIONS.path),
|
||||||
editUrl: URISchema,
|
editUrl: URISchema,
|
||||||
routeBasePath: Joi.string().allow('').default(DEFAULT_OPTIONS.routeBasePath),
|
routeBasePath: Joi.string()
|
||||||
|
// '' not allowed, see https://github.com/facebook/docusaurus/issues/3374
|
||||||
|
// .allow('') ""
|
||||||
|
.default(DEFAULT_OPTIONS.routeBasePath),
|
||||||
homePageId: Joi.string().optional(),
|
homePageId: Joi.string().optional(),
|
||||||
include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
|
include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
|
||||||
sidebarPath: Joi.string().allow('').default(DEFAULT_OPTIONS.sidebarPath),
|
sidebarPath: Joi.string().allow('').default(DEFAULT_OPTIONS.sidebarPath),
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {
|
||||||
|
|
||||||
export const DEFAULT_OPTIONS: PluginOptions = {
|
export const DEFAULT_OPTIONS: PluginOptions = {
|
||||||
path: 'src/pages', // Path to data on filesystem, relative to site dir.
|
path: 'src/pages', // Path to data on filesystem, relative to site dir.
|
||||||
routeBasePath: '', // URL Route.
|
routeBasePath: '/', // URL Route.
|
||||||
include: ['**/*.{js,jsx,ts,tsx,md,mdx}'], // Extensions to include.
|
include: ['**/*.{js,jsx,ts,tsx,md,mdx}'], // Extensions to include.
|
||||||
mdxPageComponent: '@theme/MDXPage',
|
mdxPageComponent: '@theme/MDXPage',
|
||||||
remarkPlugins: [],
|
remarkPlugins: [],
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
"@types/hapi__joi": "^17.1.2"
|
"@types/hapi__joi": "^17.1.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@docusaurus/utils": "^2.0.0-alpha.62",
|
||||||
"@hapi/joi": "17.1.1",
|
"@hapi/joi": "17.1.1",
|
||||||
"chalk": "^3.0.0"
|
"chalk": "^3.0.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
import * as Joi from '@hapi/joi';
|
import * as Joi from '@hapi/joi';
|
||||||
|
import {isValidPathname} from '@docusaurus/utils';
|
||||||
|
|
||||||
export const PluginIdSchema = Joi.string()
|
export const PluginIdSchema = Joi.string()
|
||||||
.regex(/^[a-zA-Z_\-]+$/)
|
.regex(/^[a-zA-Z_\-]+$/)
|
||||||
|
@ -39,3 +40,15 @@ export const URISchema = Joi.alternatives(
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const PathnameSchema = Joi.string()
|
||||||
|
.custom((val) => {
|
||||||
|
if (!isValidPathname(val)) {
|
||||||
|
throw new Error();
|
||||||
|
} else {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.message(
|
||||||
|
'{{#label}} is not a valid pathname. Pathname should start with / and not contain any domain or query string',
|
||||||
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue