# StoryGen AI — root .htaccess for cPanel deployment.
# The repository root IS the web root (see CLAUDE.md). Laravel's
# application directories live alongside index.php, so we have to
# explicitly deny direct browser access to them.

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Forward authorization headers to PHP (needed for some auth flows).
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Drop trailing slashes from non-directory URLs.
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # ----- Deny direct access to Laravel application directories -----
    # If the request URL targets one of these directories (or anything
    # underneath it), return 403 Forbidden before the front controller
    # can run.
    RewriteRule ^(?:app|bootstrap|config|database|resources|routes|storage|tests|vendor|node_modules)(?:/|$) - [F,L,NC]

    # The legacy public/ directory still exists for some Laravel
    # internals but must not be browsable on this layout.
    RewriteRule ^public(?:/|$) - [F,L,NC]

    # ----- Deny direct access to sensitive files -----
    RewriteRule ^(?:\.env(?:\..*)?|\.git(?:/|$)|\.github(?:/|$)|\.htaccess|composer\.(?:json|lock)|package(?:-lock)?\.json|artisan|phpunit\.xml(?:\.dist)?|README\.md|CLAUDE\.md|.*\.example)$ - [F,L,NC]

    # ----- Front controller -----
    # Anything that isn't an existing file or directory falls through
    # to index.php, which boots Laravel.
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

# Belt-and-braces: even if mod_rewrite isn't loaded, deny dotfiles.
<FilesMatch "^\.">
    Require all denied
</FilesMatch>

# Likewise for these specific files.
<FilesMatch "^(composer\.(json|lock)|package(-lock)?\.json|artisan|phpunit\.xml(\.dist)?|README\.md|CLAUDE\.md)$">
    Require all denied
</FilesMatch>
