# Defense-in-depth backup for the `^(user)/...` rules in the site root .htaccess.
# Keep the folder and extension lists in sync with them.
#
# InheritDownBefore pushes these rules down into every subdirectory and runs them
# first, so a plugin or theme shipping its own RewriteEngine cannot switch them
# off (getgrav/grav#4236). Everything here is deliberately FileInfo-class:
# `Require` is AuthConfig-class and returns 500 for the whole user/ tree on hosts
# that grant only `AllowOverride FileInfo` (getgrav/grav#4309).
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteOptions InheritDownBefore

    RewriteRule ^(config|env)/ - [F,NC]

    # The same two exceptions the site root makes: avatar images under
    # user/accounts (`avatars/<file>` for flatfile accounts, `<username>/<file>`
    # for Flex folder storage) and public asset uploads under user/data are
    # served; everything else in both folders is denied. The conditions read
    # REQUEST_URI, which is the whole original path, so they are written exactly
    # as they are in the root — a per-directory rule only sees the path below
    # this folder. Keep all three copies in sync.
    RewriteCond %{REQUEST_URI} !/user/accounts/[^/]+/[^/]+\.(jpe?g|png|gif|webp|avif|bmp|ico)$ [NC]
    RewriteRule ^accounts/ - [F,NC]
    RewriteCond %{REQUEST_URI} !\.(jpe?g|png|gif|webp|avif|bmp|ico|mp4|webm|ogg|ogv|mov|mp3|wav|m4a|flac|pdf|woff2|woff|ttf|otf|eot|css|js)$ [NC]
    RewriteRule ^data/ - [F,NC]
    RewriteRule (?i)\.(txt|md|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$ - [F]

    # `(^|/)`, not `^`: paths are relative to whichever folder the rules run in.
    RewriteRule (?i)(^|/)\. - [F]

    # The site root's front-controller rule no longer reaches us. `../index.php`,
    # not `/index.php`, or a subdirectory install lands on the wrong one.
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . ../index.php [L]
</IfModule>

# Backstop for the rules above. A subfolder that turns RewriteEngine on with
# `RewriteOptions Inherit` and then ends its own rules with an unconditional [L]
# never reaches them, because the inherited rules run last and [L] stops first.
# mod_alias is FileInfo-class like mod_rewrite, but it sits outside the rewrite
# pipeline and its rules merge into subdirectories instead of replacing what is
# there, so no [L] can reach past this. It only covers the file types, which is
# the case that matters: third-party packages, the ones that ship an .htaccess
# of their own (getgrav/grav#4236), install into user/plugins and user/themes.
#
# Deliberately unanchored. These rules only run for requests that resolve into
# this folder, which is what scopes them, and matching the tail rather than a
# leading /user/ keeps them correct for a Grav installed in a subdirectory.
# Keep the extension list in sync with the rule above.
<IfModule mod_alias.c>
    RedirectMatch 403 (?i)\.(txt|md|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$
    RedirectMatch 403 (?i)(^|/)\.
</IfModule>
