From 8968bfd309e505f7e33796d9d2084783bcfae377 Mon Sep 17 00:00:00 2001
From: Camilla Ett <camilla.ett@gmail.com>
Date: Sat, 2 Dec 2023 17:07:57 +0900
Subject: [PATCH] =?UTF-8?q?fix(backend):=20=E3=82=AB=E3=82=B9=E3=82=BF?=
 =?UTF-8?q?=E3=83=A0=E7=B5=B5=E6=96=87=E5=AD=97=E3=81=AE=E3=82=A4=E3=83=B3?=
 =?UTF-8?q?=E3=83=9D=E3=83=BC=E3=83=88=E6=99=82=E3=81=AE=E5=8B=95=E4=BD=9C?=
 =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3=20(#12360)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
---
 .../server/api/endpoints/admin/emoji/copy.ts  | 42 +++++++++----------
 .../src/pages/custom-emojis-manager.vue       |  4 +-
 2 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts b/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts
index a65e4e7624..5b41dfb514 100644
--- a/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts
+++ b/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts
@@ -6,11 +6,10 @@
 import { Inject, Injectable } from '@nestjs/common';
 import { Endpoint } from '@/server/api/endpoint-base.js';
 import type { EmojisRepository } from '@/models/_.js';
-import { IdService } from '@/core/IdService.js';
 import type { MiDriveFile } from '@/models/DriveFile.js';
 import { DI } from '@/di-symbols.js';
 import { DriveService } from '@/core/DriveService.js';
-import { GlobalEventService } from '@/core/GlobalEventService.js';
+import { CustomEmojiService } from '@/core/CustomEmojiService.js';
 import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
 import { ApiError } from '../../../error.js';
 
@@ -26,6 +25,11 @@ export const meta = {
 			code: 'NO_SUCH_EMOJI',
 			id: 'e2785b66-dca3-4087-9cac-b93c541cc425',
 		},
+		duplicateName: {
+			message: 'Duplicate name.',
+			code: 'DUPLICATE_NAME',
+			id: 'f7a3462c-4e6e-4069-8421-b9bd4f4c3975',
+		},
 	},
 
 	res: {
@@ -56,15 +60,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 	constructor(
 		@Inject(DI.emojisRepository)
 		private emojisRepository: EmojisRepository,
-
 		private emojiEntityService: EmojiEntityService,
-		private idService: IdService,
-		private globalEventService: GlobalEventService,
+		private customEmojiService: CustomEmojiService,
 		private driveService: DriveService,
 	) {
 		super(meta, paramDef, async (ps, me) => {
 			const emoji = await this.emojisRepository.findOneBy({ id: ps.emojiId });
-
 			if (emoji == null) {
 				throw new ApiError(meta.errors.noSuchEmoji);
 			}
@@ -75,28 +76,27 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				// Create file
 				driveFile = await this.driveService.uploadFromUrl({ url: emoji.originalUrl, user: null, force: true });
 			} catch (e) {
+				// TODO: need to return Drive Error
 				throw new ApiError();
 			}
 
-			const copied = await this.emojisRepository.insert({
-				id: this.idService.gen(),
-				updatedAt: new Date(),
+			// Duplication Check
+			const isDuplicate = await this.customEmojiService.checkDuplicate(emoji.name);
+			if (isDuplicate) throw new ApiError(meta.errors.duplicateName);
+
+			const addedEmoji = await this.customEmojiService.add({
+				driveFile,
 				name: emoji.name,
+				category: emoji.category,
+				aliases: emoji.aliases,
 				host: null,
-				aliases: [],
-				originalUrl: driveFile.url,
-				publicUrl: driveFile.webpublicUrl ?? driveFile.url,
-				type: driveFile.webpublicType ?? driveFile.type,
 				license: emoji.license,
-			}).then(x => this.emojisRepository.findOneByOrFail(x.identifiers[0]));
+				isSensitive: emoji.isSensitive,
+				localOnly: emoji.localOnly,
+				roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction,
+			}, me);
 
-			this.globalEventService.publishBroadcastStream('emojiAdded', {
-				emoji: await this.emojiEntityService.packDetailed(copied.id),
-			});
-
-			return {
-				id: copied.id,
-			};
+			return this.emojiEntityService.packDetailed(addedEmoji);
 		});
 	}
 }
diff --git a/packages/frontend/src/pages/custom-emojis-manager.vue b/packages/frontend/src/pages/custom-emojis-manager.vue
index 7450cf97c9..316dbaa3aa 100644
--- a/packages/frontend/src/pages/custom-emojis-manager.vue
+++ b/packages/frontend/src/pages/custom-emojis-manager.vue
@@ -155,7 +155,7 @@ const edit = (emoji) => {
 	}, 'closed');
 };
 
-const im = (emoji) => {
+const importEmoji = (emoji) => {
 	os.apiWithDialog('admin/emoji/copy', {
 		emojiId: emoji.id,
 	});
@@ -168,7 +168,7 @@ const remoteMenu = (emoji, ev: MouseEvent) => {
 	}, {
 		text: i18n.ts.import,
 		icon: 'ti ti-plus',
-		action: () => { im(emoji); },
+		action: () => { importEmoji(emoji); },
 	}], ev.currentTarget ?? ev.target);
 };