feat(auth): Integrate Cloudflare Turnstile bot protection and enhance swarm tracking
- Add Cloudflare Turnstile integration for login and registration forms - Create turnstile verification utility with server-side token validation - Add turnstile_site_key and turnstile_secret_key fields to nodes table - Implement admin panel UI for configuring Turnstile keys in settings - Update login and register API routes to verify Turnstile tokens - Expose turnstile_site_key via GET /api/node endpoint for frontend - Add admin endpoint to save and update Turnstile configuration - Create remote_likes and remote_reposts tables for federated interaction tracking - Add swarm reply metadata fields (swarm_reply_to_id, swarm_reply_to_content, swarm_reply_to_author) to posts table - Add comprehensive TURNSTILE_SETUP.md documentation with setup instructions and security notes - Create database migration 0007 with schema updates and indexes - Protects against bot registrations and automated attacks on federated nodes
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authenticateUser, createSession } from '@/lib/auth';
|
||||
import { verifyTurnstileToken } from '@/lib/turnstile';
|
||||
import { z } from 'zod';
|
||||
|
||||
const loginSchema = z.object({
|
||||
email: z.string().email(),
|
||||
password: z.string(),
|
||||
turnstileToken: z.string().optional(),
|
||||
});
|
||||
|
||||
export async function POST(request: Request) {
|
||||
@@ -12,6 +14,18 @@ export async function POST(request: Request) {
|
||||
const body = await request.json();
|
||||
const data = loginSchema.parse(body);
|
||||
|
||||
// Verify Turnstile token if provided
|
||||
if (data.turnstileToken) {
|
||||
const ip = request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || undefined;
|
||||
const isValid = await verifyTurnstileToken(data.turnstileToken, ip);
|
||||
if (!isValid) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Bot verification failed. Please try again.' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const user = await authenticateUser(data.email, data.password);
|
||||
|
||||
// Create session
|
||||
|
||||
@@ -2,6 +2,7 @@ import { NextResponse } from 'next/server';
|
||||
import { registerUser, createSession } from '@/lib/auth';
|
||||
import { db, nodes, users } from '@/db';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { verifyTurnstileToken } from '@/lib/turnstile';
|
||||
import { z } from 'zod';
|
||||
|
||||
const registerSchema = z.object({
|
||||
@@ -9,6 +10,7 @@ const registerSchema = z.object({
|
||||
email: z.string().email(),
|
||||
password: z.string().min(8),
|
||||
displayName: z.string().optional(),
|
||||
turnstileToken: z.string().optional(),
|
||||
});
|
||||
|
||||
export async function POST(request: Request) {
|
||||
@@ -16,6 +18,18 @@ export async function POST(request: Request) {
|
||||
const body = await request.json();
|
||||
const data = registerSchema.parse(body);
|
||||
|
||||
// Verify Turnstile token if provided
|
||||
if (data.turnstileToken) {
|
||||
const ip = request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || undefined;
|
||||
const isValid = await verifyTurnstileToken(data.turnstileToken, ip);
|
||||
if (!isValid) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Bot verification failed. Please try again.' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const user = await registerUser(
|
||||
data.handle,
|
||||
data.email,
|
||||
|
||||
Reference in New Issue
Block a user