Options -Indexes
DirectoryIndex index.php index.html


# cPanel/shared-hosting parity: disable Apache content negotiation so an
# extensionless request never selects a different legacy file than localhost.
<IfModule mod_negotiation.c>
    Options -MultiViews
</IfModule>

AddDefaultCharset UTF-8
FileETag MTime Size

<IfModule mod_mime.c>
    AddType text/css .css
    AddType application/javascript .js
    AddType application/json .json
    AddType image/svg+xml .svg
    AddType image/webp .webp
    AddType application/pdf .pdf
</IfModule>

# Cache public assets without caching protected PHP/JSON responses.
# Static HTML revalidates quickly; versioned CSS/JS and generated media stay fast.
<IfModule mod_headers.c>
    Header always unset X-Powered-By
    <FilesMatch "\.(?:php|json)$">
        Header always set Cache-Control "no-store, no-cache, must-revalidate, max-age=0"
        Header always set Pragma "no-cache"
        Header always set Expires "0"
    </FilesMatch>
    <FilesMatch "\.(?:html?|aspx)$">
        Header always set Cache-Control "public, max-age=300, must-revalidate"
    </FilesMatch>
    <FilesMatch "\.(?:css|js)$">
        Header always set Cache-Control "public, max-age=604800, stale-while-revalidate=86400"
    </FilesMatch>
    <FilesMatch "\.(?:png|jpe?g|gif|svg|webp|ico)$">
        Header always set Cache-Control "public, max-age=2592000, stale-while-revalidate=604800"
    </FilesMatch>
    <FilesMatch "\.(?:woff2?|ttf|otf)$">
        Header always set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>
    <FilesMatch "\.pdf$">
        Header always set Cache-Control "public, max-age=86400, must-revalidate"
    </FilesMatch>
</IfModule>

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript application/json image/svg+xml
</IfModule>

<IfModule mod_rewrite.c>
    RewriteEngine On
# MYCDIC protected runtime configuration - never serve private integration secrets.
# MYCDIC deployment-source protection: Google Apps Script sources, manifests, and internal deployment notes are never public web assets.
RewriteRule ^integrations/.*\.(?:gs|md)$ - [F,L,NC]
RewriteRule ^integrations/appsscript_.*\.json$ - [F,L,NC]
RewriteRule ^PRODUCTION_DEPLOYMENT_FILES(?:/|$) - [F,L,NC]
RewriteRule ^_INSTALL(?:/|$) - [F,L,NC]
RewriteRule ^(?:VERSION_|RELEASE_|INSTALLATION_|QA_|SHA256SUMS_|SECURITY_|DEPLOYMENT_).*\.(?:txt|md|json)$ - [F,L,NC]
RewriteRule ^(?:COUNCIL_|INSIGHTS_|NETWORK_|PUBLIC_|SEARCH_|TERRITORIAL_|MYCDIC_INSIGHTS_OBSERVATORY_MANUAL).*\.txt$ - [F,L,NC]
RewriteRule (?:^|/)(?:README_)?DEPLOYMENT[^/]*\.txt$ - [F,L,NC]
RewriteRule \.md$ - [F,L,NC]
# Security hardening: block backup, secret and development artifact extensions.
RewriteRule \.(?:env|log|sql|sqlite|db|bak|old|orig|save|sh|key|yml|yaml|lock|dist|phar)(?:$|/) - [F,L,NC]
RewriteRule ^(?:SECURITY_AUDIT_FINAL|SECURITY_HARDENING_CHANGELOG|CLOUDFLARE_SECURITY_NEXT_PHASE)\.md$ - [F,L,NC]

RewriteRule ^\.private(?:/|$) - [F,L,NC]
RewriteRule ^mycdic-private(?:/|$) - [F,L,NC]
RewriteRule ^data/(?:private|runtime|security|audit|applications|application-runtime)(?:/|$) - [F,L,NC]

    # Reject obsolete request methods that should never reach MYCDIC application handlers.
    RewriteCond %{REQUEST_METHOD} ^(?:TRACE|TRACK)$ [NC]
    RewriteRule ^ - [F,L]
    # Keep ACME/hosting validation paths reachable before canonical redirects.
    RewriteRule ^\.well-known/ - [L]

    # Reject unexpected Host headers before application routing. Localhost is accepted only from loopback for controlled checks.
    RewriteCond %{HTTP_HOST} ^(?:localhost|127\.0\.0\.1)(?::[0-9]+)?$ [NC]
    RewriteCond %{REMOTE_ADDR} !^(?:127\.0\.0\.1|::1)$
    RewriteRule ^ - [R=400,L]
    RewriteCond %{HTTP_HOST} !^(?:www\.)?mycdic\.org(?::[0-9]+)?$ [NC]
    RewriteCond %{HTTP_HOST} !^(?:localhost|127\.0\.0\.1)(?::[0-9]+)?$ [NC]
    RewriteRule ^ - [R=400,L]

    # Canonical public origin: one HTTPS host prevents duplicate HTTP/www variants.
    # Proxy-aware so cPanel/CDN HTTPS forwarding does not create redirect loops.
    RewriteCond %{HTTP_HOST} ^mycdic\.org(?::[0-9]+)?$ [NC]
    RewriteRule ^ https://www.mycdic.org%{REQUEST_URI} [R=301,L,NE]
    RewriteCond %{HTTP_HOST} ^www\.mycdic\.org(?::[0-9]+)?$ [NC]
    RewriteCond %{HTTPS} !=on
    RewriteCond %{HTTP:X-Forwarded-Proto} !^https$ [NC]
    RewriteRule ^ https://www.mycdic.org%{REQUEST_URI} [R=301,L,NE]

    # v1.9.16.3.5 search-authority cleanup: retire the historical /claude/ tree
    # without sending unrelated obsolete URLs to the home page.
    RewriteRule ^claude/documents/(.+)$ https://www.mycdic.org/documents/$1 [R=301,L,NE,NC]
    RewriteRule ^claude/advisors/?$ https://www.mycdic.org/advisors.aspx [R=301,L,NE,NC]
    RewriteCond %{DOCUMENT_ROOT}/$1.html -f
    RewriteRule ^claude/([a-z0-9-]+)/?$ https://www.mycdic.org/$1.aspx [R=301,L,NE,NC]
    RewriteRule ^claude(?:/.*)?$ - [G,L,NC]

    # One stable canonical President entity URL. Historical routes remain valid
    # through permanent redirects; the application is still presidents-note.php internally.
    RewriteRule ^president/?$ presidents-note.php [L,NC]
    RewriteRule ^(?:presidents-note|president)\.(?:html|aspx)$ https://www.mycdic.org/president/ [R=301,L,NE,NC]
    RewriteRule ^data/platform(?:/|$) - [L,NC]
    RewriteRule ^data/search-authority\.json$ - [F,L,NC]
    RewriteRule ^data/(?:insights-[a-z0-9-]+|youth-in-morocco-pages|search-authority-expansion)\.json$ - [F,L,NC]
    RewriteRule ^data/platform-defaults(?:/|$) - [F,L,NC]
    RewriteRule ^data/territorial-geography(?:/|$) - [F,L,NC]
    RewriteRule ^templates(?:/|$) - [F,L,NC]


    # v1.9.16.3.1 canonical short URL for the MYCDIC Youth Diplomacy Summit.
    RewriteCond %{THE_REQUEST} \s/+events/youth-diplomacy-summit-2027/?(?:[?\s]) [NC]
    RewriteRule ^events/youth-diplomacy-summit-2027/?$ /summit [R=301,L,NE]

    # MYCDIC v1.9.16.2 ASPX public URL veneer.
    # The application remains PHP/HTML internally. Only HTML page URLs are presented
    # as .aspx. PHP endpoints, JSON, uploads, dashboards and integrations are untouched.

    # Exact legacy aliases must resolve in one hop before the generic HTML veneer.
    RewriteRule ^join-us(?:/join-us)?\.html$ https://www.mycdic.org/join-us/ [R=301,L,NE,NC]
    RewriteRule ^transparency-governance\.html$ https://www.mycdic.org/documents.aspx [R=301,L,NE,NC]
    RewriteRule ^media-press\.html$ https://www.mycdic.org/news/default/news.php [R=301,L,NE,NC]
    RewriteRule ^Cultural_office\.html$ https://www.mycdic.org/celebrity-office.aspx [R=301,L,NE,NC]
    RewriteRule ^all-ambassadors\.html$ https://www.mycdic.org/ambassadors.aspx [R=301,L,NE,NC]
    # strategic-initiatives.html canonicalizes to /strategic-initiatives.aspx; the canonical route is dashboard-backed PHP below.

    # v1.9.17.1.3 unified public verification platform.
    # Member verification intentionally remains independent at /membership-verify/.
    RewriteRule ^document-verify\.php$ /verification-center.aspx?type=document [R=301,L,NE,QSA]
    RewriteRule ^event-certificate-verify\.(?:html|aspx)$ /verification-center.aspx?type=certificate [R=301,L,NE,QSA,NC]
    RewriteRule ^join-us/verify\.(?:html|aspx)$ /verification-center.aspx?type=application [R=301,L,NE,QSA,NC]
    RewriteRule ^request-track\.(?:html|aspx)$ /verification-center.aspx?type=request [R=301,L,NE,QSA,NC]

    # Old public .html requests permanently canonicalize to .aspx. THE_REQUEST makes
    # this safe after the internal .aspx -> .html rewrite and prevents redirect loops.
    RewriteCond %{THE_REQUEST} \s/+(.+?)\.html(?:[?\s]) [NC]
    RewriteRule ^(.+)\.html$ /$1.aspx [R=301,L,NE]

    # Historical aliases without a physical root HTML file.
    RewriteRule ^join-us\.aspx$ join-us/index.html [L,NC]
    RewriteRule ^transparency-governance\.aspx$ documents.php [L,NC]
    RewriteRule ^media-press\.aspx$ news/default/news.php [L,NC]
    RewriteRule ^all-ambassadors\.aspx$ ambassadors.html [L,NC]

    # Dashboard-managed operating model.
    RewriteRule ^how-mycdic-operates\.aspx$ how-mycdic-operates.php [L,NC]

    # Dynamic public sitemap keeps the established .aspx canonical URL while reading live public registries.
    RewriteRule ^plan-du-site\.aspx$ plan-du-site.php [L,NC]

    # v1.9.16.3 authority, research and verification public systems.
    RewriteRule ^media-evidence\.aspx$ media-evidence.php [L,NC]
    RewriteRule ^partnerships\.aspx$ partnerships.php [L,NC]
    RewriteRule ^partnerships/([a-z0-9-]+)/?$ partnership-detail.php?slug=$1 [QSA,L,NC]

    # Dashboard-managed Advisory, Honorary and Celebrity Office pages.
    RewriteRule ^advisors\.aspx$ special-office.php?office=advisory [QSA,L,NC]
    RewriteRule ^Honorary_office\.aspx$ special-office.php?office=honorary [QSA,L,NC]
    RewriteRule ^celebrity-office\.aspx$ special-office.php?office=celebrity [QSA,L,NC]
    RewriteRule ^elite-board\.aspx$ /celebrity-office.aspx [R=301,L,NE,NC]
    RewriteRule ^advisors/([a-z0-9-]+)/?$ special-person.php?office=advisory&slug=$1 [QSA,L,NC]
    RewriteRule ^honorary/([a-z0-9-]+)/?$ special-person.php?office=honorary&slug=$1 [QSA,L,NC]
    RewriteRule ^celebrity/([a-z0-9-]+)/?$ special-person.php?office=celebrity&slug=$1 [QSA,L,NC]
    RewriteRule ^partnership-registry\.aspx$ partnership-registry.php [L,NC]
    RewriteRule ^impact-dashboard\.aspx$ impact-dashboard.php [L,NC]
    RewriteRule ^youth-diplomacy-observatory\.aspx$ youth-diplomacy-observatory.php [L,NC]
    RewriteRule ^knowledge-graph\.aspx$ knowledge-graph.php [L,NC]
    RewriteRule ^verification-center\.aspx$ verification-center.php [L,NC]
    RewriteRule ^trust-center\.aspx$ trust-center.php [L,NC]

    # v1.9.28.3 institutional refresh routes. Keep these before the generic physical HTML rewrite.
    RewriteRule ^documents\.aspx$ documents.php [L,NC]
    RewriteRule ^documents/records/?$ /documents.aspx#document-register [R=302,L,NE,NC]
    RewriteRule ^documents/records/([a-z0-9-]+)/?$ institutional-document.php?id=$1 [QSA,L,NC]
    RewriteRule ^organizational-chart\.aspx$ organizational-chart.php [L,NC]
    RewriteRule ^missions-and-legal-framework\.aspx$ institutional-mandate.php [L,NC]
    RewriteRule ^vision-2030\.aspx$ vision-2030.php [L,NC]
    RewriteRule ^vision-2045\.aspx$ vision-2045.php [L,NC]
    RewriteRule ^official-registration-summary\.aspx$ official-registration-summary.php [L,NC]
    RewriteRule ^headquarters-information\.aspx$ headquarters-information.php [L,NC]
    RewriteRule ^strategic-initiatives\.aspx$ strategic-initiatives.php [L,NC]
    RewriteRule ^appointment-notices\.aspx$ appointment-notices-page.php [L,NC]
    RewriteRule ^regulations\.aspx$ regulations-page.php [L,NC]
    RewriteRule ^integrity-center\.aspx$ integrity-center.php [L,NC]

    # v1.9.30.0 Search Authority, MYCDIC Insights and live Insights directory.
    RewriteRule ^youth-in-morocco/?$ youth-in-morocco.php [L,NC]
    RewriteRule ^youth-in-morocco/([a-z0-9-]+)/?$ youth-in-morocco.php?slug=$1 [QSA,L,NC]
    RewriteRule ^insights/?$ insights/index.php [L,NC]
    RewriteRule ^insights/all/?$ insights/all.php [L,NC]
    RewriteRule ^insights/feed\.xml$ insights/feed.xml.php [L,NC]
    RewriteRule ^insights/topic/([a-z0-9-]+)/?$ insights/topic.php?slug=$1 [QSA,L,NC]
    RewriteRule ^insights/author/([a-z0-9-]+)/?$ insights/author.php?slug=$1 [QSA,L,NC]
    RewriteRule ^insights/([a-z0-9-]+)/?$ insights/article.php?slug=$1 [QSA,L,NC]

    # v1.9.17 institutional authority hubs.
    RewriteRule ^issues/?$ global-issues.php [L,NC]
    RewriteRule ^issues/([a-z0-9-]+)/?$ issue.php?slug=$1 [QSA,L,NC]
    RewriteRule ^knowledge/?$ knowledge-hub.php [L,NC]
    RewriteRule ^knowledge/([a-z0-9-]+)/?$ knowledge-item.php?slug=$1 [QSA,L,NC]
    RewriteRule ^annual-reports/?$ annual-reports.php [L,NC]
    RewriteRule ^annual-reports/([a-z0-9-]+)/?$ annual-report.php?slug=$1 [QSA,L,NC]

    # Dashboard-backed institutional office pages must resolve before the generic physical HTML fallback.
    RewriteRule ^national-office-rabat\.aspx$ legacy-office.php?office=national-office [QSA,L]
    RewriteRule ^international-office-brussels\.aspx$ legacy-office.php?office=international-office [QSA,L]
    RewriteRule ^general-secretariat\.aspx$ legacy-office.php?office=general-secretariat [QSA,L]

    # v1.9.31.1 dynamic territorial geography routes. Catalog-backed planning pages do not require physical folders.
    RewriteRule ^network/([a-z0-9-]+)/territory/?$ territorial-directory.php?representation=$1 [QSA,L,NC]
    RewriteRule ^network/([a-z0-9-]+)/local/([a-z0-9-]+)/?$ territorial-office.php?representation=$1&node=$2 [QSA,L,NC]
    RewriteRule ^morocco/regions/([a-z0-9-]+)/?$ morocco-region.php?region=$1 [QSA,L,NC]
    RewriteRule ^morocco/cities/([a-z0-9-]+)/?$ morocco-city.php?city=$1 [QSA,L,NC]

    # Every physical HTML page can be requested through the corresponding .aspx URL.
    RewriteCond %{DOCUMENT_ROOT}/$1.html -f
    RewriteRule ^(.+)\.aspx$ $1.html [L,NC]
    RewriteRule (^|/)\.(?!well-known(?:/|$)) - [F,L]
    RewriteRule ^members(?:/|\.php)?$ /membership-verify/ [R=301,L,NE]
    RewriteRule ^media-press(?:\.html)?$ /news/default/news.php [R=301,L,NE]
    RewriteRule ^Elite%20Board/?$ /elite-board/apply/ [R=301,L,NE]
    RewriteRule ^national-office-rabat\.html$ legacy-office.php?office=national-office [QSA,L]
    RewriteRule ^international-office-brussels\.html$ legacy-office.php?office=international-office [QSA,L]
    RewriteRule ^general-secretariat\.html$ legacy-office.php?office=general-secretariat [QSA,L]
    RewriteRule ^members/moataz-kobry/?$ https://www.mycdic.org/president/ [R=301,L,NE]
    RewriteRule ^leadership(?:\.html)?$ leadership.php [L]
    RewriteRule ^offices/presidency/?$ https://www.mycdic.org/president/ [R=301,L,NE]
    RewriteRule ^offices/national-office/?$ https://www.mycdic.org/national-office-rabat.aspx [R=301,L,NE]
    RewriteRule ^offices/international-office/?$ https://www.mycdic.org/international-office-brussels.aspx [R=301,L,NE]
    RewriteRule ^offices/general-secretariat/?$ https://www.mycdic.org/general-secretariat.aspx [R=301,L,NE]
    RewriteRule ^offices/advisory-office/?$ https://www.mycdic.org/advisors.aspx [R=301,L,NE]
    RewriteRule ^offices/honorary-office/?$ https://www.mycdic.org/Honorary_office.aspx [R=301,L,NE]
    RewriteRule ^offices/oversight-committee/?$ https://www.mycdic.org/integrity-center.aspx [R=301,L,NE]
    RewriteRule ^offices/operations-administration/?$ https://www.mycdic.org/how-mycdic-operates.aspx#operations [R=301,L,NE]
    RewriteRule ^offices/([a-z0-9-]+)/?$ office.php?office=$1 [QSA,L,NC]
    RewriteRule ^continents/([a-z0-9-]+)/?$ continent.php?continent=$1 [QSA,L]
    RewriteRule ^(fr|ar|am|es)$ /$1/ [R=301,L,NE]
    RewriteRule \.(?:log|ini|env|sql|bak|old|orig|dist|md|sha256|key)$ - [F,L,NC]
</IfModule>

<FilesMatch "^(?:composer\.(?:json|lock)|package(?:-lock)?\.json|README(?:\..*)?|to do\.txt|req\.txt)$">
    Require all denied
</FilesMatch>

<IfModule mod_rewrite.c>
    # Camera access is denied site-wide except for the unified Verification Center scanner.
    RewriteCond %{REQUEST_URI} ^/verification-center\.(?:aspx|php)$ [NC]
    RewriteRule ^ - [E=MYCDIC_CAMERA_ALLOWED:1]
</IfModule>

<IfModule mod_headers.c>
    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"
    Header always set Permissions-Policy "camera=(self), microphone=(), geolocation=(), payment=(), usb=(), browsing-topics=(), interest-cohort=()" env=MYCDIC_CAMERA_ALLOWED
    Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), browsing-topics=(), interest-cohort=()" env=!MYCDIC_CAMERA_ALLOWED
</IfModule>


# MYCDIC v1.9.16.2 restricted administration perimeter
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^myc-ops-[a-f0-9]{18,32}/?$ institutional-admin/gateway.php [L,NC]
    RewriteRule ^(?:wp-login\.php|wp-admin(?:/.*)?|wordpress(?:/.*)?|administrator(?:/.*)?|admin-login(?:/.*)?|login(?:/.*)?|user/login(?:/.*)?|phpmyadmin(?:/.*)?|cpanel(?:/.*)?)$ security-notice.php [QSA,L,NC]
</IfModule>

ErrorDocument 403 /403.php
ErrorDocument 404 /404.php

# MYCDIC v1.9.12 dynamic SEO sitemap
<IfModule mod_rewrite.c>
    RewriteRule ^sitemap\.xml$ sitemap.xml.php [L]
    RewriteRule ^sitemaps/(core|authority|insights|news|knowledge|research|people|network|opportunities|images|pages|entities|representations|publications)\.xml$ sitemap-section.php?type=$1 [QSA,L,NC]
</IfModule>

# Defense-in-depth security headers. CSP is enforced in compatibility mode; inline legacy code remains allowed until nonce migration is complete.
<IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    Header always set Cross-Origin-Opener-Policy "same-origin"
    Header always set Cross-Origin-Resource-Policy "same-site"
    Header always set X-Permitted-Cross-Domain-Policies "none"
    Header always set X-DNS-Prefetch-Control "off"
    Header always set Origin-Agent-Cluster "?1"
    Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com https://unpkg.com https://cdn.jsdelivr.net https://www.paypal.com https://www.paypalobjects.com; style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com https://fonts.googleapis.com; font-src 'self' data: https://cdnjs.cloudflare.com https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://script.google.com https://script.googleusercontent.com https://www.paypal.com https://api-m.paypal.com https://api-m.sandbox.paypal.com; frame-src 'self' blob: https://www.google.com https://maps.google.com https://www.paypal.com https://www.sandbox.paypal.com; object-src 'none'; base-uri 'self'; form-action 'self' https://script.google.com https://www.paypal.com; frame-ancestors 'self'; upgrade-insecure-requests"
    Header always set Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://cdnjs.cloudflare.com https://unpkg.com https://cdn.jsdelivr.net https://www.paypal.com https://www.paypalobjects.com; style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com https://fonts.googleapis.com; font-src 'self' data: https://cdnjs.cloudflare.com https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://script.google.com https://script.googleusercontent.com https://www.paypal.com https://api-m.paypal.com https://api-m.sandbox.paypal.com; frame-src 'self' blob: https://www.google.com https://maps.google.com https://www.paypal.com https://www.sandbox.paypal.com; object-src 'none'; base-uri 'self'; form-action 'self' https://script.google.com https://www.paypal.com; frame-ancestors 'self'"
</IfModule>

# MYCDIC favicon and web app manifest MIME types
<IfModule mod_mime.c>
    AddType image/x-icon .ico
    AddType application/manifest+json .webmanifest
</IfModule>

# v1.7.8 English public request URLs
Redirect 301 /demande-informations.html /information-request.html
Redirect 301 /demande-assistance.html /assistance-request.html
Redirect 301 /envoyer-reclamation.html /submit-complaint.html
