Options -Indexes -MultiViews
DirectoryIndex index.php

<IfModule mod_rewrite.c>
RewriteEngine On

# Private application internals are never public URLs.
RewriteRule ^(?:bin|config|inc|lang|database|docs|tests|Storage|storage)(?:/|$) - [F,L,NC]
RewriteRule ^tests[^/]*\.php$ - [F,L,NC]

# Reject any filesystem-looking URL instead of trying to canonicalize it.
RewriteCond %{REQUEST_URI} (?:^|/)(?:home/[^/]+/public_html|public_html|\.\.|%2e%2e)(?:/|$) [NC]
RewriteRule ^ - [R=404,L]

# HTTPS is a transport-security rule, not an application routing redirect.
# L'hôte réellement demandé est conservé : le même paquet peut être servi sous
# plusieurs domaines (kalymatt.org, linh-studio.com) sans redirection croisée.
# Exception locale de recette : localhost/127.0.0.1 reste en clair pour que le serveur
# de recette (Apache local sans TLS) reproduise exactement la production.
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} !^(?:localhost|127\.0\.0\.1)(?::[0-9]+)?$ [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]

# Public landing and authenticated home are distinct, direct pages.
RewriteRule ^$ index.php [L]
RewriteRule ^home/?$ home.php [L,QSA]
RewriteRule ^login/?$ login.php [L,QSA]
RewriteRule ^logout/?$ logout.php [L,QSA]
RewriteRule ^forgot-password/?$ forgot-password.php [L,QSA]
RewriteRule ^reset-password/([a-f0-9]{64})/?$ reset-password.php?token=$1 [L,QSA,NC]

# Direct application routes. No alias/canonical redirect routes.
RewriteRule ^files/?$ explorer.php [L,QSA]
RewriteRule ^search/?$ search.php [L,QSA]
RewriteRule ^restorations/?$ restorations.php [L,QSA]
RewriteRule ^agenda/?$ agenda.php [L,QSA]
RewriteRule ^studio/?$ studio.php [L,QSA]
RewriteRule ^account/?$ account.php [L,QSA]
RewriteRule ^business-suite/?$ business-suite.php [L,QSA]
RewriteRule ^business-suite/mes-donnees/?$ mes-donnees.php [L,QSA]
RewriteRule ^media/?$ media.php [L,QSA]
RewriteRule ^media/d/([A-Za-z0-9_-]+)/?$ media.php?rid=$1 [L,QSA]
RewriteRule ^business-suite/d/([A-Za-z0-9_-]+)/?$ business-suite-workspace.php?rid=$1 [L,QSA]
RewriteRule ^business-suite/import/([A-Za-z0-9_-]+)/?$ business-suite-import.php?rid=$1 [L,QSA]
RewriteRule ^business-suite/d/([A-Za-z0-9_-]+)/export/([A-Za-z0-9_-]+)/?$ business-suite-export.php?rid=$1&format=$2 [L,QSA]
RewriteRule ^journal/?$ blog.php [L,QSA]
RewriteRule ^messages/?$ messages.php [L,QSA]
RewriteRule ^messages/attachment/([A-Za-z0-9_-]+)/?$ chat_attachment.php?rid=$1 [L,QSA]
RewriteRule ^shares/?$ shares.php [L,QSA]
# Concealed direction route: opaque and direct.
RewriteRule ^p/([A-Za-z0-9_-]{32,96})/?$ admin.php?gate=$1 [L,QSA]
RewriteRule ^p/([A-Za-z0-9_-]{32,96})/users/?$ api/admin_users.php?gate=$1 [L,QSA]
RewriteRule ^pricing/?$ pricing.php [L,QSA]
RewriteRule ^about/?$ about.php [L,QSA]
RewriteRule ^privacy/?$ privacy.php [L,QSA]
RewriteRule ^rgpd/?$ rgpd.php [L,QSA]
RewriteRule ^terms/?$ terms.php [L,QSA]
RewriteRule ^file/([A-Za-z0-9_-]+)/download/?$ download.php?rid=$1 [L,QSA]
RewriteRule ^folder-download/?$ download-folder.php [L,QSA]
RewriteRule ^file/([A-Za-z0-9_-]+)/preview/?$ preview.php?rid=$1 [L,QSA]
RewriteRule ^s/([a-f0-9]{64})/?$ share.php?token=$1 [L,QSA,NC]
RewriteRule ^s/([a-f0-9]{64})/file/([A-Za-z0-9_-]+)/?$ share.php?token=$1&rid=$2 [L,QSA,NC]

# Root PHP implementation files are never browser-facing aliases.
# Clean application URLs above are the only public page routes. Seuls les points d'API
# /api/*.php restent appelés directement par le navigateur (jeton CSRF et session vérifiés
# dans les scripts eux-mêmes). Contrôle indépendant du préfixe public (/Private,
# /Private-Spaces, racine du site) et insensible à la query string.
RewriteCond %{THE_REQUEST} \s[^?\s]*\.php(?:[?\s]) [NC]
RewriteCond %{THE_REQUEST} !\s[^?\s]*/api/ [NC]
RewriteRule ^ - [R=404,L]
# The concealed direction API must also never reveal its physical PHP path.
RewriteCond %{THE_REQUEST} \s[^?\s]*/api/admin_users\.php(?:[?\s]) [NC]
RewriteRule ^ - [R=404,L]
</IfModule>

<FilesMatch "^(?:\.env|composer\.(?:json|lock)|README\.md|phpunit\.xml|.*\.log)$">
  Require all denied
</FilesMatch>

# PS_STUDIO_NO_CACHE — interdire la reutilisation d'un ancien JavaScript ou CSS.
<IfModule mod_headers.c>
  <FilesMatch "\.(?:js|mjs|css|html?)$">
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header unset Expires
  </FilesMatch>
</IfModule>
