# Changelog All notable changes to Jambo API are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). --- ## [1.26.210] — 2026-11-06 ### Form Submissions Batch Operations, Status Filtering, CSV Export & UI Hardening (Cycle #140) - **Batch Operations for Form Submissions (`src/Controller/Admin/FormController.php`, `src/Repository/FormSubmissionRepository.php`)**: - Implemented `admin_forms_submissions_batch` endpoint (`POST /admin-api/{projectUuid}/forms/{id}/submissions/batch`) supporting bulk operations: `mark_read`, `mark_unread`, `mark_spam`, `mark_ham`, and `delete`. - Enforced security limits (500 items max per batch request, rate limiting, and project permission checks `project.manage`). - Added dedicated bulk repository methods in `FormSubmissionRepository`: `batchMarkRead()`, `batchMarkSpam()`, and `batchDelete()`. - Integrated audit trail logging via `AuditService::log()` (`admin_form_submissions_batch`) for complete enterprise traceability. - **Read/Unread Status Filtering & CSV Export Expansion (`src/Controller/Admin/FormController.php`, `src/Repository/FormSubmissionRepository.php`)**: - Enhanced `admin_forms_submissions` with `read` query parameter (`read`, `unread`, or all), updating `countByForm()` and `findPaginatedByForm()`. - Enhanced `admin_forms_submissions_export_csv` with combined `read` and `spam` filtering, enabling targeted CSV exports with full spreadsheet formula injection sanitization. - **Administrative Interface Hardening & Full I18N Compliance (`assets/js/pages/Projects/Forms/Index.tsx`)**: - Replaced hardcoded strings with comprehensive i18n translation keys. - Added multi-select checkbox controls with bulk action bar (mark as read/unread, mark as valid/spam, batch delete). - Added direct CSV export button in the submissions modal preserving active filter state. - Added interactive filter tabs (All, Unread, Read, Valid, Spam) and pagination controls (Previous/Next page with total indicator). - **Strict I18N Parity Across 4 Languages (`translations/messages.{en,fr,es,ar}.php`)**: - Added 23 new translation keys across English, French, Spanish, and Arabic dictionaries, strictly maintaining 3,855 key parity across all four locales. - **Automated Test Suite Expansion (`tests/Controller/Admin/FormControllerBatchSubmissionsTest.php`)**: - Added 6 end-to-end integration tests covering status filtering, batch read/unread updates, batch spam/ham toggling, batch deletions, validation constraints, and filtered CSV export. ## [1.26.209] — 2026-11-06 ### Form Submission Event Architecture, Realtime Mercure Broadcast & SSRF-Protected Webhooks (Cycle #139) - **Form Submission Event & Subscriber Architecture (`src/Event/FormSubmittedEvent.php`, `src/EventSubscriber/FormSubmissionSubscriber.php`, `src/Service/Form/SubmitHandler.php`)**: - Implemented decoupled `FormSubmittedEvent` triggered upon successful validation and persistence of valid (non-spam) form submissions. - Implemented `FormSubmissionSubscriber` subscribing to `FormSubmittedEvent::SUBMITTED`, centralizing post-submit operations including realtime streaming, member notifications, and webhook forwarding. - **Realtime Mercure Form Streaming (`src/Service/MercurePublisher.php`, `assets/js/hooks/useRealtime.ts`)**: - Added `MercurePublisher::formSubmitted()`, broadcasting submission events across `projects/{uuid}/forms` and `projects/{uuid}/forms/{formSlug}` topics, with automated fallback to JSONL log rotation when Mercure Hub is offline. - Extended frontend `useRealtime` hook with `form.submitted` toast handling. - **SSRF-Protected Outbound Form Webhooks (`src/EventSubscriber/FormSubmissionSubscriber.php`, `src/Service/Security/SsrfProtectionService.php`)**: - Integrated `SsrfProtectionService::isSafeUrl()` on form webhook URLs, blocking SSRF attempts targeting link-local, cloud metadata (169.254.169.254, IMDSv2), private RFC 1918 subnets, and loopback vectors. - Enforced tenant isolation by validating project UUID before dispatching asynchronous `SendWebhookMessage` payloads. - **Targeted Project Member Notifications (`src/Service/NotificationService.php`)**: - Added `NotificationService::notifyFormSubmission()` and registered `TYPE_FORM_SUBMISSION = 'form_submission'` in type validation. - Automatically notifies all active project members (`ProjectMemberStatus::Active`) when a new submission is received, generating deep links to the form submissions administrative screen. - **Strict I18N Compliance & Parity Synchronization (`translations/messages.{en,fr,es,ar}.php`, `assets/js/hooks/useRealtime.ts`)**: - Replaced hardcoded toast notification strings in `useRealtime.ts` with `useTranslation` (`t()`). - Added 5 new translation keys across English, French, Spanish, and Arabic dictionaries, maintaining strict 3,832 key parity with zero discrepancies. ## [1.26.208] — 2026-11-06 ### Realtime Event Stream, Doctrine Eager Pagination & Targeted Notification Hardening (Cycle #137) - **Realtime Event Stream & Hook Hardening (`src/Controller/RealtimeController.php`, `assets/js/hooks/useRealtime.ts`, `src/Service/MercurePublisher.php`)**: - Implemented `since=latest` cursor initialization parameter in `RealtimeController`, preventing clients on initial mount from fetching and replaying the entire historical event backlog. - Added actor isolation (`actor_id` propagation in Mercure and polling payloads), suppressing self-triggered toast notifications in `useRealtime` hook for actions initiated by the authenticated user. - Clamped `$since` query parameter against total event line count in `RealtimeController` to prevent out-of-bounds cursor anomalies. - **Doctrine Eager Pagination for Nested Comments (`src/Repository/CommentRepository.php`)**: - Wrapped `findByEntryPaginated` in `Doctrine\ORM\Tools\Pagination\Paginator` with `fetchJoinCollection: true`, guaranteeing safe SQL limit/offset execution across OneToMany `c.children` relationships and preventing parent comment truncation. - **Targeted Notification Hardening (`src/EventSubscriber/NotificationSubscriber.php`, `src/Controller/ContentController.php`)**: - Prevented self-notification loops by verifying that the update author (`updatedBy` or security context) does not equal the assigned recipient before triggering `notifyStatusChange`. - Added `previousStatus` tracking on `ContentEvent` to ensure status-change notifications are only dispatched when the entry status actually transitions to a different value. - **Strict i18n & PHPUnit Modernization (`translations/messages.{en,fr,es,ar}.php`, tests suite)**: - Added 8 real-time event status translation keys across all 4 supported languages (`en`, `fr`, `es`, `ar`). - Refactored over 40 test suites to modern PHPUnit expectation standards (`expects($this->once())`), ensuring 100% clean test execution (2,374 tests, 18,632 assertions, 0 errors, 0 failures). ## [1.26.206] — 2026-11-06 ### Dynamic Healthcheck Versioning, PHPUnit Stub Modernization & Production Deployment (Cycle #131) - **CI / GitHub Actions Green Milestone**: - Full GitHub Actions CI pipeline validated 100% GREEN (run `42226993082` and `42226996410`): Frontend Assets Compilation, PHPUnit & Static Validation (PHP 8.4 on Symfony 8.1 components), and Production Docker Image Build all succeeded with zero failures. - **Dynamic Versioning & System Healthcheck (`src/Controller/HealthController.php`, `VERSION`, `composer.json`, `package.json`)**: - Synchronized project version to `1.26.206` across `VERSION`, `composer.json`, `package.json`, and `HealthController::VERSION`. - Upgraded `HealthController` to dynamically inspect `VERSION` file as primary source of truth, ensuring `/api/health` and `/health` never report stale versions after release updates. - **Modern PHPUnit 13 Stub Refactoring (`tests/EventSubscriber/SecurityHeadersSubscriberTest.php`)**: - Refactored `HttpKernelInterface` mock to `createStub()`, eliminating PHPUnit mock-without-expectations notices and ensuring standard compliant test suite execution. - **Production Deployment Runner Hardening (`deploy.py`)**: - Added automated `sync_frontend_assets()` step using `rsync` over SSH to seamlessly distribute compiled Webpack Encore production assets (`public/build/`) to o2switch shared hosting environments lacking native Node.js/npm. - Deployed release to live production on o2switch `api.jambostack.site` with zero downtime, verified database migrations, and warmed production cache. --- ## [1.26.202] — 2026-11-06 ### CI PHPUnit Green Suite & Webpack Encore Test Resilience (Cycle #127 / #131) - **CI GitHub Actions & PHPUnit Suite Green Validation (`SchemaCrudTest`, `tests/bootstrap.php`, `webpack_encore.yaml`)**: - Resolved the root cause failure in `SchemaCrudTest::testReadSchemaWithGet` by isolating randomized collection slugs and names (`articles_`), eliminating collision and stale state across the 2,347 test suite. - Hardened Webpack Encore test environment with `strict_mode: false` in `when@test` within `config/packages/webpack_encore.yaml`. - Added automatic bootstrap provisioning of dummy test assets (`public/build/entrypoints.json` and `public/build/manifest.json`) in `tests/bootstrap.php` preventing unhandled Twig render exceptions in headless CI containers. - Synchronized `composer.lock` content-hash via `COMPOSER_ALLOW_SUPERUSER=1 composer update --lock --no-install` and validated with `composer validate` (exit code 0). - **Quality Assurance & Verification**: - Full PHPUnit test suite passing 100% cleanly. - Production frontend build validated (`npm run build` completed cleanly). - Maintained 100% strict i18n parity across 4 locales (en/fr/es/ar at 3,819 keys). --- ## [1.26.201] — 2026-11-06 ### CI Workflows Memory Hardening, PHPUnit Isolation & Composer Lock Synchronization (Cycle #130) - **CI Workflows Hardening & GitHub Actions Stability (`.github/workflows/ci.yml`)**: - Increased PHP memory limit from 512MB to 2GB (`ini-values: memory_limit=2G` and `php -d memory_limit=2G vendor/bin/phpunit --no-coverage`) to safely accommodate all 2,347+ Symfony integration tests without OOM crashes. - Added explicit `pdo_sqlite` extension to PHP setup step for complete Doctrine DBAL SQLite support. - Added explicit `DATABASE_URL` environment injection to SQLite schema creation step (`php bin/console doctrine:schema:create --env=test`). - **Composer Lock Synchronization**: - Synchronized `composer.lock` content-hash via `composer update --lock --no-install`. - Validated zero errors via `composer validate` (exit code 0). - **Quality Assurance & Verification**: - Validated local PHPUnit test suite (2,347 tests, 18,563 assertions, 0 errors, 0 failures). - Validated Webpack Encore frontend asset production compilation (`npm run build`). - Verified 100% 4-language i18n parity across 3,819 translation keys. --- ## [1.26.200] — 2026-11-06 ### Asynchronous Batch Import & JSONL/CSV Multi-Tenant Serialization Hardening (Cycle #129) - **Asynchronous Batch Import & Multi-Tenant Serialization (`ImportService`, `BatchProcessingController`)**: - Implemented `BatchProcessingController` with dedicated endpoints: `POST /api/projects/{uuid}/batch/{collectionSlug}/import`, `GET /api/projects/{uuid}/batch/{batchId}/status`, and `GET /api/projects/{uuid}/batch/{collectionSlug}/export`. - Added strict multi-tenant boundary validation: verifies that requested collections strictly belong to the authenticated project tenant, rejecting unauthorized cross-tenant operations with HTTP 404 `COLLECTION_NOT_FOUND`. - Added asynchronous background processing via Symfony Messenger (`BatchImportMessage`, `BatchImportMessageHandler`) with auto-routing to the async transport, status persistence in `var/batch/{batchId}.json`, and 202 Accepted responses. - Implemented multi-tenant IDOR defense on batch status retrieval: querying a batch job using a foreign project UUID returns HTTP 404 `BATCH_NOT_FOUND`. - **Memory Integrity & Decompression Bomb Protection (`ImportService`)**: - Added comprehensive decompression bomb defense for ZIP and GZIP streams: checks uncompressed-to-compressed ratio (max 100:1), maximum uncompressed payload (100MB), maximum files count (500), and rejects archives exceeding safety thresholds. - Built-in Zip Slip directory traversal blocking (`..`, `\0`, leading `/`, Windows drive paths) and dangerous extension rejection (`.php`, `.sh`, `.exe`, etc.). - Enforced symlink prohibition (mode `0120000`) in uploaded archives. - Implemented chunked entity flush and memory detachment (`detach()`) with periodic garbage collection (`gc_collect_cycles()`) every 50 rows. - Added dynamic memory exhaustion safeguard (`isMemoryNearLimit()`): gracefully terminates batches when memory consumption reaches 85% of PHP `memory_limit` to prevent OOM process termination. - **Data Sanitization & Injection Defense (`ImportService`)**: - Implemented CSV formula injection protection: automatically neutralizes cells starting with `=`, `+`, `-`, `@`, `\t`, `\r`. - Enforced control character removal (`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]`) while preserving standard whitespace. - Added JSONL streaming validation with depth limit protection (`MAX_JSON_DEPTH = 32`) and line-by-line error reporting. - **Streaming Multi-Tenant Export (`BatchProcessingController`, `ImportService`)**: - Implemented memory-safe paginated streaming export in CSV and JSONL formats with standard security headers and attachment disposition. - **Strict 4-Language i18n Parity (3,819 keys)**: - Added 19 new localized keys across `en`, `fr`, `es`, `ar` for batch import/export errors, memory exhaustion, decompression bombs, and status reports. - **Comprehensive Test Suite**: - Added 17 automated tests (55 assertions) in `Cycle129BatchProcessingSecurityTest` validating RBAC, CSV/JSONL import, async execution, status tracking, bomb defenses, Zip Slip, formula escaping, streaming export, and i18n parity. --- ## [1.26.199] — 2026-11-06 ### Realtime SSE Streaming & Mercure Fallback Multi-Tenant Eavesdropping Protection (Cycle #128) - **Passive Inter-Tenant Eavesdropping Protection (`MercureFallbackController`)**: - Implemented strict subscriber authentication on `/.well-known/mercure` via Bearer JWT, `mercureAuthorization` cookie, session membership, or API token. - Returns HTTP 401 `AUTH_REQUIRED` for unauthenticated subscriptions and HTTP 403 `ACCESS_DENIED` for unauthorized cross-tenant eavesdropping attempts. - Enforced single-tenant isolation: requests specifying topics spanning multiple distinct projects in a single stream are rejected with HTTP 403 `FORBIDDEN`. - Added strict control character, null byte (`NULL_BYTE_DETECTED`), and invalid topic structure validation. - **Strict CORS Origin Hardening (`MercureFallbackController`, `CorsSubscriber`)**: - Excluded `/.well-known/mercure` from wildcard public CORS rules in `CorsSubscriber`. - Preflight `OPTIONS` and streaming `GET` validate incoming `Origin` against server host and trusted origins; untrusted third-party origins receive HTTP 403 `CORS_ORIGIN_DENIED`. - Authorized requests receive matched origin and `Access-Control-Allow-Credentials: true` with `Vary: Origin`. - **Native Realtime Server-Sent Events (SSE) Stream (`RealtimeController`)**: - Implemented dedicated native SSE streaming endpoints (`GET /api/projects/{uuid}/realtime/stream` and `/sse`) returning `text/event-stream` with keep-alive, client disconnection detection, reconnect delay, and strict tenant authorization. - Added cross-tenant topic filter blocking (HTTP 403 `FORBIDDEN`) and event name syntax verification (HTTP 422 `INVALID_EVENT_NAME`) on both `/poll` and `/stream`. - **Administrative Topic Protection & Collection Containment (`MercureTopicSecurityService`)**: - Restricted sensitive administrative topics (`/audit`, `/security`, `/system`, `/members`, `/settings`) to users with manager/admin privileges or `*` API tokens. - Added project collection existence validation on topic subscriptions (`/collections/{slug}`), rejecting non-existent collections with HTTP 404 `COLLECTION_NOT_FOUND`. - Hardened `verifyToken` against path traversal (`..`, `\\`, `//`) in both `subscribe` and `publish` claims, strictly blocking cross-tenant publish tokens. - **Collection Topic Event Propagation (`MercurePublisher`, `MercureEntitySubscriber`)**: - Augmented `contentChanged` and `statusChanged` to dispatch events to collection-specific topics (`projects/{uuid}/collections/{slug}` and `projects/{uuid}/content/{slug}`). - Propagated collection slugs on entity lifecycle events (`postPersist`, `postUpdate`, `preRemove`, `onFlush`, `postFlush`). - **I18n Translation Completeness & Testing**: - Added 5 translation keys across all 4 locales (en, fr, es, ar): `realtime.sensitive_topic_denied`, `realtime.collection_not_found`, `mercure.cors_origin_denied`, `mercure.multiple_projects_denied`, and `mercure.auth_required` (3,800 keys per locale). - Created test suite `Cycle128RealtimeSseSecurityTest` (19 tests, 102 assertions). ## [1.26.171] — 2026-11-06 ### Webhook Subsystem Rate Limiting, Audit Logging & Security Hardening (Cycle #101) - **Rate Limiting Protection (`WebhookController`, `config/packages/rate_limiter.yaml`)**: - Implemented `webhook_limiter` (60 req/min sliding window) on general webhook management routes (`index`, `create`, `show`, `update`, `delete`, `logs`, `prune`). - Implemented `webhook_test_limiter` (10 req/min sliding window) specifically on the test outbound dispatch route (`POST /test`) to prevent abuse and outbound resource exhaustion. - **Audit Logging Integration (`AuditService`)**: - Added structured audit trails for all critical webhook events: `webhook_rate_limit_exceeded`, `webhook_test_rate_limit_exceeded`, `webhook_access_denied`, `webhook_create`, `webhook_update`, `webhook_rotate_secret`, `webhook_rotate_secret_rejected`, `webhook_delete`, `webhook_logs_prune`, and `webhook_test`. - Added user/token safe identifier resolution (`resolveIdentifier`, `getUserSafeIdentifier`) without throwing exceptions during unauthenticated or background contexts. - Hardened access control handling (`logAccessDenied`) with specific denial reasons (`token_insufficient_permissions`, `user_not_project_member`, `insufficient_role_permission`). - **I18n Translation Completeness**: - Added translations for `webhook.rate_limit_exceeded` and `webhook.test_rate_limit_exceeded` in French, English, Spanish, and Arabic dictionaries. - **Test Suite Verification**: - Created `Cycle101WebhookHardeningTest` covering access control, secret rotation validation, test ping execution, prune retention, delete, rate limiting, and 4-locale translation completeness (8 tests, 89 assertions). ## [1.26.170] — 2026-11-06 ### GraphQL AST Depth Hardening, UUID Enforcement, MCP & Search Audit Logging (Cycle #99 & #100) - **GraphQL API Protection (`GraphQLController`)**: - Enforced `MAX_AST_DEPTH = 15` limit on GraphQL query abstract syntax tree depth, stopping nested recursive amplification attacks. - Added strict UUID v4 format validation (`UUID_REGEX`) prior to database lookups. - Injected `AuditService` to systematically log security events: rate limit violations (`graphql_rate_limit_exceeded`), batch query rejections, operation/fragment/selection/depth limit exceedances (`graphql_security_blocked`). - **Model Context Protocol (MCP) Audit & Security (`McpController`)**: - Added comprehensive audit logging via `AuditService` for rate limit rejections (`mcp_rate_limit_exceeded`), payload size violations (`mcp_payload_too_large`), unauthorized tool requests (`mcp_tool_unauthorized`), and tool executions (`mcp_tool_call`). - **Search Engine Hardening (`SearchController`)**: - Added audit logging for search reindex rate limit violations (`search_reindex_rate_limit_exceeded`), cross-tenant access attempts (`search_tenant_mismatch`), quota exceeded denials (`search_reindex_quota_exceeded`), and successful reindex operations (`search_reindex`) with duration metrics. - **I18n Translation Completeness & Testing**: - Added translation key `graphql.ast_depth_exceeded` across French, English, Spanish, and Arabic dictionaries. - Created `Cycle99GraphQLMcpSearchHardeningTest` verifying AST depth protection, UUID validation, tenant isolation, and audit trail generation (7 tests, 88 assertions). ## [1.26.169] — 2026-11-06 ### User, Role & Permission Validation Pipeline & Quota Optimization (Cycle #98 Finalization) - **Check Ordering Hardening**: - Reordered request validation pipeline across `UserController`, `RoleController`, and `PermissionController`: HTTP 413 (Payload Too Large) and HTTP 400 (Malformed JSON) are enforced before business logic quotas and entity mutations. - Placed field constraint validations (name, format, label, email, password policy) before capacity quota limits to ensure meaningful validation error reporting. - **Quota Bounds Tuning & Safe Context Resolution**: - Calibrated platform quota limits to production scale (`MAX_USERS_COUNT = 10000`, `MAX_ROLES_COUNT = 50000`, `MAX_PERMISSIONS_COUNT = 5000`) preventing false-positive denials under multi-tenant accumulations. - Implemented resilient `getUser()` fallback guarding against uninitialized container states during standalone test contexts or mocked requests. - **Verification & Deployment**: - 100% PHPUnit passing rate across the entire test suite (2,017 tests, 14,839 assertions, 0 failures). ## [1.26.168] — 2026-11-06 ### Admin User Management, JWT TTL & Ping Rate Limiting & Security Hardening (Cycle #98) - **User Management Hardening (`UserManagement\UserController`, `RoleController`, `PermissionController`)**: - Enforced rate limiting via `limiter.token_management_limiter` across user, role, and permission management endpoints (`index`, `show`, `create`, `update`, `delete`, `bulkDelete`, `resetTwoFactor`). - Added strict platform capacity limits: `UserController::MAX_USERS_COUNT = 500`, `RoleController::MAX_ROLES_COUNT = 100`, and `PermissionController::MAX_PERMISSIONS_COUNT = 300` preventing entity exhaustion and DDoS attacks. - Safe error handling in rate limiting without reliance on uninitialized controller container. - **Admin Project JWT TTL Hardening (`Admin\ProjectJwtTtlController`)**: - Injected `limiter.project_limiter` for rate limiting requests to `getJwtTtl` and `updateJwtTtl`. - Added audit logging via `AuditService` for security-sensitive token TTL updates (`admin_project_jwt_ttl_update`), recording both successes and invalid range rejections. - Retained strict range checks (`60s <= access <= refresh <= MAX_TTL`). - **Admin API Ping & Trait Hardening (`AdminApi\PingController`, `AdminApiControllerTrait`)**: - Enforced rate limiting via `limiter.admin_api_limiter` on `GET /admin-api/_ping` with i18n error reporting (`admin_api.ping.rate_limit_exceeded`). - Added security audit logging in `AdminApiControllerTrait::requireScope` when personal access token scope violations are detected (`admin_api_scope_violation`). - **Settings Locale Hardening (`Settings\LocaleController`)**: - Enforced rate limiting via `limiter.profile_limiter` on `/settings/locale` preventing database write flooding and audit log spam. - **I18n Translation Completeness & Testing**: - Added 9 new translation keys across English, French, Spanish, and Arabic (`project.jwt_ttl.rate_limit_exceeded`, `admin_api.ping.rate_limit_exceeded`, `settings.locale.rate_limit_exceeded`, `user.admin.rate_limit_exceeded`, `user.admin.max_users_exceeded`, `role.admin.rate_limit_exceeded`, `role.admin.max_roles_exceeded`, `permission.admin.rate_limit_exceeded`, `permission.admin.max_permissions_exceeded`) — 100% symmetrical. - Added dedicated test suite `Cycle98AdminSecurityHardeningTest` (14 tests, 125 assertions, 100% pass). ## [1.26.167] — 2026-11-06 ### Admin Form & Redirect Security Hardening (Cycle #97) - **Admin Form Security Hardening (`Admin\FormController`)**: - Enforced rate limiting via `limiter.admin_api_limiter` across all form management endpoints (`index`, `create`, `show`, `update`, `delete`, `submissions`, `exportSubmissionsCsv`, `showSubmission`, `deleteSubmission`, `updateSubmission`). - Implemented project form quota limit (`MAX_FORMS_PER_PROJECT = 50`) preventing arbitrary form flooding and resource exhaustion. - Added comprehensive audit logging via `AuditService` for form creation (`admin_form_create`), form updates (`admin_form_update`), form deletions (`admin_form_delete`), submission exports (`admin_form_submissions_export`), submission updates (`admin_form_submission_update`), and submission deletions (`admin_form_submission_delete`). - Enforced strict security headers (`Cache-Control: no-store`, `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY`). - **Admin Redirect Security Hardening (`Admin\RedirectController`)**: - Enforced rate limiting via `limiter.admin_api_limiter` on all redirect endpoints (`index`, `chains`, `create`, `show`, `update`, `delete`, `toggle`). - Added project redirect quota bounds (`MAX_REDIRECTS_PER_PROJECT = 500`) preventing memory saturation and infinite loops during graph chain detection. - Added audit logging via `AuditService` for redirect creation (`admin_redirect_create`), updates (`admin_redirect_update`), toggling (`admin_redirect_toggle`), and deletion (`admin_redirect_delete`). - Enforced strict security headers (`Cache-Control: no-store`, `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY`). - **I18n Translation Completeness & Testing**: - Added 5 new translation keys across English, French, Spanish, and Arabic (`form.admin.rate_limit_exceeded`, `form.admin.project_quota_exceeded`, `form.admin.export_rate_limit_exceeded`, `redirect.admin.rate_limit_exceeded`, `redirect.admin.project_quota_exceeded`) — 3,525 keys per language, 100% symmetrical. - Added dedicated test suite `Cycle97AdminFormAndRedirectSecurityHardeningTest` (7 tests, 98 assertions, 100% pass). All 33 Form & Redirect tests pass without failures. ## [1.26.166] — 2026-11-06 ### Content API & AdminApi CSV Import Security Hardening (Cycle #96) - **Public & Token Content API Hardening (`ContentController`)**: - Enforced strict security headers (`Cache-Control: no-store, private`, `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY`, `Pragma: no-cache`) across all endpoints via `secureJson()`. - Added rate limiting protection via `limiter.project_limiter` for read, write, update, and delete actions. - Implemented strict payload size limits (`MAX_PAYLOAD_BYTES = 2MB`) returning `413 PAYLOAD_TOO_LARGE`. - Added request field count limits (`MAX_FIELDS_COUNT = 100`) returning `422 TOO_MANY_FIELDS`. - Enforced collection entry quotas (`MAX_ENTRIES_PER_COLLECTION = 10,000`) preventing storage exhaustion. - Added slug length bounds (`MAX_SLUG_LENGTH = 128`) returning `422 SLUG_TOO_LONG`. - Refactored all error messages and validation exceptions to strict i18n translation keys (`api_content.invalid_status`, `api_content.assignee_not_member`, `api_content.field_value_unique`, `api_content.collection_quota_exceeded`, `api_content.rate_limit_exceeded`, `api_content.payload_too_large`, `api_content.too_many_fields`, `api_content.slug_too_long`). - Added comprehensive audit logging for content creation (`api_content_create`), update (`api_content_update`), and soft-deletion (`api_content_delete`). - **AdminApi CSV Import Hardening (`AdminApi\ImportController`)**: - Enforced `SECURITY_HEADERS` on JSON and stream-file import endpoints. - Implemented collection quota bounds: checked current active entries against `MAX_ENTRIES_PER_COLLECTION = 10,000` before and during streaming. - Added cell sanitization: stripped ASCII control characters (`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]`) to prevent log poisoning and corrupted stored records. - Added comprehensive audit logging for CSV imports (`admin_api_import_csv`) tracking created entries, errors count, and executing actor. - **I18n Translation Completeness & Testing**: - Added 11 new translation keys across English, French, Spanish, and Arabic (3,520 keys per language, 100% symmetry). - Created dedicated test suite `Cycle96ContentAndImportSecurityHardeningTest` (10 tests, 126 assertions, 100% pass). ## [1.26.165] — 2026-11-06 ### Studio AI & Schema Hardening, Quotas & Type Sanitization (Cycle #96) - **Studio Security Hardening (`StudioController`)**: - Added payload size validation on AI endpoints (2MB schema, 10MB chat). - Added quotas on batch operations (max 50 actions, max 10 image generation prompts, max 20 translation entries). - Enforced project collection limit (max 100 collections). - TypeScript interface and identifier sanitization preventing arbitrary symbol injection in generated types. - Added audit logging on automated actions and schema provisionings. ## [1.26.164] — 2026-11-06 ### Media & Asset Security Hardening, Magic Bytes Inspection & Orphan Retention (Cycle #95) - **Media & Upload Hardening (`UploadSecurityValidator`, `DirectUploadService`, `MediaController`)**: - Full magic bytes validation for all formats (images, audio, video, documents, archives). - Cross-validation between declared MIME and real bytes; active script detection in text/data formats. - Head inspection on S3 multipart complete uploads with automatic quarantine and malicious object eviction. - Partition disk space protection (< 50MB check) and automatic remote Flysystem/S3 purging. - New pruning CLI command `app:media:prune-orphans` (`PruneOrphanUploadsCommand`). ## [1.26.163] — 2026-11-06 ### Blueprint Import & Collection Template Hardening (Cycle #94) - Hardened collection template application, alias normalization, and collection quota limits. ### Schema & Template Hardening, Anti-Injection & Inter-Collection Relation Isolation (Cycle #94) - **Collection Template Security Hardening (`CollectionTemplateController`)**: - Implemented rate limiting via `limiter.template_limiter` for create, save-from-collection, show, and delete operations. - Added strict payload size limits (`MAX_PAYLOAD_BYTES = 512KB`) preventing memory exhaustion attacks. - Sanitized template names and descriptions: stripped ASCII control characters (`[\x00-\x1F\x7F]`) and HTML/script tags. - Duplicate field slug rejection: prevents schema collisions with `422 DUPLICATE_FIELD_SLUG`. - Nested options protection: enforced maximum array depth (`MAX_OPTIONS_DEPTH = 6`) and payload size (`MAX_OPTIONS_PAYLOAD_BYTES = 32KB`). - Strict field type verification against `FieldController::ALLOWED_TYPES`. - Relation field option normalization: eliminated raw internal database ID leakage, enforcing portable `collection_slug` or isolated `orphan` tracking. - **Project Template & Builder Hardening (`ProjectTemplateBuilder`)**: - Sanitized project names, collection descriptions, and field labels. - Portable relation serialization: converts inter-collection foreign keys to target collection slugs during export. - Defensive relation binding: remaps inter-collection relations to newly created collections post-flush in target projects. - Orphan relation detection & isolation: flags relations pointing to non-existent or foreign collections with `orphan: true`, preventing cross-tenant data leakage. - **Project Structure Export/Import Hardening (`StructureExportHandler`, `StructureImportHandler`)**: - Export handler portable normalization: exports target collection slugs and strips primary key integers. - Project collection quota enforcement: validates active collections + incoming collections <= 100 (`import.structure.project_collection_quota_exceeded`). - Deep options protection (`depth > 6`) and duplicate field slug rejection within collections. - Orphan inter-collection relation isolation: sanitizes relations referencing collections absent from both target project and import payload. - **Blueprint Import Hardening (`BlueprintImportCommand`)**: - Added secure multi-format support for JSON and YAML definitions using `Yaml::parse()` with `PARSE_EXCEPTION_ON_INVALID_TYPE`. - Enforced project collection limit (maximum 100 collections). - **I18n Parity & Testing**: - Added 7 new translation keys across English, French, Spanish, and Arabic (3,461 keys each, 100% symmetry). - Created dedicated test suite `Cycle94TemplateExportHardeningTest` (12 tests, 106 assertions, 100% pass). ## [1.26.161] — 2026-11-05 ### Search Security Hardening, Query Complexity Protection, Tier Quotas & Safe Pagination (Cycle #93) - **Search Query Complexity & DoS Protection (`SearchController`)**: - Enforced query parameter validation (`q`): rejected non-string queries, empty or whitespace-only inputs. - Implemented Unicode searchable character requirement (`[\p{L}\p{N}]/u`): prevents DoS/CPU spikes on queries composed solely of wildcards, operators, or punctuation (`???`, `***`, `%%%`, `((()))`). - Added query token limitation: maximum 25 terms (`MAX_QUERY_TERMS`) to prevent token stream flooding. - Added parenthesis nesting depth protection: capped to 3 levels (`MAX_NESTING_DEPTH`) to prevent syntax tree exhaustion. - Collapsed excessive wildcard repetitions (`[%_*?~]{5,}`) to prevent ReDoS and SQL LIKE query degradation. - **Filter Injections & Safe Pagination (`SearchController`, `SearchService`)**: - Filter sanitization: strict regex checks on `collection` (`/^[a-zA-Z0-9_\-]{1,64}$/`) and `locale` (`/^[a-zA-Z]{2,4}([-_][a-zA-Z0-9]{2,8})?$/`, max 16 chars). - Added `status` filter validation: whitelisted against `['published', 'draft', 'archived', 'scheduled']`. - Added `sort` parameter validation: whitelisted sort fields (`['created_at', 'updated_at', 'published_at', 'status', 'slug']`) and directions (`asc`, `desc`). - Safe pagination: validated numeric limit (`MAX_PAGE_LIMIT = 100`) and offset (`MAX_OFFSET = 10000`), with transparent `page` to `offset` conversion and out-of-bounds rejection. - **Search Index Document Quotas by Tier (`SearchService`)**: - Introduced index document quotas by tenant tier: `free` (1,000), `starter` (5,000), `pro` (25,000), `enterprise` (100,000), with custom override support (`project.settings['max_search_documents']`). - Reindex quota enforcement: `/api/projects/{uuid}/search/reindex` returns HTTP 422 with `SEARCH_DOCUMENT_LIMIT_EXCEEDED` if project entries exceed the tier quota. - Reindex truncation safeguard: automatically truncates indexed batches in Meilisearch to the tier limit. - Real-time indexing protection: skips indexing new documents when the project document quota is reached while allowing in-place updates of already-indexed entries. - Enhanced database fallback search with `status`, `metaTitle`, and consistent pagination metadata (`estimatedTotalHits`). - **Strict 100% I18n Compliance**: - Added 11 new translation keys across all 4 locales (`en`, `fr`, `es`, `ar`), maintaining exact parity (3,454 keys per locale, 0 diffs). - **Test Suite Verification**: - Added dedicated test suite `Cycle93SearchHardeningTest` (16 tests, 152 assertions, 100% pass). ## [1.26.160] — 2026-11-05 ### Versioning Quotas, Snapshot Sanitization, Auto-Retention Pruning & Project-Wide Prune Hardening (Cycle #92) - **Content Versioning Quotas & Auto-Retention (`VersioningService`)**: - Implemented multi-tenant project version quotas based on tenant tier: `free` (500), `starter` (2,500), `pro` (10,000), `enterprise` (50,000) with custom override support (`max_versions`). - Added entry-level version retention limits: `free` (20), `starter` (50), `pro` (100), `enterprise` (250) with custom override support (`max_versions_per_entry`). - Automatic oldest-version pruning upon new snapshot creation when entry exceeds its retention quota. - Snapshot payload size validation: enforces strict 1 MB (`MAX_SNAPSHOT_BYTES`) cap preventing JSON memory-exhaustion DoS attacks. - Label sanitization: automatically strips HTML tags, filters control characters, and truncates to 150 characters (`MAX_LABEL_LENGTH`). - **Project-Wide Version Pruning & Label Modification Endpoints (`VersioningController`)**: - Added `POST /api/projects/{projectUuid}/versions/prune`: enables administrators to purge versions older than `days` (bounded 1 to 365) and/or prune all entries in project to `keep` recent versions (bounded 1 to 100). - Added `PATCH /api/projects/{projectUuid}/collections/{collectionSlug}/entries/{uuid}/versions/{versionNumber}/label`: enables updating version labels with strict sanitization and audit logging. - Bounded request payload size (`MAX_PAYLOAD_BYTES = 16384`) on all mutation endpoints. - **Optimized Content Version Repository Methods (`ContentVersionRepository`)**: - Added high-performance scalar counting: `countByEntry(ContentEntry $entry)` and `countByProject(Project $project)`. - Added `findOlderThanForProject` and batch `pruneOlderThanForProject`. - **Test Suite Regression Fix (`AutomationAndFlowHardeningTest`)**: - Fixed bilingual assertions in `AutomationAndFlowHardeningTest` for flow graph depth limit and trigger incoming edges to match Symfony Translator output across both French and English environments. - **Strict 100% I18n Compliance**: - Added 10 new translation keys across all 4 locales (`en`, `fr`, `es`, `ar`), maintaining exact parity (3,443 keys per locale, 0 diffs). - **Test Suite Verification**: - Added `Cycle92VersioningHardeningTest` covering version quotas, auto-retention pruning, label sanitization, snapshot byte caps, project prune endpoints, label updates, and repository count queries (9 tests, 116 assertions, 100% pass). ## [1.26.159] — 2026-11-05 ### Outbound HTTP Flow Node SSRF, Recursion & Complete Flow Validator I18n Hardening (Cycle #91 Finalization) - **Flow Engine HTTP Request Node Hardening (`HttpRequestHandler`)**: - Added hop count tracking and recursion limit enforcement: requests exceeding 5 hops are blocked with translated error code. - Propagated platform-guaranteed header `X-JamboApi-Hop-Count` along with `X-JamboApi-Project`, `X-JamboApi-Automation-Id`, and `X-JamboApi-Run-Id`. - Added configurable timeout support: bounded between 1.0s and 15.0s (default 5.0s) and max total duration between 2.0s and 30.0s (default 10.0s). - Added configurable retry support: bounded between 0 and 3 retries with exponential backoff on HTTP 502/503/504 errors, and strict non-retry policy on SSRF blocks (`\InvalidArgumentException`). - Added explicit translated SSRF blocking message (`flow.http_request.ssrf_blocked`). - **Complete Flow Validator I18n Localization (`FlowValidator`)**: - Replaced all 25+ hardcoded error messages with Symfony Translator calls (`$this->trans(...)`), supporting dynamic parameter placeholders with backward-compatible fallbacks. - Covers structural errors (at least one node, edges required, nodes/edges DoS limits), variable naming & sensitive patterns, node integrity (invalid ID format, duplicate ID, required/unknown type), edge integrity (source/target not found), DAG cycle detection, depth limits, trigger constraints, and orphan nodes. - **Strict 100% I18n Compliance**: - Added 27 new translation keys across all 4 locales (`en`, `fr`, `es`, `ar`), maintaining exact parity (3,433 keys per locale, 0 diffs). - **Test Suite Verification**: - Enhanced `Cycle91WebhookAndFlowHardeningTest` to 12 tests (40 assertions) with 0 failures, 0 notices, verifying `HttpRequestHandler` hop count, SSRF blocking, 503 exponential retries, and `FlowValidator` i18n translation coverage. ## [1.26.158] — 2026-11-05 ### Webhook SSRF, Flow Recursion, Retries & Log Retention Hardening (Cycle #91) - **Flow Engine SSRF Prevention & Graph Validation (`FlowValidator`, `CallWebhookHandler`)**: - Integrated `SsrfProtectionService` directly into `FlowValidator` to reject actions (`action.call_webhook`, `action.http_request`) targeting private RFC 1918 subnets (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), RFC 6598 carrier-grade NAT (`100.64.0.0/10`), IPv6 ULA/link-local, cloud metadata services (`169.254.169.254`, `fd00:ec2::254`, `metadata.google.internal`), and evasive IP formats (hexadecimal, decimal integer, octal) during flow compilation and pre-flight validation. - Enforced strict URL length (`MAX_URL_LENGTH = 2048`) and anti-CRLF control characters validation on action configurations. - **Outbound Webhooks Reliability, Timeouts & Exponential Backoff (`CallWebhookHandler`, `WebhookService`)**: - Added configurable timeout support in `CallWebhookHandler`: bounded between 1.0s and 15.0s (default 5.0s) and max total duration between 2.0s and 30.0s (default 10.0s). - Implemented exponential backoff retries (up to 3 retries) on transient network errors or HTTP 502/503/504 status codes. Strict non-retry policy enforced on SSRF security blocks (`\InvalidArgumentException`) and 4xx client errors. - Added multi-tenant outbound webhook payload size restriction (`MAX_PAYLOAD_BYTES = 512KB`) in `WebhookService` with explicit i18n logging upon violation. - **Automation Recursion & Infinite Loop Prevention (`CallWebhookHandler`, `WebhookInboundController`)**: - Implemented hop count tracking via platform-guaranteed header `X-JamboApi-Hop-Count` bounded to 5 hops across flow webhooks. - Added loop detection in `WebhookInboundController`: requests exceeding maximum hop count are rejected with 429 (`AUTOMATION_LOOP_DETECTED`). - Added direct self-trigger recursion detection in `WebhookInboundController`: inbound requests originating from the same project and same automation are rejected with 400 (`DIRECT_RECURSION_DETECTED`). - Sanitized inbound payloads to prevent injection or overwriting of internal engine variables (`_node_config`, `_hop_count`, `_trigger`). - **Webhook Log Retention & Pruning Endpoint (`WebhookController`, `WebhookLogRepository`)**: - Added `POST /api/projects/{projectUuid}/webhooks/{uuid}/logs/prune` enabling administrators to prune webhook logs older than specified retention days (bounded between 1 and 365 days) with audit logging. - Fixed comment reply nesting flattening regression in `CommentController` ensuring nested comments are flattened to root parent and 404 response on project mismatch. - **Strict 100% I18n Compliance**: - Added 11 new translation keys across all 4 locales (`en`, `fr`, `es`, `ar`), maintaining exact parity (3,406 keys per locale). - **Test Suite Verification**: - Added `Cycle91WebhookAndFlowHardeningTest` covering SSRF static/semi-static rejection, metadata blocking, hop count recursion limits, self-recursion prevention, 503 exponential retries, payload size caps, and log pruning (8 tests, 28 assertions, 100% pass). ## [1.26.157] — 2026-11-05 ### Comment Quotas, Nesting Security & Notification Volume Hardening (Cycle #90) - **Comment Quotas & Anti-XSS Sanitization (`CommentController` & `CommentRepository`)**: - Implemented multi-tenant project comment quotas based on tenant tier: `free` (250), `starter` (1,000), `pro` (5,000), `enterprise` (25,000) with custom override support (`max_comments`). - Added entry-level comment quotas: `free` (100), `starter` (250), `pro` (1,000), `enterprise` (5,000) with custom override support (`max_comments_per_entry`). - Strict anti-XSS comment body sanitation: eradicated `