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:
@@ -1,6 +1,7 @@
|
||||
import type { VerificationConfigDashboard, VerificationConfigDashboardPatch } from '@nexumi/shared';
|
||||
import type { CaptchaProvider, VerificationConfigDashboard, VerificationConfigDashboardPatch } from '@nexumi/shared';
|
||||
import type { Prisma } from '@prisma/client';
|
||||
import { prisma } from '../prisma';
|
||||
import { getAvailableCaptchaProviders } from '../captcha';
|
||||
|
||||
async function ensureVerificationConfig(guildId: string) {
|
||||
await prisma.guild.upsert({ where: { id: guildId }, update: {}, create: { id: guildId } });
|
||||
@@ -11,21 +12,39 @@ async function ensureVerificationConfig(guildId: string) {
|
||||
});
|
||||
}
|
||||
|
||||
function toDashboard(config: Awaited<ReturnType<typeof ensureVerificationConfig>>): VerificationConfigDashboard {
|
||||
function toDashboard(
|
||||
config: Awaited<ReturnType<typeof ensureVerificationConfig>>,
|
||||
available: CaptchaProvider[]
|
||||
): VerificationConfigDashboard {
|
||||
const rawProvider = (config.captchaProvider as CaptchaProvider) ?? 'MATH';
|
||||
const captchaProvider = available.includes(rawProvider) ? rawProvider : 'MATH';
|
||||
return {
|
||||
enabled: config.enabled,
|
||||
channelId: config.channelId ?? '',
|
||||
verifiedRoleId: config.verifiedRoleId ?? '',
|
||||
unverifiedRoleId: config.unverifiedRoleId ?? '',
|
||||
mode: config.mode as VerificationConfigDashboard['mode'],
|
||||
captchaProvider,
|
||||
minAccountAgeDays: config.minAccountAgeDays,
|
||||
failAction: config.failAction as VerificationConfigDashboard['failAction']
|
||||
failAction: config.failAction as VerificationConfigDashboard['failAction'],
|
||||
altDetectionEnabled: config.altDetectionEnabled,
|
||||
altBlockOnMatch: config.altBlockOnMatch,
|
||||
altIpWindowDays: config.altIpWindowDays,
|
||||
altInviteWindowHours: config.altInviteWindowHours,
|
||||
altMaxAccountsPerInvite: config.altMaxAccountsPerInvite
|
||||
};
|
||||
}
|
||||
|
||||
export async function getVerificationDashboard(guildId: string): Promise<VerificationConfigDashboard> {
|
||||
export async function getVerificationDashboard(guildId: string): Promise<{
|
||||
config: VerificationConfigDashboard;
|
||||
availableCaptchaProviders: CaptchaProvider[];
|
||||
}> {
|
||||
const config = await ensureVerificationConfig(guildId);
|
||||
return toDashboard(config);
|
||||
const availableCaptchaProviders = getAvailableCaptchaProviders();
|
||||
return {
|
||||
config: toDashboard(config, availableCaptchaProviders),
|
||||
availableCaptchaProviders
|
||||
};
|
||||
}
|
||||
|
||||
export async function updateVerificationDashboard(
|
||||
@@ -34,6 +53,11 @@ export async function updateVerificationDashboard(
|
||||
): Promise<VerificationConfigDashboard> {
|
||||
await ensureVerificationConfig(guildId);
|
||||
|
||||
const available = new Set(getAvailableCaptchaProviders());
|
||||
if (patch.captchaProvider !== undefined && !available.has(patch.captchaProvider)) {
|
||||
throw new Error(`Captcha provider ${patch.captchaProvider} is not configured in .env`);
|
||||
}
|
||||
|
||||
const { channelId, verifiedRoleId, unverifiedRoleId, ...rest } = patch;
|
||||
const data: Prisma.VerificationConfigUpdateInput = { ...rest };
|
||||
if (channelId !== undefined) {
|
||||
@@ -47,5 +71,5 @@ export async function updateVerificationDashboard(
|
||||
}
|
||||
|
||||
const updated = await prisma.verificationConfig.update({ where: { guildId }, data });
|
||||
return toDashboard(updated);
|
||||
return toDashboard(updated, getAvailableCaptchaProviders());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user