diff --git a/packages/backend/src/server/api/endpoints/pages/create.ts b/packages/backend/src/server/api/endpoints/pages/create.ts index fa03b0b4575f..79e9ddb6ac5c 100644 --- a/packages/backend/src/server/api/endpoints/pages/create.ts +++ b/packages/backend/src/server/api/endpoints/pages/create.ts @@ -39,6 +39,11 @@ export const meta = { code: 'NO_SUCH_FILE', id: 'b7b97489-0f66-4b12-a5ff-b21bd63f6e1c', }, + invalidName: { + message: 'Invalid name.', + code: 'INVALID_NAME', + id: '8702f702-f18f-4657-b50b-f746a3dffd3c', + }, nameAlreadyExists: { message: 'Specified name already exists.', code: 'NAME_ALREADY_EXISTS', @@ -81,6 +86,16 @@ export default class extends Endpoint { // eslint- private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { + const trimmedName = ps.name.trim(); + + if (trimmedName.trim() === '') { + throw new ApiError(meta.errors.invalidName); + } + + if ([' ', '/', '\\', '.', '#', '&', '%', '?', '!', '+', '<', '>'].some(c => trimmedName.includes(c))) { + throw new ApiError(meta.errors.invalidName); + } + let eyeCatchingImage = null; if (ps.eyeCatchingImageId != null) { eyeCatchingImage = await this.driveFilesRepository.findOneBy({ @@ -95,7 +110,7 @@ export default class extends Endpoint { // eslint- await this.pagesRepository.findBy({ userId: me.id, - name: ps.name, + name: trimmedName, }).then(result => { if (result.length > 0) { throw new ApiError(meta.errors.nameAlreadyExists); @@ -106,7 +121,7 @@ export default class extends Endpoint { // eslint- id: this.idService.gen(), updatedAt: new Date(), title: ps.title, - name: ps.name, + name: trimmedName, summary: ps.summary, content: ps.content, variables: ps.variables, diff --git a/packages/backend/src/server/api/endpoints/pages/update.ts b/packages/backend/src/server/api/endpoints/pages/update.ts index e52d9c32df8f..2fc01e41b064 100644 --- a/packages/backend/src/server/api/endpoints/pages/update.ts +++ b/packages/backend/src/server/api/endpoints/pages/update.ts @@ -31,13 +31,16 @@ export const meta = { code: 'NO_SUCH_PAGE', id: '21149b9e-3616-4778-9592-c4ce89f5a864', }, - accessDenied: { message: 'Access denied.', code: 'ACCESS_DENIED', id: '3c15cd52-3b4b-4274-967d-6456fc4f792b', }, - + invalidName: { + message: 'Invalid name.', + code: 'INVALID_NAME', + id: '75a78404-bcd1-4d98-9354-25c60f930e78', + }, noSuchFile: { message: 'No such file.', code: 'NO_SUCH_FILE', @@ -103,10 +106,20 @@ export default class extends Endpoint { // eslint- } if (ps.name != null) { + const trimmedName = ps.name.trim(); + + if (trimmedName.trim() === '') { + throw new ApiError(meta.errors.invalidName); + } + + if ([' ', '/', '\\', '.', '#', '&', '%', '?', '!', '+', '<', '>'].some(c => trimmedName.includes(c))) { + throw new ApiError(meta.errors.invalidName); + } + await this.pagesRepository.findBy({ id: Not(ps.pageId), userId: me.id, - name: ps.name, + name: trimmedName, }).then(result => { if (result.length > 0) { throw new ApiError(meta.errors.nameAlreadyExists); @@ -117,7 +130,7 @@ export default class extends Endpoint { // eslint- await this.pagesRepository.update(page.id, { updatedAt: new Date(), title: ps.title, - name: ps.name, + name: ps.name ? ps.name.trim() : undefined, summary: ps.summary === undefined ? page.summary : ps.summary, content: ps.content, variables: ps.variables,