#  Basic configuration
user nginx;
worker_processes auto;
error_log /dev/stderr info;
pid /var/run/nginx.pid;
load_module "modules/ngx_mail_module.so";

events {
    worker_connections  1024;
}

http {
    # Standard HTTP configuration with slight hardening
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    access_log /dev/stdout;
    sendfile on;
    keepalive_timeout  65;
    server_tokens off;
    absolute_redirect off;
    resolver {{ RESOLVER }} valid=30s;

    {% if REAL_IP_HEADER %}
    real_ip_header {{ REAL_IP_HEADER }};
    {% endif %}

    {% if REAL_IP_FROM %}{% for from_ip in REAL_IP_FROM.split(',') %}
    set_real_ip_from {{ from_ip }};
    {% endfor %}{% endif %}

    # Header maps
    map $http_x_forwarded_proto $proxy_x_forwarded_proto {
      default $http_x_forwarded_proto;
      ''      $scheme;
    }

    # Disable the main http server when on kubernetes (port 80 and 443)
    {% if KUBERNETES_INGRESS != 'true' %}
    # Main HTTP server
    server {
      # Variables for proxifying
      set $admin {{ HOST_ADMIN }};
      set $antispam {{ HOST_ANTISPAM }};
      set $webmail {{ HOST_WEBMAIL }};
      set $webdav {{ HOST_WEBDAV }};

      # Always listen over HTTP
      listen 80;
      listen [::]:80;

      # Only enable HTTPS if TLS is enabled with no error
      {% if TLS and not TLS_ERROR %}
      listen 443 ssl http2;
      listen [::]:443 ssl http2;

      include /etc/nginx/tls.conf;
      ssl_session_cache shared:SSLHTTP:50m;
      add_header Strict-Transport-Security 'max-age=31536000';

      {% if not TLS_FLAVOR in [ 'mail', 'mail-letsencrypt' ] %}
      if ($proxy_x_forwarded_proto = http) {
        return 301 https://$host$request_uri;
      }
      {% endif %}
      {% endif %}

      add_header X-Frame-Options 'SAMEORIGIN';
      add_header X-Content-Type-Options 'nosniff';
      add_header X-Permitted-Cross-Domain-Policies 'none';
      add_header X-XSS-Protection '1; mode=block';
      add_header Referrer-Policy 'same-origin';

      # In any case, enable the proxy for certbot if the flavor is letsencrypt
      {% if TLS_FLAVOR in [ 'letsencrypt', 'mail-letsencrypt' ] %}
      location ^~ /.well-known/acme-challenge/ {
          proxy_pass http://127.0.0.1:8008;
      }
      {% endif %}

      # If TLS is failing, prevent access to anything except certbot
      {% if TLS_ERROR and not TLS_FLAVOR == "mail" %}
      location / {
        return 403;
      }
      {% else %}

      include /overrides/*.conf;

      # Actual logic
      {% if WEB_WEBMAIL != '/' %}
      location / {
      {% if WEBROOT_REDIRECT %}
        return 301 {{ WEBROOT_REDIRECT }};
      {% else %}
        return 404;
      {% endif %}
      }
      {% endif %}

      {% if WEBMAIL != 'none' %}
      location {{ WEB_WEBMAIL }} {
        {% if WEB_WEBMAIL != '/' %}
        rewrite ^({{ WEB_WEBMAIL }})$ $1/ permanent;
        rewrite ^{{ WEB_WEBMAIL }}/(.*) /$1 break;
        {% endif %}
        include /etc/nginx/proxy.conf;
        client_max_body_size {{ MESSAGE_SIZE_LIMIT|int + 8388608 }};
        proxy_pass http://$webmail;
      }
      {% endif %}

      {% if ADMIN == 'true' %}
      location {{ WEB_ADMIN }} {
        return 301 {{ WEB_ADMIN }}/ui;
      }

      location ~ {{ WEB_ADMIN }}/(ui|static) {
        rewrite ^{{ WEB_ADMIN }}/(.*) /$1 break;
        include /etc/nginx/proxy.conf;
        proxy_set_header X-Forwarded-Prefix {{ WEB_ADMIN }};
        proxy_pass http://$admin;
      }

      location {{ WEB_ADMIN }}/antispam {
        rewrite ^{{ WEB_ADMIN }}/antispam/(.*) /$1 break;
        auth_request /internal/auth/admin;
        proxy_set_header X-Real-IP "";
        proxy_set_header X-Forwarded-For "";
        proxy_pass http://$antispam;
      }
      {% endif %}

      {% if WEBDAV != 'none' %}
      location /webdav {
        rewrite ^/webdav/(.*) /$1 break;
        auth_request /internal/auth/basic;
        auth_request_set $user $upstream_http_x_user;
        include /etc/nginx/proxy.conf;
        proxy_set_header X-Remote-User $user;
        proxy_set_header X-Script-Name /webdav;
        proxy_pass http://$webdav;
      }

      location ~ ^/.well-known/(carddav|caldav) {
        return 301 /webdav/;
      }
      {% endif %}
      {% endif %}

      location /internal {
        internal;

        proxy_set_header Authorization $http_authorization;
        proxy_pass_header Authorization;
        proxy_pass http://$admin;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
      }

      location /health {
        return 204;
      }
    }
    {% endif %}

    # Forwarding authentication server
    server {
      # Variables for proxifying
      set $admin {{ HOST_ADMIN }};

      listen 127.0.0.1:8000;

      location / {
        proxy_pass http://$admin/internal$request_uri;
      }
    }
}

mail {
    server_name {{ HOSTNAMES.split(",")[0] }};
    auth_http http://127.0.0.1:8000/auth/email;
    proxy_pass_error_message on;
    resolver {{ RESOLVER }} valid=30s;

    {% if TLS and not TLS_ERROR %}
    include /etc/nginx/tls.conf;
    ssl_session_cache shared:SSLMAIL:50m;
    {% endif %}

    # Default SMTP server for the webmail (no encryption, but authentication)
    server {
      listen 10025;
      protocol smtp;
      smtp_auth plain;
    }

    # Default IMAP server for the webmail (no encryption, but authentication)
    server {
      listen 10143;
      protocol imap;
      smtp_auth plain;
    }

    # SMTP is always enabled, to avoid losing emails when TLS is failing
    server {
      listen 25;
      listen [::]:25;
      {% if TLS and not TLS_ERROR %}
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
      starttls on;
      {% endif %}
      protocol smtp;
      smtp_auth none;
    }

    # All other protocols are disabled if TLS is failing
    {% if not TLS_ERROR %}
    server {
      listen 143;
      listen [::]:143;
      {% if TLS %}
      starttls only;
      {% endif %}
      protocol imap;
      imap_auth plain;
    }

    server {
      listen 110;
      listen [::]:110;
      {% if TLS %}
      starttls only;
      {% endif %}
      protocol pop3;
      pop3_auth plain;
    }

    server {
      listen 587;
      listen [::]:587;
      {% if TLS %}
      starttls only;
      {% endif %}
      protocol smtp;
      smtp_auth plain;
    }

    {% if TLS %}
    server {
      listen 465 ssl;
      listen [::]:465 ssl;
      protocol smtp;
      smtp_auth plain login;
    }

    server {
      listen 993 ssl;
      listen [::]:993 ssl;
      protocol imap;
      imap_auth plain;
    }

    server {
      listen 995 ssl;
      listen [::]:995 ssl;
      protocol pop3;
      pop3_auth plain;
    }
    {% endif %}
    {% endif %}
}
