enhance: make active email validation configurable
This commit is contained in:
		
							parent
							
								
									522ddba3d7
								
							
						
					
					
						commit
						75d516011b
					
				
					 8 changed files with 61 additions and 8 deletions
				
			
		|  | @ -9,6 +9,13 @@ | ||||||
| You should also include the user name that made the change. | 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) | ## 12.112.2 (2022/07/08) | ||||||
| 
 | 
 | ||||||
| ### Bugfixes | ### Bugfixes | ||||||
|  |  | ||||||
|  | @ -886,6 +886,7 @@ cannotUploadBecauseNoFreeSpace: "ドライブの空き容量が無いためア | ||||||
| beta: "ベータ" | beta: "ベータ" | ||||||
| enableAutoSensitive: "自動NSFW判定" | enableAutoSensitive: "自動NSFW判定" | ||||||
| enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにNSFWフラグを設定します。この機能をオフにしても、インスタンスによっては自動で設定されることがあります。" | enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにNSFWフラグを設定します。この機能をオフにしても、インスタンスによっては自動で設定されることがあります。" | ||||||
|  | activeEmailValidationDescription: "ユーザーのメールアドレスのバリデーションを、捨てアドかどうかや実際に通信可能かどうかなどを判定しより積極的に行います。オフにすると単に文字列として正しいかどうかのみチェックされます。" | ||||||
| 
 | 
 | ||||||
| _sensitiveMediaDetection: | _sensitiveMediaDetection: | ||||||
|   description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てることができます。サーバーの負荷が少し増えます。" |   description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てることができます。サーバーの負荷が少し増えます。" | ||||||
|  |  | ||||||
|  | @ -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"`); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -454,4 +454,9 @@ export class Meta { | ||||||
| 		default: false, | 		default: false, | ||||||
| 	}) | 	}) | ||||||
| 	public enableIpLogging: boolean; | 	public enableIpLogging: boolean; | ||||||
|  | 
 | ||||||
|  | 	@Column('boolean', { | ||||||
|  | 		default: true, | ||||||
|  | 	}) | ||||||
|  | 	public enableActiveEmailValidation: boolean; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -324,6 +324,10 @@ export const meta = { | ||||||
| 				type: 'boolean', | 				type: 'boolean', | ||||||
| 				optional: true, nullable: false, | 				optional: true, nullable: false, | ||||||
| 			}, | 			}, | ||||||
|  | 			enableActiveEmailValidation: { | ||||||
|  | 				type: 'boolean', | ||||||
|  | 				optional: true, nullable: false, | ||||||
|  | 			}, | ||||||
| 		}, | 		}, | ||||||
| 	}, | 	}, | ||||||
| } as const; | } as const; | ||||||
|  | @ -421,5 +425,6 @@ export default define(meta, paramDef, async (ps, me) => { | ||||||
| 		deeplAuthKey: instance.deeplAuthKey, | 		deeplAuthKey: instance.deeplAuthKey, | ||||||
| 		deeplIsPro: instance.deeplIsPro, | 		deeplIsPro: instance.deeplIsPro, | ||||||
| 		enableIpLogging: instance.enableIpLogging, | 		enableIpLogging: instance.enableIpLogging, | ||||||
|  | 		enableActiveEmailValidation: instance.enableActiveEmailValidation, | ||||||
| 	}; | 	}; | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -101,6 +101,7 @@ export const paramDef = { | ||||||
| 		objectStorageSetPublicRead: { type: 'boolean' }, | 		objectStorageSetPublicRead: { type: 'boolean' }, | ||||||
| 		objectStorageS3ForcePathStyle: { type: 'boolean' }, | 		objectStorageS3ForcePathStyle: { type: 'boolean' }, | ||||||
| 		enableIpLogging: { type: 'boolean' }, | 		enableIpLogging: { type: 'boolean' }, | ||||||
|  | 		enableActiveEmailValidation: { type: 'boolean' }, | ||||||
| 	}, | 	}, | ||||||
| 	required: [], | 	required: [], | ||||||
| } as const; | } as const; | ||||||
|  | @ -421,6 +422,10 @@ export default define(meta, paramDef, async (ps, me) => { | ||||||
| 		set.enableIpLogging = ps.enableIpLogging; | 		set.enableIpLogging = ps.enableIpLogging; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (ps.enableActiveEmailValidation !== undefined) { | ||||||
|  | 		set.enableActiveEmailValidation = ps.enableActiveEmailValidation; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	await db.transaction(async transactionalEntityManager => { | 	await db.transaction(async transactionalEntityManager => { | ||||||
| 		const metas = await transactionalEntityManager.find(Meta, { | 		const metas = await transactionalEntityManager.find(Meta, { | ||||||
| 			order: { | 			order: { | ||||||
|  |  | ||||||
|  | @ -1,34 +1,37 @@ | ||||||
| import { validate as validateEmail } from 'deep-email-validator'; | import { validate as validateEmail } from 'deep-email-validator'; | ||||||
| import { UserProfiles } from '@/models/index.js'; | import { UserProfiles } from '@/models/index.js'; | ||||||
|  | import { fetchMeta } from '@/misc/fetch-meta.js'; | ||||||
| 
 | 
 | ||||||
| export async function validateEmailForAccount(emailAddress: string): Promise<{ | export async function validateEmailForAccount(emailAddress: string): Promise<{ | ||||||
| 	available: boolean; | 	available: boolean; | ||||||
| 	reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp'; | 	reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp'; | ||||||
| }> { | }> { | ||||||
|  | 	const meta = await fetchMeta(); | ||||||
|  | 
 | ||||||
| 	const exist = await UserProfiles.countBy({ | 	const exist = await UserProfiles.countBy({ | ||||||
| 		emailVerified: true, | 		emailVerified: true, | ||||||
| 		email: emailAddress, | 		email: emailAddress, | ||||||
| 	}); | 	}); | ||||||
| 
 | 
 | ||||||
| 	const validated = await validateEmail({ | 	const validated = meta.enableActiveEmailValidation ? await validateEmail({ | ||||||
| 		email: emailAddress, | 		email: emailAddress, | ||||||
| 		validateRegex: true, | 		validateRegex: true, | ||||||
| 		validateMx: true, | 		validateMx: true, | ||||||
| 		validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
 | 		validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
 | ||||||
| 		validateDisposable: true, // 捨てアドかどうかチェック
 | 		validateDisposable: true, // 捨てアドかどうかチェック
 | ||||||
| 		validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
 | 		validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
 | ||||||
| 	}); | 	}) : { valid: true }; | ||||||
| 
 | 
 | ||||||
| 	const available = exist === 0 && validated.valid; | 	const available = exist === 0 && validated.valid; | ||||||
| 
 | 
 | ||||||
| 	return { | 	return { | ||||||
| 		available, | 		available, | ||||||
| 		reason: available ? null : | 		reason: available ? null : | ||||||
| 			exist !== 0 ? 'used' : | 		exist !== 0 ? 'used' : | ||||||
| 			validated.reason === 'regex' ? 'format' : | 		validated.reason === 'regex' ? 'format' : | ||||||
| 			validated.reason === 'disposable' ? 'disposable' : | 		validated.reason === 'disposable' ? 'disposable' : | ||||||
| 			validated.reason === 'mx' ? 'mx' : | 		validated.reason === 'mx' ? 'mx' : | ||||||
| 			validated.reason === 'smtp' ? 'smtp' : | 		validated.reason === 'smtp' ? 'smtp' : | ||||||
| 			null, | 		null, | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -57,6 +57,19 @@ | ||||||
| 					</div> | 					</div> | ||||||
| 				</FormFolder> | 				</FormFolder> | ||||||
| 
 | 
 | ||||||
|  | 				<FormFolder class="_formBlock"> | ||||||
|  | 					<template #label>Active Email Validation</template> | ||||||
|  | 					<template v-if="enableActiveEmailValidation" #suffix>Enabled</template> | ||||||
|  | 					<template v-else #suffix>Disabled</template> | ||||||
|  | 
 | ||||||
|  | 					<div class="_formRoot"> | ||||||
|  | 						<span class="_formBlock">{{ i18n.ts.activeEmailValidationDescription }}</span> | ||||||
|  | 						<FormSwitch v-model="enableActiveEmailValidation" class="_formBlock" @update:modelValue="save"> | ||||||
|  | 							<template #label>Enable</template> | ||||||
|  | 						</FormSwitch> | ||||||
|  | 					</div> | ||||||
|  | 				</FormFolder> | ||||||
|  | 
 | ||||||
| 				<FormFolder class="_formBlock"> | 				<FormFolder class="_formBlock"> | ||||||
| 					<template #label>Log IP address</template> | 					<template #label>Log IP address</template> | ||||||
| 					<template v-if="enableIpLogging" #suffix>Enabled</template> | 					<template v-if="enableIpLogging" #suffix>Enabled</template> | ||||||
|  | @ -112,6 +125,7 @@ let sensitiveMediaDetectionSensitivity: number = $ref(0); | ||||||
| let setSensitiveFlagAutomatically: boolean = $ref(false); | let setSensitiveFlagAutomatically: boolean = $ref(false); | ||||||
| let enableSensitiveMediaDetectionForVideos: boolean = $ref(false); | let enableSensitiveMediaDetectionForVideos: boolean = $ref(false); | ||||||
| let enableIpLogging: boolean = $ref(false); | let enableIpLogging: boolean = $ref(false); | ||||||
|  | let enableActiveEmailValidation: boolean = $ref(false); | ||||||
| 
 | 
 | ||||||
| async function init() { | async function init() { | ||||||
| 	const meta = await os.api('admin/meta'); | 	const meta = await os.api('admin/meta'); | ||||||
|  | @ -128,6 +142,7 @@ async function init() { | ||||||
| 	setSensitiveFlagAutomatically = meta.setSensitiveFlagAutomatically; | 	setSensitiveFlagAutomatically = meta.setSensitiveFlagAutomatically; | ||||||
| 	enableSensitiveMediaDetectionForVideos = meta.enableSensitiveMediaDetectionForVideos; | 	enableSensitiveMediaDetectionForVideos = meta.enableSensitiveMediaDetectionForVideos; | ||||||
| 	enableIpLogging = meta.enableIpLogging; | 	enableIpLogging = meta.enableIpLogging; | ||||||
|  | 	enableActiveEmailValidation = meta.enableActiveEmailValidation; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function save() { | function save() { | ||||||
|  | @ -144,6 +159,7 @@ function save() { | ||||||
| 		setSensitiveFlagAutomatically, | 		setSensitiveFlagAutomatically, | ||||||
| 		enableSensitiveMediaDetectionForVideos, | 		enableSensitiveMediaDetectionForVideos, | ||||||
| 		enableIpLogging, | 		enableIpLogging, | ||||||
|  | 		enableActiveEmailValidation, | ||||||
| 	}).then(() => { | 	}).then(() => { | ||||||
| 		fetchInstance(); | 		fetchInstance(); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue