| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- <?php
- declare(strict_types=1);
- use App\App\Bootstrap;
- use App\Security\Csrf;
- use App\Security\RateLimiter;
- use App\Storage\FileSystem;
- use App\Storage\JsonStore;
- require dirname(__DIR__) . '/src/autoload.php';
- Bootstrap::init();
- if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
- Bootstrap::jsonResponse([
- 'ok' => false,
- 'message' => Bootstrap::appMessage('common.method_not_allowed'),
- ], 405);
- }
- $csrf = $_POST['csrf'] ?? '';
- if (!Csrf::validate(is_string($csrf) ? $csrf : null)) {
- Bootstrap::jsonResponse([
- 'ok' => false,
- 'message' => Bootstrap::appMessage('common.invalid_csrf'),
- ], 419);
- }
- if (trim((string) ($_POST['website'] ?? '')) !== '') {
- Bootstrap::jsonResponse([
- 'ok' => false,
- 'message' => Bootstrap::appMessage('common.request_blocked'),
- ], 400);
- }
- $email = strtolower(trim((string) ($_POST['email'] ?? '')));
- if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
- Bootstrap::jsonResponse([
- 'ok' => false,
- 'message' => Bootstrap::appMessage('common.invalid_email'),
- ], 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' => Bootstrap::appMessage('reset.rate_limited'),
- ], 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' => Bootstrap::appMessage('reset.already_submitted'),
- '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' => Bootstrap::appMessage('reset.delete_error'),
- ], 500);
- }
- if (($result['ok'] ?? false) !== true) {
- Bootstrap::jsonResponse([
- 'ok' => false,
- 'message' => (string) ($result['message'] ?? Bootstrap::appMessage('reset.delete_error')),
- 'had_draft' => (bool) ($result['had_draft'] ?? false),
- 'had_submission' => (bool) ($result['had_submission'] ?? false),
- ], (int) ($result['status'] ?? 422));
- }
- Bootstrap::jsonResponse([
- 'ok' => true,
- 'message' => Bootstrap::appMessage('reset.success'),
- 'had_draft' => (bool) ($result['had_draft'] ?? false),
- 'had_submission' => (bool) ($result['had_submission'] ?? false),
- ]);
|