# =============================================================================
# InvenLogix v3.0 — Apache configuration for public/
# =============================================================================
# Requires mod_rewrite (and mod_headers for security headers).
# All requests that do not map to a real file or directory are routed to
# index.php (the front controller).
# =============================================================================

Options -MultiViews -Indexes

# ---------------------------------------------------------------------------
# URL Rewriting
# ---------------------------------------------------------------------------
RewriteEngine On
RewriteBase /

# If the request is for an existing file or directory, serve it directly
# (CSS, JS, images, fonts, sounds, etc.)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# Everything else goes to the front controller
RewriteRule ^ index.php [QSA,L]

# ---------------------------------------------------------------------------
# Security Headers
# ---------------------------------------------------------------------------
<IfModule mod_headers.c>
    # Prevent browsers from MIME-sniffing the content type
    Header set X-Content-Type-Options "nosniff"

    # Prevent the page from being embedded in an <iframe> on a different origin
    Header set X-Frame-Options "SAMEORIGIN"

    # Legacy XSS filter (for older browsers that still honour it)
    Header set X-XSS-Protection "1; mode=block"

    # Control what the Referer header sends on cross-origin requests
    Header set Referrer-Policy "strict-origin-when-cross-origin"

    # Only send HSTS if you are running HTTPS in production
    # Uncomment the line below and adjust max-age when TLS is configured:
    # Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"

    # Content Security Policy — restrict resource origins
    Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://unpkg.com https://api.giphy.com https://media.giphy.com; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://unpkg.com https://fonts.googleapis.com; img-src 'self' data: blob: https://media.giphy.com https://media0.giphy.com https://media1.giphy.com https://media2.giphy.com https://media3.giphy.com https://media4.giphy.com https://tile.openstreetmap.org https://*.tile.openstreetmap.org https://unpkg.com https://cdn.jsdelivr.net; font-src 'self' https://cdn.jsdelivr.net https://unpkg.com https://fonts.gstatic.com; connect-src 'self' https://api.daily.co https://api.giphy.com https://cdn.jsdelivr.net https://unpkg.com https://*.openstreetmap.org https://nominatim.openstreetmap.org wss://localhost:8181 wss://localhost:8282 wss://localhost:8383 wss://localhost:8484 wss://localhost.qz.io:8181 wss://localhost.qz.io:8282 wss://localhost.qz.io:8383 wss://localhost.qz.io:8484; media-src 'self' blob:; worker-src 'self' blob:; frame-src https://*.daily.co;"
</IfModule>

# ---------------------------------------------------------------------------
# Deny direct access to sensitive files that should never be web-accessible
# ---------------------------------------------------------------------------

# .env — contains DB credentials, SMTP passwords, app secrets
<Files ".env">
    <IfModule mod_authz_core.c>
        Require all denied
    </IfModule>
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Deny from all
    </IfModule>
</Files>

# Composer manifests — reveal dependency versions which may expose attack surface
<Files "composer.json">
    <IfModule mod_authz_core.c>
        Require all denied
    </IfModule>
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Deny from all
    </IfModule>
</Files>

<Files "composer.lock">
    <IfModule mod_authz_core.c>
        Require all denied
    </IfModule>
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Deny from all
    </IfModule>
</Files>

# PHP/Apache error logs should never be web-accessible
<FilesMatch "^(error_log|.*\.log)$">
    <IfModule mod_authz_core.c>
        Require all denied
    </IfModule>
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Deny from all
    </IfModule>
</FilesMatch>

# Deny access to any file starting with a dot (e.g. .htpasswd, .gitignore)
<FilesMatch "^\.">
    <IfModule mod_authz_core.c>
        Require all denied
    </IfModule>
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Deny from all
    </IfModule>
</FilesMatch>

# ---------------------------------------------------------------------------
# PHP settings (only effective if PHP runs as an Apache module — mod_php)
# For PHP-FPM these must be set in the pool .ini file instead.
# ---------------------------------------------------------------------------
<IfModule mod_php.c>
    # Hide PHP version from response headers
    php_flag  expose_php          Off

    # Session hardening + 24-hour lifetime
    php_flag  session.cookie_httponly  On
    php_flag  session.use_strict_mode  On
    php_value session.cookie_samesite  Lax
    php_value session.gc_maxlifetime   86400
    php_value session.cookie_lifetime  86400

    # Upload limits — large for CSV imports (up to 50k rows), smaller uploads handled by controllers
    php_value upload_max_filesize  128M
    php_value post_max_size        256M
    php_value max_execution_time   300
    php_value max_input_time       300
</IfModule>

# ---------------------------------------------------------------------------
# Cache static assets aggressively (CSS, JS, images)
# ---------------------------------------------------------------------------
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/css                  "access plus 1 year"
    ExpiresByType application/javascript    "access plus 1 year"
    ExpiresByType image/svg+xml             "access plus 1 year"
    ExpiresByType image/png                 "access plus 1 year"
    ExpiresByType image/jpeg                "access plus 1 year"
    ExpiresByType image/x-icon              "access plus 1 year"
    ExpiresByType audio/mpeg                "access plus 1 year"
</IfModule>

# ---------------------------------------------------------------------------
# Gzip compression for text assets
# ---------------------------------------------------------------------------
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>
