Bundle of cross-role changes for the gymb services deployment: - Traefik routers: OR-combine opnform/homarr/bookstack Host rules with new *_extra_domains (internal *.int.* FQDNs for a DMZ reverseproxy), and emit tls.certresolver only when traefik_cert_mode == acme (drawio, homarr, opnform, send). - Split-horizon: bookstack_extra_hosts / opnform_extra_hosts add container /etc/hosts overrides so containers reach the IdP public FQDN over the LAN. - bookstack: assert the OIDC issuer resolves concretely (reject "//v2.0"), allowing non-Entra IdPs that override bookstack_oidc_issuer. - homarr: derive the bcrypt salt from the password digest so the admin hash is idempotent — no spurious template changes / container restarts. - opnform: PATCH an existing OIDC connection instead of skipping (applies corrected inventory on re-run); add OIDC_FORCE_LOGIN (enabled only after bootstrap) and an optional direct-SSO ingress entrypoint. Docs: READMEs and meta/argument_specs.yml updated for all new variables.
54 lines
2.6 KiB
Django/Jinja
54 lines
2.6 KiB
Django/Jinja
map $original_uri $api_uri {
|
|
~^/api(/.*$) $1;
|
|
default $original_uri;
|
|
}
|
|
|
|
server {
|
|
listen 80;
|
|
server_name {{ opnform_domain }};
|
|
root /app/public;
|
|
|
|
client_max_body_size {% raw %}${NGINX_MAX_BODY_SIZE}{% endraw %};
|
|
|
|
access_log /dev/stdout;
|
|
error_log /dev/stderr error;
|
|
|
|
index index.html index.htm index.php;
|
|
|
|
{% if opnform_oidc_enabled and opnform_oidc_sso_entrypoint %}
|
|
# Direct-SSO entrypoint: a tiny page that asks the API for the IdP
|
|
# authorize URL (no email/domain check on this endpoint) and forwards
|
|
# the browser there. Link users here instead of /login to skip the
|
|
# email field entirely. Exact-match so it wins over the `/` prefix.
|
|
location = {{ opnform_oidc_sso_path }} {
|
|
default_type text/html;
|
|
return 200 '<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Redirecting to sign-in…</title></head><body style="font-family:sans-serif;text-align:center;padding:3rem;color:#374151"><p id="m">Redirecting to sign-in…</p><script>fetch("/api/auth/{{ opnform_oidc_slug }}/redirect",{method:"POST",headers:{Accept:"application/json"}}).then(function(r){if(!r.ok)throw new Error("HTTP "+r.status);return r.json()}).then(function(d){if(d&&d.redirect_url){window.location.replace(d.redirect_url)}else{throw new Error("no redirect_url")}}).catch(function(e){document.getElementById("m").textContent="Sign-in redirect failed: "+e.message+". Go to the login page instead.";var a=document.createElement("a");a.href="/login";a.textContent="Open login page";a.style.display="block";a.style.marginTop="1rem";document.body.appendChild(a)});</script></body></html>';
|
|
}
|
|
|
|
{% endif %}
|
|
location / {
|
|
proxy_http_version 1.1;
|
|
proxy_pass http://ui:3000;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header X-Forwarded-Host $host;
|
|
proxy_set_header X-Forwarded-Port $server_port;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "Upgrade";
|
|
}
|
|
|
|
location ~/(api|open|local\/temp|forms\/assets)/ {
|
|
set $original_uri $uri;
|
|
try_files $uri $uri/ /index.php$is_args$args;
|
|
}
|
|
|
|
location ~ \.php$ {
|
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
|
fastcgi_pass api:9000;
|
|
fastcgi_index index.php;
|
|
include fastcgi_params;
|
|
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/public/index.php;
|
|
fastcgi_param REQUEST_URI $api_uri;
|
|
}
|
|
}
|