| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- <?php
- declare(strict_types=1);
- use App\App\Bootstrap;
- use App\Storage\JsonStore;
- use App\Security\Csrf;
- use App\Security\FormAccess;
- use App\Security\RateLimiter;
- require dirname(__DIR__) . '/src/autoload.php';
- Bootstrap::init();
- if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
- Bootstrap::jsonResponse(['ok' => 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);
- }
- $honeypot = trim((string) ($_POST['website'] ?? ''));
- if ($honeypot !== '') {
- 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);
- }
- $activityRaw = $_POST['last_user_activity_at'] ?? null;
- $lastUserActivityAt = is_scalar($activityRaw) ? (int) $activityRaw : null;
- $formAccess = new FormAccess();
- $auth = $formAccess->assertVerifiedForEmail($email, $lastUserActivityAt);
- if (($auth['ok'] ?? false) !== true) {
- $reason = (string) ($auth['reason'] ?? '');
- Bootstrap::jsonResponse([
- 'ok' => false,
- 'message' => (string) ($auth['message'] ?? 'Bitte E-Mail erneut verifizieren.'),
- 'auth_required' => $reason === 'auth_required',
- 'auth_expired' => $reason === 'auth_expired',
- ], (int) ($auth['status_code'] ?? 401));
- }
- $app = Bootstrap::config('app');
- $limiter = new RateLimiter();
- $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
- $rateKey = sprintf('load:%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 Anfragen. Bitte später erneut versuchen.'], 429);
- }
- $store = new JsonStore();
- $submission = $store->getSubmissionByEmail($email);
- if ($submission !== null) {
- Bootstrap::jsonResponse([
- 'ok' => true,
- 'already_submitted' => true,
- 'message' => 'Für diese E-Mail liegt bereits ein abgeschlossener Antrag vor.',
- ]);
- }
- $draft = $store->getDraft($email);
- Bootstrap::jsonResponse([
- 'ok' => true,
- 'already_submitted' => false,
- 'data' => $draft['form_data'] ?? [],
- 'uploads' => $draft['uploads'] ?? [],
- 'step' => $draft['step'] ?? 1,
- 'updated_at' => $draft['updated_at'] ?? null,
- ]);
|