diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 861b0008a047dff9cff035a688b0917a3855595e..a78d91900bedceecf9df984faa3a40a349a86b93 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -4,7 +4,9 @@ "service": "app", "workspaceFolder": "/workspace", "features": { - "ghcr.io/devcontainers-contrib/features/pnpm:2": {}, + "ghcr.io/devcontainers-contrib/features/pnpm:2": { + "version": "8.8.0" + }, "ghcr.io/devcontainers/features/node:1": { "version": "20.5.1" } diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index 17f744928119bdf8e3ef4490c0bf754cc33c03eb..145c224f678af655094454d62a3c4485b1792b08 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -379,6 +379,20 @@ export class CustomEmojiService implements OnApplicationShutdown { } } + /** + * ãƒãƒ¼ã‚«ãƒ«å†…ã®çµµæ–‡å—ã«é‡è¤‡ãŒãªã„ã‹ãƒã‚§ãƒƒã‚¯ã—ã¾ã™ + * @param name 絵文å—å + */ + @bindThis + public checkDuplicate(name: string): Promise<boolean> { + return this.emojisRepository.exist({ where: { name, host: IsNull() } }); + } + + @bindThis + public getEmojiById(id: string): Promise<MiEmoji | null> { + return this.emojisRepository.findOneBy({ id }); + } + @bindThis public dispose(): void { this.cache.dispose(); diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts index 24d3a8a9439642934e0aa4b477c61bc5a4de250c..faab8ee608da61e9baa0ad8cb5dd5382d88dcfdd 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts @@ -23,6 +23,11 @@ export const meta = { code: 'NO_SUCH_FILE', id: 'fc46b5a4-6b92-4c33-ac66-b806659bb5cf', }, + duplicateName: { + message: 'Duplicate name.', + code: 'DUPLICATE_NAME', + id: 'f7a3462c-4e6e-4069-8421-b9bd4f4c3975', + }, }, } as const; @@ -64,6 +69,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- super(meta, paramDef, async (ps, me) => { const driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId }); if (driveFile == null) throw new ApiError(meta.errors.noSuchFile); + const isDuplicate = await this.customEmojiService.checkDuplicate(ps.name); + if (isDuplicate) throw new ApiError(meta.errors.duplicateName); const emoji = await this.customEmojiService.add({ driveFile, diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts index 2d69857408efe50bb79a6153edc5b73859c31f5e..04226d8953895d81e3ab1aa87293af79105be907 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts @@ -74,6 +74,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId }); if (driveFile == null) throw new ApiError(meta.errors.noSuchFile); } + const emoji = await this.customEmojiService.getEmojiById(ps.id); + if (emoji != null) { + if (ps.name !== emoji.name) { + const isDuplicate = await this.customEmojiService.checkDuplicate(ps.name); + if (isDuplicate) throw new ApiError(meta.errors.sameNameEmojiExists); + } + } else { + throw new ApiError(meta.errors.noSuchEmoji); + } await this.customEmojiService.update(ps.id, { driveFile,