Options -Indexes -MultiViews
DirectoryIndex index.php

<IfModule mod_rewrite.c>
    RewriteEngine On

    # Protect application internals when the project root itself is web-accessible.
    # Deny every private/internal tree when the project root is web-accessible.
    RewriteRule ^(?:app|database|storage|cron|modules|docs|vendor|tests|backups?|private|tmp)(?:/|$) - [F,L,NC]

    # /public is an implementation directory in root-style deployments. Block only
    # a direct browser request; internal rewrites to public/assets remain allowed.
    RewriteCond %{THE_REQUEST} \s/+[^?\ ]*/public(?:[/\s?]) [NC]
    RewriteRule ^public(?:/|$) - [F,L,NC]

    # Serve shared assets when this project root is used as the web root.
    RewriteRule ^assets/(.*)$ public/assets/$1 [L,NC]

    # Relative clean-URL redirects preserve any installation subfolder.
    RewriteCond %{THE_REQUEST} \s/+[^?\ ]*/index\.php(?:[?\ ]) [NC]
    RewriteRule ^index\.php$ ./ [R=301,L,NE]

    RewriteCond %{THE_REQUEST} \s/+[^?\ ]*/reseller\.php(?:[?\ ]) [NC]
    RewriteRule ^reseller\.php$ domain-reseller [R=301,L,NE]

    RewriteCond %{THE_REQUEST} \s/+[^?\ ]*\.php(?:[?\ ]) [NC]
    RewriteRule ^(.+)\.php$ $1 [R=301,L,NE]

    # Explicit project-root routes (wrapper PHP files exist at this level).
    RewriteRule ^admin/?$ admin.php [L,QSA,NC]
    RewriteRule ^order/?$ order.php [L,QSA,NC]
    RewriteRule ^domain/?$ domain.php [L,QSA,NC]
    RewriteRule ^domain-pricing/?$ domain-pricing.php [L,QSA,NC]
    RewriteRule ^domain-reseller/?$ reseller.php [L,QSA,NC]
    RewriteRule ^health/?$ health.php [L,QSA,NC]
    RewriteRule ^install/?$ install.php [L,QSA,NC]
    RewriteRule ^upgrade/?$ upgrade.php [L,QSA,NC]
    RewriteRule ^repair-role/?$ repair_role.php [L,QSA,NC]
    RewriteRule ^api/reseller/?$ api/reseller.php [L,QSA,NC]

    # Generic future PHP page fallback.
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME}.php -f
    RewriteRule ^(.+?)/?$ $1.php [L,QSA]
</IfModule>

<FilesMatch "(?i)^(?:config\.php|config\.example\.php|README(?:-[^/]*)?\.md|SECURITY\.md|UPGRADE-[^/]+\.txt|\.env|\.user\.ini|composer\.(?:json|lock))$">
    Require all denied
</FilesMatch>

<IfModule mod_headers.c>
    Header always unset X-Powered-By
    Header unset X-Powered-By
    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"
</IfModule>

# HostDesk v1.9 security hardening
ServerSignature Off
FileETag None
<IfModule mod_rewrite.c>
    RewriteCond %{REQUEST_METHOD} ^(?:TRACE|TRACK)$ [NC]
    RewriteRule .* - [F,L]
</IfModule>
<FilesMatch "(?i)(^\.|(?:~|\.swp|\.swo)$|\.(?:sql|sqlite|db|bak|backup|old|orig|save|tmp|temp|log|ini|env|dist|md|txt|json|xml|yml|yaml|lock|zip|rar|7z|tar|tgz|gz|bz2|xz|phar)$)">
    Require all denied
</FilesMatch>
<IfModule mod_headers.c>
    Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()"
    Header always set X-Permitted-Cross-Domain-Policies "none"
</IfModule>
