🐛 Fix Admin Console URLs escaped twice

The Admin Console location built its proxy_pass target from a capture of
$request_uri, which nginx escapes again when the path has escaped
characters: %XX became %25XX and the query string ended up in the path,
so Admin Console links returned 404. Strip the prefix with a rewrite and
let proxy_pass forward the rewritten URI instead.

AI-assisted-by: Claude
Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>
This commit is contained in:
David Barragán Merino 2026-10-21 12:09:08 +00:00 committed by David Barragán Merino
parent 1d54d170cf
commit 95bc48a08a
2 changed files with 10 additions and 14 deletions

View File

@ -1,14 +1,11 @@
# The Admin Console is served at the root of its own server: strip the public
# path and admin-console/ from the original request URI.
# The Admin Console is served at the root of its own server. Keep proxy_pass
# without a URI: building it from $request_uri escapes the path twice.
location /admin-console {
set $admin_console_uri "/";
if ($request_uri ~ "^${PENPOT_PUBLIC_PATH_REGEX}admin-console(/.*)$") {
set $admin_console_uri $1;
}
rewrite "^/admin-console(?:/(.*))?$" /$1 break;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $http_cf_connecting_ip;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass $PENPOT_ADMIN_CONSOLE_URI$admin_console_uri;
proxy_pass $PENPOT_ADMIN_CONSOLE_URI;
}

View File

@ -53,18 +53,17 @@ update_oidc_name /var/www/app/js/config.js
# Path of PENPOT_PUBLIC_URI (e.g. /penpot/ for https://example.com/penpot/).
# Requests below it are rewritten to the root, so the proxy in front of this
# server forwards them unchanged and $request_uri keeps the original path.
# server forwards them unchanged.
PENPOT_PUBLIC_PATH="$(sed -E 's|^[A-Za-z][A-Za-z0-9+.-]*://[^/]*||; s|[?#].*$||' <<< "${PENPOT_PUBLIC_URI:-}")"
PENPOT_PUBLIC_PATH="/${PENPOT_PUBLIC_PATH#/}"
export PENPOT_PUBLIC_PATH="${PENPOT_PUBLIC_PATH%/}/"
# shellcheck disable=SC2016 # literal regex metacharacters
PENPOT_PUBLIC_PATH_REGEX="$(sed -E 's/[][\.*^$(){}+?|]/\\&/g' <<< "$PENPOT_PUBLIC_PATH")"
export PENPOT_PUBLIC_PATH_REGEX
if [ "$PENPOT_PUBLIC_PATH" != "/" ]; then
# shellcheck disable=SC2016 # literal regex metacharacters
_public_path_regex="$(sed -E 's/[][\.*^$(){}+?|]/\\&/g' <<< "$PENPOT_PUBLIC_PATH")"
export PENPOT_PUBLIC_PATH_DIRECTIVES="location = ${PENPOT_PUBLIC_PATH%/} { absolute_redirect off; return 301 ${PENPOT_PUBLIC_PATH}\$is_args\$args; }
rewrite ^${PENPOT_PUBLIC_PATH_REGEX}(.*)\$ /\$1 last;"
rewrite ^${_public_path_regex}(.*)\$ /\$1 last;"
unset _public_path_regex
else
export PENPOT_PUBLIC_PATH_DIRECTIVES=""
fi
@ -81,7 +80,7 @@ envsubst "\$PENPOT_BACKEND_URI,\$PENPOT_EXPORTER_URI,\$PENPOT_HTTP_SERVER_MAX_BO
if [[ $PENPOT_FLAGS == *"enable-admin-console"* ]]; then
export PENPOT_ADMIN_CONSOLE_URI=${PENPOT_ADMIN_CONSOLE_URI:-http://penpot-admin-console:3000}
envsubst "\$PENPOT_ADMIN_CONSOLE_URI,\$PENPOT_PUBLIC_PATH_REGEX" \
envsubst "\$PENPOT_ADMIN_CONSOLE_URI" \
< /tmp/nginx-admin-console-locations.conf.template > /etc/nginx/overrides/server.d/admin-console-locations.conf
else
rm -f /etc/nginx/overrides/server.d/admin-console-locations.conf