# =============================================================================
# Apache rewrite rules to expose client-facing endpoints WITHOUT the .php
# extension. The Android app calls extension-less URLs like /auth, /add, etc.
# (the Glass UrlRewriter strips path extensions).
#
# Drop this file in the panel root. On nginx, see panel/nginx.conf.sample
# for the equivalent rules.
# =============================================================================

<IfModule mod_rewrite.c>
RewriteEngine On

# Don't touch existing files / directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

# /api/guard/key            -> /api/guard/key.php
# /api/guard/bootstrap      -> /api/guard/bootstrap.php
RewriteRule ^api/guard/key$         api/guard/key.php       [L]
RewriteRule ^api/guard/bootstrap$   api/guard/bootstrap.php [L]

# /auth /add /update /delete /has_playlist
RewriteRule ^auth$           auth.php          [L]
RewriteRule ^add$            add.php           [L]
RewriteRule ^update$         update.php        [L]
RewriteRule ^delete$         delete.php        [L]
RewriteRule ^has_playlist$   has_playlist.php  [L,QSA]

# /parent-control/update    -> /parent-control/update.php
RewriteRule ^parent-control/update$  parent-control/update.php [L]

# Browser-friendly extensionless admin URLs: /login, /dashboard, /settings,
# /downloads, etc. The first cond-pair (already above) skips real files +
# dirs, so this rule only fires when the path doesn't physically exist. If
# the same path WITH .php does exist, rewrite to it. Bookmarkable URLs +
# typed URLs both work, and we don't have to enumerate every admin page.
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^./]+)$ $1.php [L]

# Same as above, for nested module pages (e.g. modules/support/health).
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(modules/[A-Za-z0-9_-]+/[A-Za-z0-9_-]+)$ $1.php [L]
</IfModule>

# Disable directory listing globally. cPanel ships with Options +Indexes,
# which would otherwise let anyone browse data/, uploads/, modules/, etc.
Options -Indexes

# Block direct access to includes/, data/, and the error log
<IfModule mod_authz_core.c>
    <Files ~ "\.(db|sqlite|sqlite3|db-shm|db-wal|log)$">
        Require all denied
    </Files>
</IfModule>

# Deny direct hits on the includes/ tree (sensitive helpers).
RedirectMatch 403 ^/.*/includes/.*$

# Block raw HTTP access to module.php manifests — they're consumed by PHP's
# include(), never meant to be served. Lets buyers run modules/<id>/<page>.php
# (the actual admin pages) but not enumerate which modules exist via the
# manifest file.
RedirectMatch 403 ^/.*/modules/[^/]+/module\.php$

# Deny direct access to the data/ and cron/ directories at the URL level.
# (Files inside cron/ require CLI; data/ is the SQLite home.)
RedirectMatch 403 ^/.*/data(/|$)
RedirectMatch 403 ^/.*/cron(/|$)

# Recommended security headers
#
# NOTE: do NOT set X-Frame-Options here — the panel's WebView preview pages
# legitimately embed same-origin iframes (sports_settings, slideshow_settings,
# frameview_settings, tmdb_settings, the QR live preview in app_config).
# We allow same-origin framing via CSP frame-ancestors instead, which is
# strictly stronger (browsers prefer CSP when both are set).
<IfModule mod_headers.c>
    Header always set X-Content-Type-Options "nosniff"
    Header always set Referrer-Policy "no-referrer"
    Header always set Content-Security-Policy "frame-ancestors 'self'"
</IfModule>
