# ExpertAims (EAC) — AimsHub CMS · front controller routing
Options -Indexes
DirectoryIndex index.php

<IfModule mod_rewrite.c>
  RewriteEngine On
  # Deployed at  clients.expertaims.in/eac/  → the app lives under /eac/.
  RewriteBase /eac/
  # Never serve dot-paths (.env, .git …) — secrets stay private.
  RewriteRule (^|/)\.(?!well-known(/|$)) - [F]
  # Serve real files and folders (assets/, images/, uploads/, admin/) directly…
  RewriteCond %{REQUEST_FILENAME} -f [OR]
  RewriteCond %{REQUEST_FILENAME} -d
  RewriteRule ^ - [L]
  # …and route everything else through the front controller.
  RewriteRule ^ index.php [L]
</IfModule>

# Moving to the DOMAIN ROOT later? Change RewriteBase to  /  here
# and set 'base_url' => '' in app/config.php.

# Block hidden/dotfiles (e.g. .env), backup/dump extensions AND source archives
# (zip/tar/gz) from the web — deployment .zip artifacts must never be downloadable.
<FilesMatch "(^\.|\.(bak|old|orig|sql|log|zip|tar|gz)$)">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
</FilesMatch>

# ═══ PERFORMANCE (2026-07-09 v2) ═══════════════════════════════════════
# Compress text responses (HTML/CSS/JS/SVG/JSON) — cPanel ships mod_deflate.
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml
  AddOutputFilterByType DEFLATE application/javascript application/x-javascript text/javascript
  AddOutputFilterByType DEFLATE application/json application/xml image/svg+xml
  AddOutputFilterByType DEFLATE font/ttf font/otf application/vnd.ms-fontobject
</IfModule>

# Browser caching. CSS/JS are safe to cache long — every <link>/<script> the
# CMS emits carries a ?v=<file-mtime> cache-buster, so edits bust instantly.
# Images/fonts change rarely; faculty photos also carry ?v when they change.
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/jpeg  "access plus 30 days"
  ExpiresByType image/png   "access plus 30 days"
  ExpiresByType image/webp  "access plus 30 days"
  ExpiresByType image/gif   "access plus 30 days"
  ExpiresByType image/svg+xml "access plus 30 days"
  ExpiresByType image/x-icon  "access plus 30 days"
  ExpiresByType text/css    "access plus 7 days"
  ExpiresByType application/javascript "access plus 7 days"
  ExpiresByType audio/mpeg  "access plus 30 days"
  ExpiresByType application/pdf "access plus 7 days"
  ExpiresByType font/woff2  "access plus 30 days"
  # HTML is dynamic (CMS-rendered) — always revalidate.
  ExpiresByType text/html   "access plus 0 seconds"
</IfModule>

<IfModule mod_headers.c>
  # Static assets: allow shared caches; HTML: no-store handled by PHP session anyway.
  <FilesMatch "\.(jpe?g|png|webp|gif|svg|ico|mp3|woff2?)$">
    Header set Cache-Control "public, max-age=2592000"
  </FilesMatch>
  <FilesMatch "\.(css|js)$">
    Header set Cache-Control "public, max-age=604800"
  </FilesMatch>
  # ═══ SECURITY headers as a server-level backstop (PHP sends them too;
  #     this also covers static files served directly by Apache) ═══
  Header always set X-Content-Type-Options "nosniff"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()"
</IfModule>
