refactor: remove obsolete member management API module
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
emailSchema,
|
||||
requiredString,
|
||||
} from '@kit/next/route-helpers';
|
||||
import { checkRateLimit, getClientIp } from '@kit/next/routes/rate-limit';
|
||||
import { getLogger } from '@kit/shared/logger';
|
||||
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
|
||||
|
||||
@@ -20,12 +21,33 @@ const MembershipApplySchema = z.object({
|
||||
city: z.string().optional(),
|
||||
dateOfBirth: z.string().optional(),
|
||||
message: z.string().optional(),
|
||||
captchaToken: z.string().optional(),
|
||||
});
|
||||
|
||||
// Rate limits
|
||||
const MAX_PER_IP = 5;
|
||||
const MAX_PER_ACCOUNT = 20;
|
||||
const WINDOW_MS = 60 * 60 * 1000; // 1 hour
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const logger = await getLogger();
|
||||
|
||||
try {
|
||||
// Rate limit by IP
|
||||
const ip = getClientIp(request);
|
||||
const ipLimit = checkRateLimit(
|
||||
`membership-apply:ip:${ip}`,
|
||||
MAX_PER_IP,
|
||||
WINDOW_MS,
|
||||
);
|
||||
|
||||
if (!ipLimit.allowed) {
|
||||
return apiError(
|
||||
'Zu viele Anfragen. Bitte versuchen Sie es später erneut.',
|
||||
429,
|
||||
);
|
||||
}
|
||||
|
||||
const body = await request.json();
|
||||
const parsed = MembershipApplySchema.safeParse(body);
|
||||
|
||||
@@ -44,10 +66,48 @@ export async function POST(request: Request) {
|
||||
city,
|
||||
dateOfBirth,
|
||||
message,
|
||||
captchaToken,
|
||||
} = parsed.data;
|
||||
|
||||
// Rate limit by account
|
||||
const accountLimit = checkRateLimit(
|
||||
`membership-apply:account:${accountId}`,
|
||||
MAX_PER_ACCOUNT,
|
||||
WINDOW_MS,
|
||||
);
|
||||
|
||||
if (!accountLimit.allowed) {
|
||||
return apiError('Zu viele Bewerbungen für diese Organisation.', 429);
|
||||
}
|
||||
|
||||
// Verify CAPTCHA when configured — token is required, not optional
|
||||
if (process.env.CAPTCHA_SECRET_TOKEN) {
|
||||
if (!captchaToken) {
|
||||
return apiError('CAPTCHA-Überprüfung erforderlich.', 400);
|
||||
}
|
||||
|
||||
const { verifyCaptchaToken } = await import('@kit/auth/captcha/server');
|
||||
|
||||
try {
|
||||
await verifyCaptchaToken(captchaToken);
|
||||
} catch {
|
||||
return apiError('CAPTCHA-Überprüfung fehlgeschlagen.', 400);
|
||||
}
|
||||
}
|
||||
|
||||
const supabase = getSupabaseServerAdminClient();
|
||||
|
||||
// Validate that the account exists before inserting
|
||||
const { data: account } = await supabase
|
||||
.from('accounts')
|
||||
.select('id')
|
||||
.eq('id', accountId)
|
||||
.single();
|
||||
|
||||
if (!account) {
|
||||
return apiError('Ungültige Organisation.', 400);
|
||||
}
|
||||
|
||||
const { error } = await supabase.from('membership_applications').insert({
|
||||
account_id: accountId,
|
||||
first_name: firstName,
|
||||
|
||||
Reference in New Issue
Block a user