# Indomed API - upload this alongside the PHP files, into api/.
#
# WRITTEN DEFENSIVELY ON PURPOSE; the lessons below were paid for on a
# sister project. Please do not "simplify" them back out.

# --- keep bearer tokens working -----------------------------------------
# Some Apache/cPanel setups strip the Authorization header before PHP sees
# it, which silently breaks token auth and looks exactly like a wrong
# password. This is the one rule the API cannot work without.
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>

# --- force HTTPS (skipped for local XAMPP) --------------------------------
# Login credentials, bearer tokens and medical reports must never cross
# plain HTTP.
#
# LESSON 1: the forwarded-protocol checks are not optional. Testing only
# %{HTTPS} hangs every endpoint in an infinite redirect loop behind
# Cloudflare, which terminates TLS and forwards to the origin over plain
# HTTP. Every condition must hold before redirecting.
# LESSON 3: the host exemption must cover every address DEVELOPMENT
# reaches this server by, not just "localhost". The Android emulator
# calls the host machine 10.0.2.2 and a real phone on wifi uses the
# PC LAN IP, so both sent Host: <private-ip> - and a localhost-only
# exemption answered them with 301 -> https://<private-ip>, which
# XAMPP does not serve. The app then failed instantly with a bare
# connection error while curl on localhost kept working, which is
# exactly the sort of split that wastes an afternoon. Private ranges
# are safe to exempt: a public production host is never reached at
# 10.x, 192.168.x or 172.16-31.x, so this cannot weaken live HTTPS.
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^(localhost|127\.0\.0\.1|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)
    RewriteCond %{HTTPS} !=on
    RewriteCond %{HTTP:X-Forwarded-Proto} !=https
    RewriteCond %{HTTP:X-Forwarded-SSL} !=on
    RewriteCond %{HTTP:CF-Visitor} !https
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

# --- block anything that is not a live endpoint --------------------------
# The archive extensions matter most: a deploy bundle would contain
# config.php with the database password in plain text, and one guessed URL
# hands it to anyone. Never rely on nobody knowing the filename. schema.sql
# lives in this folder and is covered by the sql extension below.
#
# LESSON 2: guard directives that not every host accepts. A .htaccess that
# Apache cannot parse does not fail quietly - it returns 500 for every
# request in the directory. mod_authz_core is Apache 2.4; the Order/Deny
# form is 2.2. Shipping both means this parses on either.
<FilesMatch "(?i)\.(sql|md|log|ini|zip|tar|gz|tgz|bz2|rar|7z|bak|old|orig|swp|env|json|txt|dist|sample|sqlite|db|pem|key|crt|yml|yaml|xml|conf|cfg|htpasswd)$">
    <IfModule mod_authz_core.c>
        Require all denied
    </IfModule>
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Deny from all
    </IfModule>
</FilesMatch>

# Diagnostic scripts are dead on arrival, even if one gets uploaded by
# mistake. Defence in depth, not a substitute for never uploading them.
<FilesMatch "(?i)^(phpinfo|test|info|adminer|dbtest|admin_debug|diag_charset)\.php$">
    <IfModule mod_authz_core.c>
        Require all denied
    </IfModule>
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Deny from all
    </IfModule>
</FilesMatch>

# --- directory listing ---------------------------------------------------
# "Options -Indexes" needs AllowOverride Options on the host and 500s the
# whole directory where that is not granted. IndexIgnore asks more politely
# and degrades harmlessly.
<IfModule mod_autoindex.c>
    IndexIgnore *
</IfModule>
