| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- <?php
- declare(strict_types=1);
- use App\App\Bootstrap;
- use App\Mail\Mailer;
- 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' => 'Ungueltiges 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 gueltige E-Mail eingeben.'], 422);
- }
- $autoStartRaw = strtolower(trim((string) ($_POST['auto_start'] ?? '0')));
- $autoStart = in_array($autoStartRaw, ['1', 'true', 'yes'], true);
- $app = Bootstrap::config('app');
- $limiter = new RateLimiter();
- $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
- $rateKey = sprintf('otp-request:%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 spaeter erneut versuchen.'], 429);
- }
- $formAccess = new FormAccess();
- $request = $formAccess->requestOtp($email, $autoStart);
- if (($request['ok'] ?? false) !== true) {
- Bootstrap::jsonResponse([
- 'ok' => false,
- 'message' => (string) ($request['message'] ?? 'Code konnte nicht angefordert werden.'),
- 'retry_after' => (int) ($request['retry_after'] ?? 0),
- ], (int) ($request['status_code'] ?? 422));
- }
- if (($request['auto_skipped'] ?? false) === true) {
- Bootstrap::jsonResponse([
- 'ok' => true,
- 'auto_skipped' => true,
- 'message' => 'Automatische Code-Anfrage in dieser Sitzung bereits erfolgt.',
- ]);
- }
- $otpCode = (string) ($request['code'] ?? '');
- $ttlSeconds = (int) ($request['expires_in'] ?? $formAccess->otpTtlSeconds());
- $mailer = new Mailer();
- if (!$mailer->sendOtpMail($email, $otpCode, $ttlSeconds)) {
- $formAccess->clearPendingOtp();
- Bootstrap::jsonResponse([
- 'ok' => false,
- 'message' => 'Code konnte nicht per E-Mail gesendet werden. Bitte spaeter erneut versuchen.',
- ], 500);
- }
- Bootstrap::jsonResponse([
- 'ok' => true,
- 'message' => 'Sicherheitscode wurde per E-Mail versendet.',
- 'expires_in' => $ttlSeconds,
- 'resend_available_in' => (int) ($request['cooldown_seconds'] ?? $formAccess->resendCooldownSeconds()),
- ]);
|