Enhance verification system with multi-provider support and alt-account detection
- Added support for multiple captcha providers including Google reCAPTCHA (v2 and v3), hCaptcha, and Cloudflare Turnstile. - Introduced new fields in the verification configuration for selecting captcha providers and enabling alt-account detection. - Implemented logic to handle verification attempts and flag potential alt accounts based on IP and invite code analysis. - Updated environment configuration to include necessary keys for captcha providers. - Enhanced the user interface to allow selection of captcha providers in the verification setup. - Improved backend handling of verification records to store additional data related to captcha provider usage.
This commit is contained in:
@@ -259,6 +259,10 @@ export const commandLocales = {
|
||||
de: 'Verifizierungsmodus',
|
||||
en: 'Verification mode'
|
||||
},
|
||||
'verify.setup.options.captcha_provider': {
|
||||
de: 'Captcha-Anbieter (nur bei Captcha-Modus)',
|
||||
en: 'Captcha provider (captcha mode only)'
|
||||
},
|
||||
'verify.setup.options.min_account_age_days': {
|
||||
de: 'Mindest-Accountalter in Tagen',
|
||||
en: 'Minimum account age in days'
|
||||
@@ -267,6 +271,10 @@ export const commandLocales = {
|
||||
de: 'Aktion bei Fehlschlag',
|
||||
en: 'Action on failure'
|
||||
},
|
||||
'verify.setup.options.alt_detection': {
|
||||
de: 'Alt-Account-Erkennung aktivieren',
|
||||
en: 'Enable alt-account detection'
|
||||
},
|
||||
'verify.panel.description': {
|
||||
de: 'Verifizierungs-Panel posten',
|
||||
en: 'Post verification panel'
|
||||
|
||||
@@ -235,6 +235,13 @@ export type WelcomeConfigDashboardPatch = z.infer<typeof WelcomeConfigDashboardP
|
||||
|
||||
export const VerificationModeDashboardSchema = z.enum(['BUTTON', 'CAPTCHA']);
|
||||
export const VerificationFailActionDashboardSchema = z.enum(['KICK', 'BAN', 'NONE']);
|
||||
export const CaptchaProviderDashboardSchema = z.enum([
|
||||
'MATH',
|
||||
'RECAPTCHA_V2',
|
||||
'RECAPTCHA_V3',
|
||||
'HCAPTCHA',
|
||||
'TURNSTILE'
|
||||
]);
|
||||
|
||||
export const VerificationConfigDashboardSchema = z.object({
|
||||
enabled: z.boolean(),
|
||||
@@ -242,8 +249,14 @@ export const VerificationConfigDashboardSchema = z.object({
|
||||
verifiedRoleId: OptionalSnowflakeSchema,
|
||||
unverifiedRoleId: OptionalSnowflakeSchema,
|
||||
mode: VerificationModeDashboardSchema,
|
||||
captchaProvider: CaptchaProviderDashboardSchema,
|
||||
minAccountAgeDays: z.number().int().nonnegative(),
|
||||
failAction: VerificationFailActionDashboardSchema
|
||||
failAction: VerificationFailActionDashboardSchema,
|
||||
altDetectionEnabled: z.boolean(),
|
||||
altBlockOnMatch: z.boolean(),
|
||||
altIpWindowDays: z.number().int().min(1).max(365),
|
||||
altInviteWindowHours: z.number().int().min(1).max(720),
|
||||
altMaxAccountsPerInvite: z.number().int().min(1).max(50)
|
||||
});
|
||||
export type VerificationConfigDashboard = z.infer<typeof VerificationConfigDashboardSchema>;
|
||||
|
||||
|
||||
@@ -186,6 +186,8 @@ const de: Dictionary = {
|
||||
'verification.error.account_too_young': 'Dein Account ist zu jung für die Verifizierung.',
|
||||
'verification.error.missing_permissions': 'Dem Bot fehlen Berechtigungen.',
|
||||
'verification.error.invalid_role': 'Die Verifizierungsrolle ist ungültig.',
|
||||
'verification.error.alt_detected':
|
||||
'Verifizierung abgelehnt: möglicher Zweitaccount erkannt.',
|
||||
'verification.error.generic': 'Verifizierung fehlgeschlagen.',
|
||||
'verification.captcha.success': 'Captcha bestanden. Du wurdest verifiziert.',
|
||||
'verification.captcha.invalid': 'Captcha ungültig oder abgelaufen.',
|
||||
@@ -769,6 +771,8 @@ const en: Dictionary = {
|
||||
'verification.error.account_too_young': 'Your account is too young to verify.',
|
||||
'verification.error.missing_permissions': 'Bot lacks permissions.',
|
||||
'verification.error.invalid_role': 'Verification role is invalid.',
|
||||
'verification.error.alt_detected':
|
||||
'Verification denied: possible alternate account detected.',
|
||||
'verification.error.generic': 'Verification failed.',
|
||||
'verification.captcha.success': 'Captcha passed. You have been verified.',
|
||||
'verification.captcha.invalid': 'Captcha invalid or expired.',
|
||||
|
||||
@@ -207,13 +207,28 @@ export type VerificationMode = z.infer<typeof VerificationModeSchema>;
|
||||
export const VerificationFailActionSchema = z.enum(['KICK', 'BAN', 'NONE']);
|
||||
export type VerificationFailAction = z.infer<typeof VerificationFailActionSchema>;
|
||||
|
||||
export const CaptchaProviderSchema = z.enum([
|
||||
'MATH',
|
||||
'RECAPTCHA_V2',
|
||||
'RECAPTCHA_V3',
|
||||
'HCAPTCHA',
|
||||
'TURNSTILE'
|
||||
]);
|
||||
export type CaptchaProvider = z.infer<typeof CaptchaProviderSchema>;
|
||||
|
||||
export const VerificationSetupSchema = z.object({
|
||||
channel: z.string().min(1),
|
||||
verifiedRole: z.string().min(1),
|
||||
unverifiedRole: z.string().optional(),
|
||||
mode: VerificationModeSchema.default('BUTTON'),
|
||||
captchaProvider: CaptchaProviderSchema.default('MATH'),
|
||||
minAccountAgeDays: z.number().int().nonnegative().default(0),
|
||||
failAction: VerificationFailActionSchema.default('KICK')
|
||||
failAction: VerificationFailActionSchema.default('KICK'),
|
||||
altDetectionEnabled: z.boolean().default(false),
|
||||
altBlockOnMatch: z.boolean().default(true),
|
||||
altIpWindowDays: z.number().int().min(1).max(365).default(30),
|
||||
altInviteWindowHours: z.number().int().min(1).max(720).default(48),
|
||||
altMaxAccountsPerInvite: z.number().int().min(1).max(50).default(3)
|
||||
});
|
||||
export type VerificationSetup = z.infer<typeof VerificationSetupSchema>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user