# ChurchCRM Nginx Configuration
#
# This file configures nginx to correctly route requests to ChurchCRM's multiple
# PHP entry points. ChurchCRM uses a Slim 4 micro-framework architecture where
# each module (session, api, v2, admin, finance, etc.) is an independent PHP
# application with its own entry point (index.php) in its own subdirectory.
#
# Apache handles this automatically via per-directory .htaccess mod_rewrite rules.
# With nginx, each sub-application path must be explicitly mapped to its own
# index.php. Sending all requests to the root index.php causes an infinite
# redirect loop when unauthenticated users are redirected to /session/begin.
#
# HOW TO USE
# ----------
# 1. Mount this file to /etc/nginx/conf.d/default.conf in your nginx container.
# 2. Update `fastcgi_pass` to match your PHP-FPM container hostname and port.
# 3. Update `root` to the path where ChurchCRM's `src/` contents are served from.
# 4. For subdirectory installs (e.g., http://example.com/churchcrm/), see the
#    SUBDIRECTORY INSTALLATION section at the bottom of this file.
#
# FASTCGI HOST
# ------------
# Replace `php-fpm:9000` throughout with your PHP-FPM container name/port.
# In docker-compose, use the service name (e.g., `churchcrm-php:9000`).

server {
    listen 80;
    server_name _;

    # Document root: path to ChurchCRM's src/ directory
    root /var/www/html;
    index index.php;

    client_max_body_size 100M;

    # ── Security: block access to sensitive paths ─────────────────────────

    # Block .htaccess and other dot-files
    location ~ /\. {
        deny all;
        return 404;
    }

    # Block access to PHP error/session logs
    location ~ ^/logs(/|$) {
        deny all;
        return 404;
    }

    # Block access to uploaded file attachments (served via API only)
    location ~ ^/tmp_attach(/|$) {
        deny all;
        return 404;
    }

    # Block access to install-time configuration (Config.php, config-values.json,
    # bootstrap scripts). Nothing under Include/ should ever be served directly.
    # See GHSA-mp2w-4q3r-ppx7.
    location ~ ^/Include(/|$) {
        deny all;
        return 404;
    }

    # ── Slim sub-application routing ──────────────────────────────────────
    #
    # Each block below handles one of ChurchCRM's Slim 4 sub-applications.
    # The pattern:
    #   try_files $uri /<subdir>/index.php$is_args$args;
    # serves real static files directly and falls back to the sub-app's
    # index.php for all other requests (including clean URLs like /session/begin).
    #
    # `^~` prefix prevents regex locations from also matching these paths.

    # Session management: /session/begin, /session/end, /session/two-factor, etc.
    location ^~ /session {
        try_files $uri /session/index.php$is_args$args;

        location ~ \.php$ {
            fastcgi_pass   php-fpm:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }

    # REST API: /api/persons, /api/families, /api/events, etc.
    location ^~ /api {
        try_files $uri /api/index.php$is_args$args;

        location ~ \.php$ {
            fastcgi_pass   php-fpm:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }

    # Modern MVC pages: /v2/dashboard, /v2/people, etc.
    location ^~ /v2 {
        try_files $uri /v2/index.php$is_args$args;

        location ~ \.php$ {
            fastcgi_pass   php-fpm:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }

    # Admin panel: /admin/settings, /admin/users, etc.
    location ^~ /admin {
        try_files $uri /admin/index.php$is_args$args;

        location ~ \.php$ {
            fastcgi_pass   php-fpm:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }

    # Finance module: /finance/deposits, /finance/pledges, etc.
    location ^~ /finance {
        try_files $uri /finance/index.php$is_args$args;

        location ~ \.php$ {
            fastcgi_pass   php-fpm:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }

    # Kiosk / check-in module
    location ^~ /kiosk {
        try_files $uri /kiosk/index.php$is_args$args;

        location ~ \.php$ {
            fastcgi_pass   php-fpm:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }

    # Plugin system
    location ^~ /plugins {

        # Block direct HTTP execution of community/core plugin PHP files (GHSA-37mf-vq43-5qp9).
        # PHP is loaded by the app's PSR-4 autoloader; direct requests must be refused.
        # These nested locations are evaluated even under a ^~ parent.
        location ~ ^/plugins/community/.+\.(php|phar|phtml|pht|php[3-9])$ {
            deny all;
            return 404;
        }
        location ~ ^/plugins/core/.+\.(php|phar|phtml|pht|php[3-9])$ {
            deny all;
            return 404;
        }

        try_files $uri /plugins/index.php$is_args$args;

        location ~ \.php$ {
            fastcgi_pass   php-fpm:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }

    # External integrations (public calendar, self-registration, etc.)
    location ^~ /external {
        try_files $uri /external/index.php$is_args$args;

        location ~ \.php$ {
            fastcgi_pass   php-fpm:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }

    # Setup wizard (only needed on first install)
    location ^~ /setup {
        try_files $uri /setup/index.php$is_args$args;

        location ~ \.php$ {
            fastcgi_pass   php-fpm:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }

    # ── Static assets ──────────────────────────────────────────────────────

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|map)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        try_files $uri =404;
    }

    # ── Legacy / root routing ─────────────────────────────────────────────
    #
    # The root index.php is the legacy router for classic .php pages
    # (PersonEditor.php, FamilyEditor.php, etc.) as well as the smart URL
    # handler that converts dashed paths (e.g. /list-events -> ListEvents.php).
    # It is NOT a catch-all for the Slim sub-applications above.

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_pass   php-fpm:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

# ── SUBDIRECTORY INSTALLATION ─────────────────────────────────────────────────
#
# If ChurchCRM is installed at a subdirectory (e.g., http://example.com/churchcrm/),
# set $sRootPath = '/churchcrm' in Include/Config.php and replace the server block
# above with the following (prefix all location paths with /churchcrm):
#
# server {
#     listen 80;
#     server_name _;
#     root /var/www/html;
#     index index.php;
#     client_max_body_size 100M;
#
#     location ~ /\. { deny all; return 404; }
#     location ~ ^/churchcrm/logs(/|$) { deny all; return 404; }
#     location ~ ^/churchcrm/tmp_attach(/|$) { deny all; return 404; }
#     location ~ ^/churchcrm/Include(/|$) { deny all; return 404; }
#
#     location ^~ /churchcrm/session {
#         try_files $uri /churchcrm/session/index.php$is_args$args;
#         location ~ \.php$ {
#             fastcgi_pass php-fpm:9000;
#             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#             include fastcgi_params;
#         }
#     }
#     # ... repeat for api, v2, admin, finance, kiosk, plugins, external, setup
#
#     # Block direct HTTP execution of community/core plugin PHP (GHSA-37mf-vq43-5qp9).
#     # Deny blocks must be nested INSIDE location ^~ /churchcrm/plugins { } — not at server level.
#     location ^~ /churchcrm/plugins {
#         location ~ ^/churchcrm/plugins/community/.+\.(php|phar|phtml|pht|php[3-9])$ {
#             deny all;
#             return 404;
#         }
#         location ~ ^/churchcrm/plugins/core/.+\.(php|phar|phtml|pht|php[3-9])$ {
#             deny all;
#             return 404;
#         }
#         try_files $uri /churchcrm/plugins/index.php$is_args$args;
#         location ~ \.php$ {
#             fastcgi_pass php-fpm:9000;
#             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#             include fastcgi_params;
#         }
#     }
#
#     location /churchcrm {
#         try_files $uri $uri/ /churchcrm/index.php$is_args$args;
#     }
#     location ~ \.php$ {
#         fastcgi_pass php-fpm:9000;
#         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#         include fastcgi_params;
#     }
# }
