# ====================================================================
# Code2Door - Clean URLs
# Requires Apache with mod_rewrite enabled (standard on virtually all
# shared PHP hosting, XAMPP, and WAMP). Has no effect on Nginx - if
# you're on Nginx, ask your host for the equivalent try_files config.
# ====================================================================

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  # SEO: serve the dynamic robots.txt / sitemap.xml at the exact URLs
  # search engines expect, without exposing the .php extension
  RewriteRule ^robots\.txt$ robots.php [L]
  RewriteRule ^sitemap\.xml$ sitemap.php [L]

  # index.php always redirects to the site root, e.g. /index.php -> /
  RewriteCond %{THE_REQUEST} ^GET\ /+index\.php(\?[^\s]*)?\ HTTP [NC]
  RewriteRule ^ /%1 [R=301,L]

  # Same idea for the extension-less /index (e.g. an old bookmark or a
  # link a search engine indexed before this fix) - also collapses to
  # the bare root, so there's only ever one canonical homepage URL.
  RewriteCond %{THE_REQUEST} ^GET\ /+index/?(\?[^\s]*)?\ HTTP [NC]
  RewriteRule ^ /%1 [R=301,L]

  # Visiting any-page.php directly redirects (permanently) to the
  # extension-less URL, preserving any query string.
  RewriteCond %{REQUEST_METHOD} GET
  RewriteCond %{THE_REQUEST} ^GET\ /+(.*)\.php(\?[^\s]*)?\ HTTP [NC]
  RewriteRule ^ /%1%2 [R=301,L]

  # Internally serve foo.php when /foo is requested, without changing
  # the URL shown in the browser.
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME}\.php -f
  RewriteRule ^(.*)$ $1.php [L,QSA]
</IfModule>

# Security headers
<IfModule mod_headers.c>
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set X-Content-Type-Options "nosniff"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
</IfModule>

# Don't let visitors browse folder contents directly
Options -Indexes

# Block access to sensitive file types anywhere in the site if someone
# requests them directly - not just the two specific files that ship
# with a fresh install, but any similar file (e.g. a catch-up/migration
# .sql file you might save alongside them, notes, logs, etc.)
<IfModule mod_authz_core.c>
  <FilesMatch "\.(sql|md|log|bak|env|ini|config)$">
    Require all denied
  </FilesMatch>
</IfModule>
<IfModule !mod_authz_core.c>
  <FilesMatch "\.(sql|md|log|bak|env|ini|config)$">
    Order allow,deny
    Deny from all
  </FilesMatch>
</IfModule>

# Defense-in-depth: config/db.php holds database credentials. PHP normally
# executes this rather than serving its source, but block it explicitly
# too in case of any server misconfiguration that might serve it as plain
# text instead.
<IfModule mod_authz_core.c>
  <Files "db.php">
    Require all denied
  </Files>
</IfModule>
<IfModule !mod_authz_core.c>
  <Files "db.php">
    Order allow,deny
    Deny from all
  </Files>
</IfModule>
