From b3c4f7eddc4d97e15077f1e9041c5abecc184afb Mon Sep 17 00:00:00 2001
From: Nya Candy <dev@candinya.com>
Date: Sat, 23 Dec 2023 10:00:14 +0800
Subject: [PATCH 01/13] fix: email verify enable logic (#12743)

---
 packages/backend/src/core/EmailService.ts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts
index f31cec2b3a..d4508d5313 100644
--- a/packages/backend/src/core/EmailService.ts
+++ b/packages/backend/src/core/EmailService.ts
@@ -167,18 +167,18 @@ export class EmailService {
 		const verifymailApi = meta.enableVerifymailApi && meta.verifymailAuthKey != null;
 		let validated;
 
-		if (meta.enableActiveEmailValidation && meta.verifymailAuthKey) {
+		if (meta.enableActiveEmailValidation) {
 			if (verifymailApi) {
 				validated = await this.verifyMail(emailAddress, meta.verifymailAuthKey);
 			} else {
-				validated = meta.enableActiveEmailValidation ? await validateEmail({
+				validated = await validateEmail({
 					email: emailAddress,
 					validateRegex: true,
 					validateMx: true,
 					validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
 					validateDisposable: true, // 捨てアドかどうかチェック
 					validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
-				}) : { valid: true, reason: null };
+				});
 			}
 		} else {
 			validated = { valid: true, reason: null };

From 5b5a537f567a7a2cbce008ac19aaaea372dd4695 Mon Sep 17 00:00:00 2001
From: GrapeApple0 <84321396+GrapeApple0@users.noreply.github.com>
Date: Sat, 23 Dec 2023 12:06:22 +0900
Subject: [PATCH 02/13] =?UTF-8?q?feat:=20=E7=99=BB=E9=8C=B2=E3=82=92?=
 =?UTF-8?q?=E6=8B=92=E5=90=A6=E3=81=99=E3=82=8B=E3=83=A1=E3=83=BC=E3=83=AB?=
 =?UTF-8?q?=E3=82=A2=E3=83=89=E3=83=AC=E3=82=B9=E3=81=AE=E3=83=89=E3=83=A1?=
 =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=82=92=E6=89=8B=E5=8B=95=E3=81=A7=E8=A8=AD?=
 =?UTF-8?q?=E5=AE=9A=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?=
 =?UTF-8?q?=20(#12740)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* feat: 使い捨てアドレスのドメインを手動で設定できるように

* Update CHANGELOG.md

* disposableEmailDomains -> bannedEmailDomains

* isBlockedHostを使うように
---
 CHANGELOG.md                                   |  1 +
 locales/index.d.ts                             |  1 +
 locales/ja-JP.yml                              |  1 +
 .../1703209889304-bannedEmailDomains.js        | 18 ++++++++++++++++++
 packages/backend/src/core/EmailService.ts      | 10 ++++++++--
 packages/backend/src/models/Meta.ts            |  7 +++++++
 .../src/server/api/endpoints/admin/meta.ts     |  9 +++++++++
 .../server/api/endpoints/admin/update-meta.ts  |  5 +++++
 .../src/components/MkSignupDialog.form.vue     |  4 +++-
 packages/frontend/src/pages/admin/security.vue | 15 +++++++++++++++
 10 files changed, 68 insertions(+), 3 deletions(-)
 create mode 100644 packages/backend/migration/1703209889304-bannedEmailDomains.js

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2c21684e77..71a90620e2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -94,6 +94,7 @@
 - Fix: MFMでルビの中のテキストがnyaizeされない問題を修正
 
 ### Server
+- Feat: 使い捨てメールのドメインを手動で設定できるように
 - Enhance: MFM `$[ruby ]` が他ソフトウェアと連合されるように
 - Enhance: Meilisearchを有効にした検索で、ユーザーのミュートやブロックを考慮するように
 - Enhance: カスタム絵文字のインポート時の動作を改善
diff --git a/locales/index.d.ts b/locales/index.d.ts
index fd96fd7625..b3589082e1 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -1745,6 +1745,7 @@ export interface Locale {
         "disposable": string;
         "mx": string;
         "smtp": string;
+        "banned": string;
     };
     "_ffVisibility": {
         "public": string;
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 2c29bd20da..b59fb6e749 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1652,6 +1652,7 @@ _emailUnavailable:
   disposable: "恒久的に使用可能なアドレスではありません"
   mx: "正しいメールサーバーではありません"
   smtp: "メールサーバーが応答しません"
+  banned: "このメールアドレスでは登録できません"
 
 _ffVisibility:
   public: "公開"
diff --git a/packages/backend/migration/1703209889304-bannedEmailDomains.js b/packages/backend/migration/1703209889304-bannedEmailDomains.js
new file mode 100644
index 0000000000..5dc99c138f
--- /dev/null
+++ b/packages/backend/migration/1703209889304-bannedEmailDomains.js
@@ -0,0 +1,18 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+export class bannedEmailDomains1703209889304 {
+		constructor() {
+				this.name = 'bannedEmailDomains1703209889304';
+		}
+
+		async up(queryRunner) {
+				await queryRunner.query(`ALTER TABLE "meta" ADD "bannedEmailDomains" character varying(1024) array NOT NULL DEFAULT '{}'`);
+		}
+
+		async down(queryRunner) {
+				await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "bannedEmailDomains"`);
+		}
+}
diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts
index d4508d5313..6107b9601c 100644
--- a/packages/backend/src/core/EmailService.ts
+++ b/packages/backend/src/core/EmailService.ts
@@ -9,6 +9,7 @@ import { Inject, Injectable } from '@nestjs/common';
 import { validate as validateEmail } from 'deep-email-validator';
 import { SubOutputFormat } from 'deep-email-validator/dist/output/output.js';
 import { MetaService } from '@/core/MetaService.js';
+import { UtilityService } from '@/core/UtilityService.js';
 import { DI } from '@/di-symbols.js';
 import type { Config } from '@/config.js';
 import type Logger from '@/logger.js';
@@ -30,6 +31,7 @@ export class EmailService {
 
 		private metaService: MetaService,
 		private loggerService: LoggerService,
+		private utilityService: UtilityService,
 		private httpRequestService: HttpRequestService,
 	) {
 		this.logger = this.loggerService.getLogger('email');
@@ -155,7 +157,7 @@ export class EmailService {
 	@bindThis
 	public async validateEmailForAccount(emailAddress: string): Promise<{
 		available: boolean;
-		reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp';
+		reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp' | 'banned';
 	}> {
 		const meta = await this.metaService.fetch();
 
@@ -184,12 +186,16 @@ export class EmailService {
 			validated = { valid: true, reason: null };
 		}
 
-		const available = exist === 0 && validated.valid;
+		const emailDomain: string = emailAddress.split('@')[1];
+		const isBanned = this.utilityService.isBlockedHost(meta.bannedEmailDomains, emailDomain);
+
+		const available = exist === 0 && validated.valid && !isBanned;
 
 		return {
 			available,
 			reason: available ? null :
 			exist !== 0 ? 'used' :
+			isBanned ? 'banned' :
 			validated.reason === 'regex' ? 'format' :
 			validated.reason === 'disposable' ? 'disposable' :
 			validated.reason === 'mx' ? 'mx' :
diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts
index 83e8962f5d..84ca762492 100644
--- a/packages/backend/src/models/Meta.ts
+++ b/packages/backend/src/models/Meta.ts
@@ -495,6 +495,13 @@ export class MiMeta {
 	})
 	public manifestJsonOverride: string;
 
+	@Column('varchar', {
+		length: 1024,
+		array: true,
+		default: '{}',
+	})
+	public bannedEmailDomains: string[];
+
 	@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 07912154bd..6f8494d1d0 100644
--- a/packages/backend/src/server/api/endpoints/admin/meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/meta.ts
@@ -145,6 +145,14 @@ export const meta = {
 					type: 'string',
 				},
 			},
+			bannedEmailDomains: {
+				type: 'array',
+				optional: true, nullable: false,
+				items: {
+					type: 'string',
+					optional: false, nullable: false,
+				},
+			},
 			preservedUsernames: {
 				type: 'array',
 				optional: false, nullable: false,
@@ -513,6 +521,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				enableChartsForFederatedInstances: instance.enableChartsForFederatedInstances,
 				enableServerMachineStats: instance.enableServerMachineStats,
 				enableIdenticonGeneration: instance.enableIdenticonGeneration,
+				bannedEmailDomains: instance.bannedEmailDomains,
 				policies: { ...DEFAULT_POLICIES, ...instance.policies },
 				manifestJsonOverride: instance.manifestJsonOverride,
 				enableFanoutTimeline: instance.enableFanoutTimeline,
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 293a95a9a4..5f9de0523e 100644
--- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
@@ -122,6 +122,7 @@ export const paramDef = {
 		enableServerMachineStats: { type: 'boolean' },
 		enableIdenticonGeneration: { type: 'boolean' },
 		serverRules: { type: 'array', items: { type: 'string' } },
+		bannedEmailDomains: { type: 'array', items: { type: 'string' } },
 		preservedUsernames: { type: 'array', items: { type: 'string' } },
 		manifestJsonOverride: { type: 'string' },
 		enableFanoutTimeline: { type: 'boolean' },
@@ -526,6 +527,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				set.notesPerOneAd = ps.notesPerOneAd;
 			}
 
+			if (ps.bannedEmailDomains !== undefined) {
+				set.bannedEmailDomains = ps.bannedEmailDomains;
+			}
+
 			const before = await this.metaService.fetch(true);
 
 			await this.metaService.update(set);
diff --git a/packages/frontend/src/components/MkSignupDialog.form.vue b/packages/frontend/src/components/MkSignupDialog.form.vue
index dd05a44e04..f171e449c8 100644
--- a/packages/frontend/src/components/MkSignupDialog.form.vue
+++ b/packages/frontend/src/components/MkSignupDialog.form.vue
@@ -38,6 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<span v-else-if="emailState === 'unavailable:used'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.used }}</span>
 					<span v-else-if="emailState === 'unavailable:format'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.format }}</span>
 					<span v-else-if="emailState === 'unavailable:disposable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.disposable }}</span>
+					<span v-else-if="emailState === 'unavailable:banned'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.banned }}</span>
 					<span v-else-if="emailState === 'unavailable:mx'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.mx }}</span>
 					<span v-else-if="emailState === 'unavailable:smtp'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.smtp }}</span>
 					<span v-else-if="emailState === 'unavailable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span>
@@ -110,7 +111,7 @@ const retypedPassword = ref<string>('');
 const invitationCode = ref<string>('');
 const email = ref('');
 const usernameState = ref<null | 'wait' | 'ok' | 'unavailable' | 'error' | 'invalid-format' | 'min-range' | 'max-range'>(null);
-const emailState = ref<null | 'wait' | 'ok' | 'unavailable:used' | 'unavailable:format' | 'unavailable:disposable' | 'unavailable:mx' | 'unavailable:smtp' | 'unavailable' | 'error'>(null);
+const emailState = ref<null | 'wait' | 'ok' | 'unavailable:used' | 'unavailable:format' | 'unavailable:disposable' | 'unavailable:banned' | 'unavailable:mx' | 'unavailable:smtp' | 'unavailable' | 'error'>(null);
 const passwordStrength = ref<'' | 'low' | 'medium' | 'high'>('');
 const passwordRetypeState = ref<null | 'match' | 'not-match'>(null);
 const submitting = ref<boolean>(false);
@@ -209,6 +210,7 @@ function onChangeEmail(): void {
 			result.reason === 'used' ? 'unavailable:used' :
 			result.reason === 'format' ? 'unavailable:format' :
 			result.reason === 'disposable' ? 'unavailable:disposable' :
+			result.reason === 'banned' ? 'unavailable:banned' :
 			result.reason === 'mx' ? 'unavailable:mx' :
 			result.reason === 'smtp' ? 'unavailable:smtp' :
 			'unavailable';
diff --git a/packages/frontend/src/pages/admin/security.vue b/packages/frontend/src/pages/admin/security.vue
index 9835591fa8..bda29cee58 100644
--- a/packages/frontend/src/pages/admin/security.vue
+++ b/packages/frontend/src/pages/admin/security.vue
@@ -83,6 +83,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</div>
 				</MkFolder>
 
+				<MkFolder>
+					<template #label>Banned Email Domains</template>
+
+					<div class="_gaps_m">
+						<MkTextarea v-model="bannedEmailDomains">
+							<template #label>Banned Email Domains List</template>
+						</MkTextarea>
+						<MkButton primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+					</div>
+				</MkFolder>
+
 				<MkFolder>
 					<template #label>Log IP address</template>
 					<template v-if="enableIpLogging" #suffix>Enabled</template>
@@ -124,6 +135,7 @@ import FormSuspense from '@/components/form/suspense.vue';
 import MkRange from '@/components/MkRange.vue';
 import MkInput from '@/components/MkInput.vue';
 import MkButton from '@/components/MkButton.vue';
+import MkTextarea from '@/components/MkTextarea.vue';
 import * as os from '@/os.js';
 import { fetchInstance } from '@/instance.js';
 import { i18n } from '@/i18n.js';
@@ -141,6 +153,7 @@ const enableIpLogging = ref<boolean>(false);
 const enableActiveEmailValidation = ref<boolean>(false);
 const enableVerifymailApi = ref<boolean>(false);
 const verifymailAuthKey = ref<string | null>(null);
+const bannedEmailDomains = ref<string>('');
 
 async function init() {
 	const meta = await os.api('admin/meta');
@@ -161,6 +174,7 @@ async function init() {
 	enableActiveEmailValidation.value = meta.enableActiveEmailValidation;
 	enableVerifymailApi.value = meta.enableVerifymailApi;
 	verifymailAuthKey.value = meta.verifymailAuthKey;
+	bannedEmailDomains.value = meta.bannedEmailDomains.join('\n');
 }
 
 function save() {
@@ -180,6 +194,7 @@ function save() {
 		enableActiveEmailValidation: enableActiveEmailValidation.value,
 		enableVerifymailApi: enableVerifymailApi.value,
 		verifymailAuthKey: verifymailAuthKey.value,
+		bannedEmailDomains: bannedEmailDomains.value.split('\n'),
 	}).then(() => {
 		fetchInstance();
 	});

From 2c7d07bca6a6b6a3390674c5fcc3b618092b2507 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 23 Dec 2023 12:15:10 +0900
Subject: [PATCH 03/13] Update CHANGELOG.md

---
 CHANGELOG.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 71a90620e2..d131077bcb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,6 +31,7 @@
 - Feat: メールアドレスの認証にverifymail.ioを使えるように (cherry-pick from https://github.com/TeamNijimiss/misskey/commit/971ba07a44550f68d2ba31c62066db2d43a0caed)
 - Feat: モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能を追加 (cherry-pick from https://github.com/TeamNijimiss/misskey/commit/e0eb5a752f6e5616d6312bb7c9790302f9dbff83)
 - Feat: TL上からノートが見えなくなるワードミュートであるハードミュートを追加
+- Enhance: 指定したドメインのメールアドレスの登録を弾くことができるように
 - Enhance: 公開ロールにアサインされたときに通知が作成されるように
 - Enhance: アイコンデコレーションを複数設定できるように
 - Enhance: アイコンデコレーションの位置を微調整できるように
@@ -94,7 +95,6 @@
 - Fix: MFMでルビの中のテキストがnyaizeされない問題を修正
 
 ### Server
-- Feat: 使い捨てメールのドメインを手動で設定できるように
 - Enhance: MFM `$[ruby ]` が他ソフトウェアと連合されるように
 - Enhance: Meilisearchを有効にした検索で、ユーザーのミュートやブロックを考慮するように
 - Enhance: カスタム絵文字のインポート時の動作を改善

From 98734af9a7d9365608a8e84995eb34fdfdfb1dfe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?=
 <46447427+samunohito@users.noreply.github.com>
Date: Sat, 23 Dec 2023 14:30:39 +0900
Subject: [PATCH 04/13] =?UTF-8?q?fix:=202023.12.0=E3=81=AENote=E3=81=AE?=
 =?UTF-8?q?=E4=B8=80=E9=83=A8=E6=96=87=E8=A8=80=E3=82=92=E4=BF=AE=E6=AD=A3?=
 =?UTF-8?q?=20(#12754)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 CHANGELOG.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index d131077bcb..0f864acfee 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,12 +20,12 @@
 - 絵文字ピッカーにピン留め表示する絵文字設定が「リアクション用」と「絵文字入力用」に分かれました。以前の設定は「リアクション用」として使用されます。  
 
 	**影響:**  
-	それにより、投稿フォームから表示される絵文字ピッカーのピン留め絵文字がリセットされたように感じるかもしれません(新設された投稿用のピン留め絵文字が使われるため)。   
+	それにより、投稿フォームから表示される絵文字ピッカーのピン留め絵文字がリセットされたように感じるかもしれません(新設された"ピン留め(全般)"の設定が使われるため)。   
 	投稿用のピン留め絵文字をアップデート前の状態にするには、以下の手順で操作します。
 
 	1. 「設定」メニューに移動し、「絵文字ピッカー」タブを選択します。
 	2. 「ピン留 (全般)」のタブを選択します。
-	3. 「リアクション設定からコピーする」ボタンを押すことで、アップデート前の状態に戻すことができます。
+	3. 「リアクション設定から上書きする」ボタンを押すことで、アップデート前の状態に戻すことができます。
 
 ### General
 - Feat: メールアドレスの認証にverifymail.ioを使えるように (cherry-pick from https://github.com/TeamNijimiss/misskey/commit/971ba07a44550f68d2ba31c62066db2d43a0caed)

From 6e4894c1656d283906b679866923fddab2b146bf Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 23 Dec 2023 14:39:01 +0900
Subject: [PATCH 05/13] lint

---
 packages/backend/src/core/EmailService.ts | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts
index 6107b9601c..3a61e353f1 100644
--- a/packages/backend/src/core/EmailService.ts
+++ b/packages/backend/src/core/EmailService.ts
@@ -166,11 +166,10 @@ export class EmailService {
 			email: emailAddress,
 		});
 
-		const verifymailApi = meta.enableVerifymailApi && meta.verifymailAuthKey != null;
 		let validated;
 
 		if (meta.enableActiveEmailValidation) {
-			if (verifymailApi) {
+			if (meta.enableVerifymailApi && meta.verifymailAuthKey != null) {
 				validated = await this.verifyMail(emailAddress, meta.verifymailAuthKey);
 			} else {
 				validated = await validateEmail({

From 1716c6562c86c20aaba734b427913fc6a6abd67c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?=
 <46447427+samunohito@users.noreply.github.com>
Date: Sat, 23 Dec 2023 15:32:31 +0900
Subject: [PATCH 06/13] =?UTF-8?q?fix:=20.npmrc=E3=81=AB=E3=82=88=E3=82=8Ap?=
 =?UTF-8?q?ackage.json=E8=A8=98=E8=BC=89=E3=81=AEnode=E3=83=90=E3=83=BC?=
 =?UTF-8?q?=E3=82=B8=E3=83=A7=E3=83=B3=E3=81=AB=E6=BA=80=E3=81=9F=E3=81=AA?=
 =?UTF-8?q?=E3=81=84=E5=A0=B4=E5=90=88=E3=81=AF=E3=83=93=E3=83=AB=E3=83=89?=
 =?UTF-8?q?=E3=81=AB=E5=A4=B1=E6=95=97=E3=81=99=E3=82=8B=E3=82=88=E3=81=86?=
 =?UTF-8?q?=E3=81=AB=E3=81=99=E3=82=8B=20(#12755)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .npmrc | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 .npmrc

diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000000..c42da845b4
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+engine-strict = true

From 30cf5c3ab09717829a2e49a6afe14fe6478140dc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=9A=90=E6=9C=88=E3=81=AA=E3=81=B5=20=28Nafu=20Satsuki?=
 =?UTF-8?q?=29?= <satsuki@nafusoft.dev>
Date: Sat, 23 Dec 2023 15:32:53 +0900
Subject: [PATCH 07/13] =?UTF-8?q?chore(frontend):=20API=E8=A8=AD=E5=AE=9A?=
 =?UTF-8?q?=E9=A0=85=E7=9B=AE=E3=81=AE=E5=90=8D=E5=89=8D=E3=82=92=E3=81=8D?=
 =?UTF-8?q?=E3=81=A1=E3=82=93=E3=81=A8=E3=82=B5=E3=83=BC=E3=83=93=E3=82=B9?=
 =?UTF-8?q?=E3=81=AE=E5=90=8D=E5=89=8D=E3=81=A7=E8=A1=A8=E8=A8=98=E3=81=99?=
 =?UTF-8?q?=E3=82=8B=20(#12753)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/frontend/src/pages/admin/security.vue | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/frontend/src/pages/admin/security.vue b/packages/frontend/src/pages/admin/security.vue
index bda29cee58..7070157ca9 100644
--- a/packages/frontend/src/pages/admin/security.vue
+++ b/packages/frontend/src/pages/admin/security.vue
@@ -74,11 +74,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 							<template #label>Enable</template>
 						</MkSwitch>
 						<MkSwitch v-model="enableVerifymailApi" @update:modelValue="save">
-							<template #label>Use Verifymail API</template>
+							<template #label>Use Verifymail.io API</template>
 						</MkSwitch>
 						<MkInput v-model="verifymailAuthKey" @update:modelValue="save">
 							<template #prefix><i class="ti ti-key"></i></template>
-							<template #label>Verifymail API Auth Key</template>
+							<template #label>Verifymail.io API Auth Key</template>
 						</MkInput>
 					</div>
 				</MkFolder>

From 59b47b862340f772a51e5d8e8cbaab5f1c4e53f5 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 23 Dec 2023 16:40:31 +0900
Subject: [PATCH 08/13] Update CHANGELOG.md

---
 CHANGELOG.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0f864acfee..c7afb101db 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,7 +15,7 @@
 ## 2023.12.0
 
 ### Note
-- Node.js 20.10.0が最小要件になりました
+- 依存関係の更新に伴い、Node.js 20.10.0が最小要件になりました
 - 絵文字の追加辞書を既にインストールしている場合は、お手数ですが再インストールのほどお願いします
 - 絵文字ピッカーにピン留め表示する絵文字設定が「リアクション用」と「絵文字入力用」に分かれました。以前の設定は「リアクション用」として使用されます。  
 

From 8caf2b0a4ac771d4568f1549bdce850de2af7777 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 23 Dec 2023 16:43:06 +0900
Subject: [PATCH 09/13] New Crowdin updates (#12748)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (French)

* New translations ja-jp.yml (Chinese Traditional)
---
 locales/fr-FR.yml | 1 +
 locales/ko-KR.yml | 1 +
 locales/zh-TW.yml | 1 +
 3 files changed, 3 insertions(+)

diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml
index e12b508617..43cc1d45b6 100644
--- a/locales/fr-FR.yml
+++ b/locales/fr-FR.yml
@@ -1917,6 +1917,7 @@ _notification:
     pollEnded: "Sondages se cloturant"
     receiveFollowRequest: "Demande d'abonnement reçue"
     followRequestAccepted: "Demande d'abonnement acceptée"
+    roleAssigned: "Rôle reçu"
     achievementEarned: "Accomplissement"
     app: "Notifications provenant des apps"
   _actions:
diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml
index d8efa7f04e..6cdcc2c246 100644
--- a/locales/ko-KR.yml
+++ b/locales/ko-KR.yml
@@ -2193,6 +2193,7 @@ _notification:
     pollEnded: "투표가 종료됨"
     receiveFollowRequest: "팔로우 요청을 받았을 때"
     followRequestAccepted: "팔로우 요청이 승인되었을 때"
+    roleAssigned: "역할이 부여 됨"
     achievementEarned: "도전 과제 획득"
     app: "연동된 앱을 통한 알림"
   _actions:
diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml
index d05691d42e..51ba42e66c 100644
--- a/locales/zh-TW.yml
+++ b/locales/zh-TW.yml
@@ -2193,6 +2193,7 @@ _notification:
     pollEnded: "問卷調查結束"
     receiveFollowRequest: "已收到追隨請求"
     followRequestAccepted: "追隨請求已接受"
+    roleAssigned: "已授予角色"
     achievementEarned: "獲得成就"
     app: "應用程式通知"
   _actions:

From f43599552fb5764aa3121b083e441d3946c72cd8 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 23 Dec 2023 17:54:29 +0900
Subject: [PATCH 10/13] =?UTF-8?q?fix(backend):=20renote=E5=88=A4=E5=AE=9A?=
 =?UTF-8?q?=E3=81=8C=E3=81=8A=E3=81=8B=E3=81=97=E3=81=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/backend/src/core/NoteCreateService.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts
index 54493612b8..c4fc51847b 100644
--- a/packages/backend/src/core/NoteCreateService.ts
+++ b/packages/backend/src/core/NoteCreateService.ts
@@ -293,7 +293,7 @@ export class NoteCreateService implements OnApplicationShutdown {
 		}
 
 		// Check blocking
-		if (this.isQuote(data)) {
+		if (data.renote && data.text == null && data.poll == null && (data.files == null || data.files.length === 0)) {
 			if (data.renote.userHost === null) {
 				if (data.renote.userId !== user.id) {
 					const blocked = await this.userBlockingService.checkBlocked(data.renote.userId, user.id);

From e852f4b60d48edc5b28e6db104ca6a88dd678740 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 23 Dec 2023 17:55:27 +0900
Subject: [PATCH 11/13] =?UTF-8?q?Revert=20"fix(backend):=20renote=E5=88=A4?=
 =?UTF-8?q?=E5=AE=9A=E3=81=8C=E3=81=8A=E3=81=8B=E3=81=97=E3=81=84"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This reverts commit f43599552fb5764aa3121b083e441d3946c72cd8.
---
 packages/backend/src/core/NoteCreateService.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts
index c4fc51847b..54493612b8 100644
--- a/packages/backend/src/core/NoteCreateService.ts
+++ b/packages/backend/src/core/NoteCreateService.ts
@@ -293,7 +293,7 @@ export class NoteCreateService implements OnApplicationShutdown {
 		}
 
 		// Check blocking
-		if (data.renote && data.text == null && data.poll == null && (data.files == null || data.files.length === 0)) {
+		if (this.isQuote(data)) {
 			if (data.renote.userHost === null) {
 				if (data.renote.userId !== user.id) {
 					const blocked = await this.userBlockingService.checkBlocked(data.renote.userId, user.id);

From 2f425aa03f705bc886711bc3b61f6fdd5f014f0b Mon Sep 17 00:00:00 2001
From: anatawa12 <anatawa12@icloud.com>
Date: Sat, 23 Dec 2023 17:55:34 +0900
Subject: [PATCH 12/13] =?UTF-8?q?fix:=20=E3=83=96=E3=83=AD=E3=83=83?=
 =?UTF-8?q?=E3=82=AF=E3=81=95=E3=82=8C=E3=81=A6=E3=81=A6=E3=82=82pure=20RN?=
 =?UTF-8?q?=E3=81=A7=E3=81=8D=E3=82=8B=20(#12758)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

なぜかわからないけど元々Quoteはできるようなのでそれに戻しました
---
 packages/backend/src/core/NoteCreateService.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts
index 54493612b8..2bdff872ad 100644
--- a/packages/backend/src/core/NoteCreateService.ts
+++ b/packages/backend/src/core/NoteCreateService.ts
@@ -293,7 +293,7 @@ export class NoteCreateService implements OnApplicationShutdown {
 		}
 
 		// Check blocking
-		if (this.isQuote(data)) {
+		if (data.renote && !this.isQuote(data)) {
 			if (data.renote.userHost === null) {
 				if (data.renote.userId !== user.id) {
 					const blocked = await this.userBlockingService.checkBlocked(data.renote.userId, user.id);

From 471c8ec0509741cd1c813535aa0e751f85b64a7c Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 23 Dec 2023 19:59:27 +0900
Subject: [PATCH 13/13] Update CHANGELOG.md

---
 CHANGELOG.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c7afb101db..ac31bc0d28 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -73,6 +73,7 @@
 - Enhance: チャンネルに新規の投稿がある場合にバッジを表示させる
 - Enhance: サウンド設定に「サウンドを出力しない」と「Misskeyがアクティブな時のみサウンドを出力する」を追加
 - Enhance: 設定したタグをトレンドに表示させないようにする項目を管理画面で設定できるように
+- Enhance: 絵文字ピッカーのカテゴリに「/」を入れることでフォルダ分け表示できるように
 - Fix: 「設定のバックアップ」で一部の項目がバックアップに含まれていなかった問題を修正
 - Fix: ウィジェットのジョブキューにて音声の発音方法変更に追従できていなかったのを修正 #12367
 - Fix: コードエディタが正しく表示されない問題を修正
@@ -243,7 +244,6 @@
 ### Client
 - Enhance: TLの返信表示オプションを記憶するように
 - Enhance: 投稿されてから時間が経過しているノートであることを視覚的に分かりやすく
-- Feat: 絵文字ピッカーのカテゴリに「/」を入れることでフォルダ分け表示できるように
 
 ### Server
 - Enhance: タイムライン取得時のパフォーマンスを向上