From a7270735b0786ccc2539ee9ad0de1ae8d5da052b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=B4=87=E5=B3=B0=20=E6=9C=94=E8=8F=AF?=
 <sakuhana@tsuitachi.net>
Date: Mon, 25 Nov 2024 21:38:32 +0900
Subject: [PATCH] =?UTF-8?q?Add:=20=E3=83=A1=E3=83=BC=E3=83=AB=E3=83=89?=
 =?UTF-8?q?=E3=83=A1=E3=82=A4=E3=83=B3=E3=81=AE=E8=87=AA=E5=8B=95=E3=83=96?=
 =?UTF-8?q?=E3=83=A9=E3=83=83=E3=82=AF=E3=83=AA=E3=82=B9=E3=83=88=E8=BF=BD?=
 =?UTF-8?q?=E5=8A=A0=E3=82=92=E8=BF=BD=E5=8A=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../1732535648378-AddAutoAddBannedEmailDomain.js | 16 ++++++++++++++++
 packages/backend/src/core/EmailService.ts        | 14 ++++++++++++++
 packages/backend/src/models/Meta.ts              |  5 +++++
 .../src/server/api/endpoints/admin/meta.ts       |  5 +++++
 .../server/api/endpoints/admin/update-meta.ts    |  5 +++++
 packages/frontend/src/pages/admin/security.vue   |  5 +++++
 packages/misskey-js/src/autogen/types.ts         |  2 ++
 7 files changed, 52 insertions(+)
 create mode 100644 packages/backend/migration/1732535648378-AddAutoAddBannedEmailDomain.js

diff --git a/packages/backend/migration/1732535648378-AddAutoAddBannedEmailDomain.js b/packages/backend/migration/1732535648378-AddAutoAddBannedEmailDomain.js
new file mode 100644
index 0000000000..d0744b3e3f
--- /dev/null
+++ b/packages/backend/migration/1732535648378-AddAutoAddBannedEmailDomain.js
@@ -0,0 +1,16 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+export class AddAutoAddBannedEmailDomain1732535648378 {
+    name = 'AddAutoAddBannedEmailDomain1732535648378'
+
+    async up(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "meta" ADD "enableAutoAddBannedEmailDomain" boolean NOT NULL DEFAULT false`);
+    }
+
+    async down(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableAutoAddBannedEmailDomain"`);
+    }
+}
diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts
index d80ae280c6..71d2c2c668 100644
--- a/packages/backend/src/core/EmailService.ts
+++ b/packages/backend/src/core/EmailService.ts
@@ -16,6 +16,7 @@ import type { MiMeta, UserProfilesRepository } from '@/models/_.js';
 import { LoggerService } from '@/core/LoggerService.js';
 import { bindThis } from '@/decorators.js';
 import { HttpRequestService } from '@/core/HttpRequestService.js';
+import { MetaService } from '@/core/MetaService.js';
 
 @Injectable()
 export class EmailService {
@@ -34,6 +35,7 @@ export class EmailService {
 		private loggerService: LoggerService,
 		private utilityService: UtilityService,
 		private httpRequestService: HttpRequestService,
+		private metaService: MetaService,
 	) {
 		this.logger = this.loggerService.getLogger('email');
 	}
@@ -227,6 +229,11 @@ export class EmailService {
 				blacklist: 'blacklist',
 			};
 
+			// 自動追加が有効な場合はブラックリストに追加する
+			if (this.meta.enableAutoAddBannedEmailDomain) {
+				await this.addBlockedHost(emailDomain);
+			}
+
 			return {
 				available: false,
 				reason: validated.reason ? formatReason[validated.reason] ?? null : null,
@@ -372,4 +379,11 @@ export class EmailService {
 			};
 		}
 	}
+
+	private async addBlockedHost(domain: string) {
+		const set = {} as Partial<MiMeta>;
+		set.bannedEmailDomains = this.meta.bannedEmailDomains;
+		set.bannedEmailDomains.push(domain);
+		await this.metaService.update(set);
+	}
 }
diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts
index 252f45cf42..7966df0bcf 100644
--- a/packages/backend/src/models/Meta.ts
+++ b/packages/backend/src/models/Meta.ts
@@ -576,6 +576,11 @@ export class MiMeta {
 	})
 	public allowedEmailDomains: string[];
 
+	@Column('boolean', {
+		default: false,
+	})
+	public enableAutoAddBannedEmailDomain: boolean;
+
 	@Column('varchar', {
 		length: 1024, array: true, default: '{ "admin", "administrator", "root", "system", "maintainer", "host", "mod", "moderator", "owner", "superuser", "staff", "auth", "i", "me", "everyone", "all", "mention", "mentions", "example", "user", "users", "account", "accounts", "official", "help", "helps", "support", "supports", "info", "information", "informations", "announce", "announces", "announcement", "announcements", "notice", "notification", "notifications", "dev", "developer", "developers", "tech", "misskey" }',
 	})
diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts
index b15597f784..4a6322f8f7 100644
--- a/packages/backend/src/server/api/endpoints/admin/meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/meta.ts
@@ -348,6 +348,10 @@ export const meta = {
 				type: 'string',
 				optional: false, nullable: true,
 			},
+			enableAutoAddBannedEmailDomain: {
+				type: 'boolean',
+				optional: false, nullable: false,
+			},
 			enableChartsForRemoteUser: {
 				type: 'boolean',
 				optional: false, nullable: false,
@@ -645,6 +649,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				enableTruemailApi: instance.enableTruemailApi,
 				truemailInstance: instance.truemailInstance,
 				truemailAuthKey: instance.truemailAuthKey,
+				enableAutoAddBannedEmailDomain: instance.enableAutoAddBannedEmailDomain,
 				enableChartsForRemoteUser: instance.enableChartsForRemoteUser,
 				enableChartsForFederatedInstances: instance.enableChartsForFederatedInstances,
 				enableStatsForFederatedInstances: instance.enableStatsForFederatedInstances,
diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
index 2e1c2515ad..cf6c46a33b 100644
--- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
@@ -142,6 +142,7 @@ export const paramDef = {
 		serverRules: { type: 'array', items: { type: 'string' } },
 		bannedEmailDomains: { type: 'array', items: { type: 'string' } },
 		allowedEmailDomains: { type: 'array', items: { type: 'string' } },
+		enableAutoAddBannedEmailDomain: { type: 'boolean' },
 		preservedUsernames: { type: 'array', items: { type: 'string' } },
 		manifestJsonOverride: { type: 'string' },
 		enableFanoutTimeline: { type: 'boolean' },
@@ -644,6 +645,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				set.allowedEmailDomains = ps.allowedEmailDomains;
 			}
 
+			if (ps.enableAutoAddBannedEmailDomain !== undefined) {
+				set.enableAutoAddBannedEmailDomain = ps.enableAutoAddBannedEmailDomain;
+			}
+
 			if (ps.urlPreviewEnabled !== undefined) {
 				set.urlPreviewEnabled = ps.urlPreviewEnabled;
 			}
diff --git a/packages/frontend/src/pages/admin/security.vue b/packages/frontend/src/pages/admin/security.vue
index 9e6eda1310..b9cf7a4578 100644
--- a/packages/frontend/src/pages/admin/security.vue
+++ b/packages/frontend/src/pages/admin/security.vue
@@ -85,6 +85,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<template #prefix><i class="ti ti-key"></i></template>
 						<template #label>TrueMail API Auth Key</template>
 					</MkInput>
+					<MkSwitch v-model="emailValidationForm.state.enableAutoAddBannedEmailDomain">
+						<template #label>Enable Auto Add Banned Email Domain</template>
+					</MkSwitch>
 				</div>
 			</MkFolder>
 
@@ -194,6 +197,7 @@ const emailValidationForm = useForm({
 	enableTruemailApi: meta.enableTruemailApi,
 	truemailInstance: meta.truemailInstance,
 	truemailAuthKey: meta.truemailAuthKey,
+	enableAutoAddBannedEmailDomain: meta.enableAutoAddBannedEmailDomain,
 }, async (state) => {
 	await os.apiWithDialog('admin/update-meta', {
 		enableActiveEmailValidation: state.enableActiveEmailValidation,
@@ -202,6 +206,7 @@ const emailValidationForm = useForm({
 		enableTruemailApi: state.enableTruemailApi,
 		truemailInstance: state.truemailInstance,
 		truemailAuthKey: state.truemailAuthKey,
+		enableAutoAddBannedEmailDomain: state.enableAutoAddBannedEmailDomain,
 	});
 	fetchInstance(true);
 });
diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts
index a497d51e27..06dea39fc3 100644
--- a/packages/misskey-js/src/autogen/types.ts
+++ b/packages/misskey-js/src/autogen/types.ts
@@ -5176,6 +5176,7 @@ export type operations = {
             enableTruemailApi: boolean;
             truemailInstance: string | null;
             truemailAuthKey: string | null;
+            enableAutoAddBannedEmailDomain: boolean;
             enableChartsForRemoteUser: boolean;
             enableChartsForFederatedInstances: boolean;
             enableStatsForFederatedInstances: boolean;
@@ -9580,6 +9581,7 @@ export type operations = {
           serverRules?: string[];
           bannedEmailDomains?: string[];
           allowedEmailDomains?: string[];
+          enableAutoAddBannedEmailDomain?: boolean;
           preservedUsernames?: string[];
           manifestJsonOverride?: string;
           enableFanoutTimeline?: boolean;