diff --git a/CHANGELOG.md b/CHANGELOG.md index 8354d72ba6..29f91596c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ You should also include the user name that made the change. --> +## 12.x.x (unreleased) + +### Improvements +- Make active email validation configurable + +### Bugfixes + ## 12.112.2 (2022/07/08) ### Bugfixes diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 3eecc3b576..0e278bead6 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -886,6 +886,7 @@ cannotUploadBecauseNoFreeSpace: "ドライブの空き容量が無いためア beta: "ベータ" enableAutoSensitive: "自動NSFW判定" enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにNSFWフラグを設定します。この機能をオフにしても、インスタンスによっては自動で設定されることがあります。" +activeEmailValidationDescription: "ユーザーのメールアドレスのバリデーションを、捨てアドかどうかや実際に通信可能かどうかなどを判定しより積極的に行います。オフにすると単に文字列として正しいかどうかのみチェックされます。" _sensitiveMediaDetection: description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てることができます。サーバーの負荷が少し増えます。" diff --git a/packages/backend/migration/1657346559800-active-email-validation.js b/packages/backend/migration/1657346559800-active-email-validation.js new file mode 100644 index 0000000000..f8e03eeb07 --- /dev/null +++ b/packages/backend/migration/1657346559800-active-email-validation.js @@ -0,0 +1,11 @@ +export class activeEmailValidation1657346559800 { + name = 'activeEmailValidation1657346559800' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "enableActiveEmailValidation" boolean NOT NULL DEFAULT true`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableActiveEmailValidation"`); + } +} diff --git a/packages/backend/src/models/entities/meta.ts b/packages/backend/src/models/entities/meta.ts index ebc082dfbb..d33ff2519e 100644 --- a/packages/backend/src/models/entities/meta.ts +++ b/packages/backend/src/models/entities/meta.ts @@ -454,4 +454,9 @@ export class Meta { default: false, }) public enableIpLogging: boolean; + + @Column('boolean', { + default: true, + }) + public enableActiveEmailValidation: boolean; } diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index cb50e128af..8746119687 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -324,6 +324,10 @@ export const meta = { type: 'boolean', optional: true, nullable: false, }, + enableActiveEmailValidation: { + type: 'boolean', + optional: true, nullable: false, + }, }, }, } as const; @@ -421,5 +425,6 @@ export default define(meta, paramDef, async (ps, me) => { deeplAuthKey: instance.deeplAuthKey, deeplIsPro: instance.deeplIsPro, enableIpLogging: instance.enableIpLogging, + enableActiveEmailValidation: instance.enableActiveEmailValidation, }; }); 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 cc32e73c53..f14aa41050 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -101,6 +101,7 @@ export const paramDef = { objectStorageSetPublicRead: { type: 'boolean' }, objectStorageS3ForcePathStyle: { type: 'boolean' }, enableIpLogging: { type: 'boolean' }, + enableActiveEmailValidation: { type: 'boolean' }, }, required: [], } as const; @@ -421,6 +422,10 @@ export default define(meta, paramDef, async (ps, me) => { set.enableIpLogging = ps.enableIpLogging; } + if (ps.enableActiveEmailValidation !== undefined) { + set.enableActiveEmailValidation = ps.enableActiveEmailValidation; + } + await db.transaction(async transactionalEntityManager => { const metas = await transactionalEntityManager.find(Meta, { order: { diff --git a/packages/backend/src/services/validate-email-for-account.ts b/packages/backend/src/services/validate-email-for-account.ts index 132168fb31..b5fa99b935 100644 --- a/packages/backend/src/services/validate-email-for-account.ts +++ b/packages/backend/src/services/validate-email-for-account.ts @@ -1,34 +1,37 @@ import { validate as validateEmail } from 'deep-email-validator'; import { UserProfiles } from '@/models/index.js'; +import { fetchMeta } from '@/misc/fetch-meta.js'; export async function validateEmailForAccount(emailAddress: string): Promise<{ available: boolean; reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp'; }> { + const meta = await fetchMeta(); + const exist = await UserProfiles.countBy({ emailVerified: true, email: emailAddress, }); - const validated = await validateEmail({ + const validated = meta.enableActiveEmailValidation ? await validateEmail({ email: emailAddress, validateRegex: true, validateMx: true, validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので validateDisposable: true, // 捨てアドかどうかチェック validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので - }); + }) : { valid: true }; const available = exist === 0 && validated.valid; return { available, reason: available ? null : - exist !== 0 ? 'used' : - validated.reason === 'regex' ? 'format' : - validated.reason === 'disposable' ? 'disposable' : - validated.reason === 'mx' ? 'mx' : - validated.reason === 'smtp' ? 'smtp' : - null, + exist !== 0 ? 'used' : + validated.reason === 'regex' ? 'format' : + validated.reason === 'disposable' ? 'disposable' : + validated.reason === 'mx' ? 'mx' : + validated.reason === 'smtp' ? 'smtp' : + null, }; } diff --git a/packages/client/src/pages/admin/security.vue b/packages/client/src/pages/admin/security.vue index c4a4994bb8..07ee412f3e 100644 --- a/packages/client/src/pages/admin/security.vue +++ b/packages/client/src/pages/admin/security.vue @@ -57,6 +57,19 @@ + + + + + +
+ {{ i18n.ts.activeEmailValidationDescription }} + + + +
+
+ @@ -112,6 +125,7 @@ let sensitiveMediaDetectionSensitivity: number = $ref(0); let setSensitiveFlagAutomatically: boolean = $ref(false); let enableSensitiveMediaDetectionForVideos: boolean = $ref(false); let enableIpLogging: boolean = $ref(false); +let enableActiveEmailValidation: boolean = $ref(false); async function init() { const meta = await os.api('admin/meta'); @@ -128,6 +142,7 @@ async function init() { setSensitiveFlagAutomatically = meta.setSensitiveFlagAutomatically; enableSensitiveMediaDetectionForVideos = meta.enableSensitiveMediaDetectionForVideos; enableIpLogging = meta.enableIpLogging; + enableActiveEmailValidation = meta.enableActiveEmailValidation; } function save() { @@ -144,6 +159,7 @@ function save() { setSensitiveFlagAutomatically, enableSensitiveMediaDetectionForVideos, enableIpLogging, + enableActiveEmailValidation, }).then(() => { fetchInstance(); });