false, 'message' => 'Method not allowed'], 405); } $csrf = $_POST['csrf'] ?? ''; if (!Csrf::validate(is_string($csrf) ? $csrf : null)) { Bootstrap::jsonResponse(['ok' => false, 'message' => 'Ungültiges CSRF-Token.'], 419); } if (trim((string) ($_POST['website'] ?? '')) !== '') { Bootstrap::jsonResponse(['ok' => false, 'message' => 'Anfrage blockiert.'], 400); } $email = strtolower(trim((string) ($_POST['email'] ?? ''))); if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) { Bootstrap::jsonResponse(['ok' => false, 'message' => 'Bitte gültige E-Mail eingeben.'], 422); } $app = Bootstrap::config('app'); $limiter = new RateLimiter(); $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; $rateKey = sprintf('reset:%s:%s', $ip, $email); if (!$limiter->allow($rateKey, (int) $app['rate_limit']['requests'], (int) $app['rate_limit']['window_seconds'])) { Bootstrap::jsonResponse(['ok' => false, 'message' => 'Zu viele Löschanfragen. Bitte später erneut versuchen.'], 429); } $store = new JsonStore(); try { $result = $store->withEmailLock($email, static function () use ($store, $app, $email): array { $hadDraft = $store->getDraft($email) !== null; $submission = $store->getSubmissionByEmail($email); $hadSubmission = $submission !== null; if ($hadSubmission) { return [ 'ok' => false, 'status' => 409, 'message' => 'Für diese E-Mail liegt bereits ein abgeschlossener Antrag vor. Ein Zurücksetzen ist nicht möglich.', 'had_draft' => $hadDraft, 'had_submission' => true, ]; } $store->deleteDraft($email); $uploadDir = rtrim((string) $app['storage']['uploads'], '/') . '/' . $store->emailKey($email); FileSystem::removeTree($uploadDir); return [ 'ok' => true, 'status' => 200, 'had_draft' => $hadDraft, 'had_submission' => $hadSubmission, ]; }); } catch (Throwable $e) { Bootstrap::log('app', 'reset error: ' . $e->getMessage()); Bootstrap::jsonResponse(['ok' => false, 'message' => 'Daten konnten nicht gelöscht werden.'], 500); } if (($result['ok'] ?? false) !== true) { Bootstrap::jsonResponse([ 'ok' => false, 'message' => (string) ($result['message'] ?? 'Daten konnten nicht gelöscht werden.'), 'had_draft' => (bool) ($result['had_draft'] ?? false), 'had_submission' => (bool) ($result['had_submission'] ?? false), ], (int) ($result['status'] ?? 422)); } Bootstrap::jsonResponse([ 'ok' => true, 'message' => 'Gespeicherte Daten wurden gelöscht.', 'had_draft' => (bool) ($result['had_draft'] ?? false), 'had_submission' => (bool) ($result['had_submission'] ?? false), ]);