Options -Indexes
DirectoryIndex index.php

<IfModule mod_rewrite.c>
RewriteEngine On

ErrorDocument 403 /assets/error-pages/error.php?code=403
ErrorDocument 404 /assets/error-pages/error.php?code=404
ErrorDocument 500 /assets/error-pages/error.php?code=500
ErrorDocument 503 /assets/error-pages/error.php?code=503

# Preserve Authorization for PHP/FastCGI so CardDAV Basic auth reaches the app.
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

# Error page templates must stay directly executable because they are used
# before the normal application boot can be trusted.
RewriteRule ^assets/error-pages/(.+)$ system/assets/error-pages/$1 [L,QSA,NC]

# Block direct requests into application internals and non-public storage.
RewriteRule (^|/)\.(?!well-known/) - [F,L]
RewriteRule ^(?:includes|logs|\.metis-integrity|system/(?:config|docs|modules|src|tests|tools|cloudflare|vendor))(?:/|$) - [F,L,NC]
RewriteRule ^storage(?:/|$) - [F,L,NC]
RewriteRule ^(?:vendor)(?:/|$) - [F,L,NC]

# Route unknown requests through the front controller. The kernel classifies
# portal, AJAX, webhook, cron, and asset requests from REQUEST_URI.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L,QSA]
</IfModule>

<IfModule mod_setenvif.c>
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
</IfModule>

<IfModule mod_authz_core.c>
<FilesMatch "(?i)\.(?:env|ini|log|md|markdown|pem|key|crt|sql|sqlite3?|toml|txt|ya?ml|zip|bak|dist|old)$">
    Require all denied
</FilesMatch>
<FilesMatch "^(?i:composer\.(json|lock))$">
    Require all denied
</FilesMatch>
</IfModule>

<IfModule !mod_authz_core.c>
<FilesMatch "(?i)\.(?:env|ini|log|md|markdown|pem|key|crt|sql|sqlite3?|toml|txt|ya?ml|zip|bak|dist|old)$">
    Order allow,deny
    Deny from all
</FilesMatch>
<FilesMatch "^(?i:composer\.(json|lock))$">
    Order allow,deny
    Deny from all
</FilesMatch>
</IfModule>
