request-otp.php 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. <?php
  2. declare(strict_types=1);
  3. use App\App\Bootstrap;
  4. use App\Mail\Mailer;
  5. use App\Security\Csrf;
  6. use App\Security\FormAccess;
  7. require dirname(__DIR__) . '/src/autoload.php';
  8. Bootstrap::init();
  9. if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  10. Bootstrap::jsonResponse(['ok' => false, 'message' => 'Method not allowed'], 405);
  11. }
  12. $csrf = $_POST['csrf'] ?? '';
  13. if (!Csrf::validate(is_string($csrf) ? $csrf : null)) {
  14. Bootstrap::jsonResponse(['ok' => false, 'message' => 'Ungültiges CSRF-Token.'], 419);
  15. }
  16. if (trim((string) ($_POST['website'] ?? '')) !== '') {
  17. Bootstrap::jsonResponse(['ok' => false, 'message' => 'Anfrage blockiert.'], 400);
  18. }
  19. $email = strtolower(trim((string) ($_POST['email'] ?? '')));
  20. if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
  21. Bootstrap::jsonResponse(['ok' => false, 'message' => 'Bitte gültige E-Mail eingeben.'], 422);
  22. }
  23. $autoStartRaw = strtolower(trim((string) ($_POST['auto_start'] ?? '0')));
  24. $autoStart = in_array($autoStartRaw, ['1', 'true', 'yes'], true);
  25. $formAccess = new FormAccess();
  26. $request = $formAccess->requestOtp($email, $autoStart);
  27. if (($request['ok'] ?? false) !== true) {
  28. Bootstrap::jsonResponse([
  29. 'ok' => false,
  30. 'message' => (string) ($request['message'] ?? 'Code konnte nicht angefordert werden.'),
  31. 'retry_after' => (int) ($request['retry_after'] ?? 0),
  32. ], (int) ($request['status_code'] ?? 422));
  33. }
  34. if (($request['auto_skipped'] ?? false) === true) {
  35. Bootstrap::jsonResponse([
  36. 'ok' => true,
  37. 'auto_skipped' => true,
  38. 'message' => 'Automatische Code-Anfrage in dieser Sitzung bereits erfolgt.',
  39. ]);
  40. }
  41. $otpCode = (string) ($request['code'] ?? '');
  42. $ttlSeconds = (int) ($request['expires_in'] ?? $formAccess->otpTtlSeconds());
  43. $mailer = new Mailer();
  44. if (!$mailer->sendOtpMail($email, $otpCode, $ttlSeconds)) {
  45. $formAccess->clearPendingOtp();
  46. Bootstrap::jsonResponse([
  47. 'ok' => false,
  48. 'message' => 'Code konnte nicht per E-Mail gesendet werden. Bitte später erneut versuchen.',
  49. ], 500);
  50. }
  51. Bootstrap::jsonResponse([
  52. 'ok' => true,
  53. 'message' => 'Sicherheitscode wurde per E-Mail versendet.',
  54. 'expires_in' => $ttlSeconds,
  55. 'resend_available_in' => (int) ($request['cooldown_seconds'] ?? $formAccess->resendCooldownSeconds()),
  56. ]);