Files
FreshRSS/Docker/entrypoint.sh
Cron 09478222ce Docker/OIDC: redirect to a default URL on expired auth state instead of 400-ing (#9143)
## Problem

With OIDC on the official Docker image, interactive SSO logins intermittently return `HTTP 400` at the `/i/oidc/` callback. The failure tracks login duration. `mod_auth_openidc` sets an anti-CSRF state cookie bounded by `OIDCStateTimeout` (default 300 s). If a login through an external IdP takes longer than that (MFA, a slow provider screen, the user stepping away), the cookie is already gone when the callback returns. The image does not set `OIDCDefaultURL`, so the module has no fallback and returns an error instead of restarting the login.

Apache log:

```
oidc_response_proto_state_restore: state has expired
oidc_response_process: invalid authorization response state and
        no default SSO URL is set, sending an error...
→ GET /i/oidc/?code=…&state=… 400
```

This is [documented mod_auth_openidc behaviour](72c9f479c2/auth_openidc.conf (L723-L733)) when `OIDCDefaultURL` is unset. Both `OIDCDefaultURL` and `OIDCStateTimeout` are `RSRC_CONF` (server config only), so the `./FreshRSS/p/i/.htaccess` escape hatch cannot set them and the fix has to live in the image.

Reproduce: log out, start SSO, wait more than 5 minutes on the IdP screen, complete.

## Fix

Add `OIDC_DEFAULT_URL`, wired through the existing `${OIDC_*}` env pattern, defaulting to `/i/` (the index, consistent with `OIDCRedirectURI /i/oidc/`). On an expired or unmatchable state the module now redirects to `/i/`, which is protected and starts a fresh login against the existing IdP session. `OIDCStateTimeout` stays at 300 s; the window is fine, the missing fallback was the bug.

`OIDC_STATE_TIMEOUT` is intentionally not exposed. It can be added the same way if there is a reason to tune the window.

* Docker/OIDC: redirect to a default URL on expired auth state instead of 400-ing

Adds OIDC_DEFAULT_URL (default /i/), wired through the existing ${OIDC_*} env
pattern, so an expired or unmatchable mod_auth_openidc state redirects to the
FreshRSS index and restarts the login instead of returning HTTP 400.

* git commit update

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-07-24 17:55:36 +02:00

110 lines
3.4 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh
ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime
echo "$TZ" >/etc/timezone
find /etc/php*/ -type f -name php.ini -exec sed -i -E \
-e "\\#^;?date.timezone#s#^.*#date.timezone = $TZ#" \
-e "\\#^;?post_max_size#s#^.*#post_max_size = 32M#" \
-e "\\#^;?upload_max_filesize#s#^.*#upload_max_filesize = 32M#" {} \;
while read -r config_path _; do
if [ -f "$config_path" ]; then
APACHE_CONFIG="$config_path"
break
fi
done <<EOF
/etc/apache2/sites-available/FreshRSS.Apache.conf # Debian
/etc/apache2/conf.d/FreshRSS.Apache.conf # Alpine
/etc/httpd/conf/conf.d/FreshRSS.Apache.conf # Arch
EOF
if [ -z "$APACHE_CONFIG" ]; then
echo '❌ Apache configuration file not found!'
exit 11
fi
if [ -n "$LISTEN" ]; then
sed -r -i "\\#^Listen#s#^.*#Listen $LISTEN#" "$APACHE_CONFIG"
fi
if [ -n "$TRUSTED_PROXY" ]; then
if [ "$TRUSTED_PROXY" = "0" ]; then
# Disable RemoteIPHeader and RemoteIPInternalProxy
sed -r -i "/^\s*RemoteIP.*$/s/^/#/" "$APACHE_CONFIG"
else
# Custom list for RemoteIPInternalProxy
sed -r -i "\\#^\s*RemoteIPInternalProxy#s#^.*#\tRemoteIPInternalProxy $TRUSTED_PROXY#" "$APACHE_CONFIG"
fi
fi
if [ -n "$OIDC_ENABLED" ] && [ "$OIDC_ENABLED" -ne 0 ]; then
# Default values
export OIDC_SESSION_INACTIVITY_TIMEOUT="${OIDC_SESSION_INACTIVITY_TIMEOUT:-300}"
export OIDC_SESSION_MAX_DURATION="${OIDC_SESSION_MAX_DURATION:-27200}"
export OIDC_SESSION_TYPE="${OIDC_SESSION_TYPE:-server-cache}"
export OIDC_DEFAULT_URL="${OIDC_DEFAULT_URL:-/i/}"
# Debian
(which a2enmod >/dev/null && a2enmod -q auth_openidc) ||
# Alpine
(mv /etc/apache2/conf.d/mod-auth-openidc.conf.bak /etc/apache2/conf.d/mod-auth-openidc.conf && echo 'Enabling module auth_openidc.') ||
# Misc.
(echo '❌ Failed to enable auth_openidc module!' && exit 12)
if [ -n "$OIDC_SCOPES" ]; then
# Compatibility with : as separator instead of space
OIDC_SCOPES=$(echo "$OIDC_SCOPES" | tr ':' ' ')
export OIDC_SCOPES
fi
fi
if [ -n "$CRON_MIN" ]; then
awk -v RS='\0' '!/^(FRESHRSS_INSTALL|FRESHRSS_USER|HOME|PATH|PWD|SHLVL|TERM|_)=/ {gsub("\047", "\047\\\047\047"); print "export \047" $0 "\047"}' /proc/self/environ >/var/www/FreshRSS/Docker/env.txt
sed </etc/crontab.freshrss.default \
-r "s#^[^ ]+ #$CRON_MIN #" | crontab -
fi
./cli/access-permissions.sh --only-userdirs
php -f ./cli/prepare.php >/dev/null
if [ -n "$FRESHRSS_INSTALL" ]; then
# shellcheck disable=SC2046
php -f ./cli/do-install.php -- \
$(eval "echo \"$FRESHRSS_INSTALL\"" | sed -r 's/[\r\n]+/\n/g' | paste -s -)
EXITCODE=$?
if [ $EXITCODE -eq 3 ]; then
echo ' FreshRSS already installed; no change performed.'
elif [ $EXITCODE -eq 0 ]; then
echo '✅ FreshRSS successfully installed.'
else
echo '❌ FreshRSS error during installation!'
exit $EXITCODE
fi
fi
if [ -n "$FRESHRSS_USER" ]; then
# shellcheck disable=SC2046
php -f ./cli/create-user.php -- \
$(eval "echo \"$FRESHRSS_USER\"" | sed -r 's/[\r\n]+/\n/g' | paste -s -)
EXITCODE=$?
if [ $EXITCODE -eq 3 ]; then
echo ' FreshRSS user already exists; no change performed.'
elif [ $EXITCODE -eq 0 ]; then
echo '✅ FreshRSS user successfully created.'
./cli/list-users.php | xargs -n1 ./cli/actualize-user.php --user
else
echo '❌ FreshRSS error during the creation of a user!'
exit $EXITCODE
fi
fi
# Fix permissions of data added by prepare.php as well as a potential
# installation/user setup
./cli/access-permissions.sh --only-userdirs
exec "$@"