true, 'time' => date('c'), 'app' => 'SoftEdge API', 'env' => \SoftEdge\Env::get('APP_ENV', 'production'), ]); break; case $method === 'POST' && $route === '/auth/login': $body = json_body(); $csrf = (string)($body['csrf'] ?? ($_SERVER['HTTP_X_CSRF_TOKEN'] ?? '')); if (!\SoftEdge\Csrf::validate($csrf)) { Response::json(['ok' => false, 'error' => 'CSRF inválido'], 400); break; } $email = trim((string)($body['email'] ?? '')); $password = (string)($body['password'] ?? ''); if (!Validation::email($email)) { Response::json(['ok' => false, 'error' => 'Email inválido'], 422); break; } $res = AuthService::login($email, $password); Response::json($res, (int)($res['status'] ?? 200)); break; case $method === 'POST' && $route === '/auth/logout': AuthService::logout(); Response::json(['ok' => true]); break; case $method === 'POST' && $route === '/contact': $body = json_body(); $csrf = (string)($body['csrf'] ?? ($_SERVER['HTTP_X_CSRF_TOKEN'] ?? '')); if (!\SoftEdge\Csrf::validate($csrf)) { Response::json(['ok' => false, 'error' => 'CSRF inválido'], 400); break; } $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; if (!RateLimiter::allow('contact:' . $ip, \SoftEdge\Env::int('RATE_LIMIT_CONTACT', 3), 3600)) { Response::json(['ok' => false, 'error' => 'Muitas solicitações. Tente mais tarde.'], 429); break; } $name = trim((string)($body['name'] ?? '')); $email = trim((string)($body['email'] ?? '')); $message = trim((string)($body['message'] ?? '')); $phone = trim((string)($body['phone'] ?? '')); $company = trim((string)($body['company'] ?? '')); $subject = trim((string)($body['subject'] ?? '')); $errors = Validation::required(['name' => $name, 'email' => $email, 'message' => $message], ['name','email','message']); if (!empty($errors) || !Validation::email($email)) { $errors['email'] = $errors['email'] ?? (!Validation::email($email) ? 'Email inválido' : null); Response::json(['ok' => false, 'errors' => array_filter($errors)], 422); break; } $pdo = DB::pdo(); $stmt = $pdo->prepare('INSERT INTO contact_submissions (name, email, phone, company, subject, message, status) VALUES (:name,:email,:phone,:company,:subject,:message,\'new\')'); $stmt->execute([ ':name' => $name, ':email' => $email, ':phone' => $phone ?: null, ':company' => $company ?: null, ':subject' => $subject ?: null, ':message' => $message, ]); Response::json(['ok' => true, 'id' => (int)$pdo->lastInsertId()], 201); break; default: Response::json(['ok' => false, 'error' => 'Rota não encontrada', 'route' => $route], 404); break; } } catch (Throwable $e) { Response::json([ 'ok' => false, 'error' => 'Erro interno', ], 500); }